Skip to content

Instantly share code, notes, and snippets.

@hackeys
Created August 28, 2013 16:53
Show Gist options
  • Save hackeys/6368351 to your computer and use it in GitHub Desktop.
Save hackeys/6368351 to your computer and use it in GitHub Desktop.
AddingBulkDevices
#!/usr/bin/env python
#
# Use the Zenoss JSON API to add a list of hosts
#
import re, string
import getopt, sys
import os, pwd
import time
import urllib
import urllib2
import json
import getpass
debug=1
# Zenoss connection info, including username and password
ZENOSS_INSTANCE = 'http://zenoss.example.com:8080'
ZENOSS_USERNAME = pwd.getpwuid(os.getuid()).pw_name
ZENOSS_PASSWORD = getpass.getpass('Password: ')
ROUTERS = { 'MessagingRouter': 'messaging',
'EventsRouter': 'evconsole',
'ProcessRouter': 'process',
'ServiceRouter': 'service',
'DeviceRouter': 'device',
'NetworkRouter': 'network',
'TemplateRouter': 'template',
'DetailNavRouter': 'detailnav',
'ReportRouter': 'report',
'JobsRouter': 'jobs',
'MibRouter': 'mib',
'ZenPackRouter': 'zenpack' }
class ZenossAPI():
def __init__(self, debug=False):
"""
Initialize the API connection, log in, and store authentication cookie
"""
# Use the HTTPCookieProcessor as urllib2 does not save cookies by default
self.urlOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
if debug: self.urlOpener.add_handler(urllib2.HTTPHandler(debuglevel=1))
self.reqCount = 1
# Contruct POST params and submit login.
loginParams = urllib.urlencode(dict(
__ac_name = ZENOSS_USERNAME,
__ac_password = ZENOSS_PASSWORD,
submitted = 'true',
came_from = ZENOSS_INSTANCE + '/zport/dmd'))
self.urlOpener.open(ZENOSS_INSTANCE + '/zport/acl_users/cookieAuthHelper/login',
loginParams)
def _router_request(self, router, method, data=[]):
if router not in ROUTERS:
raise Exception('Router "' + router + '" not available.')
# Contruct a standard URL request for API calls
req = urllib2.Request(ZENOSS_INSTANCE + '/zport/dmd/' +
ROUTERS[router] + '_router')
# NOTE: Content-type MUST be set to 'application/json' for these requests
req.add_header('Content-type', 'application/json; charset=utf-8')
# Convert the request parameters into JSON
reqData = json.dumps([dict(
action=router,
method=method,
data=data,
type='rpc',
tid=self.reqCount)])
# Increment the request count ('tid'). More important if sending multiple
# calls in a single request
self.reqCount += 1
# Submit the request and convert the returned JSON to objects
return json.loads(self.urlOpener.open(req, reqData).read())
# Get devices from zenoss in the specified device class
def get_devices(self, deviceClass='/zport/dmd/Devices', limit=50, start=0, params=None):
return self._router_request('DeviceRouter', 'getDevices',
data=[{'uid': deviceClass,
'params': params,
'limit': limit,
'start': start}])['result']
# Add a device to Zenoss
def add_device(self, deviceName, deviceClass='/Server/Linux', snmpCommunity='public', productionState=450, comments=''):
data = dict(deviceName=deviceName, deviceClass=deviceClass, snmpCommunity=snmpCommunity, productionState=productionState, comments=comments, model=True)
# Use the RWC collector for pdi.com hosts
if 'pdi.com' in deviceName:
data['collector'] = 'cia.pdi.com'
return self._router_request('DeviceRouter', 'addDevice', [data])
# Get details about the specified job
def job_detail(self, jobId):
data = dict(jobid=jobId['uuid'])
return self._router_request('JobsRouter', 'detail', [data])
def usage(message=''):
if message != '':
print message
print """Usage: zenoss_addhost -h|--host= [-c|--class=] [-C|--comments=] [-s|--state=] [--comments=] """
sys.exit(3)
if __name__ == '__main__':
z = ZenossAPI() # Create API instance
# Defaults
deviceName = None
deviceClass = '/Server/Linux'
snmpCommunity = 'public'
productionState = 450
comments = ''
# Parse command line
try:
options, args = getopt.getopt(sys.argv[1:],
"h:c:C:s:",
["host=", "class=", "community=", "state=", "comments="],
)
except getopt.GetoptError, err:
usage(str(err))
sys.exit(3)
for o, a in options:
if o in ("-h", "--host"):
deviceName = a
elif o in ("-c", "--class"):
deviceClass = a
elif o in ("-C", "--comments"):
comments = a
elif o in ("-s", "--state"):
productionState = int(a)
elif o in ("--community"):
snmpCommunity = a
if deviceName == None:
usage("hostname may not be null!")
# Add the device
jobId = z.add_device(deviceName=deviceName, deviceClass=deviceClass, snmpCommunity=snmpCommunity, productionState=productionState, comments=comments)
if (debug):
print jobId
if jobId['result']['success'] != True:
msg = jobId['result']['msg']
idx = jobId['result']['msg'].find("<") # attempt to strip URLs
if idx >= 0:
msg = jobId['result']['msg'][:(idx-1)]
print "ERROR: %s" % msg
sys.exit(1)
# Loop until we get a job status back
jobUuid = jobId['result']['new_jobs'][0]
jobComplete = False
count = 0
while not jobComplete:
time.sleep(5)
jobStatus = z.job_detail(jobUuid)
if (debug):
print jobStatus
count += 1
if count > 10:
jobComplete = True
if 'finished with' in jobStatus['result']['content'][len(jobStatus['result']['content'])-1]:
jobComplete = True
msg=jobStatus['result']['content'][len(jobStatus['result']['content'])-1]
if 'result 0' in msg:
sys.exit(0)
else:
print "ERROR: %s" % msg
print "see %s on the Zenoss server for full details" % jobStatus['resultt']['logfile']
sys.exit(1)
@lunne
Copy link

lunne commented Nov 18, 2014

Hi,
Have you any idéa how you add a device to a deviceClass that does not exist?
Cant find in the API documentation how to create a deviceclass.

@theetallest
Copy link

I am hoping you are still around. The Script is just what i am looking for. I consider my a fairly bright person but where do I Put my username in your script or I am using the URL To pass that info along.??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment