From 0f5d582d1f17f3f8b3a6fc9e2215d4f440615bed Mon Sep 17 00:00:00 2001 From: Daniel Noulet Date: Wed, 7 Oct 2026 15:07:22 +0200 Subject: [PATCH] chore: helm configuration --- deploy/helm/go-loose/Chart.yaml | 23 ++++ deploy/helm/go-loose/templates/NOTES.txt | 19 +++ deploy/helm/go-loose/templates/_helpers.tpl | 60 ++++++++ .../helm/go-loose/templates/deployment.yaml | 68 ++++++++++ deploy/helm/go-loose/templates/hpa.yaml | 23 ++++ deploy/helm/go-loose/templates/ingress.yaml | 36 +++++ deploy/helm/go-loose/templates/secret.yaml | 12 ++ deploy/helm/go-loose/templates/service.yaml | 16 +++ .../go-loose/templates/serviceaccount.yaml | 13 ++ deploy/helm/go-loose/values-prd.yaml | 95 +++++++++++++ deploy/helm/go-loose/values.yaml | 128 ++++++++++++++++++ docker-compose.tst.yaml | 65 +++++++++ 12 files changed, 558 insertions(+) create mode 100644 deploy/helm/go-loose/Chart.yaml create mode 100644 deploy/helm/go-loose/templates/NOTES.txt create mode 100644 deploy/helm/go-loose/templates/_helpers.tpl create mode 100644 deploy/helm/go-loose/templates/deployment.yaml create mode 100644 deploy/helm/go-loose/templates/hpa.yaml create mode 100644 deploy/helm/go-loose/templates/ingress.yaml create mode 100644 deploy/helm/go-loose/templates/secret.yaml create mode 100644 deploy/helm/go-loose/templates/service.yaml create mode 100644 deploy/helm/go-loose/templates/serviceaccount.yaml create mode 100644 deploy/helm/go-loose/values-prd.yaml create mode 100644 deploy/helm/go-loose/values.yaml create mode 100644 docker-compose.tst.yaml diff --git a/deploy/helm/go-loose/Chart.yaml b/deploy/helm/go-loose/Chart.yaml new file mode 100644 index 0000000..3f6e183 --- /dev/null +++ b/deploy/helm/go-loose/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +name: go-loose +description: Authentication and authorization service for urpi platform. Provides OIDC, session management, and tenant isolation. +type: application +version: 1.0.0 +appVersion: "1.0.0" +kubeVersion: ">=1.28.0-0" +keywords: + - authentication + - authorization + - oidc + - identity + - sso +icon: https://raw.githubusercontent.com/urpi/go-loose/main/docs/assets/logo.svg +home: https://github.com/urpi/go-loose +sources: + - https://github.com/urpi/go-loose +maintainers: + - name: urpi platform team + url: https://github.com/urpi +annotations: + category: Security + licenses: MIT \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/NOTES.txt b/deploy/helm/go-loose/templates/NOTES.txt new file mode 100644 index 0000000..bc94cbb --- /dev/null +++ b/deploy/helm/go-loose/templates/NOTES.txt @@ -0,0 +1,19 @@ +go-loose has been deployed to namespace {{ .Release.Namespace }}. + +Access the service: + https://auth.urpi.be + +Health check: + curl https://auth.urpi.be/healthz + +PostgreSQL is deployed as a sub-chart. Credentials are in: + kubectl get secret {{ include "go-loose.fullname" . }}-postgresql -n {{ .Release.Namespace }} -o jsonpath='{.data.postgres-password}' | base64 -d + +Environment variables are stored in secret: + kubectl get secret {{ include "go-loose.fullname" . }}-env -n {{ .Release.Namespace }} -o yaml + +To update secrets (SESSION_SECRET, DATABASE_URL): + kubectl patch secret {{ include "go-loose.fullname" . }}-env -n {{ .Release.Namespace }} -p '{"stringData":{"GO_LOOSE_SESSION_SECRET":"new-secret"}}' + kubectl rollout restart deployment {{ include "go-loose.fullname" . }} -n {{ .Release.Namespace }} + +Default admin user is created on first startup via GO_LOOSE_LOCAL_LOGIN=true. \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/_helpers.tpl b/deploy/helm/go-loose/templates/_helpers.tpl new file mode 100644 index 0000000..3f5e6b7 --- /dev/null +++ b/deploy/helm/go-loose/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "go-loose.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "go-loose.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "go-loose.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "go-loose.labels" -}} +helm.sh/chart: {{ include "go-loose.chart" . }} +{{ include "go-loose.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "go-loose.selectorLabels" -}} +app.kubernetes.io/name: {{ include "go-loose.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "go-loose.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "go-loose.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/deployment.yaml b/deploy/helm/go-loose/templates/deployment.yaml new file mode 100644 index 0000000..cf51f60 --- /dev/null +++ b/deploy/helm/go-loose/templates/deployment.yaml @@ -0,0 +1,68 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "go-loose.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "go-loose.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "go-loose.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "go-loose.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "go-loose.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.targetPort }} + protocol: TCP + env: + {{- 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: + {{- toYaml .Values.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/hpa.yaml b/deploy/helm/go-loose/templates/hpa.yaml new file mode 100644 index 0000000..ab86f6f --- /dev/null +++ b/deploy/helm/go-loose/templates/hpa.yaml @@ -0,0 +1,23 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "go-loose.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "go-loose.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "go-loose.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} +{{- end }} \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/ingress.yaml b/deploy/helm/go-loose/templates/ingress.yaml new file mode 100644 index 0000000..95e1b28 --- /dev/null +++ b/deploy/helm/go-loose/templates/ingress.yaml @@ -0,0 +1,36 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "go-loose.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "go-loose.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.ingress.className }} + ingressClassName: {{ . }} + {{- end }} + {{- with .Values.ingress.tls }} + tls: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType | default "Prefix" }} + backend: + service: + name: {{ include "go-loose.fullname" $ }} + port: + number: {{ $.Values.service.port }} + {{- end }} + {{- 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/service.yaml b/deploy/helm/go-loose/templates/service.yaml new file mode 100644 index 0000000..eee9358 --- /dev/null +++ b/deploy/helm/go-loose/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "go-loose.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "go-loose.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: {{ .Values.service.targetPort }} + protocol: TCP + name: http + selector: + {{- include "go-loose.selectorLabels" . | nindent 4 }} \ No newline at end of file diff --git a/deploy/helm/go-loose/templates/serviceaccount.yaml b/deploy/helm/go-loose/templates/serviceaccount.yaml new file mode 100644 index 0000000..6848881 --- /dev/null +++ b/deploy/helm/go-loose/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "go-loose.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "go-loose.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/deploy/helm/go-loose/values-prd.yaml b/deploy/helm/go-loose/values-prd.yaml new file mode 100644 index 0000000..4ed5fda --- /dev/null +++ b/deploy/helm/go-loose/values-prd.yaml @@ -0,0 +1,95 @@ +# PRD values for go-loose +replicaCount: 1 + +imagePullSecrets: + - name: nexus-registry + +image: + repository: nexus-registry.urpi.be/docker-hosted/go-loose + tag: "0.0.1" + pullPolicy: Always + +service: + type: ClusterIP + port: 8080 + targetPort: 8080 + +ingress: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod +# nginx.ingress.kubernetes.io/ssl-redirect: "true" +# nginx.ingress.kubernetes.io/proxy-body-size: "10m" + hosts: + - host: auth.urpi.be + paths: + - path: / + pathType: Prefix + tls: + - secretName: go-loose-tls + hosts: + - auth.urpi.be + +certManager: + enabled: true + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + +postgresql: + enabled: true + auth: + database: goloose + username: goloose + password: "" + primary: + persistence: + enabled: true + size: 10Gi + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 250m + memory: 512Mi + +resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 250m + memory: 512Mi + +env: + GO_LOOSE_ADDR: ":8080" + GO_LOOSE_BASE_URL: "https://auth.urpi.be" + 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: "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 + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 5 + +readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 \ No newline at end of file diff --git a/deploy/helm/go-loose/values.yaml b/deploy/helm/go-loose/values.yaml new file mode 100644 index 0000000..5e49e67 --- /dev/null +++ b/deploy/helm/go-loose/values.yaml @@ -0,0 +1,128 @@ +replicaCount: 1 + +imagePullSecrets: + - name: nexus-registry + +image: + repository: nexus.urpi.be/docker-hosted/go-loose + tag: "0.0.1" + pullPolicy: Always + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + create: true + annotations: {} + name: "" + +podAnnotations: {} +podLabels: {} + +podSecurityContext: + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + fsGroup: 65532 + +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + +service: + type: ClusterIP + port: 8080 + targetPort: 8080 + +ingress: + enabled: true + className: nginx + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "10m" + hosts: + - host: auth.urpi.be + paths: + - path: / + pathType: Prefix + tls: + - secretName: go-loose-tls + hosts: + - auth.urpi.be + +certManager: + enabled: true + issuerRef: + name: letsencrypt-prod + kind: ClusterIssuer + +resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + +postgresql: + enabled: true + auth: + database: goloose + username: goloose + password: changeme + primary: + persistence: + enabled: true + size: 5Gi + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + +env: + GO_LOOSE_ADDR: ":8080" + GO_LOOSE_BASE_URL: "https://auth.urpi.be" + 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: "true" + GO_LOOSE_ALLOW_PRIVATE_CONTRACT_URLS: "true" + +envSecrets: + GO_LOOSE_DATABASE_URL: "" + GO_LOOSE_SESSION_SECRET: "" + +livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 5 + +readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 3 + failureThreshold: 3 + +nodeSelector: {} +tolerations: [] +affinity: {} \ No newline at end of file diff --git a/docker-compose.tst.yaml b/docker-compose.tst.yaml new file mode 100644 index 0000000..c05d46d --- /dev/null +++ b/docker-compose.tst.yaml @@ -0,0 +1,65 @@ +# TST stack: docker compose -f docker-compose.tst up --build +# +# Go Loose for testing environment. Similar to dev but pointed at tst services. +# +services: + postgres: + image: postgres:17-alpine + ports: + - "${GO_LOOSE_POSTGRES_PORT:-5433}:5432" + environment: + POSTGRES_DB: goloose + POSTGRES_USER: goloose + POSTGRES_PASSWORD: goloose + volumes: + - db-data-tst:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U goloose -d goloose"] + interval: 5s + timeout: 3s + retries: 10 + networks: + - go_loose_tst_network + + go-loose: + build: + context: . + dockerfile: Dockerfile + depends_on: + postgres: + condition: service_healthy + environment: + GO_LOOSE_ADDR: ":8080" + GO_LOOSE_BASE_URL: "${GO_LOOSE_BASE_URL:-http://tst-intern-urpi.be:8080}" + GO_LOOSE_AUTH_DOMAIN: "${GO_LOOSE_AUTH_DOMAIN:-auth-tst.intern-urpi.be}" + GO_LOOSE_DATABASE_URL: "postgres://goloose:goloose@postgres:5432/goloose?sslmode=disable" + GO_LOOSE_SESSION_SECRET: "${GO_LOOSE_SESSION_SECRET:-tst-session-secret-change-me}" + GO_LOOSE_DEV_LOGIN: "false" + GO_LOOSE_LOCAL_LOGIN: "false" + GO_LOOSE_LOCAL_ADMIN_EMAIL: "admin@tst.goloose.local" + GO_LOOSE_LOCAL_ADMIN_PASSWORD: "${GO_LOOSE_LOCAL_ADMIN_PASSWORD:-}" + GO_LOOSE_ALLOWED_EMAIL_DOMAINS: "" + GO_LOOSE_ALLOW_PRIVATE_CONTRACT_URLS: "true" + GO_LOOSE_BOOTSTRAP_TENANT: "nmbs" + GO_LOOSE_BOOTSTRAP_APP: "guess" + GO_LOOSE_OIDC_ISSUER: "https://accounts.google.com" + GO_LOOSE_OIDC_CLIENT_ID: "554628171917-forvpfs44pqajv77dfhl503prfqnhor3.apps.googleusercontent.com" + GO_LOOSE_OIDC_CLIENT_SECRET: "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" + GO_LOOSE_OIDC_REDIRECT_URL: "https://auth-tst.intern-urpi.be/auth/callback" + ports: + - "${GO_LOOSE_TST_PORT:-8080}:8080" + healthcheck: + test: ["CMD", "/src/dist/go-loose", "-healthcheck"] + interval: 10s + timeout: 3s + retries: 5 + start_period: 20s + init: true + networks: + - go_loose_tst_network + +networks: + go_loose_tst_network: + +volumes: + db-data-tst: \ No newline at end of file