From 9b2e4cfd282b323684a4d10ea38cae76c5472879 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 9 Nov 2015 12:16:02 +0100 Subject: [PATCH] Add contrib/discover-api.py --- contrib/discover-api.py | 148 ++++++++++++++++++++++++++++++++++++++++ contrib/discover.py | 4 +- 2 files changed, 150 insertions(+), 2 deletions(-) create mode 100755 contrib/discover-api.py diff --git a/contrib/discover-api.py b/contrib/discover-api.py new file mode 100755 index 000000000..b990a8d8a --- /dev/null +++ b/contrib/discover-api.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python +#/****************************************************************************** +# * Icinga 2 * +# * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * +# * * +# * This program is free software; you can redistribute it and/or * +# * modify it under the terms of the GNU General Public License * +# * as published by the Free Software Foundation; either version 2 * +# * of the License, or (at your option) any later version. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU General Public License for more details. * +# * * +# * You should have received a copy of the GNU General Public License * +# * along with this program; if not, write to the Free Software Foundation * +# * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * +# ******************************************************************************/ + +import sys +import subprocess +import socket +import urlparse +import requests +import json +from xml.dom.minidom import parse + +api_url = "https://localhost:5665/" +api_user = "root" +api_password = "root" + +if len(sys.argv) < 2: + print "Syntax: %s [ ...]" % (sys.argv[0]) + sys.exit(1) + +tcp_service_commands = { + 'ssh': 'ssh', + 'http': 'http', + 'smtp': 'smtp', + 'ssmtp': 'ssmtp' +} + +udp_service_commands = { + 'ntp': 'ntp_time', + 'snmp': 'snmp-uptime' +} + +hosts = {} + +def process_host(host_element): + global hosts + + status = "down" + + for status_element in host_element.getElementsByTagName("status"): + status = status_element.getAttribute("state") + + if status != "up": + return + + for address_element in host_element.getElementsByTagName("address"): + if not address_element.getAttribute("addrtype") in [ "ipv4", "ipv6" ]: + continue + + address = address_element.getAttribute("addr") + break + + name = address + + for hostname_element in host_element.getElementsByTagName("hostname"): + name = hostname_element.getAttribute("name") + + try: + services = hosts[name]["services"] + except: + services = {} + + for port_element in host_element.getElementsByTagName("port"): + state = "closed" + + for state_element in port_element.getElementsByTagName("state"): + state = state_element.getAttribute("state") + + if state != "open": + continue + + port = int(port_element.getAttribute("portid")) + protocol = port_element.getAttribute("protocol") + + try: + serv = socket.getservbyport(port, protocol) + except: + serv = str(port) + + try: + if protocol == "tcp": + command = tcp_service_commands[serv] + elif protocol == "udp": + command = udp_service_commands[serv] + else: + raise "Unknown protocol." + except: + command = protocol + + if command == "udp": + continue + + services[serv] = { "command": command, "port": port } + + hosts[name] = { "name": name, "address": address, "services": services } + +def create_host(host): + global api_url, api_user, api_password + + req = { + "templates": [ "discovered-host" ], + "attrs": { + "address": host["address"] + } + } + + headers = {"Accept": "application/json"} + url = urlparse.urljoin(api_url, "v1/objects/hosts/%s" % (host["name"])) + requests.put(url, headers=headers, auth=(api_user, api_password), data=json.dumps(req), verify=False) + + for serv, service in host["services"].iteritems(): + req = { + "templates": [ "discovered-service" ], + "attrs": { + "vars.%s_port" % (service["command"]): service["port"], + "check_command": service["command"], + } + } + + headers = {"Accept": "application/json"} + url = urlparse.urljoin(api_url, "v1/objects/services/%s!%s" % (host["name"], serv)) + requests.put(url, headers=headers, auth=(api_user, api_password), data=json.dumps(req), verify=False) + +for arg in sys.argv[1:]: + # Expects XML output from 'nmap -oX' + dom = parse(arg) + + for host in dom.getElementsByTagName("host"): + process_host(host) + +for host in hosts.values(): + create_host(host) diff --git a/contrib/discover.py b/contrib/discover.py index b6448bce4..802d11f29 100755 --- a/contrib/discover.py +++ b/contrib/discover.py @@ -1,5 +1,4 @@ #!/usr/bin/env python - #/****************************************************************************** # * Icinga 2 * # * Copyright (C) 2012-2015 Icinga Development Team (http://www.icinga.org) * @@ -114,9 +113,10 @@ def print_host(host): print "" for serv, service in host["services"].iteritems(): - print "apply Service \"%s\" {" % (serv) + print "object Service \"%s\" {" % (serv) print "\timport \"discovered-service\"," print "" + print "\thost_name = \"%s\"" % (host["name"]) print "\tcheck_command = \"%s\"," % (service["command"]) print "" print "\tvars.port = %s" % (service["port"])