Skip to content

Commit

Permalink
feat: Convert config template to pydantic model
Browse files Browse the repository at this point in the history
  • Loading branch information
romeonicholas committed Feb 28, 2024
1 parent 1dd9f84 commit ae531cc
Show file tree
Hide file tree
Showing 37 changed files with 349 additions and 215 deletions.
1 change: 0 additions & 1 deletion backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

.idea
config/*
!config/config_template.yaml
.history
**/__pycache__/
.vscode
Expand Down
5 changes: 0 additions & 5 deletions backend/capellacollab/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@

from importlib import metadata

from capellacollab import config as config_module

try:
__version__ = metadata.version("capellacollab-backend")
except metadata.PackageNotFoundError:
__version__ = "0.0.0+unknown"
del metadata


config_module.validate_schema()
6 changes: 3 additions & 3 deletions backend/capellacollab/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,18 @@
handlers: list[logging.Handler] = [
logging.StreamHandler(),
core_logging.CustomTimedRotatingFileHandler(
str(config["logging"]["logPath"]) + "backend.log"
str(config.logging.logPath) + "backend.log"
),
]

for handler in handlers:
handler.setFormatter(core_logging.CustomFormatter())

logging.basicConfig(level=config["logging"]["level"], handlers=handlers)
logging.basicConfig(level=config.logging.level, handlers=handlers)


async def startup():
migration.migrate_db(engine, config["database"]["url"])
migration.migrate_db(engine, config.database.url)

Check warning on line 64 in backend/capellacollab/__main__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/__main__.py#L64

Added line #L64 was not covered by tests
logging.info("Migrations done - Server is running")

# This is needed to load the Kubernetes configuration at startup
Expand Down
4 changes: 2 additions & 2 deletions backend/capellacollab/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# access to the values within the .ini file in use.
config = context.config

logging.basicConfig(level=cfg["logging"]["level"])
logging.basicConfig(level=cfg.logging.level)
if os.getenv("ALEMBIC_CONFIGURE_LOGGER", "true") != "false":
logging.getLogger("capellacollab").setLevel("WARNING")

Expand All @@ -25,7 +25,7 @@
# this will overwrite the ini-file sqlalchemy.url path
# with the path given in the config of the main code
if not config.get_main_option("sqlalchemy.url"):
config.set_main_option("sqlalchemy.url", cfg["database"]["url"])
config.set_main_option("sqlalchemy.url", cfg.database.url)

# Import models

Expand Down
23 changes: 9 additions & 14 deletions backend/capellacollab/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,18 @@
# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
# SPDX-License-Identifier: Apache-2.0


import logging

import jsonschema
import jsonschema.exceptions

from . import exceptions, loader
from . import generate, loader, models

log = logging.getLogger(__name__)
config = loader.load_yaml()

if not loader.does_config_exist():
log.warning(

Check warning on line 11 in backend/capellacollab/config/__init__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/__init__.py#L11

Added line #L11 was not covered by tests
"No configuration file found. Generating default configuration at backend/capellacollab/config/config.yaml"
)
generate.write_config()

Check warning on line 14 in backend/capellacollab/config/__init__.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/__init__.py#L14

Added line #L14 was not covered by tests


def validate_schema():
config_schema = loader.load_config_schema()
try:
jsonschema.validate(config, config_schema)
except jsonschema.exceptions.ValidationError as error:
raise exceptions.InvalidConfigurationError(
f"{error.__class__.__name__}: {error.message}",
) from None
config_data = loader.load_yaml()
config = models.AppConfig(**config_data)
Original file line number Diff line number Diff line change
Expand Up @@ -4,99 +4,64 @@
docker:
registry: k3d-myregistry.localhost:12345
externalRegistry: docker.io

k8s:
# Only required when using operator k8s
context: k3d-collab-cluster # Only required, if you'd like to use a local k3d environment
context: k3d-collab-cluster
namespace: collab-sessions

# apiURL: dummy # Only required when no kubectl context is available
# token: dummy # Only required when no kubectl context is available

storageClassName: local-path
storageAccessMode: ReadWriteOnce

cluster:
imagePullPolicy: Always
podSecurityContext:
runAsUser: 1004370000
runAsGroup: 1004370000
fsGroup: 1004370000
runAsNonRoot: true

promtail:
lokiEnabled: True
lokiEnabled: true
lokiUrl: http://localhost:30001/loki/api/v1/push
lokiUsername: localLokiUser
lokiPassword: localLokiPassword
serverPort: 3101

ingressClassName: traefik
general:
host: localhost
port: 8000
scheme: http
wildcardHost: False

wildcardHost: false
extensions:
guacamole:
baseURI: http://localhost:8080/guacamole
publicURI: http://localhost:8080/guacamole

