"""Application configuration.""" import base64 import json import logging import os from os.path import abspath from os.path import dirname from os.path import join from os.path import pardir from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import serialization from dotenv import load_dotenv from secrets_manager.flask_ext import FlaskSecretsManager from sqlalchemy.pool import QueuePool from sqlalchemy.pool import StaticPool # Load environment variables from a .env file dotenv_path = abspath(join(dirname(__file__), pardir, '.env')) load_dotenv(dotenv_path) # Service information SERVICE_NAME = 'ows-product-physical' SERVICE_VERSION = os.environ.get('SERVICE_VERSION', '0.0.1') # Production environment PROD_ENVIRONMENT = 'prod' DEV_ENVIRONMENT = 'dev' QA_ENVIRONMENT = 'qa' TEST_ENVIRONMENT = 'test' ENVIRONMENT = os.environ.get('Environment', DEV_ENVIRONMENT) # Errors and loggers secrets_manager_client = FlaskSecretsManager( application_context=False, environment=ENVIRONMENT, service_name=SERVICE_NAME) # Errors and loggers try: SENTRY = secrets_manager_client.get_cred('SENTRY_DSN') except: # noqa SENTRY = None LOGGER_LEVEL = os.environ.get('LOGGER_LEVEL', logging.INFO) LOGGER_NAME = 'ows1' if ENVIRONMENT == TEST_ENVIRONMENT: DB_URL = 'sqlite://' DELIVERY_DB_URL = 'sqlite://' POOL_CLASS = StaticPool else: # Database config DB_URL = ( 'mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}' '@{MYSQL_HOST}/{MYSQL_DATABASE}?charset=utf8mb4').format( MYSQL_USER=os.environ.get('MYSQL_USER'), MYSQL_PASSWORD=os.environ.get('MYSQL_PASSWORD'), MYSQL_HOST=os.environ.get('MYSQL_HOST'), MYSQL_DATABASE=os.environ.get('MYSQL_DATABASE')) MYSQL_DELIVERY_USER = os.environ.get('MYSQL_DELIVERY_USER') MYSQL_DELIVERY_PASSWORD = os.environ.get('MYSQL_DELIVERY_PASSWORD') MYSQL_DELIVERY_HOST = os.environ.get('MYSQL_DELIVERY_HOST') MYSQL_DELIVERY_DATABASE = os.environ.get('MYSQL_DELIVERY_DATABASE') DELIVERY_DB_URL = ( f'mysql+pymysql://{MYSQL_DELIVERY_USER}:{MYSQL_DELIVERY_PASSWORD}' f'@{MYSQL_DELIVERY_HOST}/{MYSQL_DELIVERY_DATABASE}?charset=utf8' ) POOL_CLASS = QueuePool POOL_SIZE = 5 POOL_RECYCLE_MS = 3600 # Avoids connections going stale POOL_MAX_OVERFLOW = -1 POOL_PRE_PING = True path = os.path.dirname(os.path.dirname(__file__)) # API definition API_DEFINITION_PATH = os.path.join( path, 'spec', '{service_name}-{version}.raml'.format( version=SERVICE_VERSION, service_name=SERVICE_NAME)) def _load_schema(schema_name): file_name = 'product-{name}.schema.json'.format(name=schema_name) with open(os.path.join(path, 'spec', file_name)) as f: return json.load(f) DELETE_TRACK_SCHEMA = _load_schema('track-delete') POST_TRACK_SCHEMA = _load_schema('track-post') PUT_TRACK_SCHEMA = _load_schema('track-put') POST_PRODUCT_CHANGE_HISTORY_SCHEMA = _load_schema('post-change-history') GET_RESPONSE_SCHEMA = _load_schema('get-response') # Generic handlers HEALTH_CHECK = '/hello' SQS_QUEUE_NAME = '{env}-upc_repository-queue' secrets_manager_client = FlaskSecretsManager( application_context=False, environment=ENVIRONMENT, service_name=SERVICE_NAME) # Snowflake SNOWFLAKE_ACCOUNT = os.environ.get('SNOWFLAKE_ACCOUNT', 'orchard') SNOWFLAKE_USER = os.environ.get('SNOWFLAKE_USER') SNOWFLAKE_ROLE = os.environ.get('SNOWFLAKE_ROLE') SNOWFLAKE_WAREHOUSE = os.environ.get( 'SNOWFLAKE_WAREHOUSE', 'DEV_OWS_WAREHOUSE' ) # for DEV by default it takes SNOWFLAKE_PASSWORD from local environment SNOWFLAKE_PASSWORD = 'wrong_pass' 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 SNOWFLAKE_POOL_COMMIT_BEFORE_CLOSE = False SNOWFLAKE_SESSION_KEEP_ALIVE = True # Default for local dev if ENVIRONMENT == DEV_ENVIRONMENT: SNOWFLAKE_PRIVATE_KEY_PATH = \ os.environ['HOME'] + '/.ssh/snowflake/rsa_key.p8' SNOWFLAKE_PRIVATE_KEY_PATH = os.environ.get( 'SNOWFLAKE_PRIVATE_KEY_PATH', SNOWFLAKE_PRIVATE_KEY_PATH) SNOWFLAKE_KEY_PASSPHRASE = os.environ.get( '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 = {} SNOWFLAKE_PASSWORD = os.environ.get('SNOWFLAKE_PASSWORD') else: # For QA and PROD environments we use Secrets Manager SNOWFLAKE_PRIVATE_KEY = \ secrets_manager_client.get_cred('SNOWFLAKE_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'))}