def test_get_section_cluster_kwargs(patch_register, required_sections, expected_result): node1_section_content = { SectionName("one"): NODE_1, SectionName("two"): NODE_1, SectionName("three"): NODE_1 } node2_section_content = { SectionName("two"): NODE_2, SectionName("three"): NODE_2, } multi_host_sections = MultiHostSections() multi_host_sections.setdefault( HostKey("node1", "127.0.0.1", SourceType.HOST), AgentHostSections(sections=node1_section_content), ) multi_host_sections.setdefault( HostKey("node2", "127.0.0.1", SourceType.HOST), AgentHostSections(sections=node2_section_content), ) kwargs = multi_host_sections.get_section_cluster_kwargs( [ HostKey("node1", "127.0.0.1", SourceType.HOST), HostKey("node2", "127.0.0.1", SourceType.HOST), ], [ParsedSectionName(n) for n in required_sections], ) assert expected_result == kwargs,\ "Section content: Expected '%s' but got '%s'" % (expected_result, kwargs)
def test_no_sources(self, cluster, nodes, config_cache, host_config, mode): mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, None, mode=mode, sources=[], ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, ) assert len(mhs) == len(nodes) key_clu = HostKey(cluster, None, SourceType.HOST) assert key_clu not in mhs for hostname, addr in nodes.items(): key = HostKey(hostname, addr, SourceType.HOST) assert key in mhs section = mhs[key] # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]) assert not section.cache_info assert not section.piggybacked_raw_data assert not section.persisted_sections
def test_get_parsed_section(patch_register, node_section_content, expected_result): multi_host_sections = MultiHostSections() multi_host_sections.setdefault( HostKey("node1", "127.0.0.1", SourceType.HOST), AgentHostSections(sections=node_section_content), ) content = multi_host_sections.get_parsed_section( HostKey("node1", "127.0.0.1", SourceType.HOST), ParsedSectionName("parsed"), ) assert expected_result == content,\ "Section content: Expected '%s' but got '%s'" % (expected_result, content)
def test_get_section_content(hostname, host_entries, cluster_node_keys, expected_result): multi_host_sections = MultiHostSections() for nodename, node_section_content in host_entries: multi_host_sections.setdefault( HostKey(nodename, "127.0.0.1", SourceType.HOST), AgentHostSections( sections={ SectionName("section_plugin_name"): node_section_content }), ) section_content = multi_host_sections.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.HOST), check_api_utils.HOST_ONLY, "section_plugin_name", False, cluster_node_keys=cluster_node_keys, check_legacy_info= {}, # only for parse_function lookup, not needed in this test ) assert expected_result == section_content section_content = multi_host_sections.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.HOST), check_api_utils.HOST_PRECEDENCE, "section_plugin_name", False, cluster_node_keys=cluster_node_keys, check_legacy_info= {}, # only for parse_function lookup, not needed in this test ) assert expected_result == section_content section_content = multi_host_sections.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.MANAGEMENT), check_api_utils.MGMT_ONLY, "section_plugin_name", False, cluster_node_keys=None if cluster_node_keys is None else [ HostKey(hn, ip, SourceType.MANAGEMENT) for (hn, ip, _st) in cluster_node_keys ], check_legacy_info= {}, # only for parse_function lookup, not needed in this test ) assert section_content is None
def test_no_sources(self, hostname, ipaddress, mode, config_cache, host_config): mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=[], ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, ) # The length is not zero because the function always sets, # at least, a piggy back section. assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) # Public attributes from ABCHostSections: assert not section.sections assert not section.cache_info assert not section.piggybacked_raw_data assert not section.persisted_sections
def test_no_sources(self, hostname, ipaddress, mode, config_cache, host_config): mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=(), ), max_cachefile_age=0, host_config=host_config, fetcher_messages=(), selected_sections=NO_SELECTION, ) # The length is not zero because the function always sets, # at least, a piggy back section. assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] # Public attributes from HostSections: assert not section.sections assert not section.cache_info assert not section.piggybacked_raw_data
def test_one_nonsnmp_source(self, hostname, ipaddress, mode, config_cache, host_config, source): source = source(hostname, ipaddress, mode=mode) assert source.source_type is SourceType.HOST mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=[source], ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, source.source_type) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) assert len(section.sections) == 1 assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
def test_multiple_sources_from_the_same_host( self, hostname, ipaddress, mode, config_cache, host_config, ): sources = [ ProgramSource.ds( hostname, ipaddress, mode=mode, preselected_sections=AUTO_DETECT, template="", ), TCPSource( hostname, ipaddress, mode=mode, preselected_sections=AUTO_DETECT, ), ] mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=sources, ), max_cachefile_age=0, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for source in sources ], ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) assert len(section.sections) == 1 # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == len(sources) * [["section_content"]])
def test_no_sources(self, cluster, nodes, config_cache, host_config, mode): made_nodes = make_nodes( config_cache, host_config, None, mode=mode, sources=(), ) mhs = MultiHostSections() update_host_sections( mhs, made_nodes, max_cachefile_age=0, host_config=host_config, fetcher_messages=[ # We do not pass sources explicitly but still append Piggyback. FetcherMessage.from_raw_data( result.OK(AgentRawData(b"")), Snapshot.null(), FetcherType.PIGGYBACK, ) for _n in made_nodes ], selected_sections=NO_SELECTION, ) assert len(mhs) == len(nodes) key_clu = HostKey(cluster, None, SourceType.HOST) assert key_clu not in mhs for hostname, addr in nodes.items(): key = HostKey(hostname, addr, SourceType.HOST) assert key in mhs section = mhs[key] # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == [["section_content_%s" % hostname]]) assert not section.cache_info assert not section.piggybacked_raw_data
def _get_host_section_for_parse_sections_test(): node_section_content = { SectionName("one"): NODE_1, SectionName("four"): NODE_1, } host_key = HostKey("node1", "127.0.0.1", SourceType.HOST) mhs = MultiHostSections() mhs.setdefault( host_key, AgentHostSections(sections=node_section_content), ) return host_key, mhs
def test_multiple_sources_from_the_same_host( self, hostname, ipaddress, mode, config_cache, host_config, ): sources = [ ProgramSource.ds( hostname, ipaddress, mode=mode, template="", ), TCPSource( hostname, ipaddress, mode=mode, ), ] mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=sources, ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) assert len(section.sections) == 1 # yapf: disable assert (section.sections[SectionName("section_name_%s" % hostname)] == len(sources) * [["section_content"]])
def _do_inv_for_realhost( host_config: config.HostConfig, ipaddress: Optional[HostAddress], *, multi_host_sections: MultiHostSections, run_only_plugin_names: Optional[Set[InventoryPluginName]], ) -> InventoryTrees: tree_aggregator = _TreeAggregator() _set_cluster_property(tree_aggregator.trees.inventory, host_config) section.section_step("Executing inventory plugins") for inventory_plugin in agent_based_register.iter_all_inventory_plugins(): if run_only_plugin_names and inventory_plugin.name not in run_only_plugin_names: continue kwargs = multi_host_sections.get_section_kwargs( HostKey(host_config.hostname, ipaddress, SourceType.HOST), inventory_plugin.sections, ) if not kwargs: console.vverbose(" %s%s%s%s: skipped (no data)\n", tty.yellow, tty.bold, inventory_plugin.name, tty.normal) continue # Inventory functions can optionally have a second argument: parameters. # These are configured via rule sets (much like check parameters). if inventory_plugin.inventory_ruleset_name is not None: kwargs["params"] = host_config.inventory_parameters( str(inventory_plugin.inventory_ruleset_name) ) # TODO (mo): keep type! exception = tree_aggregator.aggregate_results( inventory_plugin.inventory_function(**kwargs), inventory_plugin.name, ) if exception: console.warning(" %s%s%s%s: failed: %s", tty.red, tty.bold, inventory_plugin.name, tty.normal, exception) else: console.verbose(" %s%s%s%s", tty.green, tty.bold, inventory_plugin.name, tty.normal) console.vverbose(": ok\n") console.verbose("\n") tree_aggregator.trees.inventory.normalize_nodes() tree_aggregator.trees.status_data.normalize_nodes() return tree_aggregator.trees
def test_multiple_sources_from_different_hosts(self, hostname, ipaddress, mode, config_cache, host_config): sources = [ ProgramSource.ds(hostname + "0", ipaddress, mode=mode, template="",), TCPSource(hostname + "1", ipaddress, mode=mode,), TCPSource(hostname + "2", ipaddress, mode=mode,), ] mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=sources, ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), L3Stats(CPUTracker()), source.fetcher_type, ) for source in sources ], ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) assert len(section.sections) == len(sources) for source in sources: # yapf: disable assert ( section.sections[SectionName("section_name_%s" % source.hostname)] == [["section_content"]])
def test_multiple_sources_from_different_hosts(self, hostname, ipaddress, mode, config_cache, host_config): sources = [ ProgramSource.ds(hostname + "0", ipaddress, mode=mode, template=""), TCPSource(hostname + "1", ipaddress, mode=mode), TCPSource(hostname + "2", ipaddress, mode=mode), ] nodes = make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=sources, ) mhs = MultiHostSections() update_host_sections( mhs, nodes, max_cachefile_age=0, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for _h, _i, sources in nodes for source in sources ], selected_sections=NO_SELECTION, ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert len(section.sections) == len(sources) for source in sources: # yapf: disable assert ( section.sections[SectionName("section_name_%s" % source.hostname)] == [["section_content"]])
def test_one_snmp_source(self, hostname, ipaddress, mode, config_cache, host_config): mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=[ SNMPSource.snmp( hostname, ipaddress, mode=mode, selected_sections=NO_SELECTION, on_scan_error="raise", ), ], ), max_cachefile_age=0, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK({}), Snapshot.null(), FetcherType.SNMP, ), ], selected_sections=NO_SELECTION, ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert len(section.sections) == 1 assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
def test_one_snmp_source(self, hostname, ipaddress, mode, config_cache, host_config): mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=[ SNMPSource.snmp( hostname, ipaddress, mode=mode, ), ], ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK({}), L3Stats(CPUTracker()), FetcherType.SNMP, ), ], ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, SourceType.HOST) assert key in mhs section = mhs[key] assert isinstance(section, SNMPHostSections) assert len(section.sections) == 1 assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
def test_one_nonsnmp_source(self, hostname, ipaddress, mode, config_cache, host_config, source): source = source(hostname, ipaddress, mode=mode) assert source.source_type is SourceType.HOST mhs = MultiHostSections() update_host_sections( mhs, make_nodes( config_cache, host_config, ipaddress, mode=mode, sources=[source], ), max_cachefile_age=0, selected_raw_sections=None, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), L3Stats(CPUTracker()), source.fetcher_type, ), ], ) assert len(mhs) == 1 key = HostKey(hostname, ipaddress, source.source_type) assert key in mhs section = mhs[key] assert isinstance(section, AgentHostSections) assert len(section.sections) == 1 assert section.sections[SectionName("section_name_%s" % hostname)] == [["section_content"]]
def _do_inv_for_realhost( host_config: config.HostConfig, multi_host_sections: MultiHostSections, ipaddress: Optional[HostAddress], inventory_tree: StructuredDataTree, status_data_tree: StructuredDataTree, ): section.section_step("Executing inventory plugins") console.verbose("Plugins:") for inventory_plugin in agent_based_register.iter_all_inventory_plugins(): kwargs = multi_host_sections.get_section_kwargs( HostKey(host_config.hostname, ipaddress, SourceType.HOST), inventory_plugin.sections, ) if not kwargs: continue console.verbose( " %s%s%s%s" % (tty.green, tty.bold, inventory_plugin.name, tty.normal)) # Inventory functions can optionally have a second argument: parameters. # These are configured via rule sets (much like check parameters). if inventory_plugin.inventory_ruleset_name is not None: kwargs["params"] = host_config.inventory_parameters( str(inventory_plugin.inventory_ruleset_name) ) # TODO (mo): keep type! _aggregate_inventory_results( inventory_plugin.inventory_function(**kwargs), inventory_tree, status_data_tree, ) console.verbose("\n")
def _execute_check_legacy_mode(multi_host_sections: MultiHostSections, hostname: HostName, ipaddress: Optional[HostAddress], service: Service) -> bool: legacy_check_plugin_name = config.legacy_check_plugin_names.get(service.check_plugin_name) if legacy_check_plugin_name is None: _submit_check_result(hostname, service.description, CHECK_NOT_IMPLEMENTED, None) return True check_function = config.check_info[legacy_check_plugin_name].get("check_function") if check_function is None: _submit_check_result(hostname, service.description, CHECK_NOT_IMPLEMENTED, None) return True # Make a bit of context information globally available, so that functions # called by checks know this context. check_api_utils.set_service has # already been called. item_state.set_item_state_prefix(str(service.check_plugin_name), service.item) section_name = legacy_check_plugin_name.split('.')[0] section_content = None mgmt_board_info = config.get_management_board_precedence(section_name, config.check_info) source_type = SourceType.MANAGEMENT if mgmt_board_info == LEGACY_MGMT_ONLY else SourceType.HOST try: section_content = multi_host_sections.get_section_content( HostKey(hostname, ipaddress, source_type), mgmt_board_info, section_name, for_discovery=False, cluster_node_keys=config.get_config_cache().get_clustered_service_node_keys( hostname, source_type, service.description, ip_lookup.lookup_ip_address, ), check_legacy_info=config.check_info, ) # TODO: Move this to a helper function if section_content is None: # No data for this check type return False # Call the actual check function item_state.reset_wrapped_counters() used_params = legacy_determine_check_params(service.parameters) raw_result = check_function(service.item, used_params, section_content) result = sanitize_check_result(raw_result) item_state.raise_counter_wrap() except item_state.MKCounterWrapped as e: # handle check implementations that do not yet support the # handling of wrapped counters via exception on their own. # Do not submit any check result in that case: console.verbose("%-20s PEND - Cannot compute check result: %s\n", ensure_str(service.description), e) # Don't submit to core - we're done. return True except MKTimeout: raise except Exception: if cmk.utils.debug.enabled(): raise result = 3, cmk.base.crash_reporting.create_check_crash_dump( hostname, service.check_plugin_name, { "item": service.item, "params": used_params, "section_content": section_content }, is_manual_check(hostname, service.id()), service.description, ), [] _submit_check_result( hostname, service.description, result, _legacy_determine_cache_info(multi_host_sections, SectionName(section_name)), ) return True
def get_aggregated_result( multi_host_sections: MultiHostSections, host_config: config.HostConfig, ipaddress: Optional[HostAddress], service: Service, plugin: Optional[checking_classes.CheckPlugin], params_function: Callable[[], Parameters], ) -> Tuple[bool, bool, ServiceCheckResult]: """Run the check function and aggregate the subresults This function is also called during discovery. Returns a triple: bool: should the result be submitted to the core bool: did we receive data for the plugin ServiceCheckResult: The aggregated result as returned by the plugin, or a fallback """ if plugin is None: return False, True, CHECK_NOT_IMPLEMENTED check_function = (plugin.cluster_check_function if host_config.is_cluster else plugin.check_function) source_type = (SourceType.MANAGEMENT if service.check_plugin_name.is_management_name() else SourceType.HOST) config_cache = config.get_config_cache() kwargs = {} try: kwargs = multi_host_sections.get_section_cluster_kwargs( config_cache.get_clustered_service_node_keys( host_config.hostname, source_type, service.description, ip_lookup.lookup_ip_address, ) or [], plugin.sections, ) if host_config.is_cluster else multi_host_sections.get_section_kwargs( HostKey(host_config.hostname, ipaddress, source_type), plugin.sections, ) if not kwargs and not service.check_plugin_name.is_management_name(): # in 1.6 some plugins where discovered for management boards, but with # the regular host plugins name. In this case retry with the source type # forced to MANAGEMENT: kwargs = multi_host_sections.get_section_cluster_kwargs( config_cache.get_clustered_service_node_keys( host_config.hostname, SourceType.MANAGEMENT, service.description, ip_lookup.lookup_ip_address, ) or [], plugin.sections, ) if host_config.is_cluster else multi_host_sections.get_section_kwargs( HostKey(host_config.hostname, ipaddress, SourceType.MANAGEMENT), plugin.sections, ) if not kwargs: # no data found return False, False, RECEIVED_NO_DATA if service.item is not None: kwargs["item"] = service.item if plugin.check_default_parameters is not None: kwargs["params"] = params_function() with value_store.context(plugin.name, service.item): result = _aggregate_results(check_function(**kwargs)) except (item_state.MKCounterWrapped, checking_classes.IgnoreResultsError) as e: msg = str(e) or "No service summary available" return False, True, (0, msg, []) except MKTimeout: raise except Exception: if cmk.utils.debug.enabled(): raise result = 3, cmk.base.crash_reporting.create_check_crash_dump( host_config.hostname, service.check_plugin_name, kwargs, is_manual_check(host_config.hostname, service.id()), service.description, ), [] return True, True, result
def test_get_host_sections_cluster(mode, monkeypatch, mocker): hostname = "testhost" hosts = { "host0": "10.0.0.0", "host1": "10.0.0.1", "host2": "10.0.0.2", } address = "1.2.3.4" tags = {"agent": "no-agent"} section_name = SectionName("test_section") config_cache = make_scenario(hostname, tags).apply(monkeypatch) host_config = config.HostConfig.make_host_config(hostname) def lookup_ip_address(host_config, family=None, for_mgmt_board=False): return hosts[host_config.hostname] def check(_, *args, **kwargs): return result.OK(AgentHostSections(sections={section_name: [[str(section_name)]]})) monkeypatch.setattr( ip_lookup, "lookup_ip_address", lookup_ip_address, ) monkeypatch.setattr( Source, "parse", check, ) mocker.patch.object( cmk.utils.piggyback, "remove_source_status_file", autospec=True, ) mocker.patch.object( cmk.utils.piggyback, "_store_status_file_of", autospec=True, ) # Create a cluster host_config.nodes = list(hosts.keys()) nodes = make_nodes( config_cache, host_config, address, mode=mode, sources=make_sources(host_config, address, mode=mode) ) mhs = MultiHostSections() update_host_sections( mhs, nodes, max_cachefile_age=host_config.max_cachefile_age, host_config=host_config, fetcher_messages=[ FetcherMessage.from_raw_data( result.OK(source.default_raw_data), Snapshot.null(), source.fetcher_type, ) for _h, _i, sources in nodes for source in sources ], selected_sections=NO_SELECTION, ) assert len(mhs) == len(hosts) == 3 cmk.utils.piggyback._store_status_file_of.assert_not_called() # type: ignore[attr-defined] assert cmk.utils.piggyback.remove_source_status_file.call_count == 3 # type: ignore[attr-defined] for host, addr in hosts.items(): remove_source_status_file = cmk.utils.piggyback.remove_source_status_file remove_source_status_file.assert_any_call(host) # type: ignore[attr-defined] key = HostKey(host, addr, SourceType.HOST) assert key in mhs section = mhs[key] assert len(section.sections) == 1 assert next(iter(section.sections)) == section_name assert not section.cache_info assert not section.piggybacked_raw_data
def test__find_candidates(): mhs = MultiHostSections() mhs._data = { # we just care about the keys here, content set to [] for simplicity # section names have been are chosen arbitrarily. # any HostSections type is fine. HostKey("test_node", "1.2.3.4", SourceType.HOST): AgentHostSections({ SectionName("kernel"): [], # host only SectionName("uptime"): [['123']], # host & mgmt }), HostKey("test_node", "1.2.3.4", SourceType.MANAGEMENT): AgentHostSections({ SectionName("uptime"): [['123']], # host & mgmt SectionName("liebert_fans"): [[]], # mgmt only SectionName("mgmt_snmp_info"): [[]], # is already mgmt_ prefixed }), } preliminary_candidates = list( agent_based_register.iter_all_check_plugins()) parsed_sections_of_interest = { parsed_section_name for plugin in preliminary_candidates for parsed_section_name in plugin.sections } assert discovery._find_host_candidates( mhs, preliminary_candidates, parsed_sections_of_interest, ) == { CheckPluginName('docker_container_status_uptime'), CheckPluginName("kernel"), CheckPluginName('kernel_performance'), CheckPluginName('kernel_util'), CheckPluginName("uptime"), } assert discovery._find_mgmt_candidates( mhs, preliminary_candidates, parsed_sections_of_interest, ) == { CheckPluginName('mgmt_docker_container_status_uptime'), CheckPluginName("mgmt_liebert_fans"), CheckPluginName("mgmt_uptime"), CheckPluginName("mgmt_snmp_info"), # not mgmt_mgmt_... } assert discovery._find_candidates( mhs, selected_check_plugins=None, ) == { CheckPluginName('docker_container_status_uptime'), CheckPluginName("kernel"), CheckPluginName('kernel_performance'), CheckPluginName('kernel_util'), CheckPluginName('mgmt_docker_container_status_uptime'), CheckPluginName("mgmt_liebert_fans"), CheckPluginName("mgmt_uptime"), CheckPluginName("mgmt_snmp_info"), # not mgmt_mgmt_... CheckPluginName("uptime"), }
@pytest.mark.parametrize( "hostname,host_entries,cluster_node_keys,expected_result", [ # No clusters ("heute", [ ('heute', NODE_1), ], None, NODE_1), # Clusters: host_of_clustered_service returns cluster name. That means that # the service is assigned to the cluster ("cluster", [ ('node1', NODE_1), ('node2', NODE_2), ], [ HostKey("node1", "127.0.0.1", SourceType.HOST), HostKey("node2", "127.0.0.1", SourceType.HOST), ], NODE_1 + NODE_2), # host_of_clustered_service returns either the cluster or node name. # That means that the service is assigned to the cluster resp. not to the cluster ("cluster", [ ('node1', NODE_1), ('node2', NODE_2), ], [ HostKey("node2", "127.0.0.1", SourceType.HOST), ], NODE_2), ]) def test_get_section_content(hostname, host_entries, cluster_node_keys, expected_result): multi_host_sections = MultiHostSections()
def _do_inv_for_realhost( config_cache: config.ConfigCache, host_config: config.HostConfig, sources: Sequence[ABCSource], multi_host_sections: Optional[MultiHostSections], hostname: HostName, ipaddress: Optional[HostAddress], inventory_tree: StructuredDataTree, status_data_tree: StructuredDataTree, ) -> Sequence[Tuple[ABCSource, Result[ABCHostSections, Exception]]]: results: List[Tuple[ABCSource, Result[ABCHostSections, Exception]]] = [] for source in sources: if isinstance(source, checkers.snmp.SNMPSource): # TODO(ml): This modifies the SNMP fetcher config dynamically. source.on_snmp_scan_error = "raise" # default checkers.FileCacheConfigurer.snmp_disabled = True source.use_snmpwalk_cache = False source.ignore_check_interval = True if multi_host_sections is not None: # Status data inventory already provides filled multi_host_sections object. # SNMP data source: If 'do_status_data_inv' is enabled there may be # sections for inventory plugins which were not fetched yet. host_sections = multi_host_sections.setdefault( # TODO(ml): are # hostname == source.hostname # ipaddress == source.ipaddress # ? HostKey(hostname, ipaddress, source.source_type), SNMPHostSections(), ) # TODO(ml): This modifies the SNMP fetcher config dynamically. # Can the fetcher handle that on its own? source.prefetched_sections = host_sections.sections # When executing the structured status inventory, we are in the Mode.CHECKING assert source.mode is Mode.INVENTORY or source.mode is Mode.CHECKING host_section = source.parse(source.fetch()) results.append((source, host_section)) if host_section.is_ok(): assert host_section.ok is not None host_sections.update(host_section.ok) if multi_host_sections is None: multi_host_sections = MultiHostSections() hs = checkers.update_host_sections( multi_host_sections, checkers.make_nodes( config_cache, host_config, ipaddress, checkers.Mode.INVENTORY, sources, ), max_cachefile_age=host_config.max_cachefile_age, selected_raw_sections=None, host_config=host_config, ) results.extend(hs) section.section_step("Executing inventory plugins") console.verbose("Plugins:") for inventory_plugin in agent_based_register.iter_all_inventory_plugins(): kwargs = multi_host_sections.get_section_kwargs( HostKey(hostname, ipaddress, SourceType.HOST), inventory_plugin.sections, ) if not kwargs: continue console.verbose( " %s%s%s%s" % (tty.green, tty.bold, inventory_plugin.name, tty.normal)) # Inventory functions can optionally have a second argument: parameters. # These are configured via rule sets (much like check parameters). if inventory_plugin.inventory_ruleset_name is not None: kwargs["params"] = host_config.inventory_parameters( str(inventory_plugin.inventory_ruleset_name) ) # TODO (mo): keep type! _aggregate_inventory_results( inventory_plugin.inventory_function(**kwargs), inventory_tree, status_data_tree, ) console.verbose("\n") return results