]> granicus.if.org Git - icinga2/blob - contrib/discover.py
Merge pull request #6731 from Icinga/bugfix/doc-comment
[icinga2] / contrib / discover.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 from xml.dom.minidom import parse
23
24 if len(sys.argv) < 2:
25     print "Syntax: %s <xml-file> [<xml-file> ...]" % (sys.argv[0])
26     sys.exit(1)
27
28 tcp_service_commands = {
29   'ssh': 'ssh',
30   'http': 'http_ip',
31   'https': 'https_ip',
32   'smtp': 'smtp',
33   'ssmtp': 'ssmtp'
34 }
35
36 udp_service_commands = {
37   'ntp': 'ntp_time',
38   'snmp': 'snmp-uptime'
39 }
40
41 hosts = {}
42
43 def process_host(host_element):
44     global hosts
45
46     status = "down"
47
48     for status_element in host_element.getElementsByTagName("status"):
49         status = status_element.getAttribute("state")
50
51     if status != "up":
52         return
53
54     for address_element in host_element.getElementsByTagName("address"):
55         if not address_element.getAttribute("addrtype") in [ "ipv4", "ipv6" ]:
56             continue
57
58         address = address_element.getAttribute("addr")
59         break
60
61     name = address
62
63     for hostname_element in host_element.getElementsByTagName("hostname"):
64         name = hostname_element.getAttribute("name")
65
66     try:
67         services = hosts[name]["services"]
68     except:
69         services = {}
70
71     for port_element in host_element.getElementsByTagName("port"):
72         state = "closed"
73
74         for state_element in port_element.getElementsByTagName("state"):
75             state = state_element.getAttribute("state")
76
77         if state != "open":
78             continue
79
80         port = int(port_element.getAttribute("portid"))
81         protocol = port_element.getAttribute("protocol")
82
83         try:
84             serv = socket.getservbyport(port, protocol)
85         except:
86             serv = str(port)
87
88         try:
89             if protocol == "tcp":
90                 command = tcp_service_commands[serv]
91             elif protocol == "udp":
92                 command = udp_service_commands[serv]
93             else:
94                 raise "Unknown protocol."
95         except:
96             command = protocol
97
98         if command == "udp":
99             continue
100
101         services[serv] = { "command": command, "port": port }
102
103     hosts[name] = { "name": name, "address": address, "services": services }
104
105 def print_host(host):
106     print "object Host \"%s\" {" % (host["name"])
107     print "\timport \"discovered-host\","
108     print ""
109     print "\taddress = \"%s\"," % (host["address"])
110     print "}"
111     print ""
112
113     for serv, service in host["services"].iteritems():
114         print "object Service \"%s\" {" % (serv)
115         print "\timport \"discovered-service\","
116         print ""
117         print "\thost_name = \"%s\"" % (host["name"])
118         print "\tcheck_command = \"%s\"," % (service["command"])
119         print ""
120         print "\tvars.port = %s" % (service["port"])
121         print "}"
122         print ""
123
124 for arg in sys.argv[1:]:
125     # Expects XML output from 'nmap -oX'
126     dom = parse(arg)
127
128     for host in dom.getElementsByTagName("host"):
129         process_host(host)
130
131 for host in hosts.values():
132     print_host(host)