From 272a46fbb9e115cf9da8615d9eb2ce76bdff48c1 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 21 Apr 2026 23:51:26 +0300 Subject: [PATCH] feat(lifecycle-keycloak): refactor secrets generation for GitOps/ArgoCD compatibility --- README.md | 2 +- charts/lifecycle-keycloak/Chart.yaml | 2 +- charts/lifecycle-keycloak/README.md | 4 +-- .../lifecycle-keycloak/templates/_helpers.tpl | 30 +++++++++++++++++++ .../templates/bootstrap-admin-secret.yaml | 27 +++++------------ .../templates/github-idp-secret.yaml | 27 +++++------------ .../templates/keycloak-idp-secrets.yaml | 12 +++++--- .../templates/keycloak-instance.yaml | 28 +++++++++-------- .../templates/lifecycle-ui-secret.yaml | 24 +++++---------- .../templates/postgres-secret.yaml | 30 ++++++------------- 10 files changed, 89 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 0326f0e..c0a1932 100644 --- a/README.md +++ b/README.md @@ -8,5 +8,5 @@ A collection of Helm charts primarily used for **Lifecycle** application deploym | :--- | :--- | :--- | :--- | | [keycloak-operator](./charts/keycloak-operator) | `0.1.0` | `26.4.7` | Helm chart for Keycloak operator based on the [official manifests](https://www.keycloak.org/operator/installation#_installing_by_using_kubectl_without_operator_lifecycle_manager) | | [lifecycle](./charts/lifecycle) | `0.9.3` | `0.1.14` | A Helm umbrella chart for full Lifecycle stack | -| [lifecycle-keycloak](./charts/lifecycle-keycloak) | `0.7.1` | `0.0.0` | Keycloak instance for Lifecycle stack with automated Operator-driven setup and imports | +| [lifecycle-keycloak](./charts/lifecycle-keycloak) | `0.8.0` | `0.0.0` | Keycloak instance for Lifecycle stack with automated Operator-driven setup and imports | | [lifecycle-ui](./charts/lifecycle-ui) | `0.3.1` | `0.1.3` | A Helm chart for Lifecycle UI (Next.js) | diff --git a/charts/lifecycle-keycloak/Chart.yaml b/charts/lifecycle-keycloak/Chart.yaml index 2505809..631a025 100644 --- a/charts/lifecycle-keycloak/Chart.yaml +++ b/charts/lifecycle-keycloak/Chart.yaml @@ -16,7 +16,7 @@ apiVersion: v2 name: lifecycle-keycloak description: Keycloak instance for Lifecycle stack with automated Operator-driven setup and imports type: application -version: 0.7.1 +version: 0.8.0 appVersion: 0.0.0 home: https://goodrxoss.github.io/helm-charts/charts/lifecycle-keycloak/ diff --git a/charts/lifecycle-keycloak/README.md b/charts/lifecycle-keycloak/README.md index 26b44b0..0d6072b 100644 --- a/charts/lifecycle-keycloak/README.md +++ b/charts/lifecycle-keycloak/README.md @@ -1,6 +1,6 @@ # lifecycle-keycloak -![Version: 0.7.1](https://img.shields.io/badge/Version-0.7.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.0.0](https://img.shields.io/badge/AppVersion-0.0.0-informational?style=flat-square) +![Version: 0.8.0](https://img.shields.io/badge/Version-0.8.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.0.0](https://img.shields.io/badge/AppVersion-0.0.0-informational?style=flat-square) Keycloak instance for Lifecycle stack with automated Operator-driven setup and imports @@ -128,7 +128,7 @@ This chart uses the `KeycloakRealmImport` resource for the initial setup. ```shell helm upgrade -i lifecycle-keycloak \ oci://ghcr.io/goodrxoss/helm-charts/lifecycle-keycloak \ - --version 0.7.1 \ + --version 0.8.0 \ -f values.yaml \ -n lifecycle-keycloak \ --create-namespace diff --git a/charts/lifecycle-keycloak/templates/_helpers.tpl b/charts/lifecycle-keycloak/templates/_helpers.tpl index 00f43a8..f053737 100644 --- a/charts/lifecycle-keycloak/templates/_helpers.tpl +++ b/charts/lifecycle-keycloak/templates/_helpers.tpl @@ -123,3 +123,33 @@ Namespace Hostname {{- printf "%s-%s" .Release.Name .Values.parentChartName -}} {{- end -}} {{- end -}} + +{{/* +Get a value from a secret if it exists, otherwise generate/use a default value +Usage: {{ include "lifecycle-keycloak.getValueFromSecret" (list "secret-name" "key-name" "provided-value" "generated-value" .Release.Namespace) }} +*/}} +{{- define "lifecycle-keycloak.getValueFromSecret" -}} +{{- $secretName := index . 0 -}} +{{- $keyName := index . 1 -}} +{{- $providedValue := index . 2 -}} +{{- $generatedValue := index . 3 -}} +{{- $namespace := index . 4 -}} +{{- if $providedValue -}} + {{- $providedValue | b64enc -}} +{{- else -}} + {{- $obj := (lookup "v1" "Secret" $namespace $secretName) -}} + {{- if $obj -}} + {{- if index $obj "data" -}} + {{- if hasKey (index $obj "data") $keyName -}} + {{- index (index $obj "data") $keyName -}} + {{- else -}} + {{- $generatedValue | b64enc -}} + {{- end -}} + {{- else -}} + {{- $generatedValue | b64enc -}} + {{- end -}} + {{- else -}} + {{- $generatedValue | b64enc -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/charts/lifecycle-keycloak/templates/bootstrap-admin-secret.yaml b/charts/lifecycle-keycloak/templates/bootstrap-admin-secret.yaml index f347a13..c1ec419 100644 --- a/charts/lifecycle-keycloak/templates/bootstrap-admin-secret.yaml +++ b/charts/lifecycle-keycloak/templates/bootstrap-admin-secret.yaml @@ -14,33 +14,22 @@ See the License for the specific language governing permissions and limitations under the License. */}} +{{- if .Values.secrets.bootstrapAdmin.enabled }} {{- $namespace := .Release.Namespace -}} -{{- $secretName := printf "%s" (include "lifecycle-keycloak.bootstrapAdminSecretName" .) -}} -{{- $apiVersion := "v1" -}} -{{- $component := "keycloak" -}} - -{{- if and .Values.secrets.bootstrapAdmin.enabled .Release.IsInstall (not (lookup $apiVersion "Secret" $namespace $secretName)) }} -{{- with .Values.secrets.bootstrapAdmin -}} -apiVersion: {{ $apiVersion }} +{{- $secretName := include "lifecycle-keycloak.bootstrapAdminSecretName" . -}} +apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} namespace: {{ $namespace }} labels: - {{- include "lifecycle-keycloak.labels" (merge (dict "component" $component) $) | nindent 4 }} + {{- include "lifecycle-keycloak.labels" (merge (dict "component" "keycloak") $) | nindent 4 }} + {{- with .Values.secrets.bootstrapAdmin.annotations }} annotations: - "helm.sh/hook": pre-install - "helm.sh/hook-weight": "0" - "helm.sh/resource-policy": keep - {{- with .annotations }} {{- toYaml . | nindent 4 }} {{- end }} type: Opaque -stringData: - username: {{ .username | default "temp-admin" | quote }} data: - {{- with . }} - password: {{ .password | default (randAlphaNum 40) | b64enc | quote }} - {{- end }} -{{- end -}} -{{- end -}} + username: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "username" .Values.secrets.bootstrapAdmin.username "temp-admin" $namespace) | quote }} + password: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "password" .Values.secrets.bootstrapAdmin.password (randAlphaNum 40) $namespace) | quote }} +{{- end }} diff --git a/charts/lifecycle-keycloak/templates/github-idp-secret.yaml b/charts/lifecycle-keycloak/templates/github-idp-secret.yaml index d60ba87..e055201 100644 --- a/charts/lifecycle-keycloak/templates/github-idp-secret.yaml +++ b/charts/lifecycle-keycloak/templates/github-idp-secret.yaml @@ -14,33 +14,22 @@ See the License for the specific language governing permissions and limitations under the License. */}} +{{- if .Values.secrets.githubIdp.enabled }} {{- $namespace := .Release.Namespace -}} -{{- $secretName := printf "%s" (include "lifecycle-keycloak.githubIdpSecretName" .) -}} -{{- $apiVersion := "v1" -}} -{{- $component := "keycloak" -}} - -{{- if and .Values.secrets.githubIdp.enabled .Release.IsInstall (not (lookup $apiVersion "Secret" $namespace $secretName)) }} -{{- with .Values.secrets.githubIdp -}} -apiVersion: {{ $apiVersion }} +{{- $secretName := include "lifecycle-keycloak.githubIdpSecretName" . -}} +apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} namespace: {{ $namespace }} labels: - {{- include "lifecycle-keycloak.labels" (merge (dict "component" $component) $) | nindent 4 }} + {{- include "lifecycle-keycloak.labels" (merge (dict "component" "keycloak") $) | nindent 4 }} + {{- with .Values.secrets.githubIdp.annotations }} annotations: - "helm.sh/hook": pre-install - "helm.sh/hook-weight": "0" - "helm.sh/resource-policy": keep - {{- with .annotations }} {{- toYaml . | nindent 4 }} {{- end }} type: Opaque -stringData: - clientId: {{ required "GitHub secrets.githubIdp.clientId is required for initial install if secrets.githubIdp.enabled == true!" .clientId | quote }} data: - {{- with . }} - clientSecret: {{ required "GitHub secrets.githubIdp.clientSecret is required for initial install if secrets.githubIdp.enabled == true!" .clientSecret | b64enc | quote }} - {{- end }} -{{- end -}} -{{- end -}} + clientId: {{ required "GitHub secrets.githubIdp.clientId is required if secrets.githubIdp.enabled == true!" (include "lifecycle-keycloak.getValueFromSecret" (list $secretName "clientId" .Values.secrets.githubIdp.clientId "" $namespace)) | quote }} + clientSecret: {{ required "GitHub secrets.githubIdp.clientSecret is required if secrets.githubIdp.enabled == true!" (include "lifecycle-keycloak.getValueFromSecret" (list $secretName "clientSecret" .Values.secrets.githubIdp.clientSecret "" $namespace)) | quote }} +{{- end }} diff --git a/charts/lifecycle-keycloak/templates/keycloak-idp-secrets.yaml b/charts/lifecycle-keycloak/templates/keycloak-idp-secrets.yaml index eca1799..5961ac2 100644 --- a/charts/lifecycle-keycloak/templates/keycloak-idp-secrets.yaml +++ b/charts/lifecycle-keycloak/templates/keycloak-idp-secrets.yaml @@ -15,11 +15,15 @@ limitations under the License. */}} --- +{{ $namespace := .Release.Namespace -}} +{{ $secretName := printf "%s-idp-secrets" (include "lifecycle-keycloak.fullname" .) -}} apiVersion: v1 kind: Secret metadata: - name: {{ include "lifecycle-keycloak.fullname" . }}-idp-secrets - namespace: {{ .Release.Namespace }} + name: {{ $secretName }} + namespace: {{ $namespace }} + labels: + {{- include "lifecycle-keycloak.labels" (merge (dict "component" "keycloak") $) | nindent 4 }} data: - company_idp_client_id: "{{ print "company-idp-" (randNumeric 10) | b64enc }}" - company_idp_client_secret: "{{ randAlphaNum 40 | b64enc }}" + company_idp_client_id: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "company_idp_client_id" "" (print "company-idp-" (randNumeric 10)) $namespace) | quote }} + company_idp_client_secret: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "company_idp_client_secret" "" (randAlphaNum 40) $namespace) | quote }} diff --git a/charts/lifecycle-keycloak/templates/keycloak-instance.yaml b/charts/lifecycle-keycloak/templates/keycloak-instance.yaml index 2be3d92..f1adda8 100644 --- a/charts/lifecycle-keycloak/templates/keycloak-instance.yaml +++ b/charts/lifecycle-keycloak/templates/keycloak-instance.yaml @@ -1,16 +1,18 @@ -# Copyright 2026 GoodRx, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +{{- /* +Copyright 2026 GoodRx, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak diff --git a/charts/lifecycle-keycloak/templates/lifecycle-ui-secret.yaml b/charts/lifecycle-keycloak/templates/lifecycle-ui-secret.yaml index b332e14..e0d8e9d 100644 --- a/charts/lifecycle-keycloak/templates/lifecycle-ui-secret.yaml +++ b/charts/lifecycle-keycloak/templates/lifecycle-ui-secret.yaml @@ -14,31 +14,21 @@ See the License for the specific language governing permissions and limitations under the License. */}} +{{- if .Values.secrets.lifecycleUi.enabled }} {{- $namespace := .Release.Namespace -}} -{{- $secretName := printf "%s" (include "lifecycle-keycloak.lifecycleUiSecretName" .) -}} -{{- $apiVersion := "v1" -}} -{{- $component := "keycloak" -}} - -{{- if and .Values.secrets.lifecycleUi.enabled .Release.IsInstall (not (lookup $apiVersion "Secret" $namespace $secretName)) }} -{{- with .Values.secrets.lifecycleUi -}} -apiVersion: {{ $apiVersion }} +{{- $secretName := include "lifecycle-keycloak.lifecycleUiSecretName" . -}} +apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} namespace: {{ $namespace }} labels: - {{- include "lifecycle-keycloak.labels" (merge (dict "component" $component) $) | nindent 4 }} + {{- include "lifecycle-keycloak.labels" (merge (dict "component" "keycloak") $) | nindent 4 }} + {{- with .Values.secrets.lifecycleUi.annotations }} annotations: - "helm.sh/hook": pre-install - "helm.sh/hook-weight": "0" - "helm.sh/resource-policy": keep - {{- with .annotations }} {{- toYaml . | nindent 4 }} {{- end }} type: Opaque data: - {{- with . }} - clientSecret: {{ .clientSecret | default (randAlphaNum 40) | b64enc | quote }} - {{- end }} -{{- end -}} -{{- end -}} + clientSecret: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "clientSecret" .Values.secrets.lifecycleUi.clientSecret (randAlphaNum 40) $namespace) | quote }} +{{- end }} diff --git a/charts/lifecycle-keycloak/templates/postgres-secret.yaml b/charts/lifecycle-keycloak/templates/postgres-secret.yaml index 593fb7d..0241144 100644 --- a/charts/lifecycle-keycloak/templates/postgres-secret.yaml +++ b/charts/lifecycle-keycloak/templates/postgres-secret.yaml @@ -14,40 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. */}} +{{- if .Values.secrets.postgres.enabled }} {{- $namespace := .Release.Namespace -}} {{- $secretName := "" -}} -{{- $apiVersion := "v1" -}} -{{- $component := "postgres" -}} - {{- if .Values.secrets.postgres.fullnameOverride -}} {{- $secretName = .Values.secrets.postgres.fullnameOverride -}} {{- else -}} - {{- $secretName = printf "%s" (include "lifecycle-keycloak.postgresSecretName" .) -}} + {{- $secretName = include "lifecycle-keycloak.postgresSecretName" . -}} {{- end -}} - -{{- if and .Values.secrets.postgres.enabled .Release.IsInstall (not (lookup $apiVersion "Secret" $namespace $secretName)) }} -{{- with .Values.secrets.postgres -}} -apiVersion: {{ $apiVersion }} +apiVersion: v1 kind: Secret metadata: name: {{ $secretName }} namespace: {{ $namespace }} labels: - {{- include "lifecycle-keycloak.labels" (merge (dict "component" $component) $) | nindent 4 }} + {{- include "lifecycle-keycloak.labels" (merge (dict "component" "postgres") $) | nindent 4 }} + {{- with .Values.secrets.postgres.annotations }} annotations: - "helm.sh/hook": pre-install - "helm.sh/hook-weight": "0" - "helm.sh/resource-policy": keep - {{- with .annotations }} {{- toYaml . | nindent 4 }} {{- end }} type: Opaque -stringData: - POSTGRES_USERNAME: {{ $.Values.keycloakPostgres.auth.username | quote }} data: - {{- with . }} - POSTGRES_ADMIN_PASSWORD: {{ .adminPassword | default (randAlphaNum 40) | b64enc | quote }} - POSTGRES_USER_PASSWORD: {{ .userPassword | default (randAlphaNum 40) | b64enc | quote }} - {{- end }} -{{- end -}} -{{- end -}} + POSTGRES_USERNAME: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "POSTGRES_USERNAME" .Values.keycloakPostgres.auth.username "keycloak" $namespace) | quote }} + POSTGRES_ADMIN_PASSWORD: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "POSTGRES_ADMIN_PASSWORD" .Values.secrets.postgres.adminPassword (randAlphaNum 40) $namespace) | quote }} + POSTGRES_USER_PASSWORD: {{ include "lifecycle-keycloak.getValueFromSecret" (list $secretName "POSTGRES_USER_PASSWORD" .Values.secrets.postgres.userPassword (randAlphaNum 40) $namespace) | quote }} +{{- end }}