username: guacadmin
password: guacadmin

jupyter:
publicURI: http://localhost:8080/jupyter

authentication:
provider: oauth # oauth | azure
provider: oauth
jwt:
usernameClaim: sub # preferred_username

usernameClaim: sub
oauth:
# Only required when using provider oauth
endpoints:
wellKnown: http://localhost:8083/default/.well-known/openid-configuration
tokenIssuance:
authorization:

tokenIssuance: null
authorization: null
audience: default

scopes:
- openid

- openid
client:
id: default
secret:

secret: null
redirectURI: http://localhost:4200/oauth2/callback

# azure:
# # Only required when using provider azure
# authorizationEndpoint: http://tbd

# client:
# id: tbd
# secret: tbd

# audience: tbd
# redirectURI: http://localhost:4200/oauth2/callback

pipelines:
timeout: 60

database:
url: postgresql://dev:dev@localhost:5432/dev

initial:
admin: admin

logging:
level: DEBUG
logPath: logs/

requests:
timeout: 2

prometheus:
url: http://localhost:8080/prometheus/
15 changes: 6 additions & 9 deletions backend/capellacollab/config/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@

# pylint: disable=bad-builtin

import pathlib

import deepdiff
import yaml

from . import loader
from . import models as config_models

Check warning on line 9 in backend/capellacollab/config/diff.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/diff.py#L9

Added line #L9 was not covered by tests


class bcolors:
Expand All @@ -22,16 +20,15 @@ class bcolors:

print("Start comparison of configuration files")

config_template = yaml.safe_load(
(
pathlib.Path(__file__).parents[2] / "config" / "config_template.yaml"
).open()
)
pydantic_config = config_models.AppConfig()

Check warning on line 23 in backend/capellacollab/config/diff.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/diff.py#L23

Added line #L23 was not covered by tests

config = loader.load_yaml()

diff = deepdiff.DeepDiff(
config, config_template, ignore_order=True, report_repetition=True
config,
pydantic_config.model_dump(),
ignore_order=True,
report_repetition=True,
)

for key, value in (
Expand Down
20 changes: 20 additions & 0 deletions backend/capellacollab/config/generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-FileCopyrightText: Copyright DB InfraGO AG and contributors
# SPDX-License-Identifier: Apache-2.0

import os

import yaml

from . import models


def write_config():
current_dir = os.path.dirname(os.path.realpath(__file__))
config_path = os.path.join(current_dir, "config.yaml")

Check warning on line 13 in backend/capellacollab/config/generate.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/generate.py#L12-L13

Added lines #L12 - L13 were not covered by tests

app_config = models.AppConfig()
config_dict = app_config.model_dump()
yaml_str = yaml.dump(config_dict, sort_keys=False)

Check warning on line 17 in backend/capellacollab/config/generate.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/generate.py#L15-L17

Added lines #L15 - L17 were not covered by tests

with open(config_path, "w", encoding="utf-8") as yaml_file:
yaml_file.write(yaml_str)

Check warning on line 20 in backend/capellacollab/config/generate.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/generate.py#L20

Added line #L20 was not covered by tests
20 changes: 17 additions & 3 deletions backend/capellacollab/config/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
from . import exceptions

log = logging.getLogger(__name__)
CONFIG_FILE_NAME = "config.yaml"

config_locations: list[pathlib.Path] = [
pathlib.Path(__file__).parents[2] / "config" / "config.yaml",
pathlib.Path(__file__).parents[0] / CONFIG_FILE_NAME,
pathlib.Path(__file__).parents[2] / "config" / CONFIG_FILE_NAME,
pathlib.Path(appdirs.user_config_dir("capellacollab", "db"))
/ "config.yaml",
pathlib.Path("/etc/capellacollab") / "config.yaml",
/ CONFIG_FILE_NAME,
pathlib.Path("/etc/capellacollab") / CONFIG_FILE_NAME,
]

config_fallback_locations: list[pathlib.Path] = [
Expand All @@ -38,6 +40,18 @@ def construct_mapping(self, node, deep=False):
return super().construct_mapping(node, deep)


def does_config_exist() -> bool:
for loc in config_locations:
if loc.exists():
return True

for loc in config_fallback_locations:
if loc.exists():
return True

Check warning on line 50 in backend/capellacollab/config/loader.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/loader.py#L50

Added line #L50 was not covered by tests

return False

Check warning on line 52 in backend/capellacollab/config/loader.py

View check run for this annotation

Codecov / codecov/patch

backend/capellacollab/config/loader.py#L52

Added line #L52 was not covered by tests


def load_yaml() -> dict:
log.debug("Searching for configuration files...")
for loc in config_locations:
Expand Down
Loading

0 comments on commit ae531cc

Please sign in to comment.