Пример #1
0
def _verify_check_mk_version(package: PackageInfo) -> None:
    """Checks whether or not the minimum required Check_MK version is older than the
    current Check_MK version. Raises an exception if not. When the Check_MK version
    can not be parsed or is a daily build, the check is simply passing without error."""

    min_version = _normalize_daily_version(package["version.min_required"])
    if min_version == "master":
        return  # can not check exact version

    version = _normalize_daily_version(str(cmk_version.__version__))
    if version == "master":
        return  # can not check exact version

    compatible = True
    try:
        compatible = parse_check_mk_version(min_version) <= parse_check_mk_version(version)
    except Exception:
        # Be compatible: When a version can not be parsed, then skip this check
        if cmk.utils.debug.enabled():
            raise
        return

    if not compatible:
        raise PackageException(
            "The package requires Check_MK version %s, "
            "but you have %s installed." % (min_version, version)
        )
Пример #2
0
def _check_min_version(
    plugins: Iterable[Plugin],
    levels_str: tuple[str, str],
    mon_state_unparsable: State,
    type_: str,
) -> CheckResult:
    levels = (parse_check_mk_version(levels_str[0]),
              parse_check_mk_version(levels_str[1]))

    render_info = {p.version_int: p.version for p in plugins}
    render_info.update(zip(levels, levels_str))

    for plugin in plugins:
        if plugin.version_int is None:
            yield Result(
                state=mon_state_unparsable,
                summary=
                f"{type_} {plugin.name!r}: unable to parse version {plugin.version!r}",
            )
        else:
            yield from check_levels(
                plugin.version_int,
                levels_lower=levels,
                render_func=lambda v: render_info[int(v)],
                label=f"{type_} {plugin.name!r}",
                notice_only=True,
            )
Пример #3
0
def is_pre_17_remote_site(site_status: SiteStatus) -> bool:
    """Decide which snapshot format is pushed to the given site

    The sync snapshot format was changed between 1.6 and 1.7. To support migrations with a
    new central site and an old remote site, we detect that case here and create the 1.6
    snapshots for the old sites.
    """
    version = site_status.get("livestatus_version")
    if not version:
        return False

    return parse_check_mk_version(version) < parse_check_mk_version("1.7.0i1")
Пример #4
0
    def _is_expected_agent_version(
        agent_version: Optional[str],
        expected_version: AgentTargetVersion,
    ) -> bool:
        try:
            if agent_version is None:
                return False

            if agent_version in ["(unknown)", "None", "unknown"]:
                return False

            if isinstance(expected_version,
                          str) and expected_version != agent_version:
                return False

            if isinstance(expected_version,
                          tuple) and expected_version[0] == "at_least":
                spec = cast(Dict[str, str], expected_version[1])
                if cmk.utils.misc.is_daily_build_version(
                        agent_version) and "daily_build" in spec:
                    expected = int(spec["daily_build"].replace(".", ""))

                    branch = cmk.utils.misc.branch_of_daily_build(
                        agent_version)
                    if branch == "master":
                        agent = int(agent_version.replace(".", ""))

                    else:  # branch build (e.g. 1.2.4-2014.06.01)
                        agent = int(
                            agent_version.split("-")[1].replace(".", ""))

                    if agent < expected:
                        return False

                elif "release" in spec:
                    if cmk.utils.misc.is_daily_build_version(agent_version):
                        return False

                    if parse_check_mk_version(
                            agent_version) < parse_check_mk_version(
                                spec["release"]):
                        return False

            return True
        except Exception as e:
            if cmk.utils.debug.enabled():
                raise
            raise MKGeneralException(
                "Unable to check agent version (Agent: %s Expected: %s, Error: %s)"
                % (agent_version, expected_version, e))
Пример #5
0
def _parse_version_int(version_str: str) -> Optional[int]:
    """
    >>> _parse_version_int("2.1.0p12")
    2010050012
    """
    try:
        return parse_check_mk_version(version_str)
    except ValueError:
        return None
