From 9feae4ef000d13b7fe144c318d5f5f4a9b5f4a13 Mon Sep 17 00:00:00 2001 From: Frederik Ring Date: Fri, 5 Jul 2019 19:54:54 +0200 Subject: [PATCH] scaffold accounts app --- .circleci/config.yml | 134 ++++++++++++++++++++----- .gitignore | 1 + Dockerfile.python | 3 + Makefile | 3 +- accounts/.gitignore | 10 ++ accounts/Makefile | 4 + accounts/accounts/__init__.py | 13 +++ accounts/accounts/templates/index.html | 9 ++ accounts/accounts/tests/__init__.py | 0 accounts/accounts/tests/test_status.py | 12 +++ accounts/requirements-dev.txt | 2 + accounts/requirements.txt | 2 + accounts/serverless.yml | 59 +++++++++++ docker-compose.yml | 30 ++++-- package.json | 4 +- 15 files changed, 252 insertions(+), 34 deletions(-) create mode 100644 Dockerfile.python create mode 100644 accounts/.gitignore create mode 100644 accounts/Makefile create mode 100644 accounts/accounts/__init__.py create mode 100644 accounts/accounts/templates/index.html create mode 100644 accounts/accounts/tests/__init__.py create mode 100644 accounts/accounts/tests/test_status.py create mode 100644 accounts/requirements-dev.txt create mode 100644 accounts/requirements.txt create mode 100644 accounts/serverless.yml diff --git a/.circleci/config.yml b/.circleci/config.yml index 4882bcf..98b06c2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,29 @@ version: 2 +production_env: &production_env + environment: + - SERVER_HOST=https://server-alpha.offen.dev + - KMS_HOST=https://kms-alpha.offen.dev + - SCRIPT_HOST=https://script-alpha.offen.dev + - AUDITORIUM_HOST=https://auditorium-alpha.offen.dev + - VAULT_HOST=https://vault-alpha.offen.dev + - ACCOUNTS_HOST=https://accounts-alpha.offen.dev + - NODE_ENV=production + +deploy_preconditions: &deploy_preconditions + requires: + - server + - kms + - vault + - script + - auditorium + - packages + - shared + - accounts + filters: + branches: + only: /^master$/ + jobs: kms: docker: @@ -160,16 +184,60 @@ jobs: name: Run tests command: npm test - deploy: + accounts: + docker: + - image: circleci/python:3.6 + working_directory: ~/offen/accounts + steps: + - checkout: + path: ~/offen + - restore_cache: + key: offen-accounts-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }} + - run: + name: Install dependencies + command: | + python3 -m venv venv + . venv/bin/activate + pip install -r requirements.txt + pip install -r requirements-dev.txt + - save_cache: + paths: + - ~/offen/accounts/venv + key: offen-accounts-{{ checksum "requirements.txt" }}-{{ checksum "requirements-dev.txt" }} + - run: + name: Run tests + command: | + . venv/bin/activate + make + + deploy_python: + docker: + - image: circleci/python:3.6-node + <<: *production_env + working_directory: ~/offen + steps: + - checkout: + path: ~/offen + - restore_cache: + key: offen-deploy-{{ checksum "package.json" }} + - run: + name: Install dependencies + command: npm install + - save_cache: + paths: + - ~/offen/packages/node_modules + key: offen-packages-{{ checksum "package.json" }} + - run: + name: Deploy + working_directory: ~/offen + command: | + echo "Deploying accounts ..." + $(npm bin)/sls deploy --config accounts/serverless.yml + + deploy_golang: docker: - image: circleci/golang:1.12-node - environment: - - SERVER_HOST=https://server-alpha.offen.dev - - KMS_HOST=https://kms-alpha.offen.dev - - SCRIPT_HOST=https://script-alpha.offen.dev - - AUDITORIUM_HOST=https://auditorium-alpha.offen.dev - - VAULT_HOST=https://vault-alpha.offen.dev - - NODE_ENV=production + <<: *production_env working_directory: ~/offen steps: - checkout: @@ -204,6 +272,33 @@ jobs: name: Manually clear go cache command: sudo rm -rf /go/pkg/mod + - run: + name: Deploy + working_directory: ~/offen + command: | + echo "Deploying server ..." + $(npm bin)/sls deploy --config server/serverless.yml + echo "Deploying kms ..." + $(npm bin)/sls deploy --config kms/serverless.yml + + deploy_node: + docker: + - image: circleci/node:10 + <<: *production_env + working_directory: ~/offen + steps: + - checkout: + path: ~/offen + - restore_cache: + key: offen-deploy-{{ checksum "package.json" }} + - run: + name: Install dependencies + command: npm install + - save_cache: + paths: + - ~/offen/packages/node_modules + key: offen-packages-{{ checksum "package.json" }} + - restore_cache: key: offen-auditorium-{{ checksum "auditorium/package.json" }} - run: @@ -229,10 +324,6 @@ jobs: name: Deploy working_directory: ~/offen command: | - echo "Deploying server ..." - $(npm bin)/sls deploy --config server/serverless.yml - echo "Deploying kms ..." - $(npm bin)/sls deploy --config kms/serverless.yml echo "Deploying auditorium ..." $(npm bin)/sls deploy --config auditorium/serverless.yml $(npm bin)/sls client deploy --config auditorium/serverless.yml --no-confirm @@ -254,15 +345,10 @@ workflows: - auditorium - packages - shared - - deploy: - requires: - - server - - kms - - vault - - script - - auditorium - - packages - - shared - filters: - branches: - only: /^master$/ + - accounts + - deploy_golang: + <<: *deploy_preconditions + - deploy_node: + <<: *deploy_preconditions + - deploy_python: + <<: *deploy_preconditions diff --git a/.gitignore b/.gitignore index 25d962e..c7ef530 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules/ package-lock.json # mkcert certificates *.pem +venv/ diff --git a/Dockerfile.python b/Dockerfile.python new file mode 100644 index 0000000..208b73f --- /dev/null +++ b/Dockerfile.python @@ -0,0 +1,3 @@ +FROM python:3.6 + +ENV PATH="/root/.local/bin:$PATH" diff --git a/Makefile b/Makefile index 6d92848..c0ce3d1 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,6 @@ help: @echo " bootstrap" @echo " Create a KMS key and initialize the database." @echo " IMPORTANT: this wipes any existing data in your local database." - @echo " build" - @echo " Build all applications." setup: @docker-compose build @@ -14,6 +12,7 @@ setup: @docker-compose run auditorium npm install @docker-compose run server go mod download @docker-compose run kms go mod download + @docker-compose run accounts pip install --user -r requirements.txt -r requirements-dev.txt @echo "Successfully built containers and installed dependencies." @echo "If this is your initial setup, you can run 'make bootstrap' next" @echo "to create the needed local keys and seed the database." diff --git a/accounts/.gitignore b/accounts/.gitignore new file mode 100644 index 0000000..37b9c3f --- /dev/null +++ b/accounts/.gitignore @@ -0,0 +1,10 @@ +*.dot +__pycache__ +*.log +.vscode/ +.pytest_cache +venv/ +*.pyc + +models/ + diff --git a/accounts/Makefile b/accounts/Makefile new file mode 100644 index 0000000..1386f9c --- /dev/null +++ b/accounts/Makefile @@ -0,0 +1,4 @@ +test: + @pytest --disable-pytest-warnings + +.PHONY: test diff --git a/accounts/accounts/__init__.py b/accounts/accounts/__init__.py new file mode 100644 index 0000000..90d5781 --- /dev/null +++ b/accounts/accounts/__init__.py @@ -0,0 +1,13 @@ +from flask import Flask, jsonify, render_template + +app = Flask(__name__) + + +@app.route("/") +def home(): + return render_template("index.html") + + +@app.route("/status") +def status(): + return jsonify({"ok": True}) diff --git a/accounts/accounts/templates/index.html b/accounts/accounts/templates/index.html new file mode 100644 index 0000000..0ddf8bd --- /dev/null +++ b/accounts/accounts/templates/index.html @@ -0,0 +1,9 @@ + + + + offen accounts + + +

