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
示例#2
0
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))
示例#3
0
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