예제 #1
0
 def store(self):
     return SNMPPluginStore({
         SectionName("section0"): SNMPPluginStoreItem(
             [
                 BackendSNMPTree(base=".1.2.3",
                                 oids=[
                                     BackendOIDSpec("4.5", "string", False),
                                     BackendOIDSpec("9.7", "string", False)
                                 ]),
                 BackendSNMPTree(base=".8.9.0",
                                 oids=[
                                     BackendOIDSpec("1.2", "string", False),
                                     BackendOIDSpec("3.4", "string", False)
                                 ]),
             ],
             SNMPDetectSpec([[
                 ("oid0", "regex0", True),
                 ("oid1", "regex1", True),
                 ("oid2", "regex2", False),
             ]]),
         ),
         SectionName("section1"): SNMPPluginStoreItem(
             [
                 BackendSNMPTree(base=".1.2.3",
                                 oids=[
                                     BackendOIDSpec("4.5", "string", False),
                                     BackendOIDSpec("6.7.8", "string", False)
                                 ])
             ],
             SNMPDetectSpec([[
                 ("oid3", "regex3", True),
                 ("oid4", "regex4", False),
             ]]),
         ),
     })
예제 #2
0
 def fetcher_fixture(self, file_cache):
     SNMPFetcher.snmp_plugin_store = SNMPPluginStore({
         SectionName("pim"): SNMPPluginStoreItem(
             trees=[
                 BackendSNMPTree(base=".1.1.1",
                                 oids=[
                                     BackendOIDSpec("1.2", "string", False),
                                     BackendOIDSpec("3.4", "string", False)
                                 ])
             ],
             detect_spec=SNMPDetectSpec([[("1.2.3.4", "pim device", True)]]),
         ),
         SectionName("pam"): SNMPPluginStoreItem(
             trees=[
                 BackendSNMPTree(
                     base=".1.2.3",
                     oids=[
                         BackendOIDSpec("4.5", "string", False),
                         BackendOIDSpec("6.7", "string", False),
                         BackendOIDSpec("8.9", "string", False)
                     ],
                 ),
             ],
             detect_spec=SNMPDetectSpec([[("1.2.3.4", "pam device", True)]]),
         ),
         SectionName("pum"): SNMPPluginStoreItem(
             trees=[
                 BackendSNMPTree(base=".2.2.2", oids=[BackendOIDSpec("2.2", "string", False)]),
                 BackendSNMPTree(base=".3.3.3", oids=[BackendOIDSpec("2.2", "string", False)]),
             ],
             detect_spec=SNMPDetectSpec([[]]),
         ),
     })
     return SNMPFetcher(
         file_cache,
         disabled_sections=set(),
         configured_snmp_sections=set(),
         inventory_snmp_sections=set(),
         on_error="raise",
         missing_sys_description=False,
         use_snmpwalk_cache=False,
         do_status_data_inventory=False,
         snmp_config=SNMPHostConfig(
             is_ipv6_primary=False,
             hostname="bob",
             ipaddress="1.2.3.4",
             credentials="public",
             port=42,
             is_bulkwalk_host=False,
             is_snmpv2or3_without_bulkwalk_host=False,
             bulk_walk_size_of=0,
             timing={},
             oid_range_limits=[],
             snmpv3_contexts=[],
             character_encoding=None,
             is_usewalk_host=False,
             snmp_backend=SNMPBackend.classic,
         ),
     )
예제 #3
0
def test_all_of():

    spec1 = SNMPDetectSpec([[(".1", "1?", True)]])
    spec2 = SNMPDetectSpec([[(".2", "2?", True)]])
    spec3 = SNMPDetectSpec([[(".3", "3?", True)]])

    assert utils.all_of(spec1, spec2, spec3) == SNMPDetectSpec([[
        (".1", "1?", True),
        (".2", "2?", True),
        (".3", "3?", True),
    ]])

    spec12 = utils.all_of(spec1, spec2)
    assert utils.all_of(spec1, spec2, spec3) == utils.all_of(spec12, spec3)
