From 71ffba395b9409180fd566a7399dd4cff9534974 Mon Sep 17 00:00:00 2001 From: Dmitry Volodin Date: Tue, 29 Oct 2024 18:29:56 +0100 Subject: [PATCH] noc.config section --- CHANGELOG.md | 1 + src/gufo/thor/config.py | 2 ++ src/gufo/thor/services/kafka.py | 2 +- src/gufo/thor/services/noc.py | 33 +++++++++++++++++----- src/gufo/thor/templates/noc/settings.yml | 13 --------- src/gufo/thor/utils.py | 36 ++++++++++++++++++++++-- 6 files changed, 64 insertions(+), 23 deletions(-) delete mode 100644 src/gufo/thor/templates/noc/settings.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 0927c15..ac175f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ To see unreleased changes, please see the [CHANGELOG on the master branch](https ### Added * `restart` command. +* `noc.config` section. ### Changed diff --git a/src/gufo/thor/config.py b/src/gufo/thor/config.py index 8f21864..296a722 100644 --- a/src/gufo/thor/config.py +++ b/src/gufo/thor/config.py @@ -29,6 +29,7 @@ class NocConfig(object): in the interface. theme: Web interface theme. One of: `noc`, `gray`. migrate: Run migrations on start + config: User-defined config. """ tag: str = "master" @@ -37,6 +38,7 @@ class NocConfig(object): installation_name: str = "Unconfigured Installation" theme: Literal["noc", "gray"] = "noc" migrate: bool = True + config: Optional[Dict[str, Any]] = None @staticmethod def from_dict(data: Dict[str, Any]) -> "NocConfig": diff --git a/src/gufo/thor/services/kafka.py b/src/gufo/thor/services/kafka.py index f6073d0..9a3ea28 100644 --- a/src/gufo/thor/services/kafka.py +++ b/src/gufo/thor/services/kafka.py @@ -20,7 +20,7 @@ class KafkaService(BaseService): name = "kafka" compose_image = "bitnami/kafka:3.6.2" compose_volumes = [ - "kafka_data:/data/", + "kafka_data:/bitnami/data/", ] compose_volumes_config = {"kafka_data": {}} service_discovery = {"kafka": 9093} diff --git a/src/gufo/thor/services/noc.py b/src/gufo/thor/services/noc.py index 1d424fb..a8a5556 100644 --- a/src/gufo/thor/services/noc.py +++ b/src/gufo/thor/services/noc.py @@ -1,7 +1,7 @@ # --------------------------------------------------------------------- # Gufo Thor: noc service # --------------------------------------------------------------------- -# Copyright (C) 2023, Gufo Labs +# Copyright (C) 2023-24, Gufo Labs # --------------------------------------------------------------------- """NocService base class.""" @@ -9,8 +9,12 @@ from pathlib import Path from typing import Any, Dict, List, Optional +# Third-party modules +import yaml + # Gufo Thor modules from ..config import Config, ServiceConfig +from ..utils import merge_dict, write_file from .base import BaseService, ComposeDependsCondition @@ -90,12 +94,27 @@ def prepare_compose_config( """ if self._config_prepared: return # Already configured from other subclass - NocService.render_file( - Path("etc", "noc", "settings.yml"), - "settings.yml", - installation_name=config.noc.installation_name, - theme=config.noc.theme, - ) + # Build default config + cfg = { + "installation_name": config.noc.installation_name, + "pg": { + "db": "noc", + "user": "noc", + "password": "noc", + }, + "web": { + "theme": config.noc.theme, + }, + "msgstream": { + "client_class": "noc.core.msgstream.redpanda.RedPandaClient", + }, + "redpanda": {"addresses": "kafka:9092"}, + } + # Apply user config + if config.noc.config: + cfg = merge_dict(cfg, config.noc.config) + # Write + write_file(Path("etc", "noc", "settings.yml"), yaml.dump(cfg)) self._config_prepared = True def get_compose_volumes_config( diff --git a/src/gufo/thor/templates/noc/settings.yml b/src/gufo/thor/templates/noc/settings.yml deleted file mode 100644 index ea89365..0000000 --- a/src/gufo/thor/templates/noc/settings.yml +++ /dev/null @@ -1,13 +0,0 @@ -installation_name: > - {{installation_name}} -pg: - db: noc - user: noc - password: noc -web: - theme: > - {{theme}} -msgstream: - client_class: noc.core.msgstream.redpanda.RedPandaClient -redpanda: - addresses: kafka:9092 diff --git a/src/gufo/thor/utils.py b/src/gufo/thor/utils.py index a35482f..e36c2db 100644 --- a/src/gufo/thor/utils.py +++ b/src/gufo/thor/utils.py @@ -1,7 +1,7 @@ # --------------------------------------------------------------------- # Gufo Thor: Various utilities # --------------------------------------------------------------------- -# Copyright (C) 2023, Gufo Labs +# Copyright (C) 2023--24, Gufo Labs # --------------------------------------------------------------------- """Various utilities.""" @@ -9,7 +9,7 @@ import os import shutil from pathlib import Path -from typing import Optional, Union +from typing import Any, Dict, Optional, Union # Gufo Thor modules from .log import logger @@ -59,3 +59,35 @@ def ensure_directory(path: Path) -> None: return logger.warning("Creating directory %s", path) os.makedirs(path) + + +def merge_dict(x: Dict[str, Any], y: Dict[str, Any]) -> Dict[str, Any]: + """ + Deep merge dictionaries. + + Do not affect source dictionaries. + Second dictionary overrides first. + + Args: + x: First dictionary. + y: Second dictionary. + + Returns: + Merged dictionary. + """ + r: Dict[str, Any] = {} + xk = set(x) + yk = set(y) + # Append keys which are only in first dictionary + for k in xk - yk: + r[k] = x[k] + # Append keys which are only in second dictionary + for k in yk - xk: + r[k] = y[k] + # Merge overlapped keys + for k in xk.intersection(yk): + if isinstance(x[k], dict) and isinstance(y[k], dict): + r[k] = merge_dict(x[k], y[k]) + else: + r[k] = y[k] + return r