Пример #6
0
def reverse_translate_metric_name(canonical_name: str) -> List[Tuple[str, float]]:
    "Return all known perf data names that are translated into canonical_name with corresponding scaling"
    current_version = parse_check_mk_version(cmk_version.__version__)
    possible_translations = []

    for trans in check_metrics.values():
        for metric, options in trans.items():
            if options.get("name", "") == canonical_name:
                if "deprecated" in options:
                    # From version check used unified metric, and thus deprecates old translation
                    # added a complete stable release, that gives the customer about a year of data
                    # under the appropriate metric name.
                    # We should however get all metrics unified before Cmk 2.1
                    migration_end = parse_check_mk_version(options["deprecated"]) + 10000000
                else:
                    migration_end = current_version

                if migration_end >= current_version:
                    possible_translations.append((metric, options.get("scale", 1.0)))

    return [(canonical_name, 1.0)] + sorted(set(possible_translations))
Пример #7
0
def sort_by_version_and_component(werks):
    translator = WerkTranslator()
    return sorted(
        werks,
        key=lambda w: (
            -parse_check_mk_version(w["version"]),
            translator.component_of(w),
            _CLASS_SORTING_VALUE.get(w["class"], 99),
            -w["level"],
            _COMPATIBLE_SORTING_VALUE.get(w["compatible"], 99),
            w["title"],
        ),
    )
Пример #8
0
def _check_min_version(plugins: Iterable[Plugin], levels_str: Tuple[str, str],
                       type_: str) -> Iterable[Result]:
    levels = (parse_check_mk_version(levels_str[0]),
              parse_check_mk_version(levels_str[1]))

    render_info = {p.version_int: p.version for p in plugins}
    render_info.update(zip(levels, levels_str))

    for plugin in plugins:
        if plugin.version_int is None:
            yield Result(
                state=State.UNKNOWN,
                summary=
                f"{type_} {plugin.name!r}: unable to parse version {plugin.version!r}",
            )
        else:
            (result, ) = check_levels(
                plugin.version_int,
                levels_lower=levels,
                render_func=lambda v: render_info[int(v)],
                label=f"{type_} {plugin.name!r}",
            )
            if result.state is not State.OK:
                yield result
Пример #9
0
def _is_outdated(package_name: PackageName, package_info: PackageInfo, version: str) -> bool:
    """Whether or not the given package is considered outated for the given Checkmk version

    >>> i = _is_outdated

    >>> i('a', {'version.usable_until': None}, '1.7.0i1')
    False

    >>> i('a', {'version.usable_until': '1.6.0'}, '1.7.0i1')
    True

    >>> i('a', {'version.usable_until': '1.7.0'}, '1.7.0i1')
    False

    >>> i('a', {'version.usable_until': '1.7.0i1'}, '1.7.0i1')
    True

    >>> i('a', {'version.usable_until': '1.7.0i1'}, '1.7.0i2')
    True

    >>> i('a', {'version.usable_until': '1.7.0'}, '1.7.0')
    True

    >>> i('a', {'version.usable_until': '2010.02.01'}, '1.7.0')
    False

    >>> i('a', {'version.usable_until': '1.7.0'}, '2010.02.01')
    False

    >>> i('a', {'version.usable_until': '1.6.0'}, '1.6.0-2010.02.01')
    True

    >>> i('a', {'version.usable_until': '1.6.0-2010.02.01'}, '1.6.0')
    True

    >>> i('a', {'version.usable_until': ''}, '1.6.0')
    False

    >>> i('a', {'version.usable_until': '1.6.0'}, '')
    False

    # Checkmk 1.6 shipped the first feature pack MKPs which sadly had no
    # "version.usable_until" attribute set. To be able to disable them automatically
    # we use a hard coded list of package names below. All of these packages start
    # with the version number "1.". To ensure the known and possible future packages
    # are removed, we consider the known packages to be outdated.

    >>> i('azure_ad', {'version': '1.0', 'version.usable_until': ''}, '1.7.0i1')
    True

    >>> i('prometheus', {'version': '1.3', 'version.usable_until': ''}, '1.7.0i1')
    True

    >>> i('prometheus', {'version': '2.0', 'version.usable_until': ''}, '1.7.0i1')
    False
    """
    until_version = package_info["version.usable_until"]

    if _is_16_feature_pack_package(package_name, package_info):
        logger.log(
            VERBOSE, "[%s]: This is a 1.6 feature pack package: It is outdated. ", package_name
        )
        return True

    if until_version is None:
        logger.log(VERBOSE, '[%s]: "Until version" is not set', package_name)
        return False

    # Normalize daily versions to branch version
    version = _normalize_daily_version(version)
    if version == "master":
        logger.log(
            VERBOSE, "[%s]: This is a daily build of master branch, can not decide", package_name
        )
        return False

    until_version = _normalize_daily_version(until_version)
    if until_version == "master":
        logger.log(
            VERBOSE, "[%s]: Until daily build of master branch, can not decide", package_name
        )
        return False

    try:
        is_outdated = parse_check_mk_version(version) >= parse_check_mk_version(until_version)
    except Exception:
        logger.log(
            VERBOSE,
            "[%s]: Could not compare until version %r with current version %r",
            package_name,
            until_version,
            version,
            exc_info=True,
        )
        return False

    logger.log(VERBOSE, "[%s]: %s > %s = %s", package_name, version, until_version, is_outdated)
    return is_outdated
