"""Application configuration.""" import base64 import logging import os from os.path import abspath, dirname, join, pardir from dotenv import load_dotenv from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from secrets_manager.flask_ext import FlaskSecretsManager # Load environment variables from a .env file if present dotenv_path = abspath(join(dirname(__file__), pardir, '.env')) load_dotenv(dotenv_path) # Service information SERVICE_NAME = 'ows-socials' SERVICE_VERSION = '1.0.0' # Production environment PROD_ENVIRONMENT = 'prod' DEV_ENVIRONMENT = 'dev' QA_ENVIRONMENT = 'qa' TEST_ENVIRONMENT = 'test' ENVIRONMENT = os.environ.get('Environment') or DEV_ENVIRONMENT secrets_manager_client = FlaskSecretsManager( application_context=False, environment=ENVIRONMENT, service_name=SERVICE_NAME) # Snowflake SNOWFLAKE_ACCOUNT = os.environ.get('SNOWFLAKE_ACCOUNT') SNOWFLAKE_USER = os.environ.get('SNOWFLAKE_USER') SNOWFLAKE_ROLE = os.environ.get('SNOWFLAKE_ROLE') SNOWFLAKE_WAREHOUSE = os.environ.get('SNOWFLAKE_WAREHOUSE') SNOWFLAKE_SCHEMA = os.environ.get('SNOWFLAKE_SCHEMA', 'DEV') SNOWFLAKE_DATABASE = os.environ.get('SNOWFLAKE_DATABASE') SNOWFLAKE_POOL_SIZE = 15 # UWSGI number of threads SNOWFLAKE_POOL_RECYCLE = 4 * 55 * 60 # Snowflake timeout: ~4 hours SNOWFLAKE_POOL_MAX_OVERFLOW = 5 SNOWFLAKE_POOL_PRE_PING = False SNOWFLAKE_POOL_RESET_ON_RETURN = None if ENVIRONMENT == DEV_ENVIRONMENT: SNOWFLAKE_PRIVATE_KEY_PATH = os.environ['HOME'] + '/.ssh/snowflake/rsa_key.p8' try: SNOWFLAKE_PRIVATE_KEY_PATH = secrets_manager_client.get_cred( 'SNOWFLAKE_PRIVATE_KEY_PATH') or SNOWFLAKE_PRIVATE_KEY_PATH SNOWFLAKE_KEY_PASSPHRASE = secrets_manager_client.get_cred( 'SNOWFLAKE_KEY_PASSPHRASE') or None except Exception: SNOWFLAKE_KEY_PASSPHRASE = None if SNOWFLAKE_KEY_PASSPHRASE: with open(SNOWFLAKE_PRIVATE_KEY_PATH, 'rb') as key: p_key = serialization.load_pem_private_key( key.read(), password=SNOWFLAKE_KEY_PASSPHRASE.encode(), backend=default_backend()) pkb = p_key.private_bytes( encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()) SNOWFLAKE_CONNECT_ARGS = {'private_key': pkb} else: SNOWFLAKE_CONNECT_ARGS = {} else: # For QA and PROD environments we use Secrets Manager SNOWFLAKE_PRIVATE_KEY = secrets_manager_client.get_cred('SNOWFLAKE_PRIVATE_KEY') or None if not SNOWFLAKE_PRIVATE_KEY: SNOWFLAKE_CONNECT_ARGS = {} else: SNOWFLAKE_CONNECT_ARGS = {'private_key': base64.b64decode(bytes(SNOWFLAKE_PRIVATE_KEY, encoding='utf-8'))} logging.info('Snowflake private key is set from Secrets Manager.') # Database config if ENVIRONMENT == TEST_ENVIRONMENT: DB_URL = 'sqlite://' SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ENGINE_OPTIONS = {} else: POOL_SIZE = 15 POOL_RECYCLE = 3600 # Avoids connections going stale POOL_MAX_OVERFLOW = 0 DB_URL = os.environ.get('DB_URL') SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ENGINE_OPTIONS = { 'pool_size': POOL_SIZE, 'pool_recycle': POOL_RECYCLE, 'max_overflow': POOL_MAX_OVERFLOW } # Errors and loggers SENTRY = secrets_manager_client.get_cred('SENTRY_DSN') if not SENTRY and ENVIRONMENT in [PROD_ENVIRONMENT, QA_ENVIRONMENT]: raise Exception(f'Sentry is not configured in {ENVIRONMENT}') LOGGER_DSN = os.environ.get('LOGGER_DSN') or None LOGGER_LEVEL = logging.INFO LOGGER_NAME = 'ows1' # Base URL (qa is for the integration tests) if os.environ.get('TestsIntegration') == 'true': BASE_URL = 'https://qa-ows-socials.theorchard.io' else: BASE_URL = 'http://localhost:5000' # Endpoint URLs HEALTH_CHECK = '/hello/' HEALTH_CHECK_URL = BASE_URL + HEALTH_CHECK # Swagger documentation path SWAGGER_FILE_PATH = 'spec/ows_socials-1.0.0.yaml' NEO4J_URL = secrets_manager_client.get_cred('NEO4J_URL') NEO4J_USERNAME = secrets_manager_client.get_cred('NEO4J_USERNAME') NEO4J_PASSWORD = secrets_manager_client.get_cred('NEO4J_PASSWORD') NEO4J_DATABASE_NAME = os.environ.get('NEO4J_DATABASE_NAME', 'graph.db') # Neo4j Aura NEO4J_AURA_URL = secrets_manager_client.get_cred('NEO4J_AURA_URL') NEO4J_AURA_USERNAME = secrets_manager_client.get_cred('NEO4J_AURA_USERNAME') NEO4J_AURA_PASSWORD = secrets_manager_client.get_cred('NEO4J_AURA_PASSWORD') REDIS_HOST = os.environ.get("REDIS_HOST") REDIS_PORT = int(os.environ.get("REDIS_PORT", 6379)) REDIS_CACHE_TTL = int(os.environ.get("REDIS_CACHE_TTL", 60 * 60 * 8)) # 8 hour by default