2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 from cmk
.utils
.exceptions
import MKGeneralException
28 import cmk
.utils
.tty
as tty
30 import cmk_base
.check_utils
31 import cmk_base
.config
as config
32 import cmk_base
.console
as console
33 from cmk_base
.exceptions
import MKSNMPError
34 import cmk_base
.snmp
as snmp
35 import cmk_base
.check_api_utils
as check_api_utils
38 # gather auto_discovered check_plugin_names for this host
39 def gather_snmp_check_plugin_names(host_config
,
43 for_mgmt_board
=False):
44 check_plugin_names
= set()
47 check_plugin_names
.update(
51 do_snmp_scan
=do_snmp_scan
,
52 for_inv
=for_inventory
,
53 for_mgmt_board
=for_mgmt_board
))
54 except Exception as e
:
55 if on_error
== "raise":
57 elif on_error
== "warn":
58 console
.error("SNMP scan failed: %s\n" % e
)
60 return list(check_plugin_names
)
63 def _snmp_scan(host_config
,
67 for_mgmt_board
=False):
68 import cmk_base
.inventory_plugins
as inventory_plugins
70 # Make hostname globally available for scan functions.
71 # This is rarely used, but e.g. the scan for if/if64 needs
72 # this to evaluate if_disabled_if64_checks.
73 check_api_utils
.set_hostname(host_config
.hostname
)
75 snmp
.initialize_single_oid_cache(host_config
)
76 console
.vverbose(" SNMP scan:\n")
77 if not config
.in_binary_hostlist(host_config
.hostname
, config
.snmp_without_sys_descr
):
78 for oid
, name
in [(".1.3.6.1.2.1.1.1.0", "system description"),
79 (".1.3.6.1.2.1.1.2.0", "system object")]:
80 value
= snmp
.get_single_oid(host_config
, oid
, do_snmp_scan
=do_snmp_scan
)
83 "Cannot fetch %s OID %s. This might be OK for some bogus devices. "
84 "In that case please configure the ruleset \"Hosts without system "
85 "description OID\" to tell Check_MK not to fetch the system "
86 "description and system object OIDs." % (name
, oid
))
88 # Fake OID values to prevent issues with a lot of scan functions
89 console
.vverbose(" Skipping system description OID "
90 "(Set .1.3.6.1.2.1.1.1.0 and .1.3.6.1.2.1.1.2.0 to \"\")\n")
91 snmp
.set_single_oid_cache(host_config
, ".1.3.6.1.2.1.1.1.0", "")
92 snmp
.set_single_oid_cache(host_config
, ".1.3.6.1.2.1.1.2.0", "")
94 found_check_plugin_names
= []
96 items
= inventory_plugins
.inv_info
.items()
98 items
= config
.check_info
.items()
103 for check_plugin_name
, _unused_check
in items
:
104 if config
.service_ignored(host_config
.hostname
, check_plugin_name
, None):
107 if for_inv
and not inventory_plugins
.is_snmp_plugin(check_plugin_name
):
109 elif not for_inv
and not cmk_base
.check_utils
.is_snmp_check(check_plugin_name
):
112 section_name
= cmk_base
.check_utils
.section_name_of(check_plugin_name
)
113 # The scan function should be assigned to the section_name, because
114 # subchecks sharing the same SNMP info of course should have
115 # an identical scan function. But some checks do not do this
117 if check_plugin_name
in config
.snmp_scan_functions
:
118 scan_function
= config
.snmp_scan_functions
[check_plugin_name
]
119 elif section_name
in config
.snmp_scan_functions
:
120 scan_function
= config
.snmp_scan_functions
[section_name
]
121 elif section_name
in inventory_plugins
.inv_info
:
122 scan_function
= inventory_plugins
.inv_info
[section_name
].get("snmp_scan_function")
129 def oid_function(oid
, default_value
=None, cp_name
=check_plugin_name
):
130 value
= snmp
.get_single_oid(
131 host_config
, oid
, cp_name
, do_snmp_scan
=do_snmp_scan
)
132 return default_value
if value
is None else value
134 result
= scan_function(oid_function
)
135 if result
is not None and not isinstance(result
, (str, bool)):
136 if on_error
== "warn":
137 console
.warning(" SNMP scan function of %s returns invalid type %s." %
138 (check_plugin_name
, type(result
)))
139 elif on_error
== "raise":
140 raise MKGeneralException("SNMP Scan aborted.")
142 found_check_plugin_names
.append(check_plugin_name
)
143 positive_found
.append(check_plugin_name
)
144 except MKGeneralException
:
145 # some error messages which we explicitly want to show to the user
146 # should be raised through this
149 if on_error
== "warn":
150 console
.warning(" Exception in SNMP scan function of %s" % check_plugin_name
)
151 elif on_error
== "raise":
154 found_check_plugin_names
.append(check_plugin_name
)
155 default_found
.append(check_plugin_name
)
157 _output_snmp_check_plugins("SNMP scan found", positive_found
)
159 _output_snmp_check_plugins("SNMP without scan function", default_found
)
161 filtered
= config
.filter_by_management_board(
162 host_config
.hostname
,
163 found_check_plugin_names
,
166 for_inventory
=for_inv
)
168 _output_snmp_check_plugins("SNMP filtered check plugin names", filtered
)
169 snmp
.write_single_oid_cache(host_config
)
170 return sorted(filtered
)
173 def _output_snmp_check_plugins(title
, collection
):
175 collection_out
= " ".join(sorted(collection
))
178 console
.vverbose(" %-35s%s%s%s%s\n" % \
179 (title
, tty
.bold
, tty
.yellow
, collection_out
, tty
.normal
))