Skip to content

Commit 64360bb

Browse files
committed
feat: add rh-keycloak wrapper chart with PostSync cleanup
Add a wrapper chart (charts/rh-keycloak) that consumes the rhbk chart as a dependency and adds a PostSync cleanup job for one-shot ExternalSecret provisioning. The PostSync job: 1. Waits for labeled ExternalSecrets to sync 2. Deletes them with --cascade=orphan (Secrets survive) 3. Cleans up ephemeral Secrets labeled for deletion (keycloak-users) Switch values-hub.yaml from the remote rhbk chart to the local rh-keycloak wrapper chart path. Requires rhbk-chart >= 0.0.9 with externalSecrets.oneShot support. Commented-out overrides updated with rhbk. prefix to match the wrapper chart structure. Signed-off-by: Min Zhang <minzhang@redhat.com>
1 parent 8600d62 commit 64360bb

4 files changed

Lines changed: 131 additions & 5 deletions

File tree

charts/rh-keycloak/Chart.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: v2
2+
name: rh-keycloak
3+
description: ZTVP Keycloak deployment — wraps the rhbk chart and adds PostSync cleanup for one-shot ExternalSecrets
4+
type: application
5+
version: 0.1.0
6+
dependencies:
7+
- name: rhbk
8+
version: ">=0.0.9"
9+
repository: "oci://quay.io/validatedpatterns"
10+
maintainers:
11+
- name: Zero Trust Validated Patterns Team
12+
email: ztvp-arch-group@redhat.com
13+
keywords:
14+
- keycloak
15+
- rhbk
16+
- zero-trust
17+
- pattern
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
{{- if .Values.cleanup.enabled }}
2+
---
3+
apiVersion: v1
4+
kind: ServiceAccount
5+
metadata:
6+
name: cleanup-ephemeral-secrets
7+
namespace: {{ .Release.Namespace }}
8+
annotations:
9+
argocd.argoproj.io/hook: PostSync
10+
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
11+
---
12+
apiVersion: rbac.authorization.k8s.io/v1
13+
kind: Role
14+
metadata:
15+
name: cleanup-ephemeral-secrets
16+
namespace: {{ .Release.Namespace }}
17+
annotations:
18+
argocd.argoproj.io/hook: PostSync
19+
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
20+
rules:
21+
- apiGroups: ["external-secrets.io"]
22+
resources: ["externalsecrets"]
23+
verbs: ["get", "list", "delete"]
24+
- apiGroups: [""]
25+
resources: ["secrets"]
26+
verbs: ["get", "list", "delete"]
27+
---
28+
apiVersion: rbac.authorization.k8s.io/v1
29+
kind: RoleBinding
30+
metadata:
31+
name: cleanup-ephemeral-secrets
32+
namespace: {{ .Release.Namespace }}
33+
annotations:
34+
argocd.argoproj.io/hook: PostSync
35+
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
36+
roleRef:
37+
apiGroup: rbac.authorization.k8s.io
38+
kind: Role
39+
name: cleanup-ephemeral-secrets
40+
subjects:
41+
- kind: ServiceAccount
42+
name: cleanup-ephemeral-secrets
43+
namespace: {{ .Release.Namespace }}
44+
---
45+
apiVersion: batch/v1
46+
kind: Job
47+
metadata:
48+
name: cleanup-ephemeral-secrets
49+
namespace: {{ .Release.Namespace }}
50+
annotations:
51+
argocd.argoproj.io/hook: PostSync
52+
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
53+
spec:
54+
backoffLimit: 2
55+
activeDeadlineSeconds: {{ .Values.cleanup.activeDeadlineSeconds }}
56+
template:
57+
spec:
58+
serviceAccountName: cleanup-ephemeral-secrets
59+
restartPolicy: Never
60+
containers:
61+
- name: cleanup
62+
image: {{ .Values.cleanup.image }}
63+
command:
64+
- /bin/bash
65+
- -ce
66+
- |
67+
LABEL="{{ .Values.cleanup.label }}"
68+
NS="{{ .Release.Namespace }}"
69+
70+
ES_COUNT=$(oc get externalsecret -l "${LABEL}=one-shot" -n "${NS}" --no-headers 2>/dev/null | wc -l)
71+
if [ "${ES_COUNT}" -eq 0 ]; then
72+
echo "No one-shot ExternalSecrets found. Nothing to do."
73+
else
74+
echo "Found ${ES_COUNT} one-shot ExternalSecret(s)."
75+
echo "Waiting for ExternalSecrets to sync..."
76+
oc wait externalsecret -l "${LABEL}=one-shot" -n "${NS}" \
77+
--for=condition=Ready --timeout=90s 2>/dev/null || \
78+
echo "WARNING: Timed out waiting for Ready, proceeding."
79+
80+
echo "Deleting ExternalSecrets (orphaning dependent Secrets)..."
81+
oc delete externalsecret -l "${LABEL}=one-shot" -n "${NS}" \
82+
--cascade=orphan --ignore-not-found
83+
fi
84+
85+
SEC_COUNT=$(oc get secret -l "${LABEL}=delete" -n "${NS}" --no-headers 2>/dev/null | wc -l)
86+
if [ "${SEC_COUNT}" -eq 0 ]; then
87+
echo "No ephemeral Secrets to clean up."
88+
else
89+
echo "Deleting ${SEC_COUNT} ephemeral Secret(s)..."
90+
oc delete secret -l "${LABEL}=delete" -n "${NS}" --ignore-not-found
91+
fi
92+
93+
echo "Cleanup complete."
94+
{{- end }}

charts/rh-keycloak/values.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# PostSync cleanup for ephemeral Secrets.
2+
# When enabled, a PostSync Job deletes the keycloak-users ExternalSecret
3+
# with --cascade=orphan (so the Secret survives), then removes Secrets
4+
# labeled for deletion (keycloak-users).
5+
cleanup:
6+
enabled: true
7+
image: registry.redhat.io/openshift4/ose-cli-rhel9:latest
8+
label: "ztvp.io/cleanup"
9+
activeDeadlineSeconds: 120
10+
11+
# Values passed through to the rhbk subchart.
12+
rhbk:
13+
externalSecrets:
14+
oneShot: true
15+
secretCleanupLabel: "ztvp.io/cleanup"

values-hub.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,16 +494,16 @@ clusterGroup:
494494
name: rh-keycloak
495495
namespace: keycloak-system
496496
project: hub
497-
chart: rhbk
498-
chartVersion: 0.0.*
497+
path: charts/rh-keycloak
499498
annotations:
500499
argocd.argoproj.io/sync-wave: "35"
501-
# SPIFFE Identity Provider is enabled by default in the chart.
500+
# SPIFFE Identity Provider is enabled by default in the rhbk subchart.
502501
# Override issuer/jwksUrl only if auto-generated values from cluster domain are not suitable.
502+
# Note: overrides must use the rhbk. prefix to reach the subchart.
503503
# overrides:
504-
# - name: keycloak.spiffeIdentityProvider.config.config.issuer
504+
# - name: rhbk.keycloak.spiffeIdentityProvider.config.config.issuer
505505
# value: "spiffe://apps.example.com"
506-
# - name: keycloak.spiffeIdentityProvider.config.config.jwksUrl
506+
# - name: rhbk.keycloak.spiffeIdentityProvider.config.config.jwksUrl
507507
# value: "https://spire-spiffe-oidc-discovery-provider.apps.example.com/keys"
508508
rh-cert-manager:
509509
name: rh-cert-manager

0 commit comments

Comments
 (0)