Skip to content

Commit

Permalink
Revert "Remove layering violation in utils"
Browse files Browse the repository at this point in the history
This reverts commit 0359a8f.
  • Loading branch information
LarsMichelsen committed May 28, 2020
1 parent 249c4ea commit acd37ae
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 146 deletions.
2 changes: 0 additions & 2 deletions cmk/base/automations/check_mk.py
Expand Up @@ -58,7 +58,6 @@
from cmk.base.core_factory import create_core
from cmk.base.diagnostics import DiagnosticsDump
from cmk.base.discovered_labels import DiscoveredHostLabels, DiscoveredServiceLabels, ServiceLabel
from cmk.fetchers import factory # pylint: disable=cmk-module-layer-violation

HistoryFile = str
HistoryFilePair = Tuple[HistoryFile, HistoryFile]
Expand Down Expand Up @@ -1401,7 +1400,6 @@ def _execute_snmp(
snmp_config,
"",
('.1.3.6.1.2.1.1', ['1.0', '4.0', '5.0', '6.0']), # type: ignore[arg-type]
backend=factory.backend(snmp_config),
)

if data:
Expand Down
20 changes: 8 additions & 12 deletions cmk/base/snmp.py
Expand Up @@ -20,21 +20,18 @@
from cmk.utils.exceptions import MKBailOut, MKGeneralException
from cmk.utils.log import console
from cmk.utils.type_defs import (
ABCSNMPBackend,
DecodedString,
HostName,
OID,
HostName,
RawValue,
DecodedString,
SNMPHostConfig,
SNMPRowInfo,
)

import cmk.base.cleanup
import cmk.base.config as config
import cmk.base.ip_lookup as ip_lookup
from cmk.fetchers import factory # pylint: disable=cmk-module-layer-violation
from cmk.fetchers.snmp_backend import (StoredWalkSNMPBackend # pylint: disable=cmk-module-layer-violation,
)
from cmk.fetchers.factory import SNMPBackendFactory # pylint: disable=cmk-module-layer-violation

try:
from cmk.fetchers.cee.snmp_backend import inline # pylint: disable=cmk-module-layer-violation, ungrouped-imports
Expand Down Expand Up @@ -71,8 +68,8 @@ def create_snmp_host_config(hostname):


