From b5d60fb3becf49ea18c785b6075d6eb292709907 Mon Sep 17 00:00:00 2001 From: codex Date: Tue, 21 Apr 2026 01:26:42 -0300 Subject: [PATCH] refactor(ariadne): split settings sections --- ariadne/settings.py | 423 ++++------------------------------- ariadne/settings_env.py | 28 +++ ariadne/settings_sections.py | 343 ++++++++++++++++++++++++++++ ci/loc_hygiene_waivers.tsv | 1 - 4 files changed, 410 insertions(+), 385 deletions(-) create mode 100644 ariadne/settings_env.py create mode 100644 ariadne/settings_sections.py diff --git a/ariadne/settings.py b/ariadne/settings.py index 57e5abb..e68b488 100644 --- a/ariadne/settings.py +++ b/ariadne/settings.py @@ -1,33 +1,28 @@ from __future__ import annotations from dataclasses import dataclass -import os -from typing import Any - -def _env(name: str, default: str = "") -> str: - value = os.getenv(name, default) - return value.strip() if isinstance(value, str) else default - - -def _env_bool(name: str, default: str = "false") -> bool: - return _env(name, default).lower() in {"1", "true", "yes", "y", "on"} - - -def _env_int(name: str, default: int) -> int: - raw = _env(name, str(default)) - try: - return int(raw) - except ValueError: - return default - - -def _env_float(name: str, default: float) -> float: - raw = _env(name, str(default)) - try: - return float(raw) - except ValueError: - return default +from .settings_env import _env, _env_bool, _env_float, _env_int +from .settings_sections import ( + _cluster_state_config, + _comms_config, + _firefly_config, + _image_sweeper_config, + _jenkins_build_weather_config, + _jenkins_workspace_cleanup_config, + _keycloak_config, + _mailu_config, + _metis_config, + _nextcloud_config, + _opensearch_config, + _platform_quality_probe_config, + _portal_group_config, + _schedule_config, + _smtp_config, + _vault_config, + _vaultwarden_config, + _wger_config, +) @dataclass(frozen=True) @@ -253,366 +248,26 @@ class Settings: metrics_path: str - @classmethod - def _keycloak_config(cls) -> dict[str, Any]: - keycloak_url = _env("KEYCLOAK_URL", "https://sso.bstein.dev").rstrip("/") - keycloak_realm = _env("KEYCLOAK_REALM", "atlas") - keycloak_client_id = _env("KEYCLOAK_CLIENT_ID", "bstein-dev-home") - keycloak_issuer = _env("KEYCLOAK_ISSUER", f"{keycloak_url}/realms/{keycloak_realm}").rstrip("/") - keycloak_jwks_url = _env("KEYCLOAK_JWKS_URL", f"{keycloak_issuer}/protocol/openid-connect/certs").rstrip("/") - return { - "keycloak_url": keycloak_url, - "keycloak_realm": keycloak_realm, - "keycloak_client_id": keycloak_client_id, - "keycloak_issuer": keycloak_issuer, - "keycloak_jwks_url": keycloak_jwks_url, - "keycloak_admin_url": _env("KEYCLOAK_ADMIN_URL", keycloak_url).rstrip("/"), - "keycloak_admin_realm": _env("KEYCLOAK_ADMIN_REALM", keycloak_realm), - "keycloak_admin_client_id": _env("KEYCLOAK_ADMIN_CLIENT_ID", ""), - "keycloak_admin_client_secret": _env("KEYCLOAK_ADMIN_CLIENT_SECRET", ""), - } - - @classmethod - def _portal_group_config(cls) -> dict[str, Any]: - return { - "portal_admin_users": [u for u in (_env("PORTAL_ADMIN_USERS", "bstein")).split(",") if u.strip()], - "portal_admin_groups": [g for g in (_env("PORTAL_ADMIN_GROUPS", "admin")).split(",") if g.strip()], - "account_allowed_groups": [ - g for g in (_env("ACCOUNT_ALLOWED_GROUPS", "dev,admin")).split(",") if g.strip() - ], - "allowed_flag_groups": [g for g in (_env("ALLOWED_FLAG_GROUPS", "demo,test")).split(",") if g.strip()], - "default_user_groups": [g for g in (_env("DEFAULT_USER_GROUPS", "dev")).split(",") if g.strip()], - } - - @classmethod - def _mailu_config(cls) -> dict[str, Any]: - mailu_domain = _env("MAILU_DOMAIN", "bstein.dev") - return { - "mailu_domain": mailu_domain, - "mailu_sync_url": _env( - "MAILU_SYNC_URL", - "http://mailu-sync-listener.mailu-mailserver.svc.cluster.local:8080/events", - ).rstrip("/"), - "mailu_event_min_interval_sec": _env_float("MAILU_EVENT_MIN_INTERVAL_SEC", 10.0), - "mailu_sync_wait_timeout_sec": _env_float("MAILU_SYNC_WAIT_TIMEOUT_SEC", 60.0), - "mailu_mailbox_wait_timeout_sec": _env_float("MAILU_MAILBOX_WAIT_TIMEOUT_SEC", 60.0), - "mailu_db_host": _env("MAILU_DB_HOST", "postgres-service.postgres.svc.cluster.local"), - "mailu_db_port": _env_int("MAILU_DB_PORT", 5432), - "mailu_db_name": _env("MAILU_DB_NAME", "mailu"), - "mailu_db_user": _env("MAILU_DB_USER", "mailu"), - "mailu_db_password": _env("MAILU_DB_PASSWORD", ""), - "mailu_host": _env("MAILU_HOST", f"mail.{mailu_domain}"), - "mailu_default_quota": _env_int("MAILU_DEFAULT_QUOTA", 20000000000), - "mailu_system_users": [u for u in _env("MAILU_SYSTEM_USERS", "").split(",") if u.strip()], - "mailu_system_password": _env("MAILU_SYSTEM_PASSWORD", ""), - } - - @classmethod - def _smtp_config(cls, mailu_domain: str) -> dict[str, Any]: - return { - "smtp_host": _env("SMTP_HOST", ""), - "smtp_port": _env_int("SMTP_PORT", 25), - "smtp_username": _env("SMTP_USERNAME", ""), - "smtp_password": _env("SMTP_PASSWORD", ""), - "smtp_starttls": _env_bool("SMTP_STARTTLS", "false"), - "smtp_use_tls": _env_bool("SMTP_USE_TLS", "false"), - "smtp_from": _env("SMTP_FROM", f"postmaster@{mailu_domain}"), - "smtp_timeout_sec": _env_float("SMTP_TIMEOUT_SEC", 10.0), - "welcome_email_enabled": _env_bool("WELCOME_EMAIL_ENABLED", "true"), - } - - @classmethod - def _nextcloud_config(cls) -> dict[str, Any]: - return { - "nextcloud_namespace": _env("NEXTCLOUD_NAMESPACE", "nextcloud"), - "nextcloud_pod_label": _env("NEXTCLOUD_POD_LABEL", "app=nextcloud"), - "nextcloud_container": _env("NEXTCLOUD_CONTAINER", "nextcloud"), - "nextcloud_exec_timeout_sec": _env_float("NEXTCLOUD_EXEC_TIMEOUT_SEC", 120.0), - "nextcloud_db_host": _env("NEXTCLOUD_DB_HOST", "postgres-service.postgres.svc.cluster.local"), - "nextcloud_db_port": _env_int("NEXTCLOUD_DB_PORT", 5432), - "nextcloud_db_name": _env("NEXTCLOUD_DB_NAME", "nextcloud"), - "nextcloud_db_user": _env("NEXTCLOUD_DB_USER", "nextcloud"), - "nextcloud_db_password": _env("NEXTCLOUD_DB_PASSWORD", ""), - "nextcloud_url": _env("NEXTCLOUD_URL", "https://cloud.bstein.dev").rstrip("/"), - "nextcloud_admin_user": _env("NEXTCLOUD_ADMIN_USER", ""), - "nextcloud_admin_password": _env("NEXTCLOUD_ADMIN_PASSWORD", ""), - } - - @classmethod - def _wger_config(cls) -> dict[str, Any]: - return { - "wger_namespace": _env("WGER_NAMESPACE", "health"), - "wger_user_sync_wait_timeout_sec": _env_float("WGER_USER_SYNC_WAIT_TIMEOUT_SEC", 60.0), - "wger_pod_label": _env("WGER_POD_LABEL", "app=wger"), - "wger_container": _env("WGER_CONTAINER", "wger"), - "wger_admin_username": _env("WGER_ADMIN_USERNAME", ""), - "wger_admin_password": _env("WGER_ADMIN_PASSWORD", ""), - "wger_admin_email": _env("WGER_ADMIN_EMAIL", ""), - } - - @classmethod - def _firefly_config(cls) -> dict[str, Any]: - return { - "firefly_namespace": _env("FIREFLY_NAMESPACE", "finance"), - "firefly_user_sync_wait_timeout_sec": _env_float("FIREFLY_USER_SYNC_WAIT_TIMEOUT_SEC", 90.0), - "firefly_pod_label": _env("FIREFLY_POD_LABEL", "app=firefly"), - "firefly_container": _env("FIREFLY_CONTAINER", "firefly"), - "firefly_cron_base_url": _env( - "FIREFLY_CRON_BASE_URL", - "http://firefly.finance.svc.cluster.local/api/v1/cron", - ), - "firefly_cron_token": _env("FIREFLY_CRON_TOKEN", ""), - "firefly_cron_timeout_sec": _env_float("FIREFLY_CRON_TIMEOUT_SEC", 30.0), - } - - @classmethod - def _vault_config(cls) -> dict[str, Any]: - return { - "vault_namespace": _env("VAULT_NAMESPACE", "vault"), - "vault_addr": _env("VAULT_ADDR", "http://vault.vault.svc.cluster.local:8200").rstrip("/"), - "vault_token": _env("VAULT_TOKEN", ""), - "vault_k8s_role": _env("VAULT_K8S_ROLE", "vault"), - "vault_k8s_role_ttl": _env("VAULT_K8S_ROLE_TTL", "1h"), - "vault_k8s_token_reviewer_jwt": _env("VAULT_K8S_TOKEN_REVIEWER_JWT", ""), - "vault_k8s_token_reviewer_jwt_file": _env("VAULT_K8S_TOKEN_REVIEWER_JWT_FILE", ""), - "vault_oidc_discovery_url": _env("VAULT_OIDC_DISCOVERY_URL", ""), - "vault_oidc_client_id": _env("VAULT_OIDC_CLIENT_ID", ""), - "vault_oidc_client_secret": _env("VAULT_OIDC_CLIENT_SECRET", ""), - "vault_oidc_default_role": _env("VAULT_OIDC_DEFAULT_ROLE", "admin"), - "vault_oidc_scopes": _env("VAULT_OIDC_SCOPES", "openid profile email groups"), - "vault_oidc_user_claim": _env("VAULT_OIDC_USER_CLAIM", "preferred_username"), - "vault_oidc_groups_claim": _env("VAULT_OIDC_GROUPS_CLAIM", "groups"), - "vault_oidc_token_policies": _env("VAULT_OIDC_TOKEN_POLICIES", ""), - "vault_oidc_admin_group": _env("VAULT_OIDC_ADMIN_GROUP", "admin"), - "vault_oidc_admin_policies": _env("VAULT_OIDC_ADMIN_POLICIES", "default,vault-admin"), - "vault_oidc_dev_group": _env("VAULT_OIDC_DEV_GROUP", "dev"), - "vault_oidc_dev_policies": _env("VAULT_OIDC_DEV_POLICIES", "default,dev-kv"), - "vault_oidc_user_group": _env("VAULT_OIDC_USER_GROUP", ""), - "vault_oidc_user_policies": _env("VAULT_OIDC_USER_POLICIES", ""), - "vault_oidc_redirect_uris": _env( - "VAULT_OIDC_REDIRECT_URIS", - "https://secret.bstein.dev/ui/vault/auth/oidc/oidc/callback", - ), - "vault_oidc_bound_audiences": _env("VAULT_OIDC_BOUND_AUDIENCES", ""), - "vault_oidc_bound_claims_type": _env("VAULT_OIDC_BOUND_CLAIMS_TYPE", "string"), - } - - @classmethod - def _comms_config(cls) -> dict[str, Any]: - return { - "comms_namespace": _env("COMMS_NAMESPACE", "comms"), - "comms_synapse_base": _env( - "COMMS_SYNAPSE_BASE", - "http://othrys-synapse-matrix-synapse:8008", - ).rstrip("/"), - "comms_auth_base": _env( - "COMMS_AUTH_BASE", - "http://matrix-authentication-service:8080", - ).rstrip("/"), - "comms_mas_admin_api_base": _env( - "COMMS_MAS_ADMIN_API_BASE", - "http://matrix-authentication-service:8081/api/admin/v1", - ).rstrip("/"), - "comms_mas_token_url": _env( - "COMMS_MAS_TOKEN_URL", - "http://matrix-authentication-service:8080/oauth2/token", - ), - "comms_mas_admin_client_id": _env("COMMS_MAS_ADMIN_CLIENT_ID", "01KDXMVQBQ5JNY6SEJPZW6Z8BM"), - "comms_mas_admin_client_secret": _env("COMMS_MAS_ADMIN_CLIENT_SECRET", ""), - "comms_server_name": _env("COMMS_SERVER_NAME", "live.bstein.dev"), - "comms_room_alias": _env("COMMS_ROOM_ALIAS", "#othrys:live.bstein.dev"), - "comms_room_name": _env("COMMS_ROOM_NAME", "Othrys"), - "comms_pin_message": _env( - "COMMS_PIN_MESSAGE", - "Invite guests: share https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join and choose 'Continue' -> 'Join as guest'.", - ), - "comms_seeder_user": _env("COMMS_SEEDER_USER", "othrys-seeder"), - "comms_seeder_password": _env("COMMS_SEEDER_PASSWORD", ""), - "comms_bot_user": _env("COMMS_BOT_USER", "atlasbot"), - "comms_bot_password": _env("COMMS_BOT_PASSWORD", ""), - "comms_synapse_db_host": _env( - "COMMS_SYNAPSE_DB_HOST", - "postgres-service.postgres.svc.cluster.local", - ), - "comms_synapse_db_port": _env_int("COMMS_SYNAPSE_DB_PORT", 5432), - "comms_synapse_db_name": _env("COMMS_SYNAPSE_DB_NAME", "synapse"), - "comms_synapse_db_user": _env("COMMS_SYNAPSE_DB_USER", "synapse"), - "comms_synapse_db_password": _env("COMMS_SYNAPSE_DB_PASSWORD", ""), - "comms_synapse_admin_token": _env("COMMS_SYNAPSE_ADMIN_TOKEN", ""), - "comms_timeout_sec": _env_float("COMMS_TIMEOUT_SEC", 30.0), - "comms_guest_stale_days": _env_int("COMMS_GUEST_STALE_DAYS", 14), - } - - @classmethod - def _image_sweeper_config(cls) -> dict[str, Any]: - return { - "image_sweeper_namespace": _env("IMAGE_SWEEPER_NAMESPACE", "maintenance"), - "image_sweeper_service_account": _env("IMAGE_SWEEPER_SERVICE_ACCOUNT", "node-image-sweeper"), - "image_sweeper_job_ttl_sec": _env_int("IMAGE_SWEEPER_JOB_TTL_SEC", 3600), - "image_sweeper_wait_timeout_sec": _env_float("IMAGE_SWEEPER_WAIT_TIMEOUT_SEC", 1200.0), - } - - @classmethod - def _platform_quality_probe_config(cls) -> dict[str, Any]: - return { - "platform_quality_probe_namespace": _env("PLATFORM_QUALITY_PROBE_NAMESPACE", "monitoring"), - "platform_quality_probe_script_configmap": _env( - "PLATFORM_QUALITY_PROBE_SCRIPT_CONFIGMAP", - "platform-quality-suite-probe-script", - ), - "platform_quality_probe_image": _env("PLATFORM_QUALITY_PROBE_IMAGE", "curlimages/curl:8.12.1"), - "platform_quality_probe_job_ttl_sec": _env_int("PLATFORM_QUALITY_PROBE_JOB_TTL_SEC", 1800), - "platform_quality_probe_wait_timeout_sec": _env_float("PLATFORM_QUALITY_PROBE_WAIT_TIMEOUT_SEC", 180.0), - "platform_quality_probe_pushgateway_url": _env( - "PLATFORM_QUALITY_PROBE_PUSHGATEWAY_URL", - "http://platform-quality-gateway.monitoring.svc.cluster.local:9091", - ).rstrip("/"), - "platform_quality_probe_http_timeout_sec": _env_int("PLATFORM_QUALITY_PROBE_HTTP_TIMEOUT_SECONDS", 12), - } - - @classmethod - def _jenkins_build_weather_config(cls) -> dict[str, Any]: - return { - "jenkins_base_url": _env("JENKINS_BASE_URL", "https://ci.bstein.dev").rstrip("/"), - "jenkins_api_user": _env("JENKINS_API_USER", ""), - "jenkins_api_token": _env("JENKINS_API_TOKEN", ""), - "jenkins_api_timeout_sec": _env_float("JENKINS_API_TIMEOUT_SEC", 10.0), - } - - @classmethod - def _jenkins_workspace_cleanup_config(cls) -> dict[str, Any]: - return { - "jenkins_workspace_namespace": _env("JENKINS_WORKSPACE_NAMESPACE", "jenkins"), - "jenkins_workspace_pvc_prefix": _env("JENKINS_WORKSPACE_PVC_PREFIX", "pvc-workspace-"), - "jenkins_workspace_cleanup_min_age_hours": _env_float("JENKINS_WORKSPACE_CLEANUP_MIN_AGE_HOURS", 12.0), - "jenkins_workspace_cleanup_dry_run": _env_bool("JENKINS_WORKSPACE_CLEANUP_DRY_RUN", "false"), - "jenkins_workspace_cleanup_max_deletions_per_run": _env_int( - "JENKINS_WORKSPACE_CLEANUP_MAX_DELETIONS_PER_RUN", - 20, - ), - } - - @classmethod - def _vaultwarden_config(cls) -> dict[str, Any]: - return { - "vaultwarden_namespace": _env("VAULTWARDEN_NAMESPACE", "vaultwarden"), - "vaultwarden_pod_label": _env("VAULTWARDEN_POD_LABEL", "app=vaultwarden"), - "vaultwarden_pod_port": _env_int("VAULTWARDEN_POD_PORT", 80), - "vaultwarden_service_host": _env( - "VAULTWARDEN_SERVICE_HOST", - "vaultwarden-service.vaultwarden.svc.cluster.local", - ), - "vaultwarden_admin_secret_name": _env("VAULTWARDEN_ADMIN_SECRET_NAME", "vaultwarden-admin"), - "vaultwarden_admin_secret_key": _env("VAULTWARDEN_ADMIN_SECRET_KEY", "ADMIN_TOKEN"), - "vaultwarden_admin_session_ttl_sec": _env_float("VAULTWARDEN_ADMIN_SESSION_TTL_SEC", 300.0), - "vaultwarden_admin_rate_limit_backoff_sec": _env_float("VAULTWARDEN_ADMIN_RATE_LIMIT_BACKOFF_SEC", 600.0), - "vaultwarden_retry_cooldown_sec": _env_float("VAULTWARDEN_RETRY_COOLDOWN_SEC", 1800.0), - "vaultwarden_failure_bailout": _env_int("VAULTWARDEN_FAILURE_BAILOUT", 2), - "vaultwarden_invite_refresh_sec": _env_float("VAULTWARDEN_INVITE_REFRESH_SEC", 86400.0), - } - - @classmethod - def _schedule_config(cls) -> dict[str, Any]: - return { - "mailu_sync_cron": _env("ARIADNE_SCHEDULE_MAILU_SYNC", "30 4 * * *"), - "nextcloud_sync_cron": _env("ARIADNE_SCHEDULE_NEXTCLOUD_SYNC", "0 5 * * *"), - "nextcloud_cron": _env("ARIADNE_SCHEDULE_NEXTCLOUD_CRON", "*/5 * * * *"), - "nextcloud_maintenance_cron": _env("ARIADNE_SCHEDULE_NEXTCLOUD_MAINTENANCE", "30 4 * * *"), - "vaultwarden_sync_cron": _env("ARIADNE_SCHEDULE_VAULTWARDEN_SYNC", "0 * * * *"), - "wger_user_sync_cron": _env("ARIADNE_SCHEDULE_WGER_USER_SYNC", "0 5 * * *"), - "wger_admin_cron": _env("ARIADNE_SCHEDULE_WGER_ADMIN", "15 3 * * *"), - "firefly_user_sync_cron": _env("ARIADNE_SCHEDULE_FIREFLY_USER_SYNC", "0 6 * * *"), - "firefly_cron": _env("ARIADNE_SCHEDULE_FIREFLY_CRON", "0 3 * * *"), - "pod_cleaner_cron": _env("ARIADNE_SCHEDULE_POD_CLEANER", "0 * * * *"), - "opensearch_prune_cron": _env("ARIADNE_SCHEDULE_OPENSEARCH_PRUNE", "23 3 * * *"), - "image_sweeper_cron": _env("ARIADNE_SCHEDULE_IMAGE_SWEEPER", "30 4 * * 0"), - "vault_k8s_auth_cron": _env("ARIADNE_SCHEDULE_VAULT_K8S_AUTH", "0 * * * *"), - "vault_oidc_cron": _env("ARIADNE_SCHEDULE_VAULT_OIDC", "0 * * * *"), - "comms_guest_name_cron": _env("ARIADNE_SCHEDULE_COMMS_GUEST_NAME", "*/5 * * * *"), - "comms_pin_invite_cron": _env("ARIADNE_SCHEDULE_COMMS_PIN_INVITE", "*/30 * * * *"), - "comms_reset_room_cron": _env("ARIADNE_SCHEDULE_COMMS_RESET_ROOM", "0 0 1 1 *"), - "comms_seed_room_cron": _env("ARIADNE_SCHEDULE_COMMS_SEED_ROOM", "*/10 * * * *"), - "keycloak_profile_cron": _env("ARIADNE_SCHEDULE_KEYCLOAK_PROFILE", "0 */6 * * *"), - "metis_k3s_token_sync_cron": _env("ARIADNE_SCHEDULE_METIS_K3S_TOKEN_SYNC", "11 */6 * * *"), - "platform_quality_suite_probe_cron": _env( - "ARIADNE_SCHEDULE_PLATFORM_QUALITY_SUITE_PROBE", - "*/15 * * * *", - ), - "jenkins_build_weather_cron": _env( - "ARIADNE_SCHEDULE_JENKINS_BUILD_WEATHER", - "*/10 * * * *", - ), - "jenkins_workspace_cleanup_cron": _env( - "ARIADNE_SCHEDULE_JENKINS_WORKSPACE_CLEANUP", - "45 */6 * * *", - ), - } - - @classmethod - def _cluster_state_config(cls) -> dict[str, Any]: - return { - "vm_url": _env( - "ARIADNE_VM_URL", - "http://victoria-metrics-single-server.monitoring.svc.cluster.local:8428", - ).rstrip("/"), - "cluster_state_vm_timeout_sec": _env_float("ARIADNE_CLUSTER_STATE_VM_TIMEOUT_SEC", 5.0), - "alertmanager_url": _env("ARIADNE_ALERTMANAGER_URL", "").rstrip("/"), - "cluster_state_cron": _env("ARIADNE_SCHEDULE_CLUSTER_STATE", "*/15 * * * *"), - "cluster_state_keep": _env_int("ARIADNE_CLUSTER_STATE_KEEP", 168), - } - - @classmethod - def _metis_config(cls) -> dict[str, Any]: - return { - "metis_base_url": _env("METIS_BASE_URL", "http://metis.maintenance.svc.cluster.local").rstrip("/"), - "metis_watch_url": _env("METIS_WATCH_URL", "").rstrip("/"), - "metis_timeout_sec": _env_float("METIS_TIMEOUT_SEC", 10.0), - "metis_sentinel_watch_cron": _env("ARIADNE_SCHEDULE_METIS_SENTINEL_WATCH", "*/15 * * * *"), - "metis_token_sync_namespace": _env("METIS_TOKEN_SYNC_NAMESPACE", "maintenance"), - "metis_token_sync_service_account": _env("METIS_TOKEN_SYNC_SERVICE_ACCOUNT", "metis-token-sync"), - "metis_token_sync_node_name": _env("METIS_TOKEN_SYNC_NODE_NAME", "titan-0a"), - "metis_token_sync_image": _env("METIS_TOKEN_SYNC_IMAGE", "hashicorp/vault:1.17.6"), - "metis_token_sync_job_ttl_sec": _env_int("METIS_TOKEN_SYNC_JOB_TTL_SEC", 1800), - "metis_token_sync_wait_timeout_sec": _env_float("METIS_TOKEN_SYNC_WAIT_TIMEOUT_SEC", 180.0), - "metis_token_sync_vault_addr": _env( - "METIS_TOKEN_SYNC_VAULT_ADDR", - "http://vault.vault.svc.cluster.local:8200", - ).rstrip("/"), - "metis_token_sync_vault_k8s_role": _env("METIS_TOKEN_SYNC_VAULT_K8S_ROLE", "maintenance-metis-token-sync"), - } - - @classmethod - def _opensearch_config(cls) -> dict[str, Any]: - return { - "opensearch_url": _env( - "OPENSEARCH_URL", - "http://opensearch-master.logging.svc.cluster.local:9200", - ).rstrip("/"), - "opensearch_limit_bytes": _env_int("OPENSEARCH_LIMIT_BYTES", 1024**4), - "opensearch_index_patterns": _env("OPENSEARCH_INDEX_PATTERNS", "kube-*,journald-*"), - "opensearch_timeout_sec": _env_float("OPENSEARCH_TIMEOUT_SEC", 30.0), - } - @classmethod def from_env(cls) -> "Settings": - keycloak_cfg = cls._keycloak_config() - portal_cfg = cls._portal_group_config() - mailu_cfg = cls._mailu_config() - smtp_cfg = cls._smtp_config(mailu_cfg["mailu_domain"]) - nextcloud_cfg = cls._nextcloud_config() - wger_cfg = cls._wger_config() - firefly_cfg = cls._firefly_config() - vault_cfg = cls._vault_config() - comms_cfg = cls._comms_config() - image_cfg = cls._image_sweeper_config() - platform_quality_probe_cfg = cls._platform_quality_probe_config() - jenkins_build_weather_cfg = cls._jenkins_build_weather_config() - jenkins_workspace_cleanup_cfg = cls._jenkins_workspace_cleanup_config() - vaultwarden_cfg = cls._vaultwarden_config() - schedule_cfg = cls._schedule_config() - cluster_cfg = cls._cluster_state_config() - metis_cfg = cls._metis_config() - opensearch_cfg = cls._opensearch_config() + keycloak_cfg = _keycloak_config() + portal_cfg = _portal_group_config() + mailu_cfg = _mailu_config() + smtp_cfg = _smtp_config(mailu_cfg["mailu_domain"]) + nextcloud_cfg = _nextcloud_config() + wger_cfg = _wger_config() + firefly_cfg = _firefly_config() + vault_cfg = _vault_config() + comms_cfg = _comms_config() + image_cfg = _image_sweeper_config() + platform_quality_probe_cfg = _platform_quality_probe_config() + jenkins_build_weather_cfg = _jenkins_build_weather_config() + jenkins_workspace_cleanup_cfg = _jenkins_workspace_cleanup_config() + vaultwarden_cfg = _vaultwarden_config() + schedule_cfg = _schedule_config() + cluster_cfg = _cluster_state_config() + metis_cfg = _metis_config() + opensearch_cfg = _opensearch_config() portal_db = _env("PORTAL_DATABASE_URL", "") ariadne_db = _env("ARIADNE_DATABASE_URL", portal_db) diff --git a/ariadne/settings_env.py b/ariadne/settings_env.py new file mode 100644 index 0000000..640fc2d --- /dev/null +++ b/ariadne/settings_env.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +import os + + +def _env(name: str, default: str = "") -> str: + value = os.getenv(name, default) + return value.strip() if isinstance(value, str) else default + + +def _env_bool(name: str, default: str = "false") -> bool: + return _env(name, default).lower() in {"1", "true", "yes", "y", "on"} + + +def _env_int(name: str, default: int) -> int: + raw = _env(name, str(default)) + try: + return int(raw) + except ValueError: + return default + + +def _env_float(name: str, default: float) -> float: + raw = _env(name, str(default)) + try: + return float(raw) + except ValueError: + return default diff --git a/ariadne/settings_sections.py b/ariadne/settings_sections.py new file mode 100644 index 0000000..b9410b4 --- /dev/null +++ b/ariadne/settings_sections.py @@ -0,0 +1,343 @@ +from __future__ import annotations + +from typing import Any + +from .settings_env import _env, _env_bool, _env_float, _env_int + + +def _keycloak_config() -> dict[str, Any]: + keycloak_url = _env("KEYCLOAK_URL", "https://sso.bstein.dev").rstrip("/") + keycloak_realm = _env("KEYCLOAK_REALM", "atlas") + keycloak_client_id = _env("KEYCLOAK_CLIENT_ID", "bstein-dev-home") + keycloak_issuer = _env("KEYCLOAK_ISSUER", f"{keycloak_url}/realms/{keycloak_realm}").rstrip("/") + keycloak_jwks_url = _env("KEYCLOAK_JWKS_URL", f"{keycloak_issuer}/protocol/openid-connect/certs").rstrip("/") + return { + "keycloak_url": keycloak_url, + "keycloak_realm": keycloak_realm, + "keycloak_client_id": keycloak_client_id, + "keycloak_issuer": keycloak_issuer, + "keycloak_jwks_url": keycloak_jwks_url, + "keycloak_admin_url": _env("KEYCLOAK_ADMIN_URL", keycloak_url).rstrip("/"), + "keycloak_admin_realm": _env("KEYCLOAK_ADMIN_REALM", keycloak_realm), + "keycloak_admin_client_id": _env("KEYCLOAK_ADMIN_CLIENT_ID", ""), + "keycloak_admin_client_secret": _env("KEYCLOAK_ADMIN_CLIENT_SECRET", ""), + } + + +def _portal_group_config() -> dict[str, Any]: + return { + "portal_admin_users": [u for u in (_env("PORTAL_ADMIN_USERS", "bstein")).split(",") if u.strip()], + "portal_admin_groups": [g for g in (_env("PORTAL_ADMIN_GROUPS", "admin")).split(",") if g.strip()], + "account_allowed_groups": [g for g in (_env("ACCOUNT_ALLOWED_GROUPS", "dev,admin")).split(",") if g.strip()], + "allowed_flag_groups": [g for g in (_env("ALLOWED_FLAG_GROUPS", "demo,test")).split(",") if g.strip()], + "default_user_groups": [g for g in (_env("DEFAULT_USER_GROUPS", "dev")).split(",") if g.strip()], + } + + +def _mailu_config() -> dict[str, Any]: + mailu_domain = _env("MAILU_DOMAIN", "bstein.dev") + return { + "mailu_domain": mailu_domain, + "mailu_sync_url": _env( + "MAILU_SYNC_URL", + "http://mailu-sync-listener.mailu-mailserver.svc.cluster.local:8080/events", + ).rstrip("/"), + "mailu_event_min_interval_sec": _env_float("MAILU_EVENT_MIN_INTERVAL_SEC", 10.0), + "mailu_sync_wait_timeout_sec": _env_float("MAILU_SYNC_WAIT_TIMEOUT_SEC", 60.0), + "mailu_mailbox_wait_timeout_sec": _env_float("MAILU_MAILBOX_WAIT_TIMEOUT_SEC", 60.0), + "mailu_db_host": _env("MAILU_DB_HOST", "postgres-service.postgres.svc.cluster.local"), + "mailu_db_port": _env_int("MAILU_DB_PORT", 5432), + "mailu_db_name": _env("MAILU_DB_NAME", "mailu"), + "mailu_db_user": _env("MAILU_DB_USER", "mailu"), + "mailu_db_password": _env("MAILU_DB_PASSWORD", ""), + "mailu_host": _env("MAILU_HOST", f"mail.{mailu_domain}"), + "mailu_default_quota": _env_int("MAILU_DEFAULT_QUOTA", 20000000000), + "mailu_system_users": [u for u in _env("MAILU_SYSTEM_USERS", "").split(",") if u.strip()], + "mailu_system_password": _env("MAILU_SYSTEM_PASSWORD", ""), + } + + +def _smtp_config(mailu_domain: str) -> dict[str, Any]: + return { + "smtp_host": _env("SMTP_HOST", ""), + "smtp_port": _env_int("SMTP_PORT", 25), + "smtp_username": _env("SMTP_USERNAME", ""), + "smtp_password": _env("SMTP_PASSWORD", ""), + "smtp_starttls": _env_bool("SMTP_STARTTLS", "false"), + "smtp_use_tls": _env_bool("SMTP_USE_TLS", "false"), + "smtp_from": _env("SMTP_FROM", f"postmaster@{mailu_domain}"), + "smtp_timeout_sec": _env_float("SMTP_TIMEOUT_SEC", 10.0), + "welcome_email_enabled": _env_bool("WELCOME_EMAIL_ENABLED", "true"), + } + + +def _nextcloud_config() -> dict[str, Any]: + return { + "nextcloud_namespace": _env("NEXTCLOUD_NAMESPACE", "nextcloud"), + "nextcloud_pod_label": _env("NEXTCLOUD_POD_LABEL", "app=nextcloud"), + "nextcloud_container": _env("NEXTCLOUD_CONTAINER", "nextcloud"), + "nextcloud_exec_timeout_sec": _env_float("NEXTCLOUD_EXEC_TIMEOUT_SEC", 120.0), + "nextcloud_db_host": _env("NEXTCLOUD_DB_HOST", "postgres-service.postgres.svc.cluster.local"), + "nextcloud_db_port": _env_int("NEXTCLOUD_DB_PORT", 5432), + "nextcloud_db_name": _env("NEXTCLOUD_DB_NAME", "nextcloud"), + "nextcloud_db_user": _env("NEXTCLOUD_DB_USER", "nextcloud"), + "nextcloud_db_password": _env("NEXTCLOUD_DB_PASSWORD", ""), + "nextcloud_url": _env("NEXTCLOUD_URL", "https://cloud.bstein.dev").rstrip("/"), + "nextcloud_admin_user": _env("NEXTCLOUD_ADMIN_USER", ""), + "nextcloud_admin_password": _env("NEXTCLOUD_ADMIN_PASSWORD", ""), + } + + +def _wger_config() -> dict[str, Any]: + return { + "wger_namespace": _env("WGER_NAMESPACE", "health"), + "wger_user_sync_wait_timeout_sec": _env_float("WGER_USER_SYNC_WAIT_TIMEOUT_SEC", 60.0), + "wger_pod_label": _env("WGER_POD_LABEL", "app=wger"), + "wger_container": _env("WGER_CONTAINER", "wger"), + "wger_admin_username": _env("WGER_ADMIN_USERNAME", ""), + "wger_admin_password": _env("WGER_ADMIN_PASSWORD", ""), + "wger_admin_email": _env("WGER_ADMIN_EMAIL", ""), + } + + +def _firefly_config() -> dict[str, Any]: + return { + "firefly_namespace": _env("FIREFLY_NAMESPACE", "finance"), + "firefly_user_sync_wait_timeout_sec": _env_float("FIREFLY_USER_SYNC_WAIT_TIMEOUT_SEC", 90.0), + "firefly_pod_label": _env("FIREFLY_POD_LABEL", "app=firefly"), + "firefly_container": _env("FIREFLY_CONTAINER", "firefly"), + "firefly_cron_base_url": _env( + "FIREFLY_CRON_BASE_URL", + "http://firefly.finance.svc.cluster.local/api/v1/cron", + ), + "firefly_cron_token": _env("FIREFLY_CRON_TOKEN", ""), + "firefly_cron_timeout_sec": _env_float("FIREFLY_CRON_TIMEOUT_SEC", 30.0), + } + + +def _vault_config() -> dict[str, Any]: + return { + "vault_namespace": _env("VAULT_NAMESPACE", "vault"), + "vault_addr": _env("VAULT_ADDR", "http://vault.vault.svc.cluster.local:8200").rstrip("/"), + "vault_token": _env("VAULT_TOKEN", ""), + "vault_k8s_role": _env("VAULT_K8S_ROLE", "vault"), + "vault_k8s_role_ttl": _env("VAULT_K8S_ROLE_TTL", "1h"), + "vault_k8s_token_reviewer_jwt": _env("VAULT_K8S_TOKEN_REVIEWER_JWT", ""), + "vault_k8s_token_reviewer_jwt_file": _env("VAULT_K8S_TOKEN_REVIEWER_JWT_FILE", ""), + "vault_oidc_discovery_url": _env("VAULT_OIDC_DISCOVERY_URL", ""), + "vault_oidc_client_id": _env("VAULT_OIDC_CLIENT_ID", ""), + "vault_oidc_client_secret": _env("VAULT_OIDC_CLIENT_SECRET", ""), + "vault_oidc_default_role": _env("VAULT_OIDC_DEFAULT_ROLE", "admin"), + "vault_oidc_scopes": _env("VAULT_OIDC_SCOPES", "openid profile email groups"), + "vault_oidc_user_claim": _env("VAULT_OIDC_USER_CLAIM", "preferred_username"), + "vault_oidc_groups_claim": _env("VAULT_OIDC_GROUPS_CLAIM", "groups"), + "vault_oidc_token_policies": _env("VAULT_OIDC_TOKEN_POLICIES", ""), + "vault_oidc_admin_group": _env("VAULT_OIDC_ADMIN_GROUP", "admin"), + "vault_oidc_admin_policies": _env("VAULT_OIDC_ADMIN_POLICIES", "default,vault-admin"), + "vault_oidc_dev_group": _env("VAULT_OIDC_DEV_GROUP", "dev"), + "vault_oidc_dev_policies": _env("VAULT_OIDC_DEV_POLICIES", "default,dev-kv"), + "vault_oidc_user_group": _env("VAULT_OIDC_USER_GROUP", ""), + "vault_oidc_user_policies": _env("VAULT_OIDC_USER_POLICIES", ""), + "vault_oidc_redirect_uris": _env( + "VAULT_OIDC_REDIRECT_URIS", + "https://secret.bstein.dev/ui/vault/auth/oidc/oidc/callback", + ), + "vault_oidc_bound_audiences": _env("VAULT_OIDC_BOUND_AUDIENCES", ""), + "vault_oidc_bound_claims_type": _env("VAULT_OIDC_BOUND_CLAIMS_TYPE", "string"), + } + + +def _comms_config() -> dict[str, Any]: + return { + "comms_namespace": _env("COMMS_NAMESPACE", "comms"), + "comms_synapse_base": _env( + "COMMS_SYNAPSE_BASE", + "http://othrys-synapse-matrix-synapse:8008", + ).rstrip("/"), + "comms_auth_base": _env( + "COMMS_AUTH_BASE", + "http://matrix-authentication-service:8080", + ).rstrip("/"), + "comms_mas_admin_api_base": _env( + "COMMS_MAS_ADMIN_API_BASE", + "http://matrix-authentication-service:8081/api/admin/v1", + ).rstrip("/"), + "comms_mas_token_url": _env( + "COMMS_MAS_TOKEN_URL", + "http://matrix-authentication-service:8080/oauth2/token", + ), + "comms_mas_admin_client_id": _env("COMMS_MAS_ADMIN_CLIENT_ID", "01KDXMVQBQ5JNY6SEJPZW6Z8BM"), + "comms_mas_admin_client_secret": _env("COMMS_MAS_ADMIN_CLIENT_SECRET", ""), + "comms_server_name": _env("COMMS_SERVER_NAME", "live.bstein.dev"), + "comms_room_alias": _env("COMMS_ROOM_ALIAS", "#othrys:live.bstein.dev"), + "comms_room_name": _env("COMMS_ROOM_NAME", "Othrys"), + "comms_pin_message": _env( + "COMMS_PIN_MESSAGE", + "Invite guests: share https://live.bstein.dev/#/room/#othrys:live.bstein.dev?action=join and choose 'Continue' -> 'Join as guest'.", + ), + "comms_seeder_user": _env("COMMS_SEEDER_USER", "othrys-seeder"), + "comms_seeder_password": _env("COMMS_SEEDER_PASSWORD", ""), + "comms_bot_user": _env("COMMS_BOT_USER", "atlasbot"), + "comms_bot_password": _env("COMMS_BOT_PASSWORD", ""), + "comms_synapse_db_host": _env( + "COMMS_SYNAPSE_DB_HOST", + "postgres-service.postgres.svc.cluster.local", + ), + "comms_synapse_db_port": _env_int("COMMS_SYNAPSE_DB_PORT", 5432), + "comms_synapse_db_name": _env("COMMS_SYNAPSE_DB_NAME", "synapse"), + "comms_synapse_db_user": _env("COMMS_SYNAPSE_DB_USER", "synapse"), + "comms_synapse_db_password": _env("COMMS_SYNAPSE_DB_PASSWORD", ""), + "comms_synapse_admin_token": _env("COMMS_SYNAPSE_ADMIN_TOKEN", ""), + "comms_timeout_sec": _env_float("COMMS_TIMEOUT_SEC", 30.0), + "comms_guest_stale_days": _env_int("COMMS_GUEST_STALE_DAYS", 14), + } + + +def _image_sweeper_config() -> dict[str, Any]: + return { + "image_sweeper_namespace": _env("IMAGE_SWEEPER_NAMESPACE", "maintenance"), + "image_sweeper_service_account": _env("IMAGE_SWEEPER_SERVICE_ACCOUNT", "node-image-sweeper"), + "image_sweeper_job_ttl_sec": _env_int("IMAGE_SWEEPER_JOB_TTL_SEC", 3600), + "image_sweeper_wait_timeout_sec": _env_float("IMAGE_SWEEPER_WAIT_TIMEOUT_SEC", 1200.0), + } + + +def _platform_quality_probe_config() -> dict[str, Any]: + return { + "platform_quality_probe_namespace": _env("PLATFORM_QUALITY_PROBE_NAMESPACE", "monitoring"), + "platform_quality_probe_script_configmap": _env( + "PLATFORM_QUALITY_PROBE_SCRIPT_CONFIGMAP", + "platform-quality-suite-probe-script", + ), + "platform_quality_probe_image": _env("PLATFORM_QUALITY_PROBE_IMAGE", "curlimages/curl:8.12.1"), + "platform_quality_probe_job_ttl_sec": _env_int("PLATFORM_QUALITY_PROBE_JOB_TTL_SEC", 1800), + "platform_quality_probe_wait_timeout_sec": _env_float("PLATFORM_QUALITY_PROBE_WAIT_TIMEOUT_SEC", 180.0), + "platform_quality_probe_pushgateway_url": _env( + "PLATFORM_QUALITY_PROBE_PUSHGATEWAY_URL", + "http://platform-quality-gateway.monitoring.svc.cluster.local:9091", + ).rstrip("/"), + "platform_quality_probe_http_timeout_sec": _env_int("PLATFORM_QUALITY_PROBE_HTTP_TIMEOUT_SECONDS", 12), + } + + +def _jenkins_build_weather_config() -> dict[str, Any]: + return { + "jenkins_base_url": _env("JENKINS_BASE_URL", "https://ci.bstein.dev").rstrip("/"), + "jenkins_api_user": _env("JENKINS_API_USER", ""), + "jenkins_api_token": _env("JENKINS_API_TOKEN", ""), + "jenkins_api_timeout_sec": _env_float("JENKINS_API_TIMEOUT_SEC", 10.0), + } + + +def _jenkins_workspace_cleanup_config() -> dict[str, Any]: + return { + "jenkins_workspace_namespace": _env("JENKINS_WORKSPACE_NAMESPACE", "jenkins"), + "jenkins_workspace_pvc_prefix": _env("JENKINS_WORKSPACE_PVC_PREFIX", "pvc-workspace-"), + "jenkins_workspace_cleanup_min_age_hours": _env_float("JENKINS_WORKSPACE_CLEANUP_MIN_AGE_HOURS", 12.0), + "jenkins_workspace_cleanup_dry_run": _env_bool("JENKINS_WORKSPACE_CLEANUP_DRY_RUN", "false"), + "jenkins_workspace_cleanup_max_deletions_per_run": _env_int( + "JENKINS_WORKSPACE_CLEANUP_MAX_DELETIONS_PER_RUN", + 20, + ), + } + + +def _vaultwarden_config() -> dict[str, Any]: + return { + "vaultwarden_namespace": _env("VAULTWARDEN_NAMESPACE", "vaultwarden"), + "vaultwarden_pod_label": _env("VAULTWARDEN_POD_LABEL", "app=vaultwarden"), + "vaultwarden_pod_port": _env_int("VAULTWARDEN_POD_PORT", 80), + "vaultwarden_service_host": _env( + "VAULTWARDEN_SERVICE_HOST", + "vaultwarden-service.vaultwarden.svc.cluster.local", + ), + "vaultwarden_admin_secret_name": _env("VAULTWARDEN_ADMIN_SECRET_NAME", "vaultwarden-admin"), + "vaultwarden_admin_secret_key": _env("VAULTWARDEN_ADMIN_SECRET_KEY", "ADMIN_TOKEN"), + "vaultwarden_admin_session_ttl_sec": _env_float("VAULTWARDEN_ADMIN_SESSION_TTL_SEC", 300.0), + "vaultwarden_admin_rate_limit_backoff_sec": _env_float("VAULTWARDEN_ADMIN_RATE_LIMIT_BACKOFF_SEC", 600.0), + "vaultwarden_retry_cooldown_sec": _env_float("VAULTWARDEN_RETRY_COOLDOWN_SEC", 1800.0), + "vaultwarden_failure_bailout": _env_int("VAULTWARDEN_FAILURE_BAILOUT", 2), + "vaultwarden_invite_refresh_sec": _env_float("VAULTWARDEN_INVITE_REFRESH_SEC", 86400.0), + } + + +def _schedule_config() -> dict[str, Any]: + return { + "mailu_sync_cron": _env("ARIADNE_SCHEDULE_MAILU_SYNC", "30 4 * * *"), + "nextcloud_sync_cron": _env("ARIADNE_SCHEDULE_NEXTCLOUD_SYNC", "0 5 * * *"), + "nextcloud_cron": _env("ARIADNE_SCHEDULE_NEXTCLOUD_CRON", "*/5 * * * *"), + "nextcloud_maintenance_cron": _env("ARIADNE_SCHEDULE_NEXTCLOUD_MAINTENANCE", "30 4 * * *"), + "vaultwarden_sync_cron": _env("ARIADNE_SCHEDULE_VAULTWARDEN_SYNC", "0 * * * *"), + "wger_user_sync_cron": _env("ARIADNE_SCHEDULE_WGER_USER_SYNC", "0 5 * * *"), + "wger_admin_cron": _env("ARIADNE_SCHEDULE_WGER_ADMIN", "15 3 * * *"), + "firefly_user_sync_cron": _env("ARIADNE_SCHEDULE_FIREFLY_USER_SYNC", "0 6 * * *"), + "firefly_cron": _env("ARIADNE_SCHEDULE_FIREFLY_CRON", "0 3 * * *"), + "pod_cleaner_cron": _env("ARIADNE_SCHEDULE_POD_CLEANER", "0 * * * *"), + "opensearch_prune_cron": _env("ARIADNE_SCHEDULE_OPENSEARCH_PRUNE", "23 3 * * *"), + "image_sweeper_cron": _env("ARIADNE_SCHEDULE_IMAGE_SWEEPER", "30 4 * * 0"), + "vault_k8s_auth_cron": _env("ARIADNE_SCHEDULE_VAULT_K8S_AUTH", "0 * * * *"), + "vault_oidc_cron": _env("ARIADNE_SCHEDULE_VAULT_OIDC", "0 * * * *"), + "comms_guest_name_cron": _env("ARIADNE_SCHEDULE_COMMS_GUEST_NAME", "*/5 * * * *"), + "comms_pin_invite_cron": _env("ARIADNE_SCHEDULE_COMMS_PIN_INVITE", "*/30 * * * *"), + "comms_reset_room_cron": _env("ARIADNE_SCHEDULE_COMMS_RESET_ROOM", "0 0 1 1 *"), + "comms_seed_room_cron": _env("ARIADNE_SCHEDULE_COMMS_SEED_ROOM", "*/10 * * * *"), + "keycloak_profile_cron": _env("ARIADNE_SCHEDULE_KEYCLOAK_PROFILE", "0 */6 * * *"), + "metis_k3s_token_sync_cron": _env("ARIADNE_SCHEDULE_METIS_K3S_TOKEN_SYNC", "11 */6 * * *"), + "platform_quality_suite_probe_cron": _env( + "ARIADNE_SCHEDULE_PLATFORM_QUALITY_SUITE_PROBE", + "*/15 * * * *", + ), + "jenkins_build_weather_cron": _env( + "ARIADNE_SCHEDULE_JENKINS_BUILD_WEATHER", + "*/10 * * * *", + ), + "jenkins_workspace_cleanup_cron": _env( + "ARIADNE_SCHEDULE_JENKINS_WORKSPACE_CLEANUP", + "45 */6 * * *", + ), + } + + +def _cluster_state_config() -> dict[str, Any]: + return { + "vm_url": _env( + "ARIADNE_VM_URL", + "http://victoria-metrics-single-server.monitoring.svc.cluster.local:8428", + ).rstrip("/"), + "cluster_state_vm_timeout_sec": _env_float("ARIADNE_CLUSTER_STATE_VM_TIMEOUT_SEC", 5.0), + "alertmanager_url": _env("ARIADNE_ALERTMANAGER_URL", "").rstrip("/"), + "cluster_state_cron": _env("ARIADNE_SCHEDULE_CLUSTER_STATE", "*/15 * * * *"), + "cluster_state_keep": _env_int("ARIADNE_CLUSTER_STATE_KEEP", 168), + } + + +def _metis_config() -> dict[str, Any]: + return { + "metis_base_url": _env("METIS_BASE_URL", "http://metis.maintenance.svc.cluster.local").rstrip("/"), + "metis_watch_url": _env("METIS_WATCH_URL", "").rstrip("/"), + "metis_timeout_sec": _env_float("METIS_TIMEOUT_SEC", 10.0), + "metis_sentinel_watch_cron": _env("ARIADNE_SCHEDULE_METIS_SENTINEL_WATCH", "*/15 * * * *"), + "metis_token_sync_namespace": _env("METIS_TOKEN_SYNC_NAMESPACE", "maintenance"), + "metis_token_sync_service_account": _env("METIS_TOKEN_SYNC_SERVICE_ACCOUNT", "metis-token-sync"), + "metis_token_sync_node_name": _env("METIS_TOKEN_SYNC_NODE_NAME", "titan-0a"), + "metis_token_sync_image": _env("METIS_TOKEN_SYNC_IMAGE", "hashicorp/vault:1.17.6"), + "metis_token_sync_job_ttl_sec": _env_int("METIS_TOKEN_SYNC_JOB_TTL_SEC", 1800), + "metis_token_sync_wait_timeout_sec": _env_float("METIS_TOKEN_SYNC_WAIT_TIMEOUT_SEC", 180.0), + "metis_token_sync_vault_addr": _env( + "METIS_TOKEN_SYNC_VAULT_ADDR", + "http://vault.vault.svc.cluster.local:8200", + ).rstrip("/"), + "metis_token_sync_vault_k8s_role": _env("METIS_TOKEN_SYNC_VAULT_K8S_ROLE", "maintenance-metis-token-sync"), + } + + +def _opensearch_config() -> dict[str, Any]: + return { + "opensearch_url": _env( + "OPENSEARCH_URL", + "http://opensearch-master.logging.svc.cluster.local:9200", + ).rstrip("/"), + "opensearch_limit_bytes": _env_int("OPENSEARCH_LIMIT_BYTES", 1024**4), + "opensearch_index_patterns": _env("OPENSEARCH_INDEX_PATTERNS", "kube-*,journald-*"), + "opensearch_timeout_sec": _env_float("OPENSEARCH_TIMEOUT_SEC", 30.0), + } diff --git a/ci/loc_hygiene_waivers.tsv b/ci/loc_hygiene_waivers.tsv index 7f0e3f4..1ed9857 100644 --- a/ci/loc_hygiene_waivers.tsv +++ b/ci/loc_hygiene_waivers.tsv @@ -3,7 +3,6 @@ ariadne/services/cluster_state.py split planned; service orchestration decomposi ariadne/app.py split planned; Flask app bootstrap/routes currently co-located ariadne/services/comms.py split planned; comms adapters still consolidated ariadne/manager/provisioning.py split planned; provisioning flow modules pending extraction -ariadne/settings.py split planned; settings schema + helpers pending split ariadne/services/jenkins_workspace_cleanup.py split planned; job orchestration pending extraction tests/test_provisioning.py test module split planned; broad provisioning coverage retained meanwhile tests/test_services.py test module split planned; broad service contract coverage retained meanwhile