예제 #4
0
def test_all_of_any_of():

    spec1 = SNMPDetectSpec([[(".1", "1?", True)]])
    spec2 = SNMPDetectSpec([[(".2", "2?", True)]])
    spec3 = SNMPDetectSpec([[(".3", "3?", True)]])
    spec4 = SNMPDetectSpec([[(".4", "4?", True)]])

    spec12 = utils.any_of(spec1, spec2)
    spec34 = utils.any_of(spec3, spec4)

    assert utils.all_of(spec12, spec34) == SNMPDetectSpec([
        [(".1", "1?", True), (".3", "3?", True)],
        [(".1", "1?", True), (".4", "4?", True)],
        [(".2", "2?", True), (".3", "3?", True)],
        [(".2", "2?", True), (".4", "4?", True)],
    ])
예제 #5
0
 def test_rule_indipendent(
     self,
     monkeypatch,
     hostname,
     ipaddress,
 ):
     plugin = section_plugins.create_snmp_section_plugin(
         name="norris",
         parse_function=lambda string_table: None,
         trees=[
             SNMPTree(
                 base='.1.2.3',
                 oids=['2.3'],
             ),
         ],
         detect_spec=SNMPDetectSpec([[('.1.2.3.4.5', 'Foo.*', True)]]),
     )
     source = self.do_monkeypatch_and_make_source(
         monkeypatch,
         plugin,
         hostname,
         ipaddress,
     )
     assert source._make_snmp_section_detects() == [(plugin.name,
                                                     plugin.detect_spec)]
예제 #6
0
def test_create_snmp_section_plugin():

    trees: List[SNMPTree] = [
        SNMPTree(
            base='.1.2.3',
            oids=[OIDEnd(), '2.3'],
        ),
    ]

    detect = SNMPDetectSpec([
        [('.1.2.3.4.5', 'Foo.*', True)],
    ])

    plugin = section_plugins.create_snmp_section_plugin(
        name="norris",
        parsed_section_name="chuck",
        parse_function=_parse_dummy,
        fetch=trees,
        detect_spec=detect,
        supersedes=["foo", "bar"],
    )

    assert isinstance(plugin, SNMPSectionPlugin)
    assert len(plugin) == 8
    assert plugin.name == SectionName("norris")
    assert plugin.parsed_section_name == ParsedSectionName("chuck")
    assert plugin.parse_function is _parse_dummy
    assert plugin.host_label_function is section_plugins._noop_host_label_function
    assert plugin.detect_spec == detect
    assert plugin.trees == trees
    assert plugin.supersedes == {SectionName("bar"), SectionName("foo")}
예제 #7
0
    def from_json(cls, serialized: Dict[str, Any]) -> 'SNMPFetcher':
        # The SNMPv3 configuration is represented by a tuple of different lengths (see
        # SNMPCredentials). Since we just deserialized from JSON, we have to convert the
        # list used by JSON back to a tuple.
        # SNMPv1/v2 communities are represented by a string: Leave it untouched.
        if isinstance(serialized["snmp_config"]["credentials"], list):
            serialized["snmp_config"]["credentials"] = tuple(
                serialized["snmp_config"]["credentials"])

        return cls(
            file_cache=SNMPFileCache.from_json(serialized.pop("file_cache")),
            snmp_section_trees={
                SectionName(name): [SNMPTree.from_json(tree) for tree in trees
                                   ] for name, trees in serialized["snmp_section_trees"].items()
            },
            snmp_section_detects=[
                (
                    SectionName(name),
                    # The cast is necessary as mypy does not infer types in a list comprehension.
                    # See https://github.com/python/mypy/issues/5068
                    SNMPDetectSpec([[cast(SNMPDetectAtom, tuple(inner))
                                     for inner in outer]
                                    for outer in specs]),
                )
                for name, specs in serialized["snmp_section_detects"]
            ],
            configured_snmp_sections={
                SectionName(name) for name in serialized["configured_snmp_sections"]
            },
            on_error=serialized["on_error"],
            missing_sys_description=serialized["missing_sys_description"],
            use_snmpwalk_cache=serialized["use_snmpwalk_cache"],
            snmp_config=SNMPHostConfig(**serialized["snmp_config"]),
        )
