diff --git a/contrib/discover.py b/contrib/discover.py index a41d264c1..a008a5dd1 100755 --- a/contrib/discover.py +++ b/contrib/discover.py @@ -2,9 +2,13 @@ import sys import subprocess import socket -from xml.dom.minidom import parseString +from xml.dom.minidom import parse -service_templates = { +if len(sys.argv) < 2: + print "Syntax: %s [ ...]" % (sys.argv[0]) + sys.exit(1) + +tcp_service_templates = { 'ssh': 'ssh', 'http': 'http_ip', 'https': 'https_ip', @@ -12,34 +16,52 @@ service_templates = { 'ssmtp': 'ssmtp' } -# Expects XML output from 'nmap -oX' -dom = parseString(sys.stdin.read()) +udp_service_templates = { + 'ntp': 'ntp_time', + 'snmp': 'snmp-uptime' +} -def processHost(host): - for element in host.getElementsByTagName("status"): - if element.getAttribute("state") != "up": - return +hosts = {} - for element in host.getElementsByTagName("address"): - if not element.getAttribute("addrtype") in [ "ipv4", "ipv6" ]: +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 = element.getAttribute("addr") + + address = address_element.getAttribute("addr") break - hostname = address + name = address - for element in host.getElementsByTagName("hostname"): - hostname = element.getAttribute("name") + for hostname_element in host_element.getElementsByTagName("hostname"): + name = hostname_element.getAttribute("name") - print "object Host \"%s\" inherits \"itl-host\" {" % (hostname) - print "\tmacros = {" - print "\t\taddress = \"%s\"" % (address) - print "\t}," + try: + services = hosts[name]["services"] + except: + services = {} - for element in host.getElementsByTagName("port"): - port = int(element.getAttribute("portid")) - protocol = element.getAttribute("protocol") + 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) @@ -47,23 +69,51 @@ def processHost(host): serv = str(port) try: - template = service_templates[serv] + if protocol == "tcp": + template = tcp_service_templates[serv] + elif protocol == "udp": + template = udp_service_templates[serv] + else: + raise "Unknown protocol." except: template = protocol + if template == "udp": + continue + + services[serv] = { "template": template, "port": port } + + hosts[name] = { "name": name, "address": address, "services": services } + +def print_host(host): + print "object Host \"%s\" inherits \"discovered-host\" {" % (host["name"]) + print "\tmacros = {" + print "\t\taddress = \"%s\"" % (host["address"]) + print "\t}," + + for serv, service in host["services"].iteritems(): print "" print "\tservices[\"%s\"] = {" % (serv) - print "\t\ttemplates = { \"%s\" }," % (template) + print "\t\ttemplates = { \"%s\" }," % (service["template"]) print "" print "\t\tmacros = {" - print "\t\t\tport = %s" % (port) + print "\t\t\tport = %s" % (service["port"]) print "\t\t}" print "\t}," print "}" print "" -print "#include " -for host in dom.getElementsByTagName("host"): - processHost(host) +print "#include " +print "" + +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(): + print_host(host) diff --git a/itl/service-common.conf b/itl/service-common.conf index e1fc5eef5..625955194 100644 --- a/itl/service-common.conf +++ b/itl/service-common.conf @@ -210,3 +210,22 @@ template Service "load" inherits "plugin-service" { cload15 = 4.0 } } + +template Service "snmp" inherits "plugin-service" { + check_command = { + "$plugindir$/check_snmp", + "-H", "$address$", + "-o", "$oid$", + "-C", "$community$" + }, + + macros = { + community = "public" + } +} + +template Service "snmp-uptime" inherits "snmp" { + macros += { + oid = "1.3.6.1.2.1.1.3.0" + } +} diff --git a/lib/base/dynamicobject.cpp b/lib/base/dynamicobject.cpp index f3c0e4cce..d0693d64f 100644 --- a/lib/base/dynamicobject.cpp +++ b/lib/base/dynamicobject.cpp @@ -431,6 +431,9 @@ ScriptTask::Ptr DynamicObject::MakeMethodTask(const String& method, methods = m_Methods; + if (!methods) + return ScriptTask::Ptr(); + String funcName = methods->Get(method); if (funcName.IsEmpty()) diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp index ec9514982..7d469661f 100644 --- a/lib/icinga/macroprocessor.cpp +++ b/lib/icinga/macroprocessor.cpp @@ -64,7 +64,7 @@ String MacroProcessor::InternalResolveMacros(const String& str, const Dictionary pos_second = result.FindFirstOf("$", pos_first + 1); if (pos_second == String::NPos) - BOOST_THROW_EXCEPTION(runtime_error("Closing $ not found in macro format String.")); + BOOST_THROW_EXCEPTION(runtime_error("Closing $ not found in macro format string.")); String name = result.SubStr(pos_first + 1, pos_second - pos_first - 1);