commit c07913b65f2f9aa5d864520dfe61ffde91f9bfe4 Author: Dustin Frisch Date: Tue Jan 28 16:29:44 2020 +0100 Initial import diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a09c56d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.idea diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..1eee96a --- /dev/null +++ b/Pipfile @@ -0,0 +1,14 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +requests = "*" +click = "*" +munch = "*" + +[requires] +python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..52c8736 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,80 @@ +{ + "_meta": { + "hash": { + "sha256": "05c89642e212fe9daf6d32672e810f0effe4bb3b51450c47d54c491cdbc130a1" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.8" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "certifi": { + "hashes": [ + "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", + "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" + ], + "version": "==2019.11.28" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "index": "pypi", + "version": "==7.0" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, + "munch": { + "hashes": [ + "sha256:2d735f6f24d4dba3417fa448cae40c6e896ec1fdab6cdb5e6510999758a4dbd2", + "sha256:6f44af89a2ce4ed04ff8de41f70b226b984db10a91dcc7b9ac2efc1c77022fdd" + ], + "index": "pypi", + "version": "==2.5.0" + }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, + "six": { + "hashes": [ + "sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a", + "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c" + ], + "version": "==1.14.0" + }, + "urllib3": { + "hashes": [ + "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", + "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" + ], + "version": "==1.25.8" + } + }, + "develop": {} +} diff --git a/main.py b/main.py new file mode 100644 index 0000000..e72e38e --- /dev/null +++ b/main.py @@ -0,0 +1,84 @@ +import click +import requests +import json + +from xml.etree import ElementTree + + +def search_services(base_url, username, password, service): + ifservices = requests.get(base_url + '/api/v2/ifservices', + params={'limit': 0, + '_s': 'serviceType.name==' + service}, + headers={'Accept': 'application/xml'}, + auth=(username, password)) + ifservices.raise_for_status() + ifservices = ElementTree.fromstring(ifservices.content) + + for service in ifservices.iter('service'): + ipiface_id = service.find('ipInterfaceId').text + + node = requests.get(base_url + '/api/v2/nodes', + params={'limit': 0, + '_s': 'ipInterface.id==' + ipiface_id}, + headers={'Accept': 'application/xml'}, + auth=(username, password)) + node.raise_for_status() + node = ElementTree.fromstring(node.content).find('node') + + node_id = node.get('id') + node_label = node.get('label') + + ipiface = requests.get(base_url + '/api/v2/nodes/' + node_id + '/ipinterfaces', + params={'limit': 0, + '_s': 'id==' + ipiface_id}, + headers={'Accept': 'application/xml'}, + auth=(username, password)) + ipiface.raise_for_status() + ipiface = ElementTree.fromstring(ipiface.content).find('ipInterface') + + ipiface_address = ipiface.find('ipAddress').text + + yield node_label, node_id, ipiface_address + + +@click.command() +@click.option('--base-url', default='http://localhost:8980/opennms') +@click.option('--username', default='admin') +@click.option('--password', default='admin') +@click.option('--service', default='HTTP') +@click.option('--bs-id', default=0) +def main(base_url, username, password, service, bs_id): + # Strip trailing slash from base URL + if base_url.endswith('/'): + base_url = base_url[:-1] + + rkeys = ((label, 'uei.opennms.org/nodes/nodeLostService::%s:%s:%s' % (node, addr, service)) + for (label, node, addr) + in search_services(base_url, username, password, service)) + + bs = {'name': service, + 'reduce-function': {'type': 'HighestSeverity'}, + 'reduction-key-edges': [{ + 'weight': 1, + 'map-function': {'type': 'Identity'}, + 'reduction-key': rkey, + } for (label, rkey) in rkeys]} + + bs = json.dumps(bs) + + r = requests.put(base_url + '/api/v2/business-services/' + str(bs_id), + headers={'Accept': 'application/json', + 'Content-Type': 'application/json'}, + auth=(username, password), + data=bs) + r.raise_for_status() + + r = requests.post(base_url + '/api/v2/business-services/daemon/reload', + headers={'Accept': 'application/json', + 'Content-Type': 'application/json'}, + auth=(username, password)) + r.raise_for_status() + + +if __name__ == '__main__': + main()