예제 #8
0
 def deserialize(cls, serialized: Mapping[str,
                                          Any]) -> "SNMPPluginStoreItem":
     return cls(
         [BackendSNMPTree.from_json(tree) for tree in serialized["trees"]],
         SNMPDetectSpec.from_json(serialized["detect_spec"]),
         serialized["inventory"],
     )
예제 #9
0
 def _make_snmp_plugin_store() -> SNMPPluginStore:
     return SNMPPluginStore({
         s.name: SNMPPluginStoreItem(
             [BackendSNMPTree.from_frontend(base=t.base, oids=t.oids) for t in s.trees],
             SNMPDetectSpec(s.detect_spec))
         for s in agent_based_register.iter_all_snmp_sections()
     })
예제 #10
0
 def snmp_plugin_fixture(self) -> None:
     SNMPFetcher.plugin_store = SNMPPluginStore({
         SectionName("pim"):
         SNMPPluginStoreItem(
             trees=[
                 BackendSNMPTree(
                     base=".1.1.1",
                     oids=[
                         BackendOIDSpec("1.2", "string", False),
                         BackendOIDSpec("3.4", "string", False),
                     ],
                 )
             ],
             detect_spec=SNMPDetectSpec([[("1.2.3.4", "pim device", True)]
                                         ]),
             inventory=False,
         ),
         SectionName("pam"):
         SNMPPluginStoreItem(
             trees=[
                 BackendSNMPTree(
                     base=".1.2.3",
                     oids=[
                         BackendOIDSpec("4.5", "string", False),
                         BackendOIDSpec("6.7", "string", False),
                         BackendOIDSpec("8.9", "string", False),
                     ],
                 ),
             ],
             detect_spec=SNMPDetectSpec([[("1.2.3.4", "pam device", True)]
                                         ]),
             inventory=False,
         ),
         SectionName("pum"):
         SNMPPluginStoreItem(
             trees=[
                 BackendSNMPTree(
                     base=".2.2.2",
                     oids=[BackendOIDSpec("2.2", "string", False)]),
                 BackendSNMPTree(
                     base=".3.3.3",
                     oids=[BackendOIDSpec("2.2", "string", False)]),
             ],
             detect_spec=SNMPDetectSpec([[]]),
             inventory=False,
         ),
     })
예제 #11
0
파일: snmp.py 프로젝트: xorsiz0r/checkmk
 def deserialize(cls, serialized: Dict[str, Any]) -> "SNMPPluginStoreItem":
     try:
         return cls(
             [SNMPTree.from_json(tree) for tree in serialized["trees"]],
             SNMPDetectSpec.from_json(serialized["detect_spec"]),
         )
     except (LookupError, TypeError, ValueError) as exc:
         raise ValueError(serialized) from exc
예제 #12
0
def test_any_of():

    spec1 = SNMPDetectSpec([[(".1", "1?", True)]])
    spec2 = SNMPDetectSpec([[(".2", "2?", True)]])
    spec3 = SNMPDetectSpec([[(".3", "3?", True)]])

    spec123 = utils.any_of(spec1, spec2, spec3)

    _validate_detect_spec(spec123)
    assert spec123 == [
        [(".1", "1?", True)],
        [(".2", "2?", True)],
        [(".3", "3?", True)],
    ]

    spec12 = utils.any_of(spec1, spec2)

    assert spec123 == utils.any_of(spec12, spec3)
