def test_make_object_diff_multiple_changes(): assert make_object_diff( { "a": "0", "b": "1" }, {"a": "1"} ) == 'Attribute "b" with value "1" removed.\nValue of "a" changed from "0" to "1".'
def automation_discovery( *, config_cache: config.ConfigCache, host_config: config.HostConfig, mode: DiscoveryMode, service_filters: Optional[_ServiceFilters], on_error: OnError, use_cached_snmp_data: bool, max_cachefile_age: cmk.core_helpers.cache.MaxAge, ) -> DiscoveryResult: console.verbose(" Doing discovery with mode '%s'...\n" % mode) host_name = host_config.hostname result = DiscoveryResult() if host_name not in config_cache.all_active_hosts(): result.error_text = "" return result cmk.core_helpers.cache.FileCacheFactory.use_outdated = True cmk.core_helpers.cache.FileCacheFactory.maybe = use_cached_snmp_data try: # in "refresh" mode we first need to remove all previously discovered # checks of the host, so that _get_host_services() does show us the # new discovered check parameters. if mode is DiscoveryMode.REFRESH: result.self_removed += host_config.remove_autochecks( ) # this is cluster-aware! if host_config.is_cluster: ipaddress = None else: ipaddress = config.lookup_ip_address(host_config) parsed_sections_broker, _source_results = make_broker( config_cache=config_cache, host_config=host_config, ip_address=ipaddress, mode=Mode.DISCOVERY, selected_sections=NO_SELECTION, file_cache_max_age=max_cachefile_age, fetcher_messages=(), force_snmp_cache_refresh=not use_cached_snmp_data, on_scan_error=on_error, ) if mode is not DiscoveryMode.REMOVE: host_labels = analyse_host_labels( host_config=host_config, ipaddress=ipaddress, parsed_sections_broker=parsed_sections_broker, load_labels=True, save_labels=True, on_error=on_error, ) result.self_new_host_labels = len(host_labels.new) result.self_total_host_labels = len(host_labels.present) if mode is DiscoveryMode.ONLY_HOST_LABELS: # This is the result of a refactoring, and the following code was added # to ensure a compatible behaviour. I don't think it is particularly # sensible. We used to only compare service descriptions of old and new # services, so `make_object_diff` was always comparing two identical objects # if the mode was DiscoveryMode.ONLY_HOST_LABEL. # We brainlessly mimic that behaviour, for now. result.diff_text = make_object_diff(set(), set()) return result # Compute current state of new and existing checks services = _get_host_services( host_config, ipaddress, parsed_sections_broker, on_error=on_error, ) old_services = services.get("old", []) # Create new list of checks new_services = _get_post_discovery_services( host_name, services, service_filters or _ServiceFilters.accept_all(), result, mode) host_config.set_autochecks(new_services) # If old_services == new_services, make_object_diff will return # something along the lines of "nothing changed". # I guess this was written before discovered host labels were invented. result.diff_text = make_object_diff( {x.service.description for x in old_services}, {x.service.description for x in new_services}, ) except MKTimeout: raise # let general timeout through except Exception as e: if cmk.utils.debug.enabled(): raise result.error_text = str(e) result.self_total = result.self_new + result.self_kept return result
def discover_on_host( *, config_cache: config.ConfigCache, host_config: config.HostConfig, mode: DiscoveryMode, service_filters: Optional[_ServiceFilters], on_error: str, use_cached_snmp_data: bool, max_cachefile_age: int, ) -> DiscoveryResult: console.verbose(" Doing discovery with mode '%s'...\n" % mode) host_name = host_config.hostname result = DiscoveryResult() discovery_parameters = DiscoveryParameters( on_error=on_error, load_labels=(mode is not DiscoveryMode.REMOVE), save_labels=(mode is not DiscoveryMode.REMOVE), only_host_labels=(mode is DiscoveryMode.ONLY_HOST_LABELS), ) if host_name not in config_cache.all_active_hosts(): result.error_text = "" return result _set_cache_opts_of_checkers(use_cached_snmp_data=use_cached_snmp_data) try: # in "refresh" mode we first need to remove all previously discovered # checks of the host, so that _get_host_services() does show us the # new discovered check parameters. if mode is DiscoveryMode.REFRESH: result.self_removed += host_config.remove_autochecks() # this is cluster-aware! if host_config.is_cluster: ipaddress = None else: ipaddress = config.lookup_ip_address(host_config) parsed_sections_broker, _source_results = make_broker( config_cache=config_cache, host_config=host_config, ip_address=ipaddress, mode=Mode.DISCOVERY, selected_sections=NO_SELECTION, file_cache_max_age=max_cachefile_age, fetcher_messages=(), force_snmp_cache_refresh=not use_cached_snmp_data, on_scan_error=on_error, ) # Compute current state of new and existing checks services, host_labels = _get_host_services( host_config, ipaddress, parsed_sections_broker, discovery_parameters, ) old_services = services.get("old", []) # Create new list of checks new_services = _get_post_discovery_services(host_name, services, service_filters or _ServiceFilters.accept_all(), result, mode) host_config.set_autochecks(new_services) result.diff_text = make_object_diff( _make_services_audit_log_object([x.service for x in old_services]), _make_services_audit_log_object([x.service for x in new_services])) except MKTimeout: raise # let general timeout through except Exception as e: if cmk.utils.debug.enabled(): raise result.error_text = str(e) else: if mode is not DiscoveryMode.REMOVE: result.self_new_host_labels = len(host_labels.new) result.self_total_host_labels = len(host_labels.present) result.self_total = result.self_new + result.self_kept return result
def make_diff_text(old_object: Any, new_object: Any) -> Optional[str]: if old_object is not None and new_object is not None: return make_object_diff(old_object, new_object) return None
def test_make_object_diff_nothing_changed(): assert make_object_diff(None, None) == "Nothing was changed." assert make_object_diff({}, {}) == "Nothing was changed." assert make_object_diff([], []) == "Nothing was changed."
def test_make_object_diff_list_remove_dict(): assert make_object_diff([1, { "1": "a" }], [1]) == "Item 1 with value {'1': 'a'} removed."
def test_make_object_diff_list_remove_item(): assert make_object_diff([1, 2], [1]) == "Item 1 with value 2 removed."
def test_make_object_diff_changed_dict_value(): assert make_object_diff( {"a": "0"}, {"a": "1"}) == 'Value of "a" changed from "0" to "1".'
def test_make_object_diff_removed_dict_key(): assert make_object_diff({"a": "1"}, {}) == 'Attribute "a" with value "1" removed.'
def test_make_object_diff_new_dict_key(): assert make_object_diff( {}, {"a": "1"}) == 'Attribute "a" with value "1" added.'
def test_make_object_diff_str(): assert make_object_diff("a", "b") == 'Value of object changed from "a" to "b".'
def test_make_object_diff_list_remove_dict(): assert make_object_diff([1, { "1": "a" }], [1]) == 'Item 1 with value {\'1\': \'a\'} removed.'