Skip to content

Instantly share code, notes, and snippets.

@jcurry
Created December 22, 2015 22:47
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jcurry/ebb20c6665ba249bce55 to your computer and use it in GitHub Desktop.
Save jcurry/ebb20c6665ba249bce55 to your computer and use it in GitHub Desktop.
JSON API code to get Zenoss events
#!/usr/bin/env python
# Zenoss-4.x JSON API Example (python)
#
# To quickly explore, execute 'python -i get_events.py
#
# >>> z = getEventsWithJSON()
# >>> events = z.get_events()
# etc.
import json
import urllib
import urllib2
from optparse import OptionParser
import pprint
#ZENOSS_INSTANCE = 'http://ZENOSS-SERVER:8080'
# Change the next line(s) to suit your environment
#
#ZENOSS_INSTANCE = 'http://zen42.class.example.org:8080'
ZENOSS_INSTANCE = 'https://zen42.class.example.org'
ZENOSS_USERNAME = 'admin'
ZENOSS_PASSWORD = 'zenoss'
ROUTERS = { 'MessagingRouter': 'messaging',
'EventsRouter': 'evconsole',
'ProcessRouter': 'process',
'ServiceRouter': 'service',
'DeviceRouter': 'device',
'NetworkRouter': 'network',
'TemplateRouter': 'template',
'DetailNavRouter': 'detailnav',
'ReportRouter': 'report',
'MibRouter': 'mib',
'ZenPackRouter': 'zenpack' }
class getEventsWithJSON():
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())
def get_events(self, filter={}, sort='severity', dir='DESC', arch=False, lim=1000):
""" Use EventsRouter action (Class) and query method found
in JSON API docs on Zenoss website:
query(self, limit=0, start=0, sort='lastTime', dir='desc', params=None,
archive=False, uid=None, detailFormat=False)
Parameters:
limit (integer) - (optional) Max index of events to retrieve (default: 0)
start (integer) - (optional) Min index of events to retrieve (default: 0)
sort (string) - (optional) Key on which to sort the return results (default: 'lastTime')
dir (string) - (optional) Sort order; can be either 'ASC' or 'DESC' (default: 'DESC')
params (dictionary) - (optional) Key-value pair of filters for this search. (default: None)
params are the filters to the query method and can be found in the _buildFilter method.
severity = params.get('severity'),
status = [i for i in params.get('eventState', [])],
event_class = filter(None, [params.get('eventClass')]),
Note that the time vaues can be ranges where a valid range would be
'2012-09-07 07:57:33/2012-11-22 17:57:33'
first_seen = params.get('firstTime') and self._timeRange(params.get('firstTime')),
last_seen = params.get('lastTime') and self._timeRange(params.get('lastTime')),
status_change = params.get('stateChange') and self._timeRange(params.get('stateChange')),
uuid = filterEventUuids,
count_range = params.get('count'),
element_title = params.get('device'),
element_sub_title = params.get('component'),
event_summary = params.get('summary'),
current_user_name = params.get('ownerid'),
agent = params.get('agent'),
monitor = params.get('monitor'),
fingerprint = params.get('dedupid'),
tags = params.get('tags'),
details = details,
archive (boolean) - (optional) True to search the event history table instead of active events (default: False)
uid (string) - (optional) Context for the query (default: None)
Returns: dictionary
Properties:
events: ([dictionary]) List of objects representing events
totalCount: (integer) Total count of events returned
asof: (float) Current time
"""
#data = dict(start=0, limit=1000)
#data = dict(start=0, limit=1000)
data = dict(start=0, archive=arch, limit=lim)
if sort: data['sort'] = sort
if dir: data['dir'] = dir
data['params'] = filter
#print 'data[params] is %s \n' % (data['params'])
#print 'data is %s \n' % (data)
return self._router_request('EventsRouter', 'query', [data])['result']
def printEvents(out):
for e in out['events']:
#pp.pprint(e)
outState=e['eventState']
if e['DeviceClass']:
outDeviceClass=e['DeviceClass'][0]['name']
else: outDeviceClass=[]
outcount=e['count']
outdevice=e['device']['text']
if e['Location']:
outLocation=e['Location'][0]['name']
else: outLocation=[]
outSystems=[]
for pos,val in enumerate(e['Systems']):
sy=str(e['Systems'][pos]['name'])
outSystems.append(sy)
outseverity=e['severity']
outfirstTime=e['firstTime']
outlastTime=e['lastTime']
outsummary=e['summary']
print '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s' % (outState, outDeviceClass, outcount, outdevice, outLocation, outSystems, outseverity, outfirstTime, outlastTime, outsummary)
if __name__ == "__main__":
usage = 'python %prog --severity=severity --eventState=eventState --device=device --eventClass=eventClass --component=component --agent=agent --monitor=monitor --count=count --lastTime=lastTime --firstTime=firstTime --stateChange=stateChange --sort=lastTime --dir=DESC --archive=archive --limit=limit'
parser = OptionParser(usage)
parser.add_option("--severity", dest='severity',
help='severity comma-separated numeric values eg. severity=5,4 for Critical and Error')
parser.add_option("--eventState", dest='eventState', default='0,1',
help='eventState comma-separated numeric values eg. eventState=0,1 for New and Ack')
parser.add_option("--device", dest='device',
help='eg. --device=\'zen42.class.example.org\'')
parser.add_option("--eventClass", dest='eventClass',
help='eg. --eventClass=\'/Skills\'')
parser.add_option("--component", dest='component',
help='eg. --component=\'Test Component\'')
parser.add_option("--agent", dest='agent',
help='eg. --agent=\'zensyslog\'')
parser.add_option("--monitor", dest='monitor',
help='eg. --monitor=\'localhost\'')
parser.add_option("--count", dest='count',
help='numeric value eg. --count=3 or range --count 3,30')
parser.add_option("--lastTime", dest='lastTime',
help='eg. for a range separate start & end with / --lastTime=\'2012-09-07 07:57:33/2012-11-22 17:57:33\'')
parser.add_option("--firstTime", dest='firstTime',
help='eg. --firstTime=\'2012-11-22 17:57:33\'')
parser.add_option("--stateChange", dest='stateChange',
help='eg. --stateChange=\'2012-11-22 17:57:33\'')
parser.add_option("--sort", dest='sort', default='lastTime',
help='the key to sort on eg. --sort=\'lastTime\'')
parser.add_option("--dir", dest='dir', default='DESC',
help='the direction to sort eg. --dir=\'ASC\' or --dir=\'DESC\'')
parser.add_option("--archive", dest='archive', default=False,
help='include archived events as well as summary events. Default is False. eg. --archive=True ')
parser.add_option("--limit", dest='limit', default=1000,
help='Number of events to return. Default is 1000 for summary and 1000 for archive (if specified). Eg. --limit=500 ')
(options, args) = parser.parse_args()
# options is an object - we want the dictionary value of it
# Some of the options need a little munging...
option_dict = vars(options)
if option_dict['severity']:
option_dict['severity'] = option_dict['severity'].split(',')
if option_dict['eventState']:
option_dict['eventState'] = option_dict['eventState'].split(',')
# count can either be a number or a range (in either list or tuple format)
# (see $ZENHOME/Products/Zuul/facades/zepfacade.py - createEventFilter method )
# but if this method gets a list it assumes there are 2 elements to the list.
# We may get a list with a single value so convert it to a number and the
# createEventFilter method can cope
if option_dict['count']:
option_dict['count'] = option_dict['count'].split(',')
if len(option_dict['count']) == 1:
option_dict['count'] = int(option_dict['count'][0])
# option_dict includes the sort, dir, limit and archive keys (as we have defaulted them in optparse)
# These are not part of the filter string so we need to pop them out of the dictionary
# to use separately.
s = option_dict.pop('sort')
d = option_dict.pop('dir')
if option_dict['archive'] == 'True':
ar = True
else:
ar = False
a = option_dict.pop('archive')
l = option_dict.pop('limit')
# Need to check these keys for sanity
# and provide sensible defaults otherwise
dirlist=['ASC','DESC']
if not d in dirlist:
d='DESC'
sortlist = ['severity', 'eventState', 'eventClass', 'firstTime', 'lastTime',
'stateChange', 'count', 'device', 'component', 'agent', 'monitor']
if not s in sortlist:
s='lastTime'
#if type(a) != bool:
# a = False
if type(l) != str:
l = 1000
else:
l=int(l)
#print 'options is %s \n' % (options)
#print 'option_dict is %s \n' % (option_dict)
events = getEventsWithJSON()
#filter['evid'] = '000c29d9-f87b-8389-11e2-347cddf7a720'
pp = pprint.PrettyPrinter(indent=4)
fields = ['eventState', 'DeviceClass', 'count', 'device', 'Location', 'Systems', 'severity', 'firstTime', 'lastTime', 'summary']
print 'Summary events \n'
print 'eventState, DeviceClass, count, device, Location, Systems, severity, firstTime, lastTime, summary \n'
sumout = events.get_events(filter=option_dict, sort=s, dir=d, arch=False, lim=l)
#print 'sumout is %s \n' % (sumout)
#print 'Length of sumout is %s\n' % (len(sumout['events']))
printEvents(sumout)
if l < sumout['totalCount']:
print '\n totalCount in Summary table is %d of which %d were selected as requested. asof is %s' % (sumout['totalCount'], l, sumout['asof'])
sumTotal = l
else:
print '\n totalCount in Summary table is %d and asof is %s' % (sumout['totalCount'], sumout['asof'])
sumTotal = sumout['totalCount']
if ar: #want archive events as well as summary events
print '\n\nArchive events \n'
print 'eventState, DeviceClass, count, device, Location, Systems, severity, firstTime, lastTime, summary \n'
archout = events.get_events(filter=option_dict, sort=s, dir=d, arch=True, lim=l)
#print 'Length of archout is %s\n' % (len(archout['events']))
printEvents(archout)
if l < archout['totalCount']:
print '\n totalCount in Archive table is %d of which %d were selected as requested. asof is %s' % (archout['totalCount'], l, archout['asof'])
print '\n\n Grand total of selected events is %d \n' % (l + sumTotal)
else:
print '\n totalCount in Archive table is %d and asof is %s' % (archout['totalCount'], archout['asof'])
print '\n\n Grand total of selected events is %d \n' % (sumTotal + archout['totalCount'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment