Update config

Source the configuration from an environment file, this way it is similar to how the aws environment works
This commit is contained in:
Rebecca Law
2016-02-16 15:25:46 +00:00
parent 7ff5f6c45a
commit 08ba5de61b
13 changed files with 69 additions and 132 deletions

3
.gitignore vendored
View File

@@ -60,4 +60,5 @@ target/
.idea/ .idea/
# Mac # Mac
*.DS_Store *.DS_Store
environment.sh

View File

@@ -9,3 +9,19 @@ Read and write notifications/status queue.
Get and update notification status. Get and update notification status.
mkvirtualenv -p /usr/local/bin/python3 notifications-api mkvirtualenv -p /usr/local/bin/python3 notifications-api
```
export ADMIN_CLIENT_USER_NAME = 'dev-notify-admin'
export ADMIN_CLIENT_SECRET = 'dev-notify-secret-key'
export AWS_REGION='eu-west-1'
export DANGEROUS_SALT = 'dangerous-salt'
export DELIVERY_CLIENT_USER_NAME='dev-notify-delivery'
export DELIVERY_CLIENT_SECRET='dev-notify-secret-key'
export NOTIFY_JOB_QUEUE='notify-jobs-queue-[-unique-to-environment]'
export NOTIFICATION_QUEUE_PREFIX='notification_development[-unique-to-environment]'
export SECRET_KEY = 'secret-key'
export SQLALCHEMY_DATABASE_URI = 'postgresql://localhost/notification_api'
```

View File

@@ -8,7 +8,6 @@ from flask import Flask, _request_ctx_stack
from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow from flask_marshmallow import Marshmallow
from werkzeug.local import LocalProxy from werkzeug.local import LocalProxy
from config import configs
from utils import logging from utils import logging
@@ -18,15 +17,14 @@ ma = Marshmallow()
api_user = LocalProxy(lambda: _request_ctx_stack.top.api_user) api_user = LocalProxy(lambda: _request_ctx_stack.top.api_user)
def create_app(config_name, config_overrides=None): def create_app():
application = Flask(__name__) application = Flask(__name__)
application.config['NOTIFY_API_ENVIRONMENT'] = config_name application.config.from_object(os.environ['NOTIFY_API_ENVIRONMENT'])
application.config.from_object(configs[config_name])
db.init_app(application) db.init_app(application)
ma.init_app(application) ma.init_app(application)
init_app(application, config_overrides) init_app(application)
logging.init_app(application) logging.init_app(application)
from app.service.rest import service as service_blueprint from app.service.rest import service as service_blueprint
@@ -46,16 +44,7 @@ def create_app(config_name, config_overrides=None):
return application return application
def init_app(app, config_overrides): def init_app(app):
for key, value in app.config.items():
if key in os.environ:
app.config[key] = convert_to_boolean(os.environ[key])
if config_overrides:
for key in app.config.keys():
if key in config_overrides:
app.config[key] = config_overrides[key]
@app.before_request @app.before_request
def required_authentication(): def required_authentication():
if request.path != url_for('status.show_status'): if request.path != url_for('status.show_status'):
@@ -72,51 +61,6 @@ def init_app(app, config_overrides):
return response return response
def convert_to_boolean(value):
"""Turn strings to bools if they look like them
Truthy things should be True
>>> for truthy in ['true', 'on', 'yes', '1']:
... assert convert_to_boolean(truthy) == True
Falsey things should be False
>>> for falsey in ['false', 'off', 'no', '0']:
... assert convert_to_boolean(falsey) == False
Other things should be unchanged
>>> for value in ['falsey', 'other', True, 0]:
... assert convert_to_boolean(value) == value
"""
if isinstance(value, string_types):
if value.lower() in ['t', 'true', 'on', 'yes', '1']:
return True
elif value.lower() in ['f', 'false', 'off', 'no', '0']:
return False
return value
def convert_to_number(value):
"""Turns numeric looking things into floats or ints
Integery things should be integers
>>> for inty in ['0', '1', '2', '99999']:
... assert isinstance(convert_to_number(inty), int)
Floaty things should be floats
>>> for floaty in ['0.99', '1.1', '1000.0000001']:
... assert isinstance(convert_to_number(floaty), float)
Other things should be unchanged
>>> for value in [0, 'other', True, 123]:
... assert convert_to_number(value) == value
"""
try:
return float(value) if "." in value else int(value)
except (TypeError, ValueError):
return value
def get_api_version(): def get_api_version():
build = 'n/a' build = 'n/a'
build_time = "n/a" build_time = "n/a"

View File

@@ -6,7 +6,7 @@ from flask.ext.script import Manager, Server
from flask.ext.migrate import Migrate, MigrateCommand from flask.ext.migrate import Migrate, MigrateCommand
from app import (create_app, db, get_api_version, get_db_version) from app import (create_app, db, get_api_version, get_db_version)
application = create_app(os.getenv('NOTIFY_API_ENVIRONMENT') or 'development') application = create_app()
manager = Manager(application) manager = Manager(application)
port = int(os.environ.get('PORT', 6011)) port = int(os.environ.get('PORT', 6011))
manager.add_command("runserver", Server(host='0.0.0.0', port=port)) manager.add_command("runserver", Server(host='0.0.0.0', port=port))

View File

@@ -3,60 +3,27 @@ import os
class Config(object): class Config(object):
DEBUG = False DEBUG = False
NOTIFY_LOG_LEVEL = 'DEBUG' ADMIN_CLIENT_USER_NAME = os.environ['ADMIN_CLIENT_USER_NAME']
ADMIN_CLIENT_SECRET = os.environ['ADMIN_CLIENT_SECRET']
AWS_REGION = os.environ['AWS_REGION']
DANGEROUS_SALT = os.environ['DANGEROUS_SALT']
DELIVERY_CLIENT_USER_NAME = os.environ['DELIVERY_CLIENT_USER_NAME']
DELIVERY_CLIENT_SECRET = os.environ['DELIVERY_CLIENT_SECRET']
NOTIFY_APP_NAME = 'api' NOTIFY_APP_NAME = 'api'
NOTIFY_LOG_PATH = '/var/log/notify/application.log' NOTIFY_LOG_PATH = '/var/log/notify/application.log'
SQLALCHEMY_COMMIT_ON_TEARDOWN = False NOTIFY_JOB_QUEUE = os.environ['NOTIFY_JOB_QUEUE']
SQLALCHEMY_RECORD_QUERIES = True
SQLALCHEMY_DATABASE_URI = 'postgresql://localhost/notification_api'
NOTIFY_DATA_API_URL = os.getenv('NOTIFY_API_URL', "http://localhost:6001")
NOTIFY_DATA_API_AUTH_TOKEN = os.getenv('NOTIFY_API_TOKEN', "dev-token")
ADMIN_CLIENT_USER_NAME = None
ADMIN_CLIENT_SECRET = None
DELIVERY_CLIENT_USER_NAME = None
DELIVERY_CLIENT_SECRET = None
AWS_REGION = 'eu-west-1'
NOTIFY_JOB_QUEUE = os.getenv('NOTIFY_JOB_QUEUE', 'notify-jobs-queue')
# Notification Queue names are a combination of a prefx plus a name # Notification Queue names are a combination of a prefx plus a name
NOTIFICATION_QUEUE_PREFIX = 'notification' NOTIFICATION_QUEUE_PREFIX = os.environ['NOTIFICATION_QUEUE_PREFIX']
VERIFY_CODE_FROM_EMAIL_ADDRESS = 'notify@digital.cabinet-office.gov.uk' SECRET_KEY = os.environ['SECRET_KEY']
SQLALCHEMY_COMMIT_ON_TEARDOWN = False
SQLALCHEMY_DATABASE_URI = os.environ['SQLALCHEMY_DATABASE_URI']
SQLALCHEMY_RECORD_QUERIES = True
VERIFY_CODE_FROM_EMAIL_ADDRESS=os.environ['VERIFY_CODE_FROM_EMAIL_ADDRESS']
class Development(Config): class Development(Config):
DEBUG = True DEBUG = True
SECRET_KEY = 'secret-key'
DANGEROUS_SALT = 'dangerous-salt'
ADMIN_CLIENT_USER_NAME = 'dev-notify-admin'
ADMIN_CLIENT_SECRET = 'dev-notify-secret-key'
DELIVERY_CLIENT_USER_NAME = 'dev-notify-delivery'
DELIVERY_CLIENT_SECRET = 'dev-notify-secret-key'
NOTIFICATION_QUEUE_PREFIX = 'notification_development'
VERIFY_CODE_FROM_EMAIL_ADDRESS = 'notify-tests-preview@digital.cabinet-office.gov.uk'
class Test(Development): class Test(Development):
SQLALCHEMY_DATABASE_URI = 'postgresql://localhost/test_notification_api' pass
NOTIFICATION_QUEUE_PREFIX = 'notification_test'
class Preview(Config):
NOTIFICATION_QUEUE_PREFIX = 'notification_preview'
VERIFY_CODE_FROM_EMAIL_ADDRESS = 'notify-tests-preview@digital.cabinet-office.gov.uk'
class Staging(Config):
NOTIFICATION_QUEUE_PREFIX = 'notification_staging'
class Live(Config):
NOTIFICATION_QUEUE_PREFIX = 'notification_live'
configs = {
'development': Development,
'preview': Preview,
'staging': Staging,
'test': Test,
'live': Live,
}

2
db.py
View File

@@ -5,7 +5,7 @@ from credstash import getAllSecrets
secrets = getAllSecrets(region="eu-west-1") secrets = getAllSecrets(region="eu-west-1")
application = create_app('live', secrets) application = create_app()
manager = Manager(application) manager = Manager(application)
migrate = Migrate(application, db) migrate = Migrate(application, db)

12
environment_test.sh Normal file
View File

@@ -0,0 +1,12 @@
export NOTIFY_API_ENVIRONMENT='config.Test'
export ADMIN_CLIENT_USER_NAME='dev-notify-admin'
export ADMIN_CLIENT_SECRET='dev-notify-secret-key'
export AWS_REGION='eu-west-1'
export DANGEROUS_SALT='dangerous-salt'
export DELIVERY_CLIENT_USER_NAME='dev-notify-delivery'
export DELIVERY_CLIENT_SECRET='dev-notify-secret-key'
export NOTIFY_JOB_QUEUE='notify-jobs-queue-test'
export NOTIFICATION_QUEUE_PREFIX='notification_development-test'
export SECRET_KEY='secret-key'
export SQLALCHEMY_DATABASE_URI='postgresql://localhost/test_notification_api'

View File

@@ -34,4 +34,5 @@ createdb notification_api
createdb test_notification_api createdb test_notification_api
# Upgrade databases # Upgrade databases
source environment.sh
python application.py db upgrade python application.py db upgrade

View File

@@ -1,3 +1,6 @@
#!/bin/bash #!/bin/bash
python application.py runserver set -e
source environment.sh
python3 application.py runserver

View File

@@ -9,6 +9,8 @@
set -o pipefail set -o pipefail
source environment_test.sh
function display_result { function display_result {
RESULT=$1 RESULT=$1
EXIT_STATUS=$2 EXIT_STATUS=$2

View File

@@ -114,7 +114,7 @@ def test_create_job(notify_api, notify_db, notify_db_session, sample_template):
assert resp_json['data']['original_file_name'] == original_file_name assert resp_json['data']['original_file_name'] == original_file_name
boto3.setup_default_session(region_name='eu-west-1') boto3.setup_default_session(region_name='eu-west-1')
q = boto3.resource('sqs').get_queue_by_name(QueueName='notify-jobs-queue') q = boto3.resource('sqs').get_queue_by_name(QueueName=notify_api.config['NOTIFY_JOB_QUEUE'])
messages = q.receive_messages() messages = q.receive_messages()
assert len(messages) == 1 assert len(messages) == 1

View File

@@ -1,20 +1,20 @@
import pytest
import mock
import os import os
import boto3 import boto3
from config import configs import mock
import pytest
from alembic.command import upgrade from alembic.command import upgrade
from alembic.config import Config from alembic.config import Config
from flask.ext.migrate import Migrate, MigrateCommand from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.script import Manager from flask.ext.script import Manager
from sqlalchemy.schema import MetaData from sqlalchemy.schema import MetaData
from app import create_app, db from app import create_app, db
from app import models
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def notify_api(request): def notify_api(request):
app = create_app('test') app = create_app()
ctx = app.app_context() ctx = app.app_context()
ctx.push() ctx.push()
@@ -59,12 +59,6 @@ def notify_db_session(request):
request.addfinalizer(teardown) request.addfinalizer(teardown)
@pytest.fixture(scope='function')
def notify_config(notify_api):
notify_api.config['NOTIFY_API_ENVIRONMENT'] = 'test'
notify_api.config.from_object(configs['test'])
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def os_environ(request): def os_environ(request):
env_patch = mock.patch('os.environ', {}) env_patch = mock.patch('os.environ', {})

15
wsgi.py
View File

@@ -1,17 +1,14 @@
from app import create_app
from credstash import getAllSecrets
import os import os
config = 'live' from app import create_app
default_env_file = '/home/ubuntu/environment' from credstash import getAllSecrets
if os.path.isfile(default_env_file):
environment = open(default_env_file, 'r')
config = environment.readline().strip()
# on aws get secrets and export to env
secrets = getAllSecrets(region="eu-west-1") secrets = getAllSecrets(region="eu-west-1")
for key, val in secrets.items():
os.environ[key] = val
application = create_app(config, secrets) application = create_app()
if __name__ == "__main__": if __name__ == "__main__":
application.run() application.run()