diff --git a/.forgejo/scripts/deploy-prd.sh b/.forgejo/scripts/deploy-prd.sh deleted file mode 100644 index efc8972..0000000 --- a/.forgejo/scripts/deploy-prd.sh +++ /dev/null @@ -1,122 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -NAMESPACE=go-insane-prd -REGISTRY=nexus.urpi.be -CERT_MANAGER_VERSION=v1.19.1 -LOCAL_PATH_VERSION=v0.0.37 -LOCK_NAME=forgejo-prd-deploy-lock -if [[ $# -lt 4 ]]; then echo "Usage: $0 [helm args...]" >&2; exit 2; fi -CHART=$1; RELEASE=$2; IMAGE_NAME=$3; IMAGE_TAG=$4; shift 4 -: "${KUBECONFIG_PRD:?Set the Forgejo secret KUBECONFIG_PRD to the PRD kubeconfig contents}" -: "${NEXUS_USERNAME:?Set the Forgejo secret NEXUS_USERNAME}" -: "${NEXUS_PASSWORD:?Set the Forgejo secret NEXUS_PASSWORD}" -KUBECONFIG="${RUNNER_TEMP:-/tmp}/kubeconfig-prd-${GITHUB_RUN_ID:-$$}" -umask 077; printf '%s\n' "$KUBECONFIG_PRD" > "$KUBECONFIG"; export KUBECONFIG -LOCK_ACQUIRED=false -cleanup() { if [[ "$LOCK_ACQUIRED" == true ]]; then kubectl -n "$NAMESPACE" delete configmap "$LOCK_NAME" --ignore-not-found --wait=false >/dev/null 2>&1 || true; fi; rm -f "$KUBECONFIG"; } -trap cleanup EXIT -secret_value() { - local name=$1 key=$2 encoded - encoded="$(kubectl -n "$NAMESPACE" get secret "$name" -o go-template="{{index .data \"${key}\"}}" 2>/dev/null || true)" - [[ -z "$encoded" || "$encoded" == "" ]] && return 0 - printf '%s' "$encoded" | base64 -d 2>/dev/null || true -} -kubectl get --raw=/readyz >/dev/null -if [[ "$RELEASE" == go-loose ]] && ! kubectl -n "$NAMESPACE" get secret go-loose-wildcard-tls >/dev/null 2>&1; then - echo "Required go-loose-wildcard-tls Secret is missing; provision the tenant wildcard certificate before bootstrap/deploy." >&2 - exit 1 -fi -kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - -for attempt in {1..360}; do if kubectl -n "$NAMESPACE" create configmap "$LOCK_NAME" --from-literal=owner="${GITHUB_REPOSITORY:-local}:${GITHUB_RUN_ID:-$$}" >/dev/null 2>&1; then LOCK_ACQUIRED=true; break; fi; sleep 5; done -if [[ "$LOCK_ACQUIRED" != true ]]; then echo "Timed out waiting for another go-insane-prd deploy to release its lock." >&2; exit 1; fi -kubectl -n "$NAMESPACE" create secret docker-registry nexus-registry --docker-server="$REGISTRY" --docker-username="$NEXUS_USERNAME" --docker-password="$NEXUS_PASSWORD" --dry-run=client -o yaml | kubectl apply -f - -DEFAULT_STORAGE_CLASS="$(kubectl get storageclass -o=jsonpath='{range .items[*]}{.metadata.name}{" "}{.metadata.annotations.storageclass\.kubernetes\.io/is-default-class}{"\n"}{end}' | awk '$2 == "true" { print $1; exit }')" -if [[ -z "$DEFAULT_STORAGE_CLASS" ]]; then - if ! kubectl get storageclass local-path >/dev/null 2>&1 || ! kubectl -n local-path-storage get deployment local-path-provisioner >/dev/null 2>&1; then kubectl apply -f "https://raw.githubusercontent.com/rancher/local-path-provisioner/${LOCAL_PATH_VERSION}/deploy/local-path-storage.yaml"; kubectl -n local-path-storage rollout status deployment/local-path-provisioner --timeout=5m; fi - kubectl annotate storageclass local-path storageclass.kubernetes.io/is-default-class=true --overwrite -fi -if ! kubectl get ingressclass nginx >/dev/null 2>&1; then - helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx --force-update - helm repo update ingress-nginx - helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx --create-namespace --set controller.service.type=NodePort --set controller.hostPort.enabled=true --set controller.kind=DaemonSet --set controller.admissionWebhooks.enabled=false --wait --timeout 10m -fi -if ! kubectl get crd clusterissuers.cert-manager.io >/dev/null 2>&1 || ! kubectl -n cert-manager get deployment cert-manager >/dev/null 2>&1; then - kubectl apply --validate=false -f "https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml" - kubectl -n cert-manager rollout status deployment/cert-manager --timeout=5m - kubectl -n cert-manager rollout status deployment/cert-manager-cainjector --timeout=5m - kubectl -n cert-manager rollout status deployment/cert-manager-webhook --timeout=5m -fi -if ! kubectl get clusterissuer letsencrypt-prod >/dev/null 2>&1; then - kubectl apply -f - <<'ISSUER' -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt-prod -spec: - acme: - server: https://acme-v02.api.letsencrypt.org/directory - email: admin@urpi.be - privateKeySecretRef: - name: letsencrypt-prod - solvers: - - http01: - ingress: - class: nginx -ISSUER -fi -kubectl wait --for=condition=Ready clusterissuer/letsencrypt-prod --timeout=2m -[[ -d "$CHART" ]] || { echo "Helm chart not found: $CHART" >&2; exit 1; } -if [[ -f "$CHART/Chart.lock" ]]; then helm dependency build "$CHART"; fi -HELM_ARGS=(--namespace "$NAMESPACE" --create-namespace) -if [[ "$RELEASE" != go-guess ]]; then HELM_ARGS+=(--set-string "image.repository=${REGISTRY}/docker-hosted/${IMAGE_NAME}" --set-string "image.tag=${IMAGE_TAG}"); fi -[[ ! -f "$CHART/values-prd.yaml" ]] || HELM_ARGS+=(--values "$CHART/values-prd.yaml") -case "$RELEASE" in - go-loose) - db_password="$(secret_value go-loose-runtime postgresql-password)" - [[ -n "$db_password" ]] || db_password="$(secret_value go-loose-postgresql postgres-password)" - [[ -n "$db_password" ]] || db_password="$(secret_value go-loose-postgresql password)" - if [[ -z "$db_password" ]] && kubectl -n "$NAMESPACE" get pvc -o name | grep -Eq 'go-loose.*postgresql|data-go-loose'; then - echo "Existing go-loose database storage has no recoverable password secret; refusing to rotate its credentials." >&2 - exit 1 - fi - [[ -n "$db_password" ]] || db_password="$(openssl rand -hex 24)" - session_secret="$(secret_value go-loose-runtime session-secret)" - [[ -n "$session_secret" ]] || session_secret="$(secret_value go-loose-env GO_LOOSE_SESSION_SECRET)" - [[ -n "$session_secret" ]] || session_secret="$(openssl rand -hex 32)" - database_url="postgres://goloose:${db_password}@go-loose-postgresql:5432/goloose?sslmode=disable" - kubectl -n "$NAMESPACE" create secret generic go-loose-runtime \ - --from-literal=postgresql-password="$db_password" \ - --from-literal=postgres-password="$db_password" \ - --from-literal=database-url="$database_url" \ - --from-literal=session-secret="$session_secret" \ - --dry-run=client -o yaml | kubectl apply -f - - ;; - go-mad) - if ! kubectl -n "$NAMESPACE" get secret go-mad-runtime >/dev/null 2>&1; then - db_password="$(secret_value go-mad-postgresql password)"; [[ -n "$db_password" ]] || db_password="$(secret_value go-mad-postgresql postgres-password)" - if [[ -z "$db_password" ]] && kubectl -n "$NAMESPACE" get pvc -o name | grep -Eq 'go-mad.*postgresql|data-go-mad'; then echo "Existing go-mad database storage has no recoverable password secret; refusing to rotate its credentials." >&2; exit 1; fi - [[ -n "$db_password" ]] || db_password="$(openssl rand -hex 24)" - kubectl -n "$NAMESPACE" create secret generic go-mad-runtime --from-literal=postgresql-password="$db_password" --from-literal=jwt-secret="$(openssl rand -hex 32)" - fi - db_password="$(secret_value go-mad-runtime postgresql-password)"; jwt_secret="$(secret_value go-mad-runtime jwt-secret)" - HELM_ARGS+=(--set-string "postgresql.auth.password=${db_password}" --set-string "go-mad.jwtSecret=${jwt_secret}") - ;; - go-first) - if ! kubectl -n "$NAMESPACE" get secret go-first-runtime >/dev/null 2>&1; then - kubectl -n "$NAMESPACE" create secret generic go-first-runtime --from-literal=jwt-secret="$(openssl rand -hex 32)" - fi - ;; - go-places) - : "${GO_LOOSE_JWT_SECRET:?Set Forgejo secret GO_LOOSE_JWT_SECRET to the same signing key used by go-loose}" - kubectl -n "$NAMESPACE" create secret generic go-loose-jwt --from-literal=secret="$GO_LOOSE_JWT_SECRET" --dry-run=client -o yaml | kubectl apply -f - - ;; - go-bananas) - : "${GO_BANANAS_OIDC_CLIENT_SECRET:?Set Forgejo secret GO_BANANAS_OIDC_CLIENT_SECRET}" - session_secret="$(secret_value go-bananas-auth session-secret)" - if [[ -z "$session_secret" ]]; then session_secret="$(openssl rand -hex 32)"; fi - kubectl -n "$NAMESPACE" create secret generic go-bananas-auth --from-literal=session-secret="$session_secret" --from-literal=oidc-client-secret="$GO_BANANAS_OIDC_CLIENT_SECRET" --dry-run=client -o yaml | kubectl apply -f - - ;; -esac -helm upgrade --install "$RELEASE" "$CHART" "${HELM_ARGS[@]}" "$@" --wait --timeout 15m -kubectl -n "$NAMESPACE" get deployments,statefulsets,pods,services,ingresses diff --git a/.forgejo/workflows/ci-cd.yaml b/.forgejo/workflows/ci-cd.yaml index b8bb112..3f513a2 100644 --- a/.forgejo/workflows/ci-cd.yaml +++ b/.forgejo/workflows/ci-cd.yaml @@ -1,41 +1,58 @@ -name: Build, test, publish, deploy +name: CI/CD on: push: + branches: [main, develop] + tags: ['v*'] pull_request: - workflow_dispatch: + branches: [main, develop] env: - GO_VERSION: "1.27.1" - REGISTRY: nexus.urpi.be + REGISTRY: nexus-registry.urpi.be IMAGE_NAME: docker-hosted/go-loose + GO_VERSION: '1.27.1' jobs: - build-test: + build-and-test: + name: Build and Test runs-on: ubuntu-latest + permissions: + contents: read + steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 with: - go-version-file: go.mod + go-version: ${{ env.GO_VERSION }} cache: true - - name: Build and test Go service + + - name: Download dependencies + run: go mod download + + - name: Build + run: go build ./... + + - name: Run unit tests + run: go test -race ./... -count=1 + + - name: Run vet + run: go vet ./... + + - name: Check formatting run: | - go mod download - go vet ./... - go test -race ./... -count=1 - go build ./... - - uses: azure/setup-helm@v4 - with: - version: v3.18.6 - - name: Validate production chart - run: | - helm dependency build deploy/helm/go-loose - helm lint deploy/helm/go-loose -f deploy/helm/go-loose/values-prd.yaml + if [ "$(gofmt -l . | grep -v vendor | grep -v dist | wc -l)" -gt 0 ]; then + echo "Code is not formatted:" + gofmt -l . | grep -v vendor | grep -v dist + exit 1 + fi integration-test: + name: Integration Tests runs-on: ubuntu-latest - needs: build-test + needs: build-and-test services: postgres: image: postgres:17-alpine @@ -43,70 +60,151 @@ jobs: POSTGRES_DB: goloose POSTGRES_USER: goloose POSTGRES_PASSWORD: goloose - ports: [5432:5432] + ports: ['5432:5432'] options: >- --health-cmd="pg_isready -U goloose -d goloose" --health-interval=5s --health-timeout=3s --health-retries=10 + steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 with: - go-version-file: go.mod + go-version: ${{ env.GO_VERSION }} cache: true - - name: Run database-backed tests - env: - PGPASSWORD: goloose - GO_LOOSE_TEST_DATABASE_URL: postgres://goloose:goloose@localhost:5432/goloose_test?sslmode=disable - GO_LOOSE_TEST_SERVER_DATABASE_URL: postgres://goloose:goloose@localhost:5432/goloose_server_test?sslmode=disable - GO_LOOSE_BEHAVIOUR_DATABASE_URL: postgres://goloose:goloose@localhost:5432/goloose_behaviour_test?sslmode=disable + + - name: Download dependencies + run: go mod download + + - name: Create test databases run: | sleep 5 createdb -h localhost -U goloose goloose_test || true createdb -h localhost -U goloose goloose_server_test || true createdb -h localhost -U goloose goloose_behaviour_test || true + + - name: Run integration tests + env: + GO_LOOSE_TEST_DATABASE_URL: postgres://goloose:goloose@localhost:5432/goloose_test?sslmode=disable + GO_LOOSE_TEST_SERVER_DATABASE_URL: postgres://goloose:goloose@localhost:5432/goloose_server_test?sslmode=disable + GO_LOOSE_BEHAVIOUR_DATABASE_URL: postgres://goloose:goloose@localhost:5432/goloose_behaviour_test?sslmode=disable + run: | go test -race ./internal/store/ ./internal/server/ -count=1 GO_LOOSE_BEHAVIOUR=1 go test ./internal/behaviour/ -count=1 -v - publish: - if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') - needs: [build-test, integration-test] + docker: + name: Build and Push Docker Image runs-on: ubuntu-latest + needs: [build-and-test, integration-test] + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + permissions: + contents: read + packages: write + steps: - - uses: actions/checkout@v4 - - uses: docker/setup-buildx-action@v3 - - uses: docker/login-action@v3 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Nexus Registry + uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.NEXUS_USERNAME }} password: ${{ secrets.NEXUS_PASSWORD }} - - uses: docker/build-push-action@v6 + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha + + - name: Build and push Docker image + uses: docker/build-push-action@v5 with: context: . - file: Dockerfile push: true - tags: | - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + +# deploy-tst: +# name: Deploy to TST +# runs-on: ubuntu-latest +# needs: docker +# if: github.event_name == 'push' && github.ref == 'refs/heads/develop' +# permissions: +# contents: read +# id-token: write +# environment: tst +# +# steps: +# - name: Checkout repository +# uses: actions/checkout@v4 +# +# - name: Set up Helm +# uses: azure/setup-helm@v4 +# with: +# version: 'v3.14.0' +# +# - name: Set up kubectl +# uses: azure/k8s-set-context@v4 +# with: +# kubeconfig: ${{ secrets.KUBECONFIG_TST }} +# +# - name: Deploy to TST with Helm +# run: | +# helm upgrade --install go-loose ./deploy/helm/go-loose \ +# --namespace go-loose \ +# --create-namespace \ +# --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \ +# --set image.tag=${{ github.sha }} \ +# --set image.pullSecrets[0].name=nexus-registry \ +# --wait --timeout 5m deploy-prd: - if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') - needs: publish + name: Deploy to PRD runs-on: ubuntu-latest + needs: docker + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + permissions: + contents: read + id-token: write + environment: prd + steps: - - uses: actions/checkout@v4 - - uses: azure/setup-helm@v4 + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 with: - version: v3.18.6 - - uses: azure/setup-kubectl@v4 + version: 'v3.14.0' + + - name: Set up kubectl + uses: azure/k8s-set-context@v4 with: - version: v1.32.2 - - name: Bootstrap resources and deploy go-loose - env: - KUBECONFIG_PRD: ${{ secrets.KUBECONFIG_PRD }} - NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} - NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + kubeconfig: ${{ secrets.KUBECONFIG_PRD }} + + - name: Deploy to PRD with Helm run: | - set -Eeuo pipefail - bash .forgejo/scripts/deploy-prd.sh deploy/helm/go-loose go-loose go-loose "${{ github.sha }}" + helm upgrade --install go-loose ./deploy/helm/go-loose \ + --namespace go-loose \ + --create-namespace \ + --values ./deploy/helm/go-loose/values-prd.yaml \ + --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \ + --set image.tag=${{ github.ref_name }} \ + --wait --timeout 5m \ No newline at end of file diff --git a/deploy/helm/go-loose/Chart.lock b/deploy/helm/go-loose/Chart.lock deleted file mode 100644 index 10b4a65..0000000 --- a/deploy/helm/go-loose/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: - - name: postgresql - repository: https://charts.bitnami.com/bitnami - version: 16.7.27 -digest: sha256:e8b999a3aaad6328a13d0c666207650897b69c61367c947d363b2acbe0ea1b42 -generated: "2026-10-04T19:38:06.343578353+02:00" diff --git a/deploy/helm/go-loose/Chart.yaml b/deploy/helm/go-loose/Chart.yaml index 0c18efa..3f6e183 100644 --- a/deploy/helm/go-loose/Chart.yaml +++ b/deploy/helm/go-loose/Chart.yaml @@ -2,14 +2,9 @@ apiVersion: v2 name: go-loose description: Authentication and authorization service for urpi platform. Provides OIDC, session management, and tenant isolation. type: application -version: 1.1.0 +version: 1.0.0 appVersion: "1.0.0" kubeVersion: ">=1.28.0-0" -dependencies: - - name: postgresql - version: "16.x.x" - repository: "https://charts.bitnami.com/bitnami" - condition: postgresql.enabled keywords: - authentication - authorization @@ -25,4 +20,4 @@ maintainers: url: https://github.com/urpi annotations: category: Security - licenses: MIT + licenses: MIT \ No newline at end of file diff --git a/deploy/helm/go-loose/README.md b/deploy/helm/go-loose/README.md deleted file mode 100644 index cf1b2c6..0000000 --- a/deploy/helm/go-loose/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Go Loose Helm chart - -This is the canonical Go Loose chart. The central deploy script and the Go Loose -CI workflow both use this directory. - -## Environment profiles - -Use one profile file per environment: - -| Environment | Namespace | Profile | Ingress class | TLS issuer | -|---|---|---|---|---| -| `dev` | `go-insane-dev` | `values-dev.yaml` | nginx | `letsencrypt-staging` | -| `tst` | `go-insane-tst` | `values-tst.yaml` | nginx | `letsencrypt-staging` | -| `prd` | `go-insane-prd` | `values-prd.yaml` | nginx | `letsencrypt-prod` | -| `lcl` | `go-insane-lcl` | `values-lcl.yaml` | Traefik | local TLS | - -The namespace is supplied by Helm's release namespace; it is not hard-coded in -the chart templates. - -## Runtime Secret contract - -Before a release, the target namespace must contain `go-loose-runtime` with: - -| Key | Used for | -|---|---| -| `postgresql-password` | PostgreSQL application user's password | -| `postgres-password` | PostgreSQL administrator password | -| `database-url` | `GO_LOOSE_DATABASE_URL` | -| `session-secret` | `GO_LOOSE_SESSION_SECRET` | - -The chart reads these values using Kubernetes `secretKeyRef` and the PostgreSQL -subchart's `existingSecret` support. Runtime credentials are not stored in chart -values or Helm release configuration. - -To provision/update the secret from protected files without printing its values: - -```bash -/home/dnoulet/go/ops/scripts/apply-go-loose-secret.sh \ - \ - /secure/path/postgresql-password \ - /secure/path/database-url \ - /secure/path/session-secret \ - [kubeconfig] -``` - -The input files should contain only the required value (no trailing newline). -The helper creates the environment namespace if it is not present, then applies -the Secret. It does not print secret values. - -The PRD CI deployment script maintains the same secret contract automatically. -Do not commit the input files or put their contents in a Helm values file. - -## Tenant wildcard ingress - -Go Guess signs in through tenant-specific hosts such as -`nmbs.auth.dev-urpi.be` and `nmbs.auth.urpi.be`. The chart therefore -creates a second ingress for `*.auth-...` and requires a separate TLS Secret -named `go-loose-wildcard-tls` in the same namespace. The central deploy script -and PRD CI check for this Secret before installing the release. - -Provision it from a trusted wildcard certificate and private key: - -```bash -kubectl --kubeconfig --namespace go-insane- create secret tls \ - go-loose-wildcard-tls --cert=/secure/path/wildcard.crt \ - --key=/secure/path/wildcard.key -``` - -The PRD `letsencrypt-prod` issuer documented for the apex ingress uses HTTP-01; -HTTP-01 cannot issue wildcard certificates. Obtain this certificate through -DNS-01 or the approved certificate authority, then provision the Secret. Do not -put the private key in the chart, repository, or Helm release values. - -## Validation - -```bash -helm lint . -f values-dev.yaml -helm lint . -f values-tst.yaml -helm lint . -f values-prd.yaml -helm lint . -f values-lcl.yaml -``` diff --git a/deploy/helm/go-loose/templates/deployment.yaml b/deploy/helm/go-loose/templates/deployment.yaml index bd9fb28..cf51f60 100644 --- a/deploy/helm/go-loose/templates/deployment.yaml +++ b/deploy/helm/go-loose/templates/deployment.yaml @@ -40,20 +40,14 @@ spec: containerPort: {{ .Values.service.targetPort }} protocol: TCP env: - - name: GO_LOOSE_DATABASE_URL - valueFrom: - secretKeyRef: - name: {{ .Values.runtimeSecret.name }} - key: {{ .Values.runtimeSecret.keys.databaseURL }} - - name: GO_LOOSE_SESSION_SECRET - valueFrom: - secretKeyRef: - name: {{ .Values.runtimeSecret.name }} - key: {{ .Values.runtimeSecret.keys.sessionSecret }} {{- range $key, $value := .Values.env }} - name: {{ $key }} value: {{ $value | quote }} {{- end }} + {{- range $key, $value := .Values.envSecrets }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} livenessProbe: {{- toYaml .Values.livenessProbe | nindent 12 }} readinessProbe: @@ -71,4 +65,4 @@ spec: {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} - {{- end }} + {{- end }} \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/secret.yaml b/deploy/helm/go-loose/templates/secret.yaml new file mode 100644 index 0000000..5c0fab9 --- /dev/null +++ b/deploy/helm/go-loose/templates/secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "go-loose.fullname" . }}-env + namespace: {{ .Release.Namespace }} + labels: + {{- include "go-loose.labels" . | nindent 4 }} +type: Opaque +stringData: + {{- range $key, $value := .Values.envSecrets }} + {{ $key }}: {{ $value | quote }} + {{- end }} \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/wildcard-ingress.yaml b/deploy/helm/go-loose/templates/wildcard-ingress.yaml deleted file mode 100644 index b7fbfca..0000000 --- a/deploy/helm/go-loose/templates/wildcard-ingress.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- if .Values.wildcardIngress.enabled }} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ include "go-loose.fullname" . }}-wildcard - namespace: {{ .Release.Namespace }} - labels: - {{- include "go-loose.labels" . | nindent 4 }} - {{- with .Values.wildcardIngress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - ingressClassName: {{ .Values.wildcardIngress.className }} - tls: - - secretName: {{ .Values.wildcardIngress.tlsSecretName }} - hosts: - - {{ .Values.wildcardIngress.host | quote }} - rules: - - host: {{ .Values.wildcardIngress.host | quote }} - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: {{ include "go-loose.fullname" . }} - port: - number: {{ .Values.service.port }} -{{- end }} diff --git a/deploy/helm/go-loose/values-dev.yaml b/deploy/helm/go-loose/values-dev.yaml deleted file mode 100644 index 185b2f1..0000000 --- a/deploy/helm/go-loose/values-dev.yaml +++ /dev/null @@ -1,46 +0,0 @@ -replicaCount: 1 - -image: - repository: nexus.urpi.be/docker-hosted/go-loose - tag: latest - pullPolicy: Always - -imagePullSecrets: - - name: nexus-registry - -ingress: - enabled: true - className: nginx - annotations: - cert-manager.io/cluster-issuer: letsencrypt-staging - nginx.ingress.kubernetes.io/ssl-redirect: "true" - hosts: - - host: auth.dev-urpi.be - paths: - - path: / - pathType: Prefix - tls: - - secretName: go-loose-dev-tls - hosts: - - auth.dev-urpi.be - -wildcardIngress: - enabled: true - className: nginx - host: "*.auth.dev-urpi.be" - tlsSecretName: go-loose-wildcard-tls - annotations: - nginx.ingress.kubernetes.io/ssl-redirect: "true" - -postgresql: - primary: - persistence: - enabled: true - size: 5Gi - -env: - GO_LOOSE_BASE_URL: https://auth.dev-urpi.be - GO_LOOSE_AUTH_DOMAIN: auth.dev-urpi.be - GO_LOOSE_OIDC_REDIRECT_URL: https://auth.dev-urpi.be/auth/callback - GO_LOOSE_DEV_LOGIN: "true" - GO_LOOSE_LOCAL_LOGIN: "true" diff --git a/deploy/helm/go-loose/values-lcl.yaml b/deploy/helm/go-loose/values-lcl.yaml deleted file mode 100644 index d17bfcc..0000000 --- a/deploy/helm/go-loose/values-lcl.yaml +++ /dev/null @@ -1,65 +0,0 @@ -replicaCount: 1 -imagePullSecrets: [] - -ingress: - enabled: true - className: traefik - annotations: - cert-manager.io/cluster-issuer: urpi-private-ca - hosts: - # Apex only. The tenant hosts are served by wildcardIngress below, so that - # each host family keeps its own certificate: go-loose-lcl-tls covers the - # apex, go-loose-wildcard-tls covers *.auth.lcl-urpi.be. - - host: auth.lcl-urpi.be - paths: - - path: / - pathType: Prefix - tls: - - secretName: go-loose-lcl-tls - hosts: - - auth.lcl-urpi.be - -# Serves every .auth.lcl-urpi.be. Adding a tenant is then a row in the -# database only: no Helm upgrade, no new certificate, no per-host rule. -wildcardIngress: - enabled: true - className: traefik - host: "*.auth.lcl-urpi.be" - tlsSecretName: go-loose-wildcard-tls - annotations: - nginx.ingress.kubernetes.io/ssl-redirect: "true" - -certManager: - enabled: true - issuerRef: - name: urpi-private-ca - kind: ClusterIssuer - -postgresql: - enabled: true - image: - # Bitnami removed its versioned tags from Docker Hub; only :latest remains - # for bitnami/postgresql. The tag pinned in values.yaml (16.4.0) now 404s - # and leaves the StatefulSet in ImagePullBackOff. - tag: "latest" - auth: - database: goloose - username: goloose - password: "goloose" - existingSecret: go-loose-runtime - secretKeys: - adminPasswordKey: postgres-password - userPasswordKey: postgresql-password - primary: - persistence: - enabled: false - size: 5Gi - -env: - GO_LOOSE_ADDR: ":8080" - GO_LOOSE_BASE_URL: "https://lcl-urpi.be" - GO_LOOSE_AUTH_DOMAIN: "auth.lcl-urpi.be" - GO_LOOSE_OIDC_REDIRECT_URL: "https://lcl-urpi.be/auth/callback" - GO_LOOSE_DEV_LOGIN: "true" - GO_LOOSE_LOCAL_LOGIN: "true" - GO_LOOSE_ALLOW_PRIVATE_CONTRACT_URLS: "true" diff --git a/deploy/helm/go-loose/values-prd.yaml b/deploy/helm/go-loose/values-prd.yaml index 93f4dcb..4ed5fda 100644 --- a/deploy/helm/go-loose/values-prd.yaml +++ b/deploy/helm/go-loose/values-prd.yaml @@ -5,7 +5,7 @@ imagePullSecrets: - name: nexus-registry image: - repository: nexus.urpi.be/docker-hosted/go-loose + repository: nexus-registry.urpi.be/docker-hosted/go-loose tag: "0.0.1" pullPolicy: Always @@ -16,10 +16,9 @@ service: ingress: enabled: true - className: nginx + className: traefik annotations: cert-manager.io/cluster-issuer: letsencrypt-prod - nginx.ingress.kubernetes.io/ssl-redirect: "true" # nginx.ingress.kubernetes.io/ssl-redirect: "true" # nginx.ingress.kubernetes.io/proxy-body-size: "10m" hosts: @@ -32,14 +31,6 @@ ingress: hosts: - auth.urpi.be -wildcardIngress: - enabled: true - className: nginx - host: "*.auth.urpi.be" - tlsSecretName: go-loose-wildcard-tls - annotations: - nginx.ingress.kubernetes.io/ssl-redirect: "true" - certManager: enabled: true issuerRef: @@ -78,9 +69,13 @@ env: GO_LOOSE_AUTH_DOMAIN: "auth.urpi.be" GO_LOOSE_OIDC_REDIRECT_URL: "https://auth.urpi.be/auth/callback" GO_LOOSE_DEV_LOGIN: "false" - GO_LOOSE_LOCAL_LOGIN: "false" + GO_LOOSE_LOCAL_LOGIN: "true" GO_LOOSE_ALLOW_PRIVATE_CONTRACT_URLS: "true" +envSecrets: + GO_LOOSE_DATABASE_URL: "postgres://goloose:changeme@go-loose-postgresql:5432/goloose?sslmode=disable" + GO_LOOSE_SESSION_SECRET: "changeme-generate-secure-random" + livenessProbe: httpGet: path: /healthz @@ -97,4 +92,4 @@ readinessProbe: initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 3 - failureThreshold: 3 + failureThreshold: 3 \ No newline at end of file diff --git a/deploy/helm/go-loose/values-tst.yaml b/deploy/helm/go-loose/values-tst.yaml deleted file mode 100644 index d656f2e..0000000 --- a/deploy/helm/go-loose/values-tst.yaml +++ /dev/null @@ -1,46 +0,0 @@ -replicaCount: 1 - -image: - repository: nexus.urpi.be/docker-hosted/go-loose - tag: latest - pullPolicy: Always - -imagePullSecrets: - - name: nexus-registry - -ingress: - enabled: true - className: nginx - annotations: - cert-manager.io/cluster-issuer: letsencrypt-staging - nginx.ingress.kubernetes.io/ssl-redirect: "true" - hosts: - - host: auth.tst-urpi.be - paths: - - path: / - pathType: Prefix - tls: - - secretName: go-loose-tst-tls - hosts: - - auth.tst-urpi.be - -wildcardIngress: - enabled: true - className: nginx - host: "*.auth.tst-urpi.be" - tlsSecretName: go-loose-wildcard-tls - annotations: - nginx.ingress.kubernetes.io/ssl-redirect: "true" - -postgresql: - primary: - persistence: - enabled: true - size: 5Gi - -env: - GO_LOOSE_BASE_URL: https://auth.tst-urpi.be - GO_LOOSE_AUTH_DOMAIN: auth.tst-urpi.be - GO_LOOSE_OIDC_REDIRECT_URL: https://auth.tst-urpi.be/auth/callback - GO_LOOSE_DEV_LOGIN: "false" - GO_LOOSE_LOCAL_LOGIN: "false" diff --git a/deploy/helm/go-loose/values.yaml b/deploy/helm/go-loose/values.yaml index 2e2b0c1..5e49e67 100644 --- a/deploy/helm/go-loose/values.yaml +++ b/deploy/helm/go-loose/values.yaml @@ -54,13 +54,6 @@ ingress: hosts: - auth.urpi.be -wildcardIngress: - enabled: false - className: nginx - host: "*.auth.urpi.be" - tlsSecretName: go-loose-wildcard-tls - annotations: {} - certManager: enabled: true issuerRef: @@ -81,24 +74,12 @@ autoscaling: maxReplicas: 3 targetCPUUtilizationPercentage: 80 -runtimeSecret: - name: go-loose-runtime - keys: - databaseURL: database-url - sessionSecret: session-secret - postgresql: enabled: true - image: - tag: "16.4.0" auth: database: goloose username: goloose - password: "goloose" - existingSecret: go-loose-runtime - secretKeys: - adminPasswordKey: postgres-password - userPasswordKey: postgresql-password + password: changeme primary: persistence: enabled: true @@ -117,9 +98,13 @@ env: GO_LOOSE_AUTH_DOMAIN: "auth.urpi.be" GO_LOOSE_OIDC_REDIRECT_URL: "https://auth.urpi.be/auth/callback" GO_LOOSE_DEV_LOGIN: "false" - GO_LOOSE_LOCAL_LOGIN: "false" + GO_LOOSE_LOCAL_LOGIN: "true" GO_LOOSE_ALLOW_PRIVATE_CONTRACT_URLS: "true" +envSecrets: + GO_LOOSE_DATABASE_URL: "" + GO_LOOSE_SESSION_SECRET: "" + livenessProbe: httpGet: path: /healthz @@ -140,4 +125,4 @@ readinessProbe: nodeSelector: {} tolerations: [] -affinity: {} +affinity: {} \ No newline at end of file diff --git a/docs/commands b/docs/commands deleted file mode 100644 index da94146..0000000 --- a/docs/commands +++ /dev/null @@ -1,18 +0,0 @@ -# Delete the incomplete secret -kubectl delete secret go-loose-runtime --kubeconfig=/home/dnoulet/.kube/config_lcl --insecure-skip-tls-verify -n go-insane-lcl --ignore-not-found - -# Recreate it with all required properties mapped correctly -kubectl create secret generic go-loose-runtime \ - --from-literal=postgres-password="goloose" \ - --from-literal=postgresql-password="goloose" \ - --from-literal=session-secret="localdevsecret123" \ - --from-literal=database-url="postgres://goloose:goloose@go-loose-postgresql:5432/goloose?sslmode=disable" \ - --kubeconfig=/home/dnoulet/.kube/config_lcl \ - --insecure-skip-tls-verify \ - -n go-insane-lcl - -KUBECONFIG=~/.kube/config_lcl kubectl config set-cluster local --insecure-skip-tls-verify=true - -openssl s_client -showcerts -connect rancher.intern-urpi.be:443 /dev/null | sed -n '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.kube/rancher-ca.crt -KUBECONFIG=~/.kube/config_lcl kubectl config set-cluster local --certificate-authority=/home/dnoulet/.kube/rancher-ca.crt -KUBECONFIG=~/.kube/config_lcl kubectl config set-cluster local --insecure-skip-tls-verify=false