diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b939f857e842f3218a93c39d49938655ab380023..b0e2d49c6c24816b8f81cb9fa36e690097f4d830 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 314ee8a677d47a4a9dbc62f879f370b709889437..6f3b97f7223e1a73acafc56f9f028098da827e40 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 a23b21d2cd3b248b1273bc66eee4e819f12cd2e4..b3a5b7ec2cc22302985a0e4130581f051218b49a 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 a3d0d5b826223850d5db9a27b076c3579eecd9f3..ccc4d1a64265942f8343ad8cb6d78fa55aedd946 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 5f376d683820ccf216c6b05b3a97cba54a733430..ef3e996625c0bd17268bc19d67a31dfb883384af 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 15809ea69cd4f1c268e95f70c9cd5c5a9eb79dcb..bd714ad92265f5e825af24f4cc1b32b22dad00e2 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 d91989542fe4e38132aa4855f4ae0adabd34e52c..129a8f6f567e4896d6191ef48834d023c5b7bbc3 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()