From ff63d88c04123515859dae89e0b3b148973bf41e Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Mon, 27 Jan 2025 18:35:04 +0100 Subject: [PATCH] deployment --- .gitignore | 3 +++ .woodpecker.yml | 36 +++++++++++++++++++++++++++++++++++ Dockerfile | 18 +++++++++++------- deployment/deploy-yml.tmpl | 17 +++++++++++++++++ deployment/deploy.sh | 39 ++++++++++++++++++++++++++++++++++++++ deployment/secrets.asc | 15 +++++++++++++++ src/run.py | 23 ++++++++-------------- start.sh | 2 +- 8 files changed, 130 insertions(+), 23 deletions(-) create mode 100644 .woodpecker.yml create mode 100644 deployment/deploy-yml.tmpl create mode 100755 deployment/deploy.sh create mode 100644 deployment/secrets.asc diff --git a/.gitignore b/.gitignore index 54f5088..f1f4fb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ .venv/ ENV +deployment/secrets.txt +src/__pycache__ + diff --git a/.woodpecker.yml b/.woodpecker.yml new file mode 100644 index 0000000..fd9dd32 --- /dev/null +++ b/.woodpecker.yml @@ -0,0 +1,36 @@ +steps: + build: + image: plugins/kaniko + settings: + repo: ${FORGE_NAME}/${CI_REPO} + registry: + from_secret: container_registry + tags: latest,${CI_COMMIT_SHA},${CI_COMMIT_TAG} + username: + from_secret: container_registry_username + password: + from_secret: container_registry_password + dockerfile: Dockerfile + when: + - event: [push, tag] + scan_image: + image: aquasec/trivy + commands: + - trivy image $FORGE_NAME/$CI_REPO:$CI_COMMIT_SHA --quiet --exit-code 1 + when: + - event: [push, tag] + deploy: + image: quay.io/wollud1969/k8s-admin-helper:0.1.3 + environment: + KUBE_CONFIG_CONTENT: + from_secret: kube_config + GPG_PASSPHRASE: + from_secret: gpg_passphrase + commands: + - export IMAGE_TAG=$CI_COMMIT_TAG + - printf "$KUBE_CONFIG_CONTENT" > /tmp/kubeconfig + - export KUBECONFIG=/tmp/kubeconfig + - ./deployment/deploy.sh + when: + - event: tag + diff --git a/Dockerfile b/Dockerfile index 3271313..75e3113 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,15 @@ FROM python:3.12-alpine3.21 +ENV REDIS_URL="" +ENV SECRET_KEY="" +ENV OIDC_CLIENT_SECRETS="" +ENV PGHOST="" +ENV PGDATABASE="" +ENV PGSSLMODE="" +ENV PGUSER="" +ENV PGPASSWORD="" + ARG APP_DIR="/opt/app" -ARG VERSION_ID1="x" -ARG VERSION_ID2="alpha" COPY ./src/ ${APP_DIR}/ COPY start.sh ${APP_DIR}/ @@ -10,12 +17,9 @@ COPY start.sh ${APP_DIR}/ WORKDIR ${APP_DIR} RUN \ - apk add --no-cache build-base libpq-dev npm && \ + apk add --no-cache libpq && \ pip install --upgrade pip && \ - pip install -r requirements.txt && \ - if [ "${VERSION_ID2}" != "" ]; then VERSION_ID=${VERSION_ID2}; else VERSION_ID=${VERSION_ID1}; fi && \ - sed -i -e 's/VERSION_ID/'$VERSION_ID'/' ${APP_DIR}/templates/index.html && \ - sed -i -e 's/VERSION_ID/'"$VERSION_ID"'/' ${APP_DIR}/templates/nutrition.html + pip install -r requirements.txt EXPOSE 8080 diff --git a/deployment/deploy-yml.tmpl b/deployment/deploy-yml.tmpl new file mode 100644 index 0000000..8042a23 --- /dev/null +++ b/deployment/deploy-yml.tmpl @@ -0,0 +1,17 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: pv-energy-calculator +spec: + schedule: "15 * * * *" + jobTemplate: + spec: + template: + spec: + restartPolicy: OnFailure + containers: + - name: pv-energy-calculator + image: %IMAGE% + envFrom: + - secretRef: + name: pv-energy-calculator diff --git a/deployment/deploy.sh b/deployment/deploy.sh new file mode 100755 index 0000000..4bbf38b --- /dev/null +++ b/deployment/deploy.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +if [ "$IMAGE_TAG" == "" ]; then + echo "Make sure IMAGE_TAG is set" + exit 1 +fi +if [ "$GPG_PASSPHRASE" == "" ]; then + echo "Make sure GPG_PASSPHRASE is set" + exit 1 +fi + +IMAGE_NAME=gitea.hottis.de/wn/mini_flask +NAMESPACE=homepages +DEPLOYMENT_DIR=$PWD/deployment + +pushd $DEPLOYMENT_DIR > /dev/null +kubectl create namespace $NAMESPACE \ + --dry-run=client \ + -o yaml | \ + kubectl -f - apply + +SECRETS_FILE=`mktemp` +gpg --decrypt --passphrase $GPG_PASSPHRASE --yes --batch --homedir /tmp/.gnupg --output $SECRETS_FILE secrets.asc + +kubectl create secret generic mini_flask \ + --dry-run=client \ + -o yaml \ + --save-config \ + --from-env-file=<(sed 's/^export //g' $SECRETS_FILE) | \ + kubectl apply -f - -n $NAMESPACE +rm $SECRETS_FILE + +# cat $DEPLOYMENT_DIR/deploy-yml.tmpl | \ +# sed -e 's,%IMAGE%,'$IMAGE_NAME':'$IMAGE_TAG','g | \ +# kubectl apply -f - -n $NAMESPACE + +popd > /dev/null + + diff --git a/deployment/secrets.asc b/deployment/secrets.asc new file mode 100644 index 0000000..b90b6dd --- /dev/null +++ b/deployment/secrets.asc @@ -0,0 +1,15 @@ +-----BEGIN PGP MESSAGE----- + +jA0ECQMCGiCDDKK8KgP/0sExAeQ99bvndkYa/C1rLsDj14oKDgqea1ylRMTSm3if +jUdbOyaNR0p0R32AS1wVlR9qxE1g/e/dCNmGjYQ0lqpyRwX6uqJFZ8KubZp0rRCV +40VpAfuu4eKE6NsxW8U4wlY5aDR21YUndoaHCwNQDgFV2exCDVeOsF1hyGgurWBG +QeAtlCN+HV6t9Gg6KUXRlr89C/wdZkkYScVGXxqemqetGntGhS96u37EFzyjnDaD +P09d6LKOIuHnKHZgBcKUZSqkYYwlNk05Wum9FqoWQc8KgCMvMv0WQNaaQxkrRah5 +DRgyXkNYrDg3WGt7357H3LO+IP1gTVAyjEsZl0OpazXLKGfrsWis+191t9omXk+x +Y9g/dx1aSqgeIQ3SiTpjdHHItSYcJ+ZYvJy+4u6FeKFrk/5Z9nBA0LxEmo5ObGmg +SrMCnzU1/JDCsAEp8mvAMQWFjJUrgUMUHM00uFm32Nq6SOAT50rW4/XIxak2w6/x +Zi7j3kxD6dfEXAeGRqCbDeTPQHNWPlvq0Rez2uaYA8w8S1hNoS8iSOSUbBoMCdFK +k61VApVRty0g35IsemcEuocIBw3YLWLLngHk7/xpKKWjbFO9H5AmxZT6FKcq7BwK +Q4DPHAmHDSCniiMzdcbcH7Y8GvO8q9jFPfQWE5MDETVlQ7Q= +=gOlN +-----END PGP MESSAGE----- diff --git a/src/run.py b/src/run.py index f58e2bc..eeabd39 100644 --- a/src/run.py +++ b/src/run.py @@ -1,8 +1,10 @@ from flask import Flask, session, g, render_template_string from flask_session import Session from flask_oidc import OpenIDConnect +from werkzeug.middleware.proxy_fix import ProxyFix from loguru import logger import redis +import json import os import plotly.express as px import pandas as pd @@ -11,7 +13,7 @@ import sqlalchemy try: redis_url = os.environ['REDIS_URL'] - client_secret = os.environ['CLIENT_SECRET'] + oidc_client_secrets = os.environ['OIDC_CLIENT_SECRETS'] secret_key = os.environ['SECRET_KEY'] except KeyError as e: logger.error(f"Required environment variable not set ({e})") @@ -23,20 +25,8 @@ app = Flask(__name__) app.config.update({ 'SECRET_KEY': secret_key, 'SESSION_TYPE': 'redis', - 'SESSION_REDIS': redis.from_url('redis://172.23.1.111:6379/4'), - 'OIDC_CLIENT_SECRETS': { - "web": { - "issuer": "https://auth2.hottis.de/realms/hottis", - "auth_uri": "https://auth2.hottis.de/ealms/hottis/protocol/openid-connect/auth", - "client_id": "mini_flask", - "client_secret": client_secret, - "redirect_uris": [ - "http://localhost:8080/*" - ], - "userinfo_uri": "https://auth2.hottis.de/realms/hottis/protocol/openid-connect/userinfo", - "token_uri": "https://auth2.hottis.de/realms/hottis/protocol/openid-connect/token" - } - }, + 'SESSION_REDIS': redis.from_url(redis_url), + 'OIDC_CLIENT_SECRETS': json.loads(oidc_client_secrets), 'OIDC_SCOPES': 'openid email', 'OIDC_USER_INFO_ENABLED': True, 'SESSION_USE_SIGNER': True, @@ -95,3 +85,6 @@ def plot(): if __name__ == '__main__': app.run(port=8080) +else: + exposed_app = ProxyFix(app, x_for=1, x_host=1) + diff --git a/start.sh b/start.sh index acc9438..fc4bd9d 100755 --- a/start.sh +++ b/start.sh @@ -1,6 +1,6 @@ #!/bin/sh -gunicorn 'Run:exposed_app' --bind 0.0.0.0:8080 --log-level=debug --workers=4 +gunicorn 'run:exposed_app' --bind 0.0.0.0:8080 --log-level=debug --workers=4