merge all alaka-*.yml files in a directory

This commit is contained in:
Moritz 2024-05-10 17:16:39 +02:00
parent 475aa6eb89
commit cfc2d619e3
1 changed files with 30 additions and 23 deletions

View File

@ -18,7 +18,6 @@ from ruamel.yaml.constructor import SafeConstructor
from ruamel.yaml.nodes import ScalarNode
COMBINE_PATH = os.path.dirname(os.path.realpath(__file__)) + "/combine.yml"
CONFIG_FILE_NAME = 'alaka.yaml'
CONFIGS = {}
@ -52,7 +51,6 @@ def read_config(filepath: str) -> Dict[str, Any]:
Returns:
dict: The configuration data extracted and processed from the YAML file, structured as a dictionary.
"""
pass
filepath = Path(filepath).expanduser()
if not filepath.exists():
logging.warning(f"config file {filepath} does not exist")
@ -120,35 +118,37 @@ def merge_dict(dict1: Dict[Any, Any], dict2: Dict[Any, Any], reverse_list_order:
return merged_dict
def merge_pool_configs(dir_path: str) -> Dict[str, Dict[str, Any]]:
def merge_all_group_configs(dir_path: str) -> Dict[str, Dict[str, Any]]:
"""
Recursively merges 'alaka.yml' files within a specified directory into a single comprehensive configuration dictionary.
Recursively merges 'alaka.yml/alaka-*.yml' files within a specified directory into a single comprehensive configuration dictionary.
Configurations at higher directory levels get inherited and potentially overridden by configurations in lower directory levels.
Args:
dir_path (str): The path to the directory containing hierarchical 'alaka.yml' configuration files. The directory should follow an organizational structure where each subdirectory can contain an 'alaka.yml' that inherits and potentially overrides settings from its parent directory's 'alaka.yml'.
dir_path (str): The path to the directory containing hierarchical 'alaka.yml/alaka-*.yml' configuration files. The directory should follow an organizational structure where each subdirectory can contain 'alaka.yml/alaka-*.yml' files that inherits and potentially overrides settings from its parent directory's 'alaka.yml/alaka-*.yml' files.
Returns:
dict: A dictionary representing the merged configurations from all the 'alaka.yml' files found in the directory hierarchy.
dict: A dictionary representing the merged configurations from all the 'alaka.yml/alaka-*.yml' files found in the directory hierarchy.
The dictionary's keys are the paths of the directories relative to the root directory specified by 'dir_path', indicating the source of the configurations. Each key maps to its respective merged configuration dictionary, which includes all inherited and overridden settings from higher-level directories down to the specified directory.
"""
pass
pass
# TODO: fix type error
dir_path = Path(dir_path).absolute()
merged_configs = {}
for root, _, files in os.walk(dir_path):
no_config = True
no_config_found = True
for file in files:
if file in ['alaka.yaml', 'alaka.yml']:
if re.match(r'^alaka(-.*)?\.ya?ml$', file):
file_path = os.path.join(root, file)
config = read_config(file_path)
# Merge the config with the merged config from the parent dir
if par_config := merged_configs.get(os.path.dirname(root)):
if dir_config := merged_configs.get(root):
# Merge the config with the merged config from the current dir
merged_configs[root] = merge_dict(dir_config, config)
elif par_config := merged_configs.get(os.path.dirname(root)):
# Merge the config with the merged config from the parent dir
merged_configs[root] = merge_dict(par_config, config)
else:
merged_configs[root] = config
no_config = False
if no_config:
no_config_found = False
if no_config_found:
merged_configs[root] = merged_configs.get(os.path.dirname(root))
return merged_configs
@ -218,7 +218,6 @@ def get_merged_instance_configs(pool_path: str, pool_configs: Dict[str, Any]) ->
Returns:
dict: A dictionary with domains as keys and their respective merged configurations as values.
"""
pass
pool_path = Path(pool_path).absolute()
if pool_path.is_file():
parent_path = os.path.dirname(pool_path)
@ -250,7 +249,6 @@ def merge_connection_configs(configs: Dict[str, Any]) -> Dict[str, Any]:
Returns:
dict: The updated instance configurations after applying the connection settings.
"""
pass
connection_config = read_config(COMBINE_PATH)
extend_shared_secrets(connection_config)
merged_configs = configs.copy()
@ -686,24 +684,24 @@ def execute_cmds(app_config: Dict[str, Any]) -> None:
@click.group()
@click.option('-l', '--log', 'loglevel')
@click.option('-p', '--pool_path', 'pool_path')
@click.option('-p', '--group_path', 'group_path')
@click.option('-c', '--config_path', 'config_path', default=".")
def cli(loglevel: str, pool_path: str, config_path: str) -> None:
def cli(loglevel: str, group_path: str, config_path: str) -> None:
"""
Command-line interface setup function for the Alakazam application. It configures logging levels, loads configuration files, and merges configuration settings from specified paths.
This function is the entry point for CLI commands provided by the Alakazam tool.
Args:
loglevel (str): Desired logging level ("debug", "info", "warning", "error", "critical").
pool_path (str): Path to the directory containing the desired configuration pool.
group_path (str): Path to the directory containing the desired configuration group.
config_path (str): Path to the root directory containing configuration files.
"""
global CONFIGS
pool_configs = merge_pool_configs(config_path)
if not Path(pool_path).exists():
logging.error(f"{pool_path} does not exists! Are you in the correct directory?")
all_group_configs = merge_all_group_configs(config_path)
if not Path(group_path).exists():
logging.error(f"{group_path} does not exists! Are you in the correct directory?")
exit(1)
instance_configs = get_merged_instance_configs(pool_path, pool_configs)
instance_configs = get_merged_instance_configs(group_path, all_group_configs)
CONFIGS = merge_connection_configs(instance_configs)
if loglevel:
numeric_level = getattr(logging, loglevel.upper(), None)
@ -711,6 +709,15 @@ def cli(loglevel: str, pool_path: str, config_path: str) -> None:
raise ValueError('Invalid log level: %s' % loglevel)
logging.basicConfig(level=numeric_level)
@cli.command()
@click.option('-a', '--apps', multiple=True)
def show_config(apps: List[str]) -> None:
filtered_configs = CONFIGS
if apps:
filtered_configs = {server: {app: app_config for app, app_config in app_configs.items() if app in apps}
for server, app_configs in CONFIGS.items()}
print(json.dumps(filtered_configs, indent=2))
@cli.command()
@click.option('-a', '--apps', multiple=True)