예제 #13
0
def _ast_convert_unary(unop_ast: ast.UnaryOp) -> SNMPDetectSpec:
    if isinstance(unop_ast.op, ast.Not):
        operand = _ast_convert_dispatcher(unop_ast.operand)
        _validate_detect_spec(operand)
        # We can only negate atomic specs, for now
        if len(operand) == 1 and len(operand[0]) == 1:
            oidstr, pattern, result = operand[0][0]
            return SNMPDetectSpec([[(oidstr, pattern, not result)]])
        raise NotImplementedError("cannot negate operand")
    raise ValueError(ast.dump(unop_ast))
예제 #14
0
 def specs(self):
     return SNMPDetectSpec(
         [
             [
                 ("oid0", "regex0", True),
                 ("oid1", "regex1", True),
                 ("oid2", "regex2", False),
             ]
         ]
     )
예제 #15
0
    def test_rule_dependent(
        self,
        monkeypatch,
        discovery_rulesets,
        hostname,
        ipaddress,
    ):
        detect_spec_1 = SNMPDetectSpec([[('.1.2.3.4.5', 'Bar.*', False)]])
        detect_spec_2 = SNMPDetectSpec([[('.7.8.9', 'huh.*', True)]])

        def evaluator(discovery_ruleset):
            if len(discovery_ruleset) > 0 and discovery_ruleset[0]:
                return detect_spec_1
            return detect_spec_2

        plugin = section_plugins.create_snmp_section_plugin(
            name="norris",
            parse_function=lambda string_table: None,
            trees=[
                SNMPTree(
                    base='.1.2.3',
                    oids=['2.3'],
                ),
            ],
            detect_spec=SNMPDetectSpec([[('.1.2.3.4.5', 'Foo.*', True)]]),
            rule_dependent_detect_spec=SNMPRuleDependentDetectSpec(
                [RuleSetName('discovery_ruleset')],
                evaluator,
            ),
        )
        snmp_configurator = self.do_monkeypatch_and_make_configurator(
            monkeypatch,
            plugin,
            hostname,
            ipaddress,
        )
        assert snmp_configurator._make_snmp_scan_sections() == [
            SNMPScanSection(
                plugin.name,
                detect_spec_1,
            )
        ]
예제 #16
0
 def fetcher_fixture(self, file_cache):
     return SNMPFetcher(
         file_cache,
         snmp_section_trees={
             SectionName("pim"):
             [SNMPTree(base=".1.1.1", oids=["1.2", "3.4"])],
             SectionName("pam"):
             [SNMPTree(base=".1.2.3", oids=["4.5", "6.7", "8.9"])],
             SectionName("pum"): [
                 SNMPTree(base=".2.2.2", oids=["2.2"]),
                 SNMPTree(base=".3.3.3", oids=["2.2"]),
             ],
         },
         snmp_section_detects={
             SectionName("pim"):
             SNMPDetectSpec([[("1.2.3.4", "pim device", True)]]),
             SectionName("pam"):
             SNMPDetectSpec([[("1.2.3.4", "pam device", True)]]),
         },
         disabled_sections=set(),
         configured_snmp_sections=set(),
         structured_data_snmp_sections=set(),
         on_error="raise",
         missing_sys_description=False,
         use_snmpwalk_cache=False,
         snmp_config=SNMPHostConfig(
             is_ipv6_primary=False,
             hostname="bob",
             ipaddress="1.2.3.4",
             credentials="public",
             port=42,
             is_bulkwalk_host=False,
             is_snmpv2or3_without_bulkwalk_host=False,
             bulk_walk_size_of=0,
             timing={},
             oid_range_limits=[],
             snmpv3_contexts=[],
             character_encoding=None,
             is_usewalk_host=False,
             snmp_backend=SNMPBackend.classic,
         ),
     )
