Skip to content

Commit

Permalink
Mijn 6927 api env agnostisch (#79)
Browse files Browse the repository at this point in the history
  • Loading branch information
timvanoostrom authored Nov 1, 2023
1 parent 2f04732 commit ff1ad31
Show file tree
Hide file tree
Showing 23 changed files with 464 additions and 186 deletions.
14 changes: 14 additions & 0 deletions .github/workflows/dependabot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Opdrachten Team Dependabot

on:
schedule: # Run the script every day at 6am UTC
- cron: "0 6 * * *"
workflow_dispatch:

jobs:
dependabot:
name: Templates
uses: amsterdam/github-workflows/.github/workflows/dependabot.yml@v1
secrets: inherit
with:
check_diff: true
61 changes: 45 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,41 +1,70 @@
FROM python:3.11-bookworm as base

ENV PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=off \
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
ENV TZ=Europe/Amsterdam
ENV PYTHONUNBUFFERED=1
ENV PIP_NO_CACHE_DIR=off

WORKDIR /api

COPY ca/* /usr/local/share/ca-certificates/extras/

RUN apt-get update \
&& apt-get dist-upgrade -y \
&& apt-get autoremove -y \
&& apt-get install --no-install-recommends -y \
&& apt-get install -y --no-install-recommends \
nano \
openssh-server \
locales \
&& rm -rf /var/lib/apt/lists/* /var/cache/debconf/*-old \
&& pip install --upgrade pip \
&& pip install uwsgi \
&& chmod -R 644 /usr/local/share/ca-certificates/extras/ \
&& update-ca-certificates
&& pip install uwsgi

COPY requirements.txt /api

RUN sed -i -e 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen
ENV LANG nl_NL.UTF-8
ENV LANGUAGE nl_NL:nl
ENV LC_ALL nl_NL.UTF-8

COPY requirements.txt /api

RUN pip install -r requirements.txt

COPY ./scripts /api/scripts
COPY ./app /api/app
COPY ./uwsgi.ini /api
COPY ./test.sh /api
COPY .flake8 /api


FROM base as tests

COPY conf/test.sh /api/
COPY .flake8 /api/

RUN chmod u+x /api/test.sh

CMD uwsgi --uid www-data --gid www-data --ini /api/uwsgi.ini
ENTRYPOINT [ "/bin/sh", "/api/test.sh"]

FROM base as publish

# ssh ( see also: https://github.com/Azure-Samples/docker-django-webapp-linux )
ENV SSH_PASSWD "root:Docker!"

EXPOSE 8000
ENV PORT 8000

ARG MA_OTAP_ENV
ENV MA_OTAP_ENV=$MA_OTAP_ENV

ARG MA_BUILD_ID
ENV MA_BUILD_ID=$MA_BUILD_ID

ARG MA_GIT_SHA
ENV MA_GIT_SHA=$MA_GIT_SHA

COPY conf/uwsgi.ini /api/
COPY conf/docker-entrypoint.sh /api/
COPY conf/sshd_config /etc/ssh/

RUN chmod u+x /api/docker-entrypoint.sh \
&& echo "$SSH_PASSWD" | chpasswd

ENTRYPOINT [ "/bin/sh", "/api/docker-entrypoint.sh"]

FROM publish as publish-final

COPY /files /app/files
46 changes: 20 additions & 26 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,42 @@ def retagAndPush(String imageName, String currentTag, String newTag)
String BRANCH = "${env.BRANCH_NAME}"
String IMAGE_NAME = "mijnams/focus"
String IMAGE_TAG = "${IMAGE_NAME}:${env.BUILD_NUMBER}"
String IMAGE_TEST = "${IMAGE_NAME}:test-${env.BUILD_NUMBER}"
String CMDB_ID = "app_mijn-focus"

node {
stage("Checkout") {
checkout scm
}

stage("Build image") {
docker.withRegistry(DOCKER_REGISTRY_HOST, "docker_registry_auth") {
def image = docker.build(IMAGE_TAG)
image.push()
}
}
}

// Skipping tests for the test branch
if (BRANCH != "test-acc") {
node {
// Skipping tests for the test branch
if (BRANCH != "test-acc") {
stage("Test") {
docker.withRegistry(DOCKER_REGISTRY_HOST, "docker_registry_auth") {
docker.image(IMAGE_TAG).pull()
sh "docker run --rm ${IMAGE_TAG} /api/test.sh"
sh "docker build -t ${IMAGE_TEST} " +
"--target=tests " +
"--shm-size 1G " +
"."
sh "docker run --rm ${IMAGE_TEST}"
}
}
}
}

if (BRANCH == "test-acc" || BRANCH == "main") {
node {
stage("Build image") {
docker.withRegistry(DOCKER_REGISTRY_HOST, "docker_registry_auth") {
def image = docker.build(IMAGE_TAG, "--target=publish .")
image.push()
}
}

if (BRANCH == "test-acc" || BRANCH == "main") {
stage("Push acceptance image") {
docker.withRegistry(DOCKER_REGISTRY_HOST, "docker_registry_auth") {
docker.image(IMAGE_TAG).pull()
retagAndPush(IMAGE_NAME, env.BUILD_NUMBER, "acceptance")
}
}
}

node {
stage("Deploy to ACC") {
build job: "Subtask_Openstack_Playbook",
parameters: [
Expand All @@ -58,23 +56,19 @@ if (BRANCH == "test-acc" || BRANCH == "main") {
]
}
}
}

if (BRANCH == "production-release") {
stage("Waiting for approval") {
input "Deploy to Production?"
}
if (BRANCH == "production-release") {
stage("Waiting for approval") {
input "Deploy to Production?"
}

node {
stage("Push production image") {
docker.withRegistry(DOCKER_REGISTRY_HOST, "docker_registry_auth") {
docker.image(IMAGE_TAG).pull()
retagAndPush(IMAGE_NAME, env.BUILD_NUMBER, "production")
}
}
}

node {
stage("Deploy") {
build job: "Subtask_Openstack_Playbook",
parameters: [
Expand Down
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This Makefile is based on the Makefile defined in the Python Best Practices repository:
# https://git.data.amsterdam.nl/Datapunt/python-best-practices/blob/master/dependency_management/

PYTHON = python3

pip-tools:
pip install pip-tools

requirements: pip-tools ## Upgrade requirements (in requirements-root.txt) to latest versions and compile requirements.txt
pip-compile --upgrade --output-file requirements.txt requirements-root.txt

diff:
@python3 ./scripts/diff.py
13 changes: 11 additions & 2 deletions app/auth.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import logging
import os
import unittest
from unittest.mock import patch
from flask_httpauth import HTTPTokenAuth

import jwt
from flask_httpauth import HTTPTokenAuth

from app.config import VERIFY_JWT_SIGNATURE

auth = HTTPTokenAuth(scheme="Bearer")

Expand Down Expand Up @@ -118,7 +122,12 @@ def get_verified_token_data(token):


def get_user_profile_from_token(token):
token_data = get_verified_token_data(token)
if VERIFY_JWT_SIGNATURE:
token_data = get_verified_token_data(token)
else:
token_data = jwt.api_jwt.decode(token, options={"verify_signature": False})

logging.info(token_data)

profile_type = get_profile_type(token_data)
profile_id = get_profile_id(token_data)
Expand Down
39 changes: 29 additions & 10 deletions app/config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import base64
import locale
import logging
import os
from datetime import date, time, datetime
import tempfile
from flask.json.provider import DefaultJSONProvider

locale.setlocale(locale.LC_TIME, "nl_NL.UTF-8")
Expand All @@ -15,27 +17,44 @@
# Environment determination
IS_PRODUCTION = SENTRY_ENV == "production"
IS_ACCEPTANCE = SENTRY_ENV == "acceptance"
IS_AP = IS_PRODUCTION or IS_ACCEPTANCE
IS_DEV = os.getenv("FLASK_ENV") == "development" and not IS_AP
IS_DEV = SENTRY_ENV == "development"
IS_TEST = SENTRY_ENV == "test"

IS_TAP = IS_PRODUCTION or IS_ACCEPTANCE or IS_TEST
IS_AP = IS_ACCEPTANCE or IS_PRODUCTION
IS_OT = IS_DEV or IS_TEST

# App constants
VERIFY_JWT_SIGNATURE = os.getenv("VERIFY_JWT_SIGNATURE", IS_AP)
API_REQUEST_TIMEOUT = 30
API_BASE_PATH = "/wpi"

# Server security / certificates for ZorgNed
SERVER_CLIENT_CERT = os.getenv("MIJN_DATA_CLIENT_CERT")
SERVER_CLIENT_KEY = os.getenv("MIJN_DATA_CLIENT_KEY")

# TODO: Add other AZ env conditions after migration.
if IS_TEST:
# https://stackoverflow.com/a/46570364/756075
# Server security / certificates
cert = tempfile.NamedTemporaryFile(delete=False)
cert.write(base64.b64decode(SERVER_CLIENT_CERT))
cert.close()

key = tempfile.NamedTemporaryFile(delete=False)
key.write(base64.b64decode(SERVER_CLIENT_KEY))
key.close()

SERVER_CLIENT_CERT = cert.name
SERVER_CLIENT_KEY = key.name

# ZorgNed vars
ZORGNED_STADSPASSEN_ENABLED = True
ZORGNED_API_REQUEST_TIMEOUT_SECONDS = 30
ZORGNED_API_TOKEN = os.getenv("WMO_NED_API_TOKEN")
ZORGNED_API_TOKEN = os.getenv("ZORGNED_API_TOKEN")
ZORGNED_API_URL = os.getenv("ZORGNED_API_URL")
ZORGNED_GEMEENTE_CODE = "0363"


# App constants
ENABLE_OPENAPI_VALIDATION = os.getenv("ENABLE_OPENAPI_VALIDATION", not IS_AP)

API_REQUEST_TIMEOUT = 30
API_BASE_PATH = "/wpi"

# Set-up logging
LOG_LEVEL = os.getenv("LOG_LEVEL", "ERROR").upper()
logging.basicConfig(
Expand Down
9 changes: 1 addition & 8 deletions app/focus_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
import os

from app.config import API_BASE_PATH, IS_ACCEPTANCE
from app.config import API_BASE_PATH

# Focus
FOCUS_WSDL = os.getenv("FOCUS_WSDL")
Expand Down Expand Up @@ -59,12 +58,6 @@
3557: "kind",
}

FOCUS_STADSPAS_ADMIN_NUMBER_CONVERSION_ACC = (
json.loads(os.getenv("FOCUS_STADSPAS_ADMIN_NUMBER_CONVERSION_ACC", "null"))
if IS_ACCEPTANCE
else None
)

zeep_config = {"wsdl": FOCUS_WSDL, "session_verify": FOCUS_CERTIFICATE}

focus_credentials = {
Expand Down
13 changes: 1 addition & 12 deletions app/focus_service_stadspas_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@ def has_groene_stip(fondsen):
return False


def get_administratienummer(number_from_source):
# Disable ACC dataset coupling, enable if we need it again.
# if FOCUS_STADSPAS_ADMIN_NUMBER_CONVERSION_ACC:
# return FOCUS_STADSPAS_ADMIN_NUMBER_CONVERSION_ACC.get(
# number_from_source, number_from_source
# )
return number_from_source


def get_first_pas_type(fondsen):
pas_type = None

Expand Down Expand Up @@ -83,8 +74,6 @@ def get_stadspas_admin_number(bsn):
pas_type = get_first_pas_type(fondsen)

return {
"admin_number": get_administratienummer(
volledig_administratienummer(admin_number)
),
"admin_number": volledig_administratienummer(admin_number),
"type": pas_type,
}
2 changes: 1 addition & 1 deletion app/gpass_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# GPASS
GPASS_API_TOKEN = os.getenv("GPASS_TOKEN")
GPASS_API_LOCATION = os.getenv("GPASS_API_LOCATION")
GPASS_FERNET_ENCRYPTION_KEY = os.getenv("FERNET_KEY")
GPASS_FERNET_ENCRYPTION_KEY = os.getenv("FERNET_ENCRYPTION_KEY")

STADSPAS_TRANSACTIONS_PATH = "/wpi/stadspas/transacties/"

Expand Down
Loading

0 comments on commit ff1ad31

Please sign in to comment.