Skip to content

Commit

Permalink
Move hosts container to hostaddress
Browse files Browse the repository at this point in the history
 * make it a frozen dataclass
 * rename to `Hosts`---it's a container of hosts, independently
   of how it gets its filled

CMK-14467

Change-Id: I644e98db2ca8e212bbbbeae584998eae37aaafde
  • Loading branch information
Synss committed Oct 17, 2023
1 parent 73b7b7f commit bfa2c79
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 59 deletions.
43 changes: 9 additions & 34 deletions cmk/base/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import socket
import struct
import sys
from collections import Counter
from collections.abc import (
Callable,
Container,
Expand Down Expand Up @@ -62,7 +61,7 @@
)
from cmk.utils.config_path import ConfigPath
from cmk.utils.exceptions import MKGeneralException, MKIPAddressLookupError, MKTerminate, OnError
from cmk.utils.hostaddress import HostAddress, HostName
from cmk.utils.hostaddress import HostAddress, HostName, Hosts
from cmk.utils.http_proxy_config import http_proxy_config_from_user_setting, HTTPProxyConfig
from cmk.utils.labels import Labels
from cmk.utils.log import console
Expand Down Expand Up @@ -1883,42 +1882,18 @@ def lookup_ip_address(
# +----------------------------------------------------------------------+


class HostsConfig:
def __init__(
self,
*,
hosts: Sequence[HostName],
clusters: Sequence[HostName], # pylint: disable=redefined-outer-name
shadow_hosts: Sequence[HostName], # pylint: disable=redefined-outer-name
) -> None:
self.hosts: Final = hosts
self.clusters: Final = clusters
self.shadow_hosts: Final = shadow_hosts

def duplicates(self, /, pred: Callable[[HostName], bool]) -> Iterable[HostName]:
return (
hn
for hn, count in Counter(
hn
for hn in itertools.chain(self.hosts, self.clusters, self.shadow_hosts)
if pred(hn)
).items()
if count > 1
)

@classmethod
def from_config(cls) -> HostsConfig:
return cls(
hosts=strip_tags(all_hosts),
clusters=strip_tags(clusters),
shadow_hosts=list(_get_shadow_hosts()),
)
def make_hosts_config() -> Hosts:
return Hosts(
hosts=strip_tags(all_hosts),
clusters=strip_tags(clusters),
shadow_hosts=list(_get_shadow_hosts()),
)


class ConfigCache:
def __init__(self) -> None:
super().__init__()
self.hosts_config = HostsConfig(hosts=(), clusters=(), shadow_hosts=())
self.hosts_config = Hosts(hosts=(), clusters=(), shadow_hosts=())
self.__enforced_services_table: dict[
HostName,
Mapping[
Expand Down Expand Up @@ -1948,7 +1923,7 @@ def __init__(self) -> None:

def initialize(self) -> ConfigCache:
self._initialize_caches()
self.hosts_config = HostsConfig.from_config()
self.hosts_config = make_hosts_config()
self._setup_clusters_nodes_cache()

tag_to_group_map = ConfigCache.get_tag_to_group_map()
Expand Down
14 changes: 4 additions & 10 deletions cmk/base/core_nagios.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from cmk.utils.check_utils import section_name_of
from cmk.utils.config_path import VersionedConfigPath
from cmk.utils.exceptions import MKGeneralException
from cmk.utils.hostaddress import HostAddress, HostName
from cmk.utils.hostaddress import HostAddress, HostName, Hosts
from cmk.utils.labels import Labels
from cmk.utils.licensing.handler import LicensingHandler
from cmk.utils.log import console
Expand All @@ -44,13 +44,7 @@
import cmk.base.ip_lookup as ip_lookup
import cmk.base.obsolete_output as out
import cmk.base.utils
from cmk.base.config import (
ConfigCache,
HostgroupName,
HostsConfig,
ObjectAttributes,
ServicegroupName,
)
from cmk.base.config import ConfigCache, HostgroupName, ObjectAttributes, ServicegroupName
from cmk.base.core_config import (
AbstractServiceID,
CollectedHostLabels,
Expand Down Expand Up @@ -146,10 +140,10 @@ def write(self, x: str) -> None:


def _validate_licensing(
hosts_config: HostsConfig, licensing_handler: LicensingHandler, licensing_counter: Counter
hosts: Hosts, licensing_handler: LicensingHandler, licensing_counter: Counter
) -> None:
if block_effect := licensing_handler.effect_core(
licensing_counter["services"], len(hosts_config.shadow_hosts)
licensing_counter["services"], len(hosts.shadow_hosts)
).block:
raise MKGeneralException(block_effect.message_raw)

Expand Down
24 changes: 23 additions & 1 deletion cmk/utils/hostaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,33 @@
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

import itertools
from collections import Counter
from collections.abc import Callable, Iterable, Sequence
from dataclasses import dataclass
from typing import NewType, TypeAlias

__all__ = ["HostAddress", "HostName"]
__all__ = ["HostAddress", "Hosts", "HostName"]

HostAddress = NewType("HostAddress", str)
# Let us be honest here, we do not actually make a difference
# between HostAddress and HostName in our code.
HostName: TypeAlias = HostAddress


@dataclass(frozen=True)
class Hosts:
hosts: Sequence[HostName]
clusters: Sequence[HostName]
shadow_hosts: Sequence[HostName]

def duplicates(self, /, pred: Callable[[HostName], bool]) -> Iterable[HostName]:
return (
hn
for hn, count in Counter(
hn
for hn in itertools.chain(self.hosts, self.clusters, self.shadow_hosts)
if pred(hn)
).items()
if count > 1
)
15 changes: 1 addition & 14 deletions tests/unit/cmk/base/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,10 @@
from cmk.base.api.agent_based.checking_classes import CheckPlugin as CheckPluginAPI
from cmk.base.api.agent_based.register.utils_legacy import LegacyCheckDefinition
from cmk.base.api.agent_based.type_defs import SNMPSectionPlugin
from cmk.base.config import ConfigCache, HostsConfig, ip_address_of
from cmk.base.config import ConfigCache, ip_address_of
from cmk.base.ip_lookup import AddressFamily


def test_duplicate_hosts() -> None:
hostnames = (
HostName("un"),
HostName("deux"),
HostName("deux"),
HostName("trois"),
HostName("trois"),
HostName("trois"),
)
hosts_config = HostsConfig(hosts=hostnames, clusters=(), shadow_hosts=())
assert list(hosts_config.duplicates(lambda *args, **kw: True)) == ["deux", "trois"]


def test_all_offline_hosts(monkeypatch: MonkeyPatch) -> None:
ts = Scenario()
ts.add_host(HostName("blub"), tags={TagGroupID("criticality"): TagID("offline")})
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/cmk/utils/test_hostaddress.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

from cmk.utils.hostaddress import HostName, Hosts


def test_duplicate_hosts() -> None:
hostnames = (
HostName("un"),
HostName("deux"),
HostName("deux"),
HostName("trois"),
HostName("trois"),
HostName("trois"),
)
hosts_config = Hosts(hosts=hostnames, clusters=(), shadow_hosts=())
assert list(hosts_config.duplicates(lambda *args, **kw: True)) == ["deux", "trois"]

0 comments on commit bfa2c79

Please sign in to comment.