예제 #17
0
def create_detect_spec(
    name: str,
    snmp_scan_function: Callable,
    fallback_files: List[str],
) -> SNMPDetectSpec:

    migrated = _lookup_migrated(snmp_scan_function)
    if migrated is not None:
        return migrated

    key = _lookup_key_from_code(snmp_scan_function.__code__)
    preconverted = PRECONVERTED_DETECT_SPECS.get(key)
    if preconverted is not None:
        return SNMPDetectSpec(preconverted)

    return SNMPDetectSpec(
        PRECONVERTED_DETECT_SPECS.setdefault(
            key,
            _compute_detect_spec(
                section_name=name,
                scan_function=snmp_scan_function,
                fallback_files=fallback_files,
            )))
예제 #18
0
def _compute_detect_spec(
    *,
    section_name: str,
    scan_function: Callable,
    fallback_files: List[str],
) -> SNMPDetectSpec:

    scan_func_ast = _get_scan_function_ast(section_name, scan_function, fallback_files)

    expression_ast = _get_expression_from_function(section_name, scan_func_ast)

    if _is_false(expression_ast):
        return SNMPDetectSpec()

    return _ast_convert_dispatcher(expression_ast)
예제 #19
0
파일: utils.py 프로젝트: hdhoang/checkmk
def any_of(*specs: SNMPDetectSpec) -> SNMPDetectSpec:
    """Detect the device if any of the passed specifications are met

    Args:
        spec: A valid specification for SNMP device detection

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = any_of(exists("1.2.3.4"), exists("1.2.3.5"))

    """
    return SNMPDetectSpec(sum(specs, []))
예제 #20
0
파일: utils.py 프로젝트: hdhoang/checkmk
def exists(oidstr: str) -> SNMPDetectSpec:
    """Detect the device if the OID exists at all

    Args:
        oidstr: The OID that is required to exist

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = exists("1.2.3")

    """
    return SNMPDetectSpec([[(oidstr, '.*', True)]])
예제 #21
0
def test_create_snmp_section_plugin_single_tree():

    single_tree = SNMPTree(base='.1.2.3', oids=[OIDEnd(), '2.3'])

    plugin = section_plugins.create_snmp_section_plugin(
        name="norris",
        parse_function=lambda string_table: string_table,
        # just one, no list:
        fetch=single_tree,
        detect_spec=SNMPDetectSpec([[('.1.2.3.4.5', 'Foo.*', True)]]),
    )

    assert plugin.trees == [single_tree]
    # the plugin only specified a single tree (not a list),
    # so a wrapper should unpack the argument:
    assert plugin.parse_function([[['A', 'B']]]) == [['A', 'B']]
예제 #22
0
파일: utils.py 프로젝트: hdhoang/checkmk
def endswith(oidstr: str, value: str) -> SNMPDetectSpec:
    """Detect the device if the value of the OID ends with the given string

    Args:
        oidstr: The OID to match the value against
        value: The expected end of the OIDs value

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = endswith("1.2.3", "nix")

    """
    return SNMPDetectSpec([[(oidstr, '.*%s' % re.escape(value), True)]])
예제 #23
0
파일: utils.py 프로젝트: hdhoang/checkmk
def contains(oidstr: str, value: str) -> SNMPDetectSpec:
    """Detect the device if the value of the OID contains the given string

    Args:
        oidstr: The OID to match the value against
        value: The substring expected to be in the OIDs value

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = contains("1.2.3", "isco")

    """
    return SNMPDetectSpec([[(oidstr, '.*%s.*' % re.escape(value), True)]])
예제 #24
0
파일: utils.py 프로젝트: hdhoang/checkmk
def matches(oidstr: str, value: str) -> SNMPDetectSpec:
    """Detect the device if the value of the OID matches the expression

    Args:
        oidstr: The OID to match the value against
        value: The regular expression that the value of the OID should match

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = match("1.2.3.4", ".* Server")

    """
    return SNMPDetectSpec([[(oidstr, value, True)]])