# Contextes can only be used when check_plugin_name is given.
def get_single_oid(snmp_config, oid, check_plugin_name=None, do_snmp_scan=True, *, backend):
# type: (SNMPHostConfig, str, Optional[str], bool, ABCSNMPBackend) -> Optional[DecodedString]
def get_single_oid(snmp_config, oid, check_plugin_name=None, do_snmp_scan=True):
# type: (SNMPHostConfig, str, Optional[str], bool) -> Optional[DecodedString]
# The OID can end with ".*". In that case we do a snmpgetnext and try to
# find an OID with the prefix in question. The *cache* is working including
# the X, however.
Expand All @@ -93,7 +90,7 @@ def get_single_oid(snmp_config, oid, check_plugin_name=None, do_snmp_scan=True,
console.vverbose(" Getting OID %s: " % oid)
for context_name in snmp_config.snmpv3_contexts_of(check_plugin_name):
try:
value = backend.get(
value = SNMPBackendFactory.get(
snmp_config,
oid=oid,
context_name=context_name,
Expand Down Expand Up @@ -123,7 +120,7 @@ def get_single_oid(snmp_config, oid, check_plugin_name=None, do_snmp_scan=True,

def walk_for_export(snmp_config, oid):
# type: (SNMPHostConfig, OID) -> SNMPRowInfoForStoredWalk
rows = StoredWalkSNMPBackend().walk(snmp_config, oid=oid)
rows = SNMPBackendFactory.walk(snmp_config, use_cache=False, oid=oid)
return _convert_rows_for_stored_walk(rows)


Expand Down Expand Up @@ -323,10 +320,9 @@ def do_snmpget(oid, hostnames):
for hostname in hostnames:
#TODO what about SNMP management boards?
snmp_config = create_snmp_host_config(hostname)
backend = factory.backend(snmp_config)
snmp_cache.initialize_single_oid_cache(snmp_config)

value = get_single_oid(snmp_config, oid, backend=backend)
value = get_single_oid(snmp_config, oid)
sys.stdout.write("%s (%s): %r\n" % (hostname, snmp_config.ipaddress, value))
cmk.base.cleanup.cleanup_globals()

Expand Down
13 changes: 2 additions & 11 deletions cmk/base/snmp_scan.py
Expand Up @@ -21,7 +21,6 @@
from cmk.base.api import PluginName
from cmk.base.api.agent_based.section_types import SNMPDetectAtom, SNMPDetectSpec
from cmk.base.snmp_utils import ScanFunction
from cmk.fetchers import factory # pylint: disable=cmk-module-layer-violation


def _evaluate_snmp_detection(oid_function, detect_spec):
Expand Down Expand Up @@ -78,7 +77,6 @@ def _snmp_scan(host_config,
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
backend = factory.backend(host_config)

# Make hostname globally available for scan functions.
# This is rarely used, but e.g. the scan for if/if64 needs
Expand All @@ -91,10 +89,7 @@ def _snmp_scan(host_config,
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,
backend=backend)
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. "
Expand Down Expand Up @@ -133,11 +128,7 @@ def _snmp_scan(host_config,

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,
backend=backend)
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):
Expand Down
59 changes: 48 additions & 11 deletions cmk/fetchers/factory.py
Expand Up @@ -6,7 +6,15 @@

from typing import Optional

from cmk.utils.type_defs import ABCSNMPBackend, SNMPHostConfig
from cmk.utils.type_defs import (
ABCSNMPBackend,
CheckPluginName,
ContextName,
OID,
RawValue,
SNMPHostConfig,
SNMPRowInfo,
)

from .snmp_backend import ClassicSNMPBackend, StoredWalkSNMPBackend

Expand All @@ -15,7 +23,7 @@
except ImportError:
inline = None # type: ignore[assignment]

__all__ = ["backend"]
__all__ = ["SNMPBackendFactory"]

_force_stored_walks = False

Expand All @@ -31,14 +39,43 @@ def get_force_stored_walks():
return _force_stored_walks


def backend(snmp_config, *, use_cache=None):
# type: (SNMPHostConfig, Optional[bool]) -> ABCSNMPBackend
if use_cache is None:
use_cache = get_force_stored_walks()
if use_cache or snmp_config.is_usewalk_host:
return StoredWalkSNMPBackend()
class SNMPBackendFactory(object): # pylint: disable=useless-object-inheritance
@staticmethod
def _factory(snmp_config, *, use_cache):
# type: (SNMPHostConfig, Optional[bool]) -> ABCSNMPBackend
if use_cache is None:
use_cache = get_force_stored_walks()
if use_cache or snmp_config.is_usewalk_host:
return StoredWalkSNMPBackend()

if snmp_config.is_inline_snmp_host:
return inline.InlineSNMPBackend(snmp_config.record_stats)
if snmp_config.is_inline_snmp_host:
return inline.InlineSNMPBackend(snmp_config.record_stats)

return ClassicSNMPBackend()
return ClassicSNMPBackend()

@classmethod
def get(cls, snmp_config, *, oid, context_name=None, use_cache=None):
# type: (SNMPHostConfig, OID, Optional[ContextName], bool) -> Optional[RawValue]
return cls._factory(snmp_config, use_cache=use_cache).get(
snmp_config,
oid=oid,
context_name=context_name,
)

@classmethod
def walk(cls,
snmp_config,
*,
oid,
context_name=None,
check_plugin_name=None,
table_base_oid=None,
use_cache=None):
# type: (SNMPHostConfig, OID, Optional[ContextName], Optional[CheckPluginName], Optional[OID], Optional[bool]) -> SNMPRowInfo
return cls._factory(snmp_config, use_cache=use_cache).walk(
snmp_config,
oid=oid,
context_name=context_name,
check_plugin_name=check_plugin_name,
table_base_oid=table_base_oid,
)
7 changes: 1 addition & 6 deletions cmk/fetchers/snmp.py
Expand Up @@ -5,16 +5,13 @@
# conditions defined in the file COPYING, which is part of this source code package.

import logging
from functools import partial
from types import TracebackType
from typing import Dict, List, Optional, Type, Union

import cmk.utils.snmp_table as snmp_table
from cmk.utils.check_utils import section_name_of
from cmk.utils.type_defs import ABCSNMPTree, OIDInfo, RawSNMPData, SNMPHostConfig, SNMPTable

from . import factory


class SNMPDataFetcher:
def __init__(
Expand Down Expand Up @@ -53,9 +50,7 @@ def data(self):

# oid_info can now be a list: Each element of that list is interpreted as one real oid_info
# and fetches a separate snmp table.
get_snmp = partial(snmp_table.get_snmp_table_cached
if self._use_snmpwalk_cache else snmp_table.get_snmp_table,
backend=factory.backend(self._snmp_config))
get_snmp = snmp_table.get_snmp_table_cached if self._use_snmpwalk_cache else snmp_table.get_snmp_table
if isinstance(oid_info, list):
# branch: List[ABCSNMPTree]
check_info = [] # type: List[SNMPTable]
Expand Down
49 changes: 22 additions & 27 deletions cmk/utils/snmp_table.py
Expand Up @@ -21,7 +21,6 @@
OID_END_BIN,
OID_END_OCTET_STRING,
OID_STRING,
ABCSNMPBackend,
ABCSNMPTree,
CheckPluginName,
Column,
Expand All @@ -42,19 +41,21 @@
SNMPValueEncoding,
)

from cmk.fetchers.factory import SNMPBackendFactory # pylint: disable=cmk-module-layer-violation

ResultColumnsUnsanitized = List[Tuple[OID, SNMPRowInfo, SNMPValueEncoding]]
ResultColumnsSanitized = List[Tuple[List[RawValue], SNMPValueEncoding]]
ResultColumnsDecoded = List[List[DecodedValues]]


def get_snmp_table(snmp_config, check_plugin_name, oid_info, *, backend):
# type: (SNMPHostConfig, CheckPluginName, Union[OIDInfo, ABCSNMPTree], ABCSNMPBackend) -> SNMPTable
return _get_snmp_table(snmp_config, check_plugin_name, oid_info, False, backend=backend)
def get_snmp_table(snmp_config, check_plugin_name, oid_info):
# type: (SNMPHostConfig, CheckPluginName, Union[OIDInfo, ABCSNMPTree]) -> SNMPTable
return _get_snmp_table(snmp_config, check_plugin_name, oid_info, False)


def get_snmp_table_cached(snmp_config, check_plugin_name, oid_info, *, backend):
# type: (SNMPHostConfig, CheckPluginName, Union[OIDInfo, ABCSNMPTree], ABCSNMPBackend) -> SNMPTable
return _get_snmp_table(snmp_config, check_plugin_name, oid_info, True, backend=backend)
def get_snmp_table_cached(snmp_config, check_plugin_name, oid_info):
# type: (SNMPHostConfig, CheckPluginName, Union[OIDInfo, ABCSNMPTree]) -> SNMPTable
return _get_snmp_table(snmp_config, check_plugin_name, oid_info, True)


SPECIAL_COLUMNS = [
Expand All @@ -67,8 +68,8 @@ def get_snmp_table_cached(snmp_config, check_plugin_name, oid_info, *, backend):


# TODO: OID_END_OCTET_STRING is not used at all. Drop it.
def _get_snmp_table(snmp_config, check_plugin_name, oid_info, use_snmpwalk_cache, *, backend):
# type: (SNMPHostConfig, CheckPluginName, Union[OIDInfo, ABCSNMPTree], bool, ABCSNMPBackend) -> SNMPTable
def _get_snmp_table(snmp_config, check_plugin_name, oid_info, use_snmpwalk_cache):
# type: (SNMPHostConfig, CheckPluginName, Union[OIDInfo, ABCSNMPTree], bool) -> SNMPTable
oid, suboids, targetcolumns = _make_target_columns(oid_info)

index_column = -1
Expand Down Expand Up @@ -96,13 +97,8 @@ def _get_snmp_table(snmp_config, check_plugin_name, oid_info, use_snmpwalk_cache
"You can only use one of OID_END, OID_STRING, OID_BIN, OID_END_BIN and OID_END_OCTET_STRING."
)

rowinfo = _get_snmpwalk(snmp_config,
check_plugin_name,
oid,
fetchoid,
column,
use_snmpwalk_cache,
backend=backend)
rowinfo = _get_snmpwalk(snmp_config, check_plugin_name, oid, fetchoid, column,
use_snmpwalk_cache)

if column in SPECIAL_COLUMNS:
index_column = len(columns)
Expand Down Expand Up @@ -245,9 +241,8 @@ def _key_oid_pairs(pair1):
return _oid_to_intlist(pair1[0].lstrip('.'))


def _get_snmpwalk(snmp_config, check_plugin_name, oid, fetchoid, column, use_snmpwalk_cache, *,
backend):
# type: (SNMPHostConfig, CheckPluginName, OID, OID, Column, bool, ABCSNMPBackend) -> SNMPRowInfo
def _get_snmpwalk(snmp_config, check_plugin_name, oid, fetchoid, column, use_snmpwalk_cache):
# type: (SNMPHostConfig, CheckPluginName, OID, OID, Column, bool) -> SNMPRowInfo
if column in SPECIAL_COLUMNS:
return []

Expand All @@ -256,23 +251,23 @@ def _get_snmpwalk(snmp_config, check_plugin_name, oid, fetchoid, column, use_snm
cached = _get_cached_snmpwalk(snmp_config.hostname, fetchoid) if get_from_cache else None
if cached is not None:
return cached
rowinfo = _perform_snmpwalk(snmp_config, check_plugin_name, oid, fetchoid, backend=backend)
rowinfo = _perform_snmpwalk(snmp_config, check_plugin_name, oid, fetchoid)
if save_to_cache:
_save_snmpwalk_cache(snmp_config.hostname, fetchoid, rowinfo)
return rowinfo


def _perform_snmpwalk(snmp_config, check_plugin_name, base_oid, fetchoid, *, backend):
# type: (SNMPHostConfig, CheckPluginName, OID, OID, ABCSNMPBackend) -> SNMPRowInfo
def _perform_snmpwalk(snmp_config, check_plugin_name, base_oid, fetchoid):
# type: (SNMPHostConfig, CheckPluginName, OID, OID) -> SNMPRowInfo
added_oids = set([]) # type: Set[OID]
rowinfo = [] # type: SNMPRowInfo

for context_name in snmp_config.snmpv3_contexts_of(check_plugin_name):
rows = backend.walk(snmp_config,
oid=fetchoid,
check_plugin_name=check_plugin_name,
table_base_oid=base_oid,
context_name=context_name)
rows = SNMPBackendFactory.walk(snmp_config,
oid=fetchoid,
check_plugin_name=check_plugin_name,
table_base_oid=base_oid,
context_name=context_name)

# I've seen a broken device (Mikrotik Router), that broke after an
# update to RouterOS v6.22. It would return 9 time the same OID when
Expand Down

0 comments on commit acd37ae

Please sign in to comment.