def find_all_resources(config, ignore_keys: Optional[list[str]] = None) -> dict[str, ResourcePath]:
    """Find all resources in a config.

    :param config: The config to search for resources.
    :param ignore_keys: A list of keys to ignore when searching for resources.
    :return: A dictionary of all resources found in the config.
        keys are tuples representing the path to the resource in the config and the values are
        the resource paths.
    """
    if isinstance(config, VALID_RESOURCE_CONFIGS):
        try:
            # don't want to accidentally modify the original config
            resource_path = create_resource_path(deepcopy(config))
            if resource_path.is_string_name():
                return {}
            return {(): resource_path}
        except ValueError:
            pass

    resources = {}
    if isinstance(config, (dict, list)):
        for k, v in config.items() if isinstance(config, dict) else enumerate(config):
            if ignore_keys and k in ignore_keys:
                continue
            resources.update({(k, *k2): v2 for k2, v2 in find_all_resources(v, ignore_keys=ignore_keys).items()})

    return resources
Find all resources in a config.

    :param config: The config to search for resources.
    :param ignore_keys: A list of keys to ignore when searching for resources.
    :return: A dictionary of all resources found in the config.
        keys are tuples representing the path to the resource in the config and the values are
        the resource paths.
    
olive/resource_path.py