예제 #25
0
파일: utils.py 프로젝트: hdhoang/checkmk
def equals(oidstr: str, value: str) -> SNMPDetectSpec:
    """Detect the device if the value of the OID equals the given string

    Args:
        oidstr: The OID to match the value against
        value: The expected value of the OID

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = equals("1.2.3", "MySwitch")

    """
    return SNMPDetectSpec([[(oidstr, '%s' % re.escape(value), True)]])
예제 #26
0
def test_make_snmp_section_detects_for_inventory(monkeypatch, hostname, ipaddress, check_plugin):
    plugin = section_plugins.create_snmp_section_plugin(
        name="norris",
        parse_function=lambda string_table: None,
        fetch=[
            SNMPTree(
                base='.1.2.3',
                oids=['2.3'],
            ),
        ],
        detect_spec=SNMPDetectSpec([[('.1.2.3.4.5', 'Foo.*', True)]]),
    )
    monkeypatch.setattr(_config, 'registered_snmp_sections', {plugin.name: plugin})
    monkeypatch.setattr(_config, 'registered_inventory_plugins', {check_plugin.name: check_plugin})

    Scenario().add_host(hostname).apply(monkeypatch)
    source = SNMPSource.snmp(hostname, ipaddress, mode=Mode.INVENTORY)
    assert source._make_snmp_section_detects() == {plugin.name: plugin.detect_spec}
예제 #27
0
def test_make_snmp_section_detects(monkeypatch, hostname, ipaddress):
    plugin = section_plugins.create_snmp_section_plugin(
        name="norris",
        parse_function=lambda string_table: None,
        fetch=[
            SNMPTree(
                base='.1.2.3',
                oids=['2.3'],
            ),
        ],
        detect_spec=SNMPDetectSpec([[('.1.2.3.4.5', 'Foo.*', True)]]),
    )
    monkeypatch.setattr(
        register,
        'iter_all_snmp_sections',
        lambda: [plugin],
    )
    Scenario().add_host(hostname).apply(monkeypatch)
    source = SNMPSource.snmp(hostname, ipaddress, mode=Mode.DISCOVERY)
    assert source._make_snmp_section_detects() == {plugin.name: plugin.detect_spec}
예제 #28
0
파일: utils.py 프로젝트: hdhoang/checkmk
def all_of(spec_0: SNMPDetectSpec, spec_1: SNMPDetectSpec,
           *specs: SNMPDetectSpec) -> SNMPDetectSpec:
    """Detect the device if all passed specifications are met

    Args:
        spec_0: A valid specification for SNMP device detection
        spec_1: A valid specification for SNMP device detection

    Returns:
        A valid specification for SNMP device detection

    Example:

        >>> DETECT = all_of(exists("1.2.3.4"), contains("1.2.3.5", "foo"))

    """
    reduced = SNMPDetectSpec(l0 + l1 for l0, l1 in itertools.product(spec_0, spec_1))
    if not specs:
        return reduced
    return all_of(reduced, *specs)
def create_detect_spec(name: str, snmp_scan_function: Callable,
                       fallback_files: List[str]) -> SNMPDetectSpec:
    if snmp_scan_function.__name__ in MIGRATED_SCAN_FUNCTIONS:
        try:
            _ = snmp_scan_function(lambda x, default=None: "")
        except NotImplementedError as exc:
            if str(exc) == "already migrated":
                return MIGRATED_SCAN_FUNCTIONS[snmp_scan_function.__name__]
        raise NotImplementedError("please remove migrated code entirely")

    scan_func_ast = _get_scan_function_ast(name, snmp_scan_function,
                                           fallback_files)

    expression_ast = _get_expression_from_function(name, scan_func_ast)

    if _is_false(expression_ast):
        spec = SNMPDetectSpec()
    else:
        spec = _ast_convert_dispatcher(expression_ast)

    return spec
예제 #30
0
 def test_serialization(self, specs):
     assert SNMPDetectSpec.from_json(specs.to_json()) == specs