def test_get_section_cluster_kwargs(patch_register, required_sections, expected_result): node1_sections = AgentHostSections(sections={ SectionName("one"): NODE_1, SectionName("two"): NODE_1, SectionName("three"): NODE_1 }) node2_sections = AgentHostSections(sections={ SectionName("two"): NODE_2, SectionName("three"): NODE_2, }) parsed_sections_broker = ParsedSectionsBroker({ HostKey("node1", "127.0.0.1", SourceType.HOST): SectionsParser(host_sections=node1_sections ), HostKey("node2", "127.0.0.1", SourceType.HOST): SectionsParser(host_sections=node2_sections ), }) kwargs = parsed_sections_broker.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_parse_function_called_once(sections_parser: SectionsParser) -> None: counter = iter((1,)) section = _section("one", lambda x: next(counter)) _ = sections_parser.parse(section) parsing_result = sections_parser.parse(section) assert parsing_result is not None assert parsing_result.data == 1
def test_get_section_kwargs( required_sections: List[str], expected_result: Dict[str, Dict[str, str]]) -> None: node_sections = AgentHostSections( sections={ SectionName("one"): NODE_1, SectionName("two"): NODE_1, SectionName("three"): NODE_1, }) host_key = HostKey(HostName("node1"), HostAddress("127.0.0.1"), SourceType.HOST) parsed_sections_broker = ParsedSectionsBroker({ host_key: ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ]), SectionsParser(host_sections=node_sections), ), }) kwargs = get_section_kwargs( parsed_sections_broker, host_key, [ParsedSectionName(n) for n in required_sections], ) assert expected_result == kwargs
def test_get_section_cluster_kwargs(required_sections: Sequence[str], expected_result: Dict[str, Any]) -> None: node1_sections = HostSections[AgentRawDataSection]( sections={ SectionName("one"): NODE_1, SectionName("two"): NODE_1, SectionName("three"): NODE_1, }) node2_sections = HostSections[AgentRawDataSection]( sections={ SectionName("two"): NODE_2, SectionName("three"): NODE_2, }) parsed_sections_broker = ParsedSectionsBroker({ HostKey(HostName("node1"), HostAddress("127.0.0.1"), SourceType.HOST): ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ], ), SectionsParser(host_sections=node1_sections, host_name=HostName("node1")), ), HostKey(HostName("node2"), HostAddress("127.0.0.1"), SourceType.HOST): ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ], ), SectionsParser(host_sections=node2_sections, host_name=HostName("node2")), ), }) kwargs = get_section_cluster_kwargs( parsed_sections_broker, [ HostKey(HostName("node1"), HostAddress("127.0.0.1"), SourceType.HOST), HostKey(HostName("node2"), HostAddress("127.0.0.1"), SourceType.HOST), ], [ParsedSectionName(n) for n in required_sections], ) assert expected_result == kwargs
def sections_parser(self) -> SectionsParser: return SectionsParser( host_sections=HostSections[AgentRawDataSection](sections={ SectionName("one"): [], SectionName("two"): [], }), host_name=HostName("only-neede-for-crash-reporting"), )
def test_parse(sections_parser: SectionsParser) -> None: parsed_data = object() section = _section("one", lambda x: parsed_data) parsing_result = sections_parser.parse(section) assert parsing_result is not None assert parsing_result.data is parsed_data assert parsing_result.cache_info is None
def _get_parser() -> SectionsParser: return SectionsParser( HostSections[AgentRawDataSection](sections={ SectionName("one"): NODE_1, SectionName("four"): NODE_1, }), host_name=HostName("some-host"), )
def sections_parser(self) -> SectionsParser: return SectionsParser( host_sections=HostSections[AgentRawDataSection]( sections={ SectionName("one"): [], SectionName("two"): [], } ) )
def _get_host_section_for_parse_sections_test(): node_sections = AgentHostSections(sections={ SectionName("one"): NODE_1, SectionName("four"): NODE_1, }) host_key = HostKey("node1", "127.0.0.1", SourceType.HOST) broker = ParsedSectionsBroker({host_key: SectionsParser(host_sections=node_sections)}) return host_key, broker
def test_get_section_content(hostname, host_entries, cluster_node_keys, expected_result): parsed_sections_broker = ParsedSectionsBroker({ HostKey(nodename, "127.0.0.1", SourceType.HOST): ( ParsedSectionsResolver( # NOTE: this tests the legacy functionality. The "proper" ParsedSectionsBroker # methods are bypassed, so these will not matter at all: section_plugins=[], ), SectionsParser(host_sections=AgentHostSections( sections={ SectionName("section_plugin_name"): node_section_content })), ) for nodename, node_section_content in host_entries }) mhs = _MultiHostSections(parsed_sections_broker) section_content = mhs.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.HOST), 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 = mhs.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.HOST), 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 = mhs.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.MANAGEMENT), 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_get_parsed_section(patch_register, node_sections, expected_result): parsed_sections_broker = ParsedSectionsBroker({ HostKey("node1", "127.0.0.1", SourceType.HOST): SectionsParser(host_sections=node_sections) }) content = parsed_sections_broker.get_parsed_section( HostKey("node1", "127.0.0.1", SourceType.HOST), ParsedSectionName("parsed"), ) assert expected_result == content
def test_get_section_cluster_kwargs(required_sections, expected_result): node1_sections = AgentHostSections( sections={ SectionName("one"): NODE_1, SectionName("two"): NODE_1, SectionName("three"): NODE_1 }) node2_sections = AgentHostSections(sections={ SectionName("two"): NODE_2, SectionName("three"): NODE_2, }) parsed_sections_broker = ParsedSectionsBroker({ HostKey("node1", "127.0.0.1", SourceType.HOST): ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ], ), SectionsParser(host_sections=node1_sections), ), HostKey("node2", "127.0.0.1", SourceType.HOST): ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ], ), SectionsParser(host_sections=node2_sections), ), }) kwargs = get_section_cluster_kwargs( parsed_sections_broker, [ 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
def test_parsing_errors(monkeypatch, sections_parser: SectionsParser) -> None: monkeypatch.setattr( crash_reporting, "create_section_crash_dump", lambda **kw: "crash dump msg", ) section = _section("one", lambda x: 1 / 0) assert sections_parser.parse(section) is None assert len(sections_parser.parsing_errors) == 1 assert sections_parser.parsing_errors[0].startswith( "Parsing of section one failed - please submit a crash report! (Crash-ID: " )
def test_parsing_errors(monkeypatch, sections_parser: SectionsParser) -> None: monkeypatch.setattr( crash_reporting, "create_section_crash_dump", lambda **kw: "crash dump msg", ) # Debug mode raises instead of creating the crash report that we want here. cmk.utils.debug.disable() section = _section("one", lambda x: 1 / 0) assert sections_parser.parse(section) is None assert len(sections_parser.parsing_errors) == 1 assert sections_parser.parsing_errors[0].startswith( "Parsing of section one failed - please submit a crash report! (Crash-ID: " )
def test_get_parsed_section(node_sections, expected_result): parsed_sections_broker = ParsedSectionsBroker({ HostKey("node1", "127.0.0.1", SourceType.HOST): ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ], ), SectionsParser(host_sections=node_sections), ), }) content = parsed_sections_broker.get_parsed_section( HostKey("node1", "127.0.0.1", SourceType.HOST), ParsedSectionName("parsed"), ) assert expected_result == content
def test_get_parsed_section(node_sections: HostSections[AgentRawDataSection], expected_result: Mapping) -> None: parsed_sections_broker = ParsedSectionsBroker({ HostKey(HostName("node1"), HostAddress("127.0.0.1"), SourceType.HOST): ( ParsedSectionsResolver(section_plugins=[ SECTION_ONE, SECTION_TWO, SECTION_THREE, SECTION_FOUR ], ), SectionsParser(host_sections=node_sections), ), }) content = parsed_sections_broker.get_parsed_section( HostKey(HostName("node1"), HostAddress("127.0.0.1"), SourceType.HOST), ParsedSectionName("parsed"), ) assert expected_result == content
def test_get_section_kwargs(patch_register, required_sections, expected_result): node_sections = AgentHostSections(sections={ SectionName("one"): NODE_1, SectionName("two"): NODE_1, SectionName("three"): NODE_1 }) host_key = HostKey("node1", "127.0.0.1", SourceType.HOST) parsed_sections_broker = ParsedSectionsBroker({ host_key: SectionsParser(host_sections=node_sections), }) kwargs = parsed_sections_broker.get_section_kwargs( host_key, [ParsedSectionName(n) for n in required_sections], ) assert expected_result == kwargs
def test_get_section_content(hostname, host_entries, cluster_node_keys, expected_result): parsed_sections_broker = ParsedSectionsBroker({ HostKey(nodename, "127.0.0.1", SourceType.HOST): SectionsParser(host_sections=AgentHostSections( sections={SectionName("section_plugin_name"): node_section_content})) for nodename, node_section_content in host_entries }) mhs = _MultiHostSections(parsed_sections_broker) section_content = mhs.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.HOST), 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 = mhs.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.HOST), 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 = mhs.get_section_content( HostKey(hostname, "127.0.0.1", SourceType.MANAGEMENT), 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__find_candidates(): broker = ParsedSectionsBroker({ # we just care about the keys here, content set to arbitrary values that can be parsed. # section names are chosen arbitrarily. HostKey("test_node", "1.2.3.4", SourceType.HOST): SectionsParser( host_sections=AgentHostSections({ SectionName("kernel"): [], # host only SectionName("uptime"): [['123']], # host & mgmt }), ), HostKey("test_node", "1.2.3.4", SourceType.MANAGEMENT): SectionsParser( host_sections=SNMPHostSections({ # host & mgmt: SectionName("uptime"): [['123']], # type: ignore[dict-item] # mgmt only: SectionName("liebert_fans"): [[['Fan', '67', 'umin']]], # type: ignore[dict-item] # is already mgmt_ prefixed: SectionName("mgmt_snmp_info"): [[['a', 'b', 'c', 'd']]], # type: ignore[dict-item] }), ), }) 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._discovered_services._find_host_candidates( broker, preliminary_candidates, parsed_sections_of_interest, ) == { CheckPluginName('docker_container_status_uptime'), CheckPluginName("kernel"), CheckPluginName('kernel_performance'), CheckPluginName('kernel_util'), CheckPluginName("uptime"), } assert discovery._discovered_services._find_mgmt_candidates( broker, preliminary_candidates, parsed_sections_of_interest, ) == { CheckPluginName('mgmt_docker_container_status_uptime'), CheckPluginName("mgmt_liebert_fans"), CheckPluginName("mgmt_uptime"), } assert discovery._discovered_services._find_candidates( broker, run_plugin_names=EVERYTHING, ) == { 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("uptime"), }
def test_parse_section_returns_none( sections_parser: SectionsParser) -> None: section = _section("one", lambda x: None) assert sections_parser.parse(section) is None
def test_parse_missing_section(sections_parser: SectionsParser) -> None: missing_section = _section("missing_section", lambda x: 42) # function does not matter assert sections_parser.parse(missing_section) is None
def test_disable(sections_parser: SectionsParser) -> None: section = _section("one", lambda x: 42) sections_parser.disable((SectionName("one"), )) assert sections_parser.parse(section) is None
def sections_parser(self) -> SectionsParser: return SectionsParser(host_sections=AgentHostSections(sections={ SectionName("one"): [], SectionName("two"): [], }))
def _cluster_scenario(monkeypatch): hostname = "test-clusterhost" ipaddress = "1.2.3.4" node1_hostname = 'test-node1' node2_hostname = 'test-node2' def fake_lookup_ip_address(*_a, **_kw): return ipaddress monkeypatch.setattr(ip_lookup, "lookup_ip_address", fake_lookup_ip_address) ts = Scenario() ts.add_host(node1_hostname) ts.add_host(node2_hostname) ts.add_cluster(hostname, nodes=[node1_hostname, node2_hostname]) ts.set_ruleset("inventory_df_rules", [{ 'value': { 'ignore_fs_types': ['tmpfs', 'nfs', 'smbfs', 'cifs', 'iso9660'], 'never_ignore_mountpoints': ['~.*/omd/sites/[^/]+/tmp$'] }, 'condition': { 'host_labels': { 'cmk/check_mk_server': 'yes' } } }]) ts.set_ruleset("clustered_services", [([], [node1_hostname], ['fs_'])]) host_config = ts.apply(monkeypatch).get_host_config(hostname) DiscoveredHostLabelsStore(node1_hostname).save({ 'node1_existing_label': { 'plugin_name': 'node1_plugin', 'value': 'true', } }) DiscoveredHostLabelsStore(hostname).save({ 'existing_label': { 'plugin_name': 'foo', 'value': 'bar', }, 'another_label': { 'plugin_name': 'labels', 'value': 'true', } }) broker = ParsedSectionsBroker({ HostKey(hostname=node1_hostname, ipaddress=ipaddress, source_type=SourceType.HOST): SectionsParser(host_sections=AgentHostSections(sections={ SectionName("labels"): [ [ '{"cmk/check_mk_server":"yes"}', ], ], SectionName("df"): [ [ '/dev/sda1', 'vfat', '523248', '3668', '519580', '1%', '/boot/test-efi', ], [ 'tmpfs', 'tmpfs', '8152916', '244', '8152672', '1%', '/opt/omd/sites/test-heute/tmp', ], ], }, ), ), HostKey(hostname=node2_hostname, ipaddress=ipaddress, source_type=SourceType.HOST): SectionsParser(host_sections=AgentHostSections(sections={ SectionName("labels"): [ [ '{"node2_live_label":"true"}', ], ], SectionName("df"): [ [ '/dev/sda1', 'vfat', '523248', '3668', '519580', '1%', '/boot/test-efi', ], [ 'tmpfs', 'tmpfs', '8152916', '244', '8152672', '1%', '/opt/omd/sites/test-heute2/tmp', ], ], }, ), ), }) return ClusterScenario( host_config, ipaddress, broker, node1_hostname, node2_hostname, )
def _get_parser() -> SectionsParser: return SectionsParser( AgentHostSections(sections={ SectionName("one"): NODE_1, SectionName("four"): NODE_1, }), )