Source code for ldap_sync.config

#  Copyright (c) 2022. The Pycroft Authors. See the AUTHORS file.
#  This file is part of the Pycroft project and licensed under the terms of
#  the Apache License, Version 2.0. See the LICENSE file for details
"""
ldap_sync.config
~~~~~~~~~~~~~~~~
"""
from __future__ import annotations

import os
from typing import NamedTuple
from distutils.util import strtobool

from . import logger
from .concepts import types


[docs] class SyncConfig(NamedTuple): # DB-related db_uri: str # LDAP-related host: str port: int use_ssl: bool ca_certs_file: str | None ca_certs_data: str | None bind_dn: types.DN bind_pw: str base_dn: types.DN required_property: str
def _from_environ_or_defaults(key: str, defaults: dict[str, str | None]) -> str | None: try: return os.environ[f'PYCROFT_LDAP_{key.upper()}'] except KeyError as e: if key not in defaults: print("defaults:", defaults) raise ValueError(f"Missing configuration key {key}") from e return defaults[key]
[docs] def get_config(**defaults: str | None) -> SyncConfig: """Fetch the config from the environments, filling in defaults as specified. Values are converted in accordance to the types hints of :class:`SyncConfig`. The environment variables need to be of the format is ``PYCROFT_LDAP_$VAR``, e.g. ``PYCROFT_LDAP_PORT``. """ db_uri = os.environ["PYCROFT_DB_URI"] config_dict: dict[str, str | None] = { # e.g. 'host': 'PYCROFT_LDAP_HOST' key: _from_environ_or_defaults(key, defaults) for key in SyncConfig._fields if key != 'db_uri' } def _get_or_fail(dict: dict[str, str | None], key: str) -> str: if (str_value := dict.pop(key)) is None: raise ValueError(f"{key} not found in environ or defaults") return str_value port = int(_get_or_fail(config_dict, "port")) use_ssl = bool(strtobool(_get_or_fail(config_dict, "use_ssl"))) bind_dn = types.DN(_get_or_fail(config_dict, "bind_dn")) base_dn = types.DN(_get_or_fail(config_dict, "base_dn")) return SyncConfig( db_uri=db_uri, port=port, use_ssl=use_ssl, bind_dn=bind_dn, base_dn=base_dn, **config_dict, )
[docs] def get_config_or_exit(**defaults: str | None) -> SyncConfig: """See :func:`get_config`""" try: return get_config(**defaults) except KeyError as exc: logger.critical("%s not set, quitting", exc.args[0]) exit()