Пример #10
0
auto_logger = logger.getChild("automations")

# Disable python warnings in background job output or logs like "Unverified
# HTTPS request is being made". We warn the user using analyze configuration.
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


class MKAutomationException(MKGeneralException):
    pass


def remote_automation_call_came_from_pre21() -> bool:
    # The header is sent by Checkmk as of 2.0.0p1. In case it is missing, assume we are too old.
    if not (remote_version := request.headers.get("x-checkmk-version")):
        return True
    return parse_check_mk_version(remote_version) < parse_check_mk_version(
        "2.1.0i1")


def check_mk_local_automation_serialized(
    *,
    command: str,
    args: Optional[Sequence[str]] = None,
    indata: Any = "",
    stdin_data: Optional[str] = None,
    timeout: Optional[int] = None,
) -> Tuple[Sequence[str], SerializedResult]:
    if args is None:
        args = []
    new_args = list(args)
Пример #11
0
        literal = spec.get("literal", site_version)
        return "" if literal == agent_version else f" (expected {literal})"

    # spec_type == "at_least"
    if is_daily_build_version(agent_version) and (
            at_least := spec.get("daily_build")) is not None:
        if int(agent_version.split("-")[-1].replace(".", "")) < int(
                at_least.replace(".", "")):
            return f" (expected at least {at_least})"

    if (at_least := spec.get("release")) is None:
        return ""

    return (f" (expected at least {at_least})"
            if is_daily_build_version(agent_version) or
            (parse_check_mk_version(agent_version) <
             parse_check_mk_version(at_least)) else "")


def _check_only_from(
    agent_only_from: Union[None, str, Sequence[str]],
    config_only_from: Union[None, str, list[str]],
    fail_state: State,
) -> CheckResult:
    if agent_only_from is None or config_only_from is None:
        return

    # do we really need 'normalize_ip_addresses'? It deals with '{' expansion.
    allowed_nets = set(normalize_ip_addresses(agent_only_from))
    expected_nets = set(normalize_ip_addresses(config_only_from))
    if allowed_nets == expected_nets:
Пример #12
0
def _validate_version(value: str, varprefix: str) -> None:
    try:
        parse_check_mk_version(value)
    except (ValueError, TypeError, KeyError):
        raise MKUserError(varprefix, _("Can't parse version %r") % value)
Пример #13
0
def test_old_parse_check_mk_version_equals_new_version_class(version_str):
    assert (
        cmk_version.parse_check_mk_version(version_str)
        == cmk_version.Version(version_str).parse_to_int()
    )