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))
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")
def _is_expected_agent_version( agent_version: Optional[str], expected_version: config.AgentTargetVersion, ) -> bool: try: if agent_version is None: return False if agent_version in ['(unknown)', 'None']: 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))
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" # We should get all metrics unified before Cmk 2.0 # 1.7 is version where metric migration started to happen migration_end_version = parse_check_mk_version('2.0.0') current_version = parse_check_mk_version(cmk_version.__version__) possible_translations = [] for trans in check_metrics.values(): for metric, options in trans.items(): if "deprecated" in options: migration_end = parse_check_mk_version(options["deprecated"]) else: migration_end = migration_end_version if (options.get('name', '') == canonical_name and migration_end >= current_version): possible_translations.append((metric, options.get('scale', 1.0))) return [(canonical_name, 1.0)] + sorted(set(possible_translations))
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))
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
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 = [ensure_str(a) for a in args]
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 """ until_version = package_info["version.usable_until"] 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