diff --git a/README.md b/README.md index f3756a3..17ad4a0 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,33 @@ master_service_checks += opsview_master['service_checks'] for template in opsview_master['host_templates']: template_detail = client.hosttemplates.find_one(template['name']) master_service_checks += template_detail['service_checks'] + +for status of a host and its service checks + service_status = client.status.service.find_one(hostname=devicename) + +for status of all unhandled hosts + service_status = list(client.status.service.find(host_filter='unhandled')) + +for all unhandled checks + unhandled_checks = list(client.status.service.find(filter= 'unhandled')) + +for adding an acknowledgement to the unhandled event for Opsview on check Connectivity - LAN + acknowldege_details = client.acknowledge_event(params={'svc.hostname': 'Opsview', 'svc.servicename': 'Connectivity - LAN'} , data={'notify': str(int(bool(True))), 'sticky': str(int(bool(True))), 'comment': 'Acknowledged and actioned by user'}) + +for adding an acknowldegement to the unhandled host event for Opsview + acknowldege_details = client.acknowledge_event(params={'hst.hostname': 'Opsview'}, data={'notify': str(int(bool(True))), 'sticky': str(int(bool(True))), 'comment': 'Acknowledged and actioned by user'}) + +for adding an acknowldegement to all unhandled host and service events for Opsview + acknowldege_details = client.acknowledge_event(params={'svc.hostname': 'Opsview'}, data={'notify': str(int(bool(True))), 'sticky': str(int(bool(True))), 'comment': 'Acknowledged and actioned by user'}) + +for deleting the acknowledgement for Opsview against check Connectivity - LAN + acknowledge_details = client.acknowledge_delete(params={'svc.hostname': 'Opsview', 'svc.servicename': 'Connectivity - LAN'}) + +for deleting the acknowledgement against a host event + acknowledge_details = client.acknowledge_delete(params={'hst.hostname': 'Opsview'}) + +for deleting all the acknowledgements against service checks for a host + acknowledge_details = client.acknowledge_delete(params={'svc.hostname': 'Opsview'}) ``` diff --git a/pyopsview/resource.py b/pyopsview/resource.py index dda1d59..5976c37 100644 --- a/pyopsview/resource.py +++ b/pyopsview/resource.py @@ -134,3 +134,99 @@ def list(self, search=None, **kwds): params['json_filter'] = json.dumps(search) return self._list(self.resource_uri, params=params) + + + +class OpsviewStateManager(object): + """Base class for Opsview resource managers""" + + # Name of the schema (e.g. service) + schema_name = None + + def __init__(self, http_client): + self._client = http_client + self._schema = http_client._load_schema('status', self.schema_name) + + def _encode(self, data): + return self._schema.encode(data) + + def _decode(self, data): + return self._schema.decode(data) + + def _get(self, url, params=None): + body = self._client.get(url, params=params) + return self._decode(body['object']) + + def _list(self, url, params=None): + # Make a copy of params so we don't start messing with the caller's + # parameters + opts = params.copy() + + body = self._client.get(url, params=opts) + print(body['summary']) + print(body['list']) + if 'summary' in body: + if 'totalpages' in body['summary']: + total_pages = int(body['summary']['totalpages']) + first_page = int(body['summary']['page']) + else: + total_pages = 1 + first_page = 1 + else: + total_pages = 1 + first_page = 1 + + for page_number in range(first_page, total_pages + 1): + # We've already got data from the first request + if page_number > first_page: + opts['page'] = page_number + body = self._client.get(url, params=opts) + + for obj in body['list']: + if obj: + yield self._decode(obj) + + +class OpsviewStatusStateManager(OpsviewStateManager): + + # URI for the resource (e.g. /status/service) + resource_uri = None + + def _get_parameters(self): + fields = self._schema.fields + keyword_arguments = [] + required_arguments = [] + + for f_name, field in six.iteritems(fields): + if field['default'] is not None or not field['required']: + keyword_arguments.append(field.get('altname', f_name)) + else: + required_arguments.append(field.get('altname', f_name)) + + return (required_arguments, keyword_arguments) + + def find(self, params=None, **kwds): + query = {'%s' % k: v for (k, v) in six.iteritems(kwds)} + if params: + opts = params.copy() + else: + opts = {} + + opts.update(query) + + return self.list(**opts) + + def find_one(self, params=None, **kwds): + try: + return next(self.find(params=params, **kwds)) + except StopIteration: + return None + + def list(self, search=None, **kwds): + params = kwds + if search: + params['json_filter'] = json.dumps(search) + + + return self._list(self.resource_uri, params=params) + diff --git a/pyopsview/v2/client.py b/pyopsview/v2/client.py index ea7607c..0b869ab 100644 --- a/pyopsview/v2/client.py +++ b/pyopsview/v2/client.py @@ -11,6 +11,7 @@ from pyopsview import schema from pyopsview.utils import json from pyopsview.v2.config import ConfigClient +from pyopsview.v2.status import StatusClient class Client(object): @@ -49,6 +50,7 @@ def __init__(self, endpoint, username=None, password=None, token=None, def _init_clients(self): self.config = ConfigClient(self) + self.status = StatusClient(self) @property def version(self): @@ -131,3 +133,9 @@ def server_info(self): def user_info(self): return self.get('/user') + + def acknowledge_event(self, **kwds): + return self.post('/acknowledge',**kwds) + + def acknowledge_delete(self, **kwds): + return self.delete('/acknowledge', **kwds) diff --git a/pyopsview/v2/schemas/6.2/status/service.json b/pyopsview/v2/schemas/6.2/status/service.json new file mode 100644 index 0000000..07e5ea4 --- /dev/null +++ b/pyopsview/v2/schemas/6.2/status/service.json @@ -0,0 +1,111 @@ +{ + "definitions": { + "reference": { + "properties": { + "markdown": { + "type": "string" + }, + "acknowledged": { + "type": "string" + }, + "state": { + "type": "string" + }, + "unhandled": { + "type": "string" + }, + "perfdata_available": { + "type": "string" + }, + "max_check_attempts": { + "type": "string" + }, + "state_duration": { + "type": "string" + }, + "name": { + "required": true, + "type": "string" + }, + "state_type": { + "type": "string" + }, + "acknowledged_author": { + "type": "string" + }, + "output": { + "type": "string" + }, + "current_check_attempt": { + "type": "string" + }, + "service_object_id": { + "type": "string" + }, + "acknowledged_comment": { + "type": "string" + }, + "downtime": { + "type": "string" + }, + "last_check": { + "type": "string" + } + }, + "type": "object" + } + }, + "properties": { + "icon": { + "type": "string" + }, + "state": { + "type": "string" + }, + "unhandled": { + "type": "string" + }, + "max_check_attempts": { + "type": "string" + }, + "num_interfaces": { + "type": "string" + }, + "state_duration": { + "type": "string" + }, + "services": { + "default": [], + "items": { + "$ref": "#/definitions/reference" + }, + "type": "array" + }, + "name": { + "required": true, + "type": "string" + }, + "state_type": { + "type": "string" + }, + "current_check_attempt": { + "type": "string" + }, + "output": { + "type": "string" + }, + "num_services": { + "type": "string" + }, + "downtime": { + "type": "string" + }, + "last_check": { + "type": "string" + }, + "alias": { + "type": "string" + } + }, + "type": "object" +} diff --git a/pyopsview/v2/status/__init__.py b/pyopsview/v2/status/__init__.py new file mode 100644 index 0000000..48a9592 --- /dev/null +++ b/pyopsview/v2/status/__init__.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python + +from pyopsview.v2.status.client import StatusClient diff --git a/pyopsview/v2/status/client.py b/pyopsview/v2/status/client.py new file mode 100644 index 0000000..c7f5255 --- /dev/null +++ b/pyopsview/v2/status/client.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +from pyopsview.v2.status.service import ServiceManager + + +class StatusClient(object): + + def __init__(self, client): + self.client = client + self._init_managers() + + def _init_managers(self): + self.service = ServiceManager(self.client) diff --git a/pyopsview/v2/status/service.py b/pyopsview/v2/status/service.py new file mode 100644 index 0000000..a7b6cb8 --- /dev/null +++ b/pyopsview/v2/status/service.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +from pyopsview.resource import OpsviewStatusStateManager + + +class ServiceManager(OpsviewStatusStateManager): + resource_uri = '/status/service' + schema_name = 'service'