]> granicus.if.org Git - icinga2/blob - contrib/discover-api.py
Merge pull request #6731 from Icinga/bugfix/doc-comment
[icinga2] / contrib / discover-api.py
1 #!/usr/bin/env python
2 # Icinga 2
3 # Copyright (C) 2012-2018 Icinga Development Team (https://icinga.com/)
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation
17 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 import sys
20 import subprocess
21 import socket
22 import urlparse
23 import requests
24 import json
25 from xml.dom.minidom import parse
26
27 api_url = "https://localhost:5665/"
28 api_user = "root"
29 api_password = "root"
30
31 if len(sys.argv) < 2:
32     print "Syntax: %s <xml-file> [<xml-file> ...]" % (sys.argv[0])
33     sys.exit(1)
34
35 tcp_service_commands = {
36   'ssh': 'ssh',
37   'http': 'http',
38   'smtp': 'smtp',
39   'ssmtp': 'ssmtp'
40 }
41
42 udp_service_commands = {
43   'ntp': 'ntp_time',
44   'snmp': 'snmp-uptime'
45 }
46
47 hosts = {}
48
49 def process_host(host_element):
50     global hosts
51
52     status = "down"
53
54     for status_element in host_element.getElementsByTagName("status"):
55         status = status_element.getAttribute("state")
56
57     if status != "up":
58         return
59
60     for address_element in host_element.getElementsByTagName("address"):
61         if not address_element.getAttribute("addrtype") in [ "ipv4", "ipv6" ]:
62             continue
63
64         address = address_element.getAttribute("addr")
65         break
66
67     name = address
68
69     for hostname_element in host_element.getElementsByTagName("hostname"):
70         name = hostname_element.getAttribute("name")
71
72     try:
73         services = hosts[name]["services"]
74     except:
75         services = {}
76
77     for port_element in host_element.getElementsByTagName("port"):
78         state = "closed"
79
80         for state_element in port_element.getElementsByTagName("state"):
81             state = state_element.getAttribute("state")
82
83         if state != "open":
84             continue
85
86         port = int(port_element.getAttribute("portid"))
87         protocol = port_element.getAttribute("protocol")
88
89         try:
90             serv = socket.getservbyport(port, protocol)
91         except:
92             serv = str(port)
93
94         try:
95             if protocol == "tcp":
96                 command = tcp_service_commands[serv]
97             elif protocol == "udp":
98                 command = udp_service_commands[serv]
99             else:
100                 raise "Unknown protocol."
101         except:
102             command = protocol
103
104         if command == "udp":
105             continue
106
107         services[serv] = { "command": command, "port": port }
108
109     hosts[name] = { "name": name, "address": address, "services": services }
110
111 def create_host(host):
112     global api_url, api_user, api_password
113
114     req = {
115       "templates": [ "discovered-host" ],
116       "attrs": {
117         "address": host["address"]
118       }
119     }
120
121     headers = {"Accept": "application/json"}
122     url = urlparse.urljoin(api_url, "v1/objects/hosts/%s" % (host["name"]))
123     requests.put(url, headers=headers, auth=(api_user, api_password), data=json.dumps(req), verify=False)
124
125     for serv, service in host["services"].iteritems():
126         req = {
127           "templates": [ "discovered-service" ],
128           "attrs": {
129             "vars.%s_port" % (service["command"]): service["port"],
130             "check_command": service["command"],
131           }
132         }
133     
134         headers = {"Accept": "application/json"}
135         url = urlparse.urljoin(api_url, "v1/objects/services/%s!%s" % (host["name"], serv))
136         requests.put(url, headers=headers, auth=(api_user, api_password), data=json.dumps(req), verify=False)
137
138 for arg in sys.argv[1:]:
139     # Expects XML output from 'nmap -oX'
140     dom = parse(arg)
141
142     for host in dom.getElementsByTagName("host"):
143         process_host(host)
144
145 for host in hosts.values():
146     create_host(host)