def test_get_single_oid_wrong_credentials(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") snmp_config = snmp_config.update(credentials="dingdong") result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result is None
def oid_function(oid, default_value=None, cp_name=check_plugin_name): # type: (OID, Optional[RawValue], Optional[CheckPluginName]) -> Optional[RawValue] value = snmp.get_single_oid(host_config, oid, cp_name, do_snmp_scan=do_snmp_scan) return default_value if value is None else value
def test_get_single_oid_not_resolvable(snmp_config, backend): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") snmp_config = snmp_config.update(ipaddress="bla.local") assert snmp.get_single_oid( snmp_config, ".1.3.6.1.2.1.1.7.0", backend=backend) is None
def oid_function(oid, default_value=None, cp_name=check_plugin_name): value = snmp.get_single_oid(host_config, oid, cp_name, do_snmp_scan=do_snmp_scan) return default_value if value is None else value
def test_get_single_oid_not_resolvable(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") cfg_dict = snmp_config._asdict() cfg_dict["ipaddress"] = "bla.local" snmp_config = snmp_utils.SNMPHostConfig(**cfg_dict) assert snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.7.0") is None
def test_get_single_oid_cache(snmp_config): oid = ".1.3.6.1.2.1.1.1.0" expected_value = "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686" assert snmp.get_single_oid(snmp_config, oid) == expected_value assert snmp._is_in_single_oid_cache(oid) cached_oid = snmp._get_oid_from_single_oid_cache(oid) assert cached_oid == expected_value assert isinstance(cached_oid, six.text_type)
def test_get_single_oid_snmpv3(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") cfg_dict = snmp_config._asdict() cfg_dict["credentials"] = ('authNoPriv', 'md5', 'authOnlyUser', 'authOnlyUser') snmp_config = snmp_utils.SNMPHostConfig(**cfg_dict) result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686"
def test_get_single_oid_wrong_credentials(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") cfg_dict = snmp_config._asdict() cfg_dict["credentials"] = "dingdong" snmp_config = snmp_utils.SNMPHostConfig(**cfg_dict) result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result is None
def test_get_single_oid_cache(snmp_config): oid = ".1.3.6.1.2.1.1.1.0" expected_value = "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686" assert snmp.get_single_oid(snmp_config, oid) == expected_value assert snmp._is_in_single_oid_cache(oid) cached_oid = snmp._get_oid_from_single_oid_cache(oid) assert cached_oid == expected_value # TODO: Encoding is incosistent between single oids and walks assert isinstance(cached_oid, str)
def test_get_single_oid_ipv6(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") snmp_config = snmp_config.update( is_ipv6_primary=True, ipaddress="::1", ) result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686"
def test_get_single_oid_ipv6(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") cfg_dict = snmp_config._asdict() cfg_dict["is_ipv6_primary"] = True cfg_dict["ipaddress"] = "::1" snmp_config = snmp_utils.SNMPHostConfig(**cfg_dict) result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686"
def test_get_single_oid_snmpv3(snmp_config): if snmp_config.is_usewalk_host: pytest.skip("Not relevant") snmp_config = snmp_config.update(credentials=( 'authNoPriv', 'md5', 'authOnlyUser', 'authOnlyUser', )) result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686"
def test_get_data_types(snmp_config, type_name, oid, expected_response): response = snmp.get_single_oid(snmp_config, oid) assert response == expected_response assert isinstance(response, six.text_type) oid_start, oid_end = oid.rsplit(".", 1) table = snmp.get_snmp_table(snmp_config, check_plugin_name=None, oid_info=(oid_start, [oid_end]), use_snmpwalk_cache=False) assert table[0][0] == expected_response assert isinstance(table[0][0], six.text_type)
def _evaluate_snmp_detection_atom(atom, host_config, cp_name, do_snmp_scan): # type: (SNMPDetectAtom, SNMPHostConfig, str, bool) -> bool oid, pattern, flag = atom value = snmp.get_single_oid( host_config, oid, cp_name, do_snmp_scan=do_snmp_scan, ) if value is None: # check for "not_exists" return pattern == '.*' and not flag # ignore case! return bool(regex(pattern, re.IGNORECASE).fullmatch(value)) is flag
def test_get_data_types(snmp_config, backend, type_name, oid, expected_response): response = snmp.get_single_oid(snmp_config, oid, backend=backend) assert response == expected_response assert isinstance(response, str) oid_start, oid_end = oid.rsplit(".", 1) table = snmp_table.get_snmp_table( snmp_config, check_plugin_name="", oid_info=(oid_start, [oid_end]), backend=backend, ) assert table[0][0] == expected_response assert isinstance(table[0][0], str)
def test_get_single_oid_value(snmp_config): assert snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.9.1.2.1") == '.1.3.6.1.6.3.10.3.1.1'
def test_get_single_oid_next(snmp_config): assert snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.9.1.*") == ".1.3.6.1.6.3.10.3.1.1"
def test_get_single_non_prefixed_oid(snmp_config): with pytest.raises(MKGeneralException, match="does not begin with"): snmp.get_single_oid(snmp_config, "1.3.6.1.2.1.1.1.0")
def _snmp_scan(host_config, on_error="ignore", for_inv=False, do_snmp_scan=True, for_mgmt_board=False): # type: (SNMPHostConfig, str, bool, bool, bool) -> Set[CheckPluginName] import cmk.base.inventory_plugins as inventory_plugins # pylint: disable=import-outside-toplevel # Make hostname globally available for scan functions. # This is rarely used, but e.g. the scan for if/if64 needs # this to evaluate if_disabled_if64_checks. check_api_utils.set_hostname(host_config.hostname) snmp_cache.initialize_single_oid_cache(host_config) console.vverbose(" SNMP scan:\n") if not config.get_config_cache().in_binary_hostlist( host_config.hostname, config.snmp_without_sys_descr): for oid, name in [(".1.3.6.1.2.1.1.1.0", "system description"), (".1.3.6.1.2.1.1.2.0", "system object")]: value = snmp.get_single_oid(host_config, oid, do_snmp_scan=do_snmp_scan) if value is None: raise MKSNMPError( "Cannot fetch %s OID %s. This might be OK for some bogus devices. " "In that case please configure the ruleset \"Hosts without system " "description OID\" to tell Check_MK not to fetch the system " "description and system object OIDs." % (name, oid)) else: # Fake OID values to prevent issues with a lot of scan functions console.vverbose( " Skipping system description OID " "(Set .1.3.6.1.2.1.1.1.0 and .1.3.6.1.2.1.1.2.0 to \"\")\n") snmp_cache.set_single_oid_cache(".1.3.6.1.2.1.1.1.0", "") snmp_cache.set_single_oid_cache(".1.3.6.1.2.1.1.2.0", "") # TODO (mo): Assumption here is that inventory plugins are significantly fewer # than check plugins. We should pass an explicit list along, instead # of this flag. That way we would also get rid of the import above. if for_inv: section_names = [PluginName(n) for n in inventory_plugins.inv_info] these_sections = [ config.registered_snmp_sections[section_name] for section_name in section_names if section_name in config.registered_snmp_sections ] else: these_sections = list(config.registered_snmp_sections.values()) found_plugins = set() # type: Set[CheckPluginName] for section_plugin in these_sections: try: if _evaluate_snmp_detection( section_plugin.detect_spec, host_config, str(section_plugin.name), do_snmp_scan, ): found_plugins.add(str(section_plugin.name)) except MKGeneralException: # some error messages which we explicitly want to show to the user # should be raised through this raise except Exception: if on_error == "warn": console.warning(" Exception in SNMP scan function of %s" % section_plugin.name) elif on_error == "raise": raise _output_snmp_check_plugins("SNMP scan found", found_plugins) filtered = config.filter_by_management_board( host_config.hostname, found_plugins, for_mgmt_board, for_discovery=True, for_inventory=for_inv, ) _output_snmp_check_plugins("SNMP filtered check plugin names", filtered) snmp_cache.write_single_oid_cache(host_config) return filtered
def test_get_single_oid(snmp_config): result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686" assert isinstance(result, six.text_type)
def _snmp_scan(host_config, on_error="ignore", for_inv=False, do_snmp_scan=True, for_mgmt_board=False): # type: (SNMPHostConfig, str, bool, bool, bool) -> Set[CheckPluginName] import cmk.base.inventory_plugins as inventory_plugins # pylint: disable=import-outside-toplevel # Make hostname globally available for scan functions. # This is rarely used, but e.g. the scan for if/if64 needs # this to evaluate if_disabled_if64_checks. check_api_utils.set_hostname(host_config.hostname) snmp_cache.initialize_single_oid_cache(host_config) console.vverbose(" SNMP scan:\n") if not config.get_config_cache().in_binary_hostlist(host_config.hostname, config.snmp_without_sys_descr): for oid, name in [(".1.3.6.1.2.1.1.1.0", "system description"), (".1.3.6.1.2.1.1.2.0", "system object")]: value = snmp.get_single_oid(host_config, oid, do_snmp_scan=do_snmp_scan) if value is None: raise MKSNMPError( "Cannot fetch %s OID %s. This might be OK for some bogus devices. " "In that case please configure the ruleset \"Hosts without system " "description OID\" to tell Check_MK not to fetch the system " "description and system object OIDs." % (name, oid)) else: # Fake OID values to prevent issues with a lot of scan functions console.vverbose(" Skipping system description OID " "(Set .1.3.6.1.2.1.1.1.0 and .1.3.6.1.2.1.1.2.0 to \"\")\n") snmp_cache.set_single_oid_cache(".1.3.6.1.2.1.1.1.0", "") snmp_cache.set_single_oid_cache(".1.3.6.1.2.1.1.2.0", "") if for_inv: these_plugin_names = [ name for name in inventory_plugins.inv_info if inventory_plugins.is_snmp_plugin(name) ] else: # TODO (mo): stop converting to string! these_plugin_names = [str(n) for n in config.registered_snmp_sections] found_plugins = set() # type: Set[CheckPluginName] for check_plugin_name in these_plugin_names: if config.service_ignored(host_config.hostname, check_plugin_name, None): continue detection_spec = _get_detection_spec_from_plugin_name(check_plugin_name, inventory_plugins.inv_info) if detection_spec is None: console.warning(" SNMP check %s: Could not detect specifications for plugin" % check_plugin_name) continue try: def oid_function(oid, default_value=None, cp_name=check_plugin_name): # type: (OID, Optional[DecodedString], Optional[CheckPluginName]) -> Optional[DecodedString] value = snmp.get_single_oid(host_config, oid, cp_name, do_snmp_scan=do_snmp_scan) return default_value if value is None else value if callable(detection_spec): result = detection_spec(oid_function) else: result = _evaluate_snmp_detection(oid_function, detection_spec) if result is not None and not isinstance(result, (str, bool)): if on_error == "warn": console.warning(" SNMP scan function of %s returns invalid type %s." % (check_plugin_name, type(result))) elif on_error == "raise": raise MKGeneralException("SNMP Scan aborted.") elif result: found_plugins.add(check_plugin_name) except MKGeneralException: # some error messages which we explicitly want to show to the user # should be raised through this raise except Exception: if on_error == "warn": console.warning(" Exception in SNMP scan function of %s" % check_plugin_name) elif on_error == "raise": raise _output_snmp_check_plugins("SNMP scan found", found_plugins) filtered = config.filter_by_management_board( host_config.hostname, found_plugins, for_mgmt_board, for_discovery=True, for_inventory=for_inv, ) _output_snmp_check_plugins("SNMP filtered check plugin names", filtered) snmp_cache.write_single_oid_cache(host_config) return filtered
def test_get_single_oid(snmp_config, backend): result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0", backend=backend) assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686" assert isinstance(result, str)
def test_get_single_oid_not_existing(snmp_config): assert snmp.get_single_oid(snmp_config, ".1.3.100.200.300.400") is None
def test_get_single_oid(snmp_config): result = snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.1.1.0") assert result == "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686" # TODO: Encoding is incosistent between single oids and walks assert isinstance(result, str)
def test_get_single_oid_hex(snmp_config): assert snmp.get_single_oid(snmp_config, ".1.3.6.1.2.1.2.2.1.6.2") == b"\x00\x12yb\xf9@"
def _snmp_scan(host_config, on_error="ignore", for_inv=False, do_snmp_scan=True, for_mgmt_board=False): import cmk.base.inventory_plugins as inventory_plugins # Make hostname globally available for scan functions. # This is rarely used, but e.g. the scan for if/if64 needs # this to evaluate if_disabled_if64_checks. check_api_utils.set_hostname(host_config.hostname) snmp.initialize_single_oid_cache(host_config) console.vverbose(" SNMP scan:\n") if not config.get_config_cache().in_binary_hostlist( host_config.hostname, config.snmp_without_sys_descr): for oid, name in [(".1.3.6.1.2.1.1.1.0", "system description"), (".1.3.6.1.2.1.1.2.0", "system object")]: value = snmp.get_single_oid(host_config, oid, do_snmp_scan=do_snmp_scan) if value is None: raise MKSNMPError( "Cannot fetch %s OID %s. This might be OK for some bogus devices. " "In that case please configure the ruleset \"Hosts without system " "description OID\" to tell Check_MK not to fetch the system " "description and system object OIDs." % (name, oid)) else: # Fake OID values to prevent issues with a lot of scan functions console.vverbose( " Skipping system description OID " "(Set .1.3.6.1.2.1.1.1.0 and .1.3.6.1.2.1.1.2.0 to \"\")\n") snmp.set_single_oid_cache(host_config, ".1.3.6.1.2.1.1.1.0", "") snmp.set_single_oid_cache(host_config, ".1.3.6.1.2.1.1.2.0", "") found_check_plugin_names = [] if for_inv: items = inventory_plugins.inv_info.items() else: items = config.check_info.items() positive_found = [] default_found = [] for check_plugin_name, _unused_check in items: if config.service_ignored(host_config.hostname, check_plugin_name, None): continue else: if for_inv and not inventory_plugins.is_snmp_plugin( check_plugin_name): continue elif not for_inv and not cmk.base.check_utils.is_snmp_check( check_plugin_name): continue section_name = cmk.base.check_utils.section_name_of(check_plugin_name) # The scan function should be assigned to the section_name, because # subchecks sharing the same SNMP info of course should have # an identical scan function. But some checks do not do this # correctly if check_plugin_name in config.snmp_scan_functions: scan_function = config.snmp_scan_functions[check_plugin_name] elif section_name in config.snmp_scan_functions: scan_function = config.snmp_scan_functions[section_name] elif section_name in inventory_plugins.inv_info: scan_function = inventory_plugins.inv_info[section_name].get( "snmp_scan_function") else: scan_function = None if scan_function: try: def oid_function(oid, default_value=None, cp_name=check_plugin_name): value = snmp.get_single_oid(host_config, oid, cp_name, do_snmp_scan=do_snmp_scan) return default_value if value is None else value result = scan_function(oid_function) if result is not None and not isinstance(result, (str, bool)): if on_error == "warn": console.warning( " SNMP scan function of %s returns invalid type %s." % (check_plugin_name, type(result))) elif on_error == "raise": raise MKGeneralException("SNMP Scan aborted.") elif result: found_check_plugin_names.append(check_plugin_name) positive_found.append(check_plugin_name) except MKGeneralException: # some error messages which we explicitly want to show to the user # should be raised through this raise except Exception: if on_error == "warn": console.warning( " Exception in SNMP scan function of %s" % check_plugin_name) elif on_error == "raise": raise else: found_check_plugin_names.append(check_plugin_name) default_found.append(check_plugin_name) _output_snmp_check_plugins("SNMP scan found", positive_found) if default_found: _output_snmp_check_plugins("SNMP without scan function", default_found) filtered = config.filter_by_management_board(host_config.hostname, found_check_plugin_names, for_mgmt_board, for_discovery=True, for_inventory=for_inv) _output_snmp_check_plugins("SNMP filtered check plugin names", filtered) snmp.write_single_oid_cache(host_config) return sorted(filtered)