From 655b4caf7586b7ae58230a5f66ab0ed8699c249b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Dietm=C3=BCller?= Date: Sat, 17 Mar 2018 15:59:23 +0100 Subject: [PATCH] Backend: Improve configuration for backend container --- .gitlab-ci.yml | 2 +- Backend/Dockerfile | 2 +- Backend/backend/app.py | 38 +++++++++++++++++++++++++++++-------- Backend/backend/settings.py | 7 ++++--- Backend/create_demo_data.py | 4 ++-- Backend/requirements.txt | 10 ++++++++-- Backend/tests/conftest.py | 2 +- 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b939f85..b0e2d49 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -80,7 +80,7 @@ backend_deploy: SSH_DEPLOY_KEY: $DEPLOY_PRIVATE_KEY script: - - ssh $DEPLOY_HOST "docker pull $CI_REGISTRY_IMAGE_BACKEND; docker service update --force $DEPLOY_SERVICE_BACKEND;" + - ssh -4 $DEPLOY_HOST "docker pull $CI_REGISTRY_IMAGE_BACKEND; docker service update --force $DEPLOY_SERVICE_BACKEND;" only: - master diff --git a/Backend/Dockerfile b/Backend/Dockerfile index 314ee8a..6f3b97f 100644 --- a/Backend/Dockerfile +++ b/Backend/Dockerfile @@ -6,7 +6,7 @@ WORKDIR /pvk # API will run on port 80 EXPOSE 8080 # Environment variable for config, use path for docker secrets as default -ENV pvk_CONFIG=/run/secrets/pvk_config +ENV PVK_CONFIG=/run/secrets/pvk_config # Install bjoern and dependencies for install (we need to keep libev) RUN apk add --no-cache --virtual .deps \ diff --git a/Backend/backend/app.py b/Backend/backend/app.py index a23b21d..b3a5b7e 100644 --- a/Backend/backend/app.py +++ b/Backend/backend/app.py @@ -17,7 +17,8 @@ Next, you should check out the following files: """ -from os import getcwd +from os import getcwd, getenv +from os.path import abspath from eve import Eve from flask import Config @@ -33,19 +34,40 @@ from backend.signups import ( ) -def create_app(settings=None): - """Super simply bootstrapping for easier testing. +def create_app(config_file=None, **kwargs): + """Create a new eve app object and initialize everything. - Initial settings are loaded from settings.py (the Flask `Config` object - makes this easy) and updated settings from the function call, if provided. + User configuration can be loaded in the following order: + + 1. Use the `config_file` arg to specify a file + 2. If `config_file` is `None`, you set the environment variable + `PVK_CONFIG` to the path of your config file + 3. If no environment variable is set either, `config.py` in the current + working directory is used + + Args: + config (path): Specify config file to use. + kwargs: All other key-value arguments will be used to update the config + Returns: + (Eve): The Eve application """ + # Load config config = Config(getcwd()) - config.from_object('backend.settings') - if settings is not None: - config.update(settings) + config.from_object("backend.settings") + + # Specified path > environment var > default path; abspath for better log + user_config = abspath(config_file or getenv('PVK_CONFIG', 'config.py')) + try: + config.from_pyfile(user_config) + config_status = "Config loaded: %s" % user_config + except IOError: + config_status = "No config found." + + config.update(kwargs) # Create the app object application = Eve(auth=APIAuth, validator=APIValidator, settings=config) + application.logger.info(config_status) # Eve provides hooks at several points of the request, # we use this do add dynamic filtering diff --git a/Backend/backend/settings.py b/Backend/backend/settings.py index a3d0d5b..ccc4d1a 100644 --- a/Backend/backend/settings.py +++ b/Backend/backend/settings.py @@ -16,16 +16,17 @@ X_DOMAINS = '*' X_HEADERS = ['Authorization', 'If-Match', 'If-Modified-Since', 'Content-Type'] # AMIVAPI URL and Admin Group -AMIVAPI_URL = environ.get('AMIVAPI_URL', 'https://amiv-api.ethz.ch') -ADMIN_GROUP_NAME = environ.get('AMIVAPI_GROUP', 'PVK Admins') +AMIVAPI_URL = 'https://amiv-api.ethz.ch' +ADMIN_GROUP_NAME = 'PVK Admins' -# DB +# DB (can be set by env for easier CI tests) MONGO_HOST = environ.get('MONGO_HOST', 'localhost') MONGO_PORT = environ.get('MONGO_PORT', 27017) MONGO_DBNAME = environ.get('MONGO_DBNAME', 'pvk') MONGO_USERNAME = environ.get('MONGO_USERNAME', 'pvkuser') MONGO_PASSWORD = environ.get('MONGO_PASSWORD', 'pvkpass') + # Only JSON, simplifies hooks XML = False diff --git a/Backend/create_demo_data.py b/Backend/create_demo_data.py index 5f376d6..ef3e996 100644 --- a/Backend/create_demo_data.py +++ b/Backend/create_demo_data.py @@ -11,7 +11,7 @@ from datetime import datetime as dt, timedelta import requests AMIVAPI_DEV_URL = "https://amiv-api.ethz.ch" -PVK_DEV_URL = 'http://localhost:80' # 'http://pvk-api-dev.amiv.ethz.ch' +PVK_DEV_URL = 'http://pvk-api-dev.amiv.ethz.ch' DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" ASSISTANTS = ['pablo', 'assi', 'anon', 'mongo'] @@ -113,7 +113,7 @@ def create_course(lecture, assistant, token, open_signup=True): 'room': next(ROOM), 'spots': randint(MIN_SPOTS, MAX_SPOTS), } - return post('courses', data, token)['_id'] + return post('courses', data, token) def create_signups(course, token): diff --git a/Backend/requirements.txt b/Backend/requirements.txt index 15809ea..bd714ad 100644 --- a/Backend/requirements.txt +++ b/Backend/requirements.txt @@ -1,8 +1,9 @@ +attrs==17.3.0 Cerberus==0.9.2 certifi==2017.11.5 chardet==3.0.4 click==6.7 -Eve==0.7.4 +Eve==0.7.8 Events==0.2.2 Flask==0.12 Flask-PyMongo==0.5.1 @@ -10,8 +11,13 @@ idna==2.6 itsdangerous==0.24 Jinja2==2.10 MarkupSafe==0.23 -pymongo==3.5.1 +pluggy==0.6.0 +py==1.5.2 +pymongo==3.6.1 requests==2.18.4 simplejson==3.13.2 +six==1.11.0 +tox==2.9.1 urllib3==1.22 +virtualenv==15.1.0 Werkzeug==0.11.15 diff --git a/Backend/tests/conftest.py b/Backend/tests/conftest.py index d919895..129a8f6 100644 --- a/Backend/tests/conftest.py +++ b/Backend/tests/conftest.py @@ -127,7 +127,7 @@ def admin(self, **kwargs): @pytest.fixture def app(): """Create app, instantiate test client, drop DB after use.""" - application = create_app(settings=TEST_SETTINGS) + application = create_app(**TEST_SETTINGS) application.test_client_class = TestClient application.client = application.test_client() -- GitLab