def test_delta_structured_data_tree_serialization(two_tree_filenames): old_tree = StructuredDataTree() new_tree = StructuredDataTree() old_filename, new_filename = two_tree_filenames old_tree.load_from(old_filename) new_tree.load_from(new_filename) _, __, ___, delta_tree = old_tree.compare_with(new_tree) raw_delta_tree = delta_tree.get_raw_tree() new_delta_tree = StructuredDataTree() new_delta_tree.create_tree_from_raw_tree(raw_delta_tree) new_raw_delta_tree = new_delta_tree.get_raw_tree() assert raw_delta_tree == new_raw_delta_tree
def _run_inventory_export_hooks(host_config: config.HostConfig, inventory_tree: StructuredDataTree) -> None: import cmk.base.inventory_plugins as inventory_plugins # pylint: disable=import-outside-toplevel hooks = host_config.inventory_export_hooks if not hooks: return section.section_step("Execute inventory export hooks") for hookname, params in hooks: console.verbose("Execute export hook: %s%s%s%s" % (tty.blue, tty.bold, hookname, tty.normal)) try: func = inventory_plugins.inv_export[hookname]["export_function"] func(host_config.hostname, params, inventory_tree.get_raw_tree()) except Exception as e: if cmk.utils.debug.enabled(): raise raise MKGeneralException("Failed to execute export hook %s: %s" % (hookname, e))
def get_history_deltas(hostname, search_timestamp=None): if '/' in hostname: return None, [] # just for security reasons inventory_path = "%s/inventory/%s" % (cmk.utils.paths.var_dir, hostname) if not os.path.exists(inventory_path): return [], [] latest_timestamp = str(int(os.stat(inventory_path).st_mtime)) inventory_archive_dir = "%s/inventory_archive/%s" % ( cmk.utils.paths.var_dir, hostname) try: archived_timestamps = sorted(os.listdir(inventory_archive_dir)) except OSError: return [], [] all_timestamps = archived_timestamps + [latest_timestamp] previous_timestamp = None if not search_timestamp: required_timestamps = all_timestamps else: new_timestamp_idx = all_timestamps.index(search_timestamp) if new_timestamp_idx == 0: required_timestamps = [search_timestamp] else: previous_timestamp = all_timestamps[new_timestamp_idx - 1] required_timestamps = [search_timestamp] tree_lookup = {} def get_tree(timestamp): if timestamp is None: return StructuredDataTree() if timestamp in tree_lookup: return tree_lookup[timestamp] if timestamp == latest_timestamp: inventory_tree = load_filtered_inventory_tree(hostname) if inventory_tree is None: return tree_lookup[timestamp] = inventory_tree else: inventory_archive_path = "%s/%s" % (inventory_archive_dir, timestamp) tree_lookup[timestamp] = _filter_tree( StructuredDataTree().load_from(inventory_archive_path)) return tree_lookup[timestamp] corrupted_history_files = [] delta_history = [] for _idx, timestamp in enumerate(required_timestamps): cached_delta_path = os.path.join( cmk.utils.paths.var_dir, "inventory_delta_cache", hostname, "%s_%s" % (previous_timestamp, timestamp)) cached_data = None try: cached_data = store.load_object_from_file(cached_delta_path) except MKGeneralException: pass if cached_data: new, changed, removed, delta_tree_data = cached_data delta_tree = StructuredDataTree() delta_tree.create_tree_from_raw_tree(delta_tree_data) delta_history.append( (timestamp, (new, changed, removed, delta_tree))) previous_timestamp = timestamp continue try: previous_tree = get_tree(previous_timestamp) current_tree = get_tree(timestamp) delta_data = current_tree.compare_with(previous_tree) new, changed, removed, delta_tree = delta_data if new or changed or removed: store.save_file( cached_delta_path, repr((new, changed, removed, delta_tree.get_raw_tree())), ) delta_history.append((timestamp, delta_data)) except RequestTimeout: raise except LoadStructuredDataError: corrupted_history_files.append( str(get_short_inventory_history_filepath(hostname, timestamp))) previous_timestamp = timestamp return delta_history, corrupted_history_files