Welcome to offen accounts

+ + diff --git a/accounts/accounts/tests/__init__.py b/accounts/accounts/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/accounts/accounts/tests/test_status.py b/accounts/accounts/tests/test_status.py new file mode 100644 index 0000000..21b8832 --- /dev/null +++ b/accounts/accounts/tests/test_status.py @@ -0,0 +1,12 @@ +import unittest + +from accounts import app + +class TestStatus(unittest.TestCase): + def setUp(self): + self.app = app.test_client() + + def test_get(self): + rv = self.app.get("/status") + assert rv.status.startswith("200") + assert b"ok" in rv.data diff --git a/accounts/requirements-dev.txt b/accounts/requirements-dev.txt new file mode 100644 index 0000000..9bb2a15 --- /dev/null +++ b/accounts/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest +black diff --git a/accounts/requirements.txt b/accounts/requirements.txt new file mode 100644 index 0000000..0a04170 --- /dev/null +++ b/accounts/requirements.txt @@ -0,0 +1,2 @@ +Flask==1.0.2 +werkzeug==0.15.4 diff --git a/accounts/serverless.yml b/accounts/serverless.yml new file mode 100644 index 0000000..e04f2ff --- /dev/null +++ b/accounts/serverless.yml @@ -0,0 +1,59 @@ +service: + name: accounts + awsKmsKeyArn: ${ssm:/aws/reference/secretsmanager/${self:custom.stage}/all/kmsArn~true} + +provider: + name: aws + endpointType: regional + runtime: python3.6 + stage: alpha + region: eu-central-1 + apiName: offen-${self:provider.stage} + logs: + restApi: true + +package: + individually: true + excludeDevDependencies: false + exclude: + - '**/*' + +plugins: + - serverless-domain-manager + - serverless-python-requirements + - serverless-wsgi + +custom: + stage: ${opt:stage, self:provider.stage} + domain: + production: accounts.offen.dev + staging: accounts-staging.offen.dev + alpha: accounts-alpha.offen.dev + customDomain: + basePath: '' + certificateName: '*.offen.dev' + domainName: ${self:custom.domain.${self:custom.stage}} + stage: ${self:custom.stage} + endpointType: regional + createRoute53Record: false + wsgi: + app: accounts.accounts.app + packRequirements: false + pythonRequirements: + slim: true + dockerizePip: non-linux + fileName: accounts/requirements.txt + +functions: + app: + package: + include: + - accounts/**/* + handler: wsgi_handler.handler + events: + - http: + path: '/' + method: any + - http: + path: '{proxy+}' + method: any diff --git a/docker-compose.yml b/docker-compose.yml index 8a8cbd1..420db72 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,11 +1,6 @@ version: '3' services: - database: - image: postgres:11.2 - environment: - - POSTGRES_PASSWORD=develop - kms: build: context: '.' @@ -21,6 +16,11 @@ services: - 8081:8081 command: refresh run + server_database: + image: postgres:11.2 + environment: + - POSTGRES_PASSWORD=develop + server: build: context: '.' @@ -30,14 +30,14 @@ services: - .:/offen - serverdeps:/go/pkg/mod environment: - - POSTGRES_CONNECTION_STRING=postgres://postgres:develop@database:5432/postgres?sslmode=disable + - POSTGRES_CONNECTION_STRING=postgres://postgres:develop@server_database:5432/postgres?sslmode=disable - KMS_ENCRYPTION_ENDPOINT=http://kms:8081/encrypt - PORT=8080 ports: - 8080:8080 command: refresh run links: - - database + - server_database depends_on: - kms @@ -86,9 +86,25 @@ services: environment: - VAULT_HOST=http://localhost:9977 + accounts: + build: + context: '.' + dockerfile: Dockerfile.python + working_dir: /offen/accounts + volumes: + - .:/offen + - accountdeps:/root/.local + command: flask run --host 0.0.0.0 + ports: + - 5000:5000 + environment: + - FLASK_APP=accounts + - FLASK_ENV=development + volumes: kmsdeps: serverdeps: scriptdeps: auditoriumdeps: vaultdeps: + accountdeps: diff --git a/package.json b/package.json index 4141330..7378bdb 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "dependencies": { "serverless": "^1.45.0", "serverless-domain-manager": "^2.6.13", - "serverless-finch": "^2.4.2" + "serverless-finch": "^2.4.2", + "serverless-python-requirements": "^4.3.0", + "serverless-wsgi": "^1.7.2" } }