# pylint: disable=too-many-instance-attributes import json import os import sys from dataclasses import asdict, dataclass from typing import Dict, Optional import boto3 from boto3_type_annotations.secretsmanager import Client as SecretsManagerClient from db_schema import generate_uri from dotenv import load_dotenv @dataclass class ReprocessingConfig: slz_bucket_archive: str slz_bucket_decompressed: str sqs_exp_split_notification_queue: str @dataclass class Config: auth0_client_id: Optional[str] auth0_client_secret: Optional[str] auth0_base_url: Optional[str] app_base_url: Optional[str] db_url: Optional[str] reprocessing: ReprocessingConfig fake_login_enabled: bool = False env: str = 'prod' is_local: bool = False sentry_secret_key: str = '' def __repr__(self) -> str: return str(asdict(self)) class ConfigService: local_env = os.path.join(os.pardir, os.pardir, 'env', 'local.env') def __init__(self) -> None: self._env = os.getenv('ENVIRONMENT', 'PROD').lower() def _load_auth0_params(self) -> Dict[str, Optional[str]]: if { 'AUTH0__CLIENT_ID', 'AUTH0__CLIENT_SECRET', 'AUTH0__BASE_URL', }.issubset(os.environ.keys()): return { 'auth0_client_id': os.getenv('AUTH0__CLIENT_ID'), 'auth0_client_secret': os.getenv('AUTH0__CLIENT_SECRET'), 'auth0_base_url': os.getenv('AUTH0__BASE_URL'), } secrets_key = f'delphi/{self._env}/slz/admin/auth0' secrets_value = self._secretsmanager.get_secret_value(SecretId=secrets_key) loaded_secrets = json.loads(secrets_value['SecretString']) return { 'auth0_client_id': os.getenv('AUTH0__CLIENT_ID', loaded_secrets.get('client_id')), 'auth0_client_secret': os.getenv('AUTH0__CLIENT_SECRET', loaded_secrets.get('client_secret')), 'auth0_base_url': os.getenv('AUTH0__BASE_URL', loaded_secrets.get('base_url')), } def _load_pg_params(self) -> Dict[str, Optional[str]]: if 'DB_URL' in os.environ: return { 'db_url': os.getenv('DB_URL'), } secrets_key = f'delphi/{self._env}/slz/storage/pg_proxy/user' secrets_value = self._secretsmanager.get_secret_value(SecretId=secrets_key) loaded_secrets = json.loads(secrets_value['SecretString']) db_url = generate_uri( host=loaded_secrets['active_endpoint'], port=loaded_secrets['port'], db=loaded_secrets['database'], user=loaded_secrets['username'], password=loaded_secrets['password'], ) return {'db_url': db_url} def _load_general_config(self) -> Dict[str, str]: if { 'SLZ_BUCKET_ARCHIVE', 'SLZ_BUCKET_DECOMPRESSED', 'SQS_EXP_SPLIT_NOTIFICATION_QUEUE', }.issubset(os.environ.keys()): return { 'slz_bucket_archive': os.environ['SLZ_BUCKET_ARCHIVE'], 'slz_bucket_decompressed': os.environ['SLZ_BUCKET_DECOMPRESSED'], 'sqs_exp_split_notification_queue': os.environ['SQS_EXP_SPLIT_NOTIFICATION_QUEUE'], } secrets_key = f'delphi/{self._env}/slz/admin/general' secrets_value = self._secretsmanager.get_secret_value(SecretId=secrets_key) loaded_secrets = json.loads(secrets_value['SecretString']) return { 'slz_bucket_archive': os.getenv('SLZ_BUCKET_ARCHIVE', loaded_secrets.get('slz_bucket_archive')), 'slz_bucket_decompressed': os.getenv('SLZ_BUCKET_DECOMPRESSED', loaded_secrets.get('slz_bucket_decompressed')), 'sqs_exp_split_notification_queue': os.getenv( 'SQS_EXP_SPLIT_NOTIFICATION_QUEUE', loaded_secrets.get('sqs_exp_split_notification_queue') ), } def load_config(self) -> Config: if 'pytest' in sys.modules or os.getenv('IS_TESTING'): return Config( app_base_url='http://foo.test', auth0_base_url='http://bar.test', auth0_client_id='bar', auth0_client_secret='baz', db_url=os.environ['DB_URL'], fake_login_enabled=bool(os.getenv('FAKE_LOGIN_ENABLED')), env='test', reprocessing=ReprocessingConfig( slz_bucket_archive='bucket_archive', slz_bucket_decompressed='bucket_decompressed', sqs_exp_split_notification_queue='arn-1' ) ) # pylint: disable=attribute-defined-outside-init self._secretsmanager: SecretsManagerClient = boto3.client('secretsmanager') try: load_dotenv(self.local_env) except IOError: pass auth0_params = self._load_auth0_params() pg_params = self._load_pg_params() general = self._load_general_config() return Config( app_base_url=os.getenv('BASE_URL'), auth0_base_url=auth0_params['auth0_base_url'], auth0_client_id=auth0_params['auth0_client_id'], auth0_client_secret=auth0_params['auth0_client_secret'], db_url=pg_params['db_url'], fake_login_enabled=bool(os.getenv('FAKE_LOGIN_ENABLED')), env=os.getenv('ENVIRONMENT', self._env), reprocessing=ReprocessingConfig( slz_bucket_archive=general['slz_bucket_archive'], slz_bucket_decompressed=general['slz_bucket_decompressed'], sqs_exp_split_notification_queue=general['sqs_exp_split_notification_queue'] ), is_local=bool(os.getenv('IS_LOCAL')), sentry_secret_key=os.getenv('SENTRY_SECRET_KEY', ''), )