Skip to content

Commit 1b56520

Browse files
authored
feat: BYO container registry support (#99)
* feat: BYO container registry support Restructure registry configuration to support three deployment states: - Fresh install: No registry configured (both disabled by default) - Built-in Quay: quay.enabled=true uses hub/infra/quay/ vault path - External/BYO: externalRegistry.enabled=true uses hub/infra/registry/ path Changes: - Add externalRegistry.enabled flag to supply-chain and qtodo charts - Separate vault paths for built-in Quay vs external registry - Templates conditionally select vault path based on enabled flags - Update supply-chain.md with BYO registry setup instructions - Add helm template method and oc monitoring commands to supply-chain.md - Follow VP best practice: external registry secrets in local ~/values-secret.yaml To enable supply-chain: 1. Uncomment openshift-pipelines namespace and subscription 2. Uncomment supply-chain vault role (JWT auth) 3. Configure registry (BYO or built-in Quay) in application overrides - For BYO registry: - Set externalRegistry.enabled=true and configure registry settings - Add registry credentials to ~/values-secret.yaml - For built-in Quay: - Enable openshift-storage namespace - Enable ODF, NooBaa MCG - Enable Quay operator subscription, quay-registry application 4. RHTAS (signing): Enable rhtas-operator subscription and trusted-artifact-signer namespace 5. RHTPA (SBOM): Enable rhtpa-operator subscription, ODF, NooBaa, and trusted-profile-analyzer Signed-off-by: Min Zhang <minzhang@redhat.com> * feat: unified registry configuration with multi-registry support Refactor supply-chain and qtodo charts to use a single, option-agnostic registry configuration instead of separate per-registry blocks. Registry options (configure one in values-hub.yaml): - Option 1: Built-in Quay Registry - Option 2: BYO/External Registry (quay.io, ghcr.io, etc.) - Option 3: Embedded OCP Image Registry Key changes: Supply-chain chart: * Unified registry.* parameters (domain, org, user, vaultPath, passwordVaultKey) * Use tpl function to resolve template expressions in registry.domain values passed as --set parameters from the validated patterns framework * Embedded OCP registry automation (registry.embeddedOCP.ensureImageNamespaceRBAC): - Auto-create image namespace matching registry.org - Grant pipeline SA system:image-builder via RoleBinding - Enable default route on OCP image registry via Kubernetes API (curl-based Job using ServiceAccount token, no oc CLI dependency) * ArgoCD hook annotations on the route-enabler Job (Sync + HookSucceeded) * Rename qtodo-registry-pass to qtodo-quay-pass for clarity Qtodo chart: * Unified app.images.main.registry.* parameters * Use tpl function in registry-external-secret.yaml for domain resolution ztvp-certificates chart: * Node-level image pull trust for kubelet (imagePullTrust.*) * Create ConfigMap with ingress CA per registry hostname in openshift-config * Patch image.config.openshift.io/cluster additionalTrustedCA * RBAC for patching image.config.openshift.io resources Documentation: * Comprehensive supply-chain.md with configuration steps for all three registry options, vault paths, and example overrides * Updated values-secret.yaml.template with registry credential examples Signed-off-by: Min Zhang <minzhang@redhat.com> * feat: add script to generate registry option test variants Add scripts/gen-byo-container-registry-variants.py that reads the base values-hub.yaml (all supply-chain components commented out) and produces up to 3 variants with the chosen registry option enabled: Option 1: Built-in Quay Registry Option 2: BYO / External Registry Option 3: Embedded OCP Image Registry Each variant also enables the common supply-chain stack (OpenShift Pipelines, ODF, NooBaa, RHTAS, RHTPA, and their namespaces, subscriptions, vault roles). Signed-off-by: Min Zhang <minzhang@redhat.com> * fix(acs-central): handle CA trust race on fresh cluster deployment On a fresh bare-metal cluster the proxy trustedCA injection may not have propagated to Central's mounted CA bundle by the time the create-auth-provider Job runs. Central caches its TLS trust pool at startup, so all Job retries fail with "x509: certificate signed by unknown authority" when Central tries to validate the Keycloak OIDC discovery endpoint. - Add retry loop in create-auth-provider Job that detects the specific TLS CA error, restarts Central to reload the CA bundle, then retries (up to 3 times) - Add apps/deployments get+patch to the service account Role so the Job can run "oc rollout restart" - Refactor script: extract wait_for_central() and escape_sed() helpers Signed-off-by: Min Zhang <minzhang@redhat.com> * refactor: centralize registry config in global.registry and derive qtodo image in chart Move shared registry credentials (domain, org, user, vaultPath, passwordVaultKey) into a single global.registry block in values-hub.yaml. Supply-chain and qtodo charts fall back to global.registry.* when local registry values are empty. Derive the qtodo container image from global.registry.domain/org when registry is enabled, avoiding Validated Patterns --set overrides (Helm templates are not available there). - Add global.registry defaults to supply-chain and qtodo chart values - Update templates to use | default .Values.global.registry.* - Simplify values-hub.yaml application overrides for option-specific flags - Rewrite gen-byo-container-registry-variants.py for the structure - Update docs/supply-chain.md for global.registry architecture Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: align vault-utils JWT placeholders and ACS init RBAC Sync common/scripts/vault-utils.sh (Helm global.pattern substitution for Ansible) and charts/acs-central cluster-init Role (list/watch deployments) from embedded-ocp-registry for parity across registry option branches. Signed-off-by: Min Zhang <minzhang@redhat.com> * feat(supply-chain): embedded OCP registry token refresh and Vault JWT Add CronJob and sync-hook seed Job for pipeline SA token refresh to Vault (SPIFFE JWT). Extend supply-chain values, docs/supply-chain.md, and values-hub for embedded OCP (merged with fresh-install baseline). Signed-off-by: Min Zhang <minzhang@redhat.com> * fix(gen-variants): fix subject regex and imagePullTrust matching Two bugs in gen-byo-container-registry-variants.py: 1. The supply-chain JWT role subject regex used ns/pipeline which no longer matches after the namespace was changed to {{ $.Values.global.pattern }}-hub. Changed to sa/pipeline which matches both old and new formats. 2. enable_image_pull_trust looked for the stale <registry-hostname> placeholder. Changed to match by position (value line after the imagePullTrust.registries line) so it works regardless of the default value in the base file. Signed-off-by: Min Zhang <minzhang@redhat.com> * docs: clarify registry secret is only needed for BYO registry - Comment out registry-user in values-secret.yaml.template (was active by default but unnecessary for minimal deployments) - Update supply-chain.md step 2 to clarify that only Option 2 (BYO registry) needs the manual registry-user secret - Option 1 (Quay) uses auto-generated quay-users secret - Option 3 (embedded OCP) token refresher writes to Vault automatically Signed-off-by: Min Zhang <minzhang@redhat.com> * refactor: address PR #99 review feedback - Rename org -> repository throughout (global.registry and supply-chain) - Rename embeddedOCP -> embeddedOpenShift in supply-chain templates and docs - Scope registry image rewrite via useRegistry flag in qtodo.image helper - Guard imagePullSecrets on vaultPath being set (not just registry.enabled) - Add Vault auth retry loop to refresh_registry_token.sh for seed Job timing - Extract image namespace from first path component of repository (splitList) - Update docs/supply-chain.md with new parameter names and examples Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: address PR review feedback (naming, sync-wave, docs) - Rename OCP_DOMAIN to OPENSHIFT_DOMAIN in vault-utils.sh - Use repository: ztvp/qtodo for all 3 registry options in values-hub.yaml - Add sync-wave "15" to qtodo-registry-auth ExternalSecret so it runs after the registry-token-refresher-seed Job at wave 10, preventing a deadlock where the ExternalSecret blocks Argo from reaching the seed - Update SYNC-WAVE-INVENTORY.md with full supply-chain chart internals Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: rename OCP to OpenShift in gen-byo-container-registry-variants.py Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: apply remaining OCP to OpenShift renames in values-hub.yaml - Rename org -> repository: ztvp/qtodo for Options 1 and 3 - Rename Embedded OCP -> Embedded OpenShift throughout - Rename embeddedOCP -> embeddedOpenShift in supply-chain overrides - Update domain/org -> domain/repository in comments Signed-off-by: Min Zhang <minzhang@redhat.com> * feat: seed image job, pipeline auto-trigger, PVC health check, and oc mirror fix Bootstrapping: registry seed image Job (qtodo chart) - New registry-seed-job.yaml: mirrors upstream qtodo image into the configured registry (embedded OpenShift, built-in Quay, or BYO) so the deployment can pull before the supply-chain pipeline runs. - Adds seedImage config block to qtodo/values.yaml (disabled by default). - Handles all three registry types: SA token auth for embedded OpenShift, dockerconfigjson secret for Quay/BYO, with registry-reachability retry. - Uses -a flag for oc image mirror auth (not skopeo --dest-creds flags). - Sync hook with HookSucceeded delete policy; runs at wave 0+5 (before the qtodo deployment at wave 51). Pipeline auto-trigger: PostSync Job wrapper (supply-chain chart) - pipelinerun-qtodo.yaml now creates a PostSync Job that imperatively runs `oc create` to launch the PipelineRun. This works around the upstream clustergroup chart's resourceExclusions for tekton.dev PipelineRun/TaskRun, which silently blocks direct PipelineRun hooks. - Dedicated pipelinerun-launcher ServiceAccount + Role + RoleBinding with minimal RBAC (create pipelineruns, get secret/PVC). Post-pipeline qtodo refresh (supply-chain chart) - New restart-qtodo Tekton Task + RBAC (pipeline-qtodo-restarter Role/RoleBinding in qtodo namespace). - Added `finally` section to pipeline-qtodo.yaml that runs restart-qtodo after successful image verification, forcing the qtodo deployment to pull the newly built and signed image. ArgoCD PVC health check (values-hub.yaml) - Added custom resourceHealthCheck for PersistentVolumeClaim: treats Pending as Healthy. WaitForFirstConsumer PVCs stay Pending until a pod mounts them, which causes ArgoCD to report the app as Progressing indefinitely and prevents PostSync hooks from firing. This is a common pattern for gp3-csi (AWS), lvms-vg1 (bare metal), etc. - Preserves existing KeycloakRealmImport health check. Generator script updates - gen-byo-container-registry-variants.py: uncomments pipelinerun.enabled and app.seedImage.enabled flags when generating supply-chain variants. Other - registry-external-secret.yaml: added sync-wave 36 annotation. - values-hub.yaml: clean base with new flags commented out; RHTAS pinned to stable-v1.3. - SYNC-WAVE-INVENTORY.md: updated qtodo and supply-chain sections. Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: make registry-seed-image job best-effort to prevent ArgoCD retry loops A Sync hook failure triggers ArgoCD retry loops for the entire sync operation (up to 20 retries with timeouts), blocking all higher sync waves and creating an unrecoverable deadlock. Wrap the seed logic in a function guarded by an unconditional exit 0 so the hook always succeeds regardless of registry availability: - No auth secret (built-in Quay first install): skip gracefully - Registry unreachable: warn and exit 0 - Mirror failure: warn and exit 0 Also tune Job parameters: - backoffLimit: 0 (K8s retries unnecessary since job always exits 0) - activeDeadlineSeconds: 600 (hard safety net) - Registry poll MAX_WAIT: 480s (enough for embedded registry startup) - hook-delete-policy: BeforeHookCreation,HookSucceeded Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: add registry readiness check to pipeline launcher job On fresh install the PostSync hook can fire before the built-in Quay registry is fully ready, causing the pipeline to fail when pushing images. Add a readiness poll loop that waits up to 480s for the registry /v2/ endpoint to respond before creating the PipelineRun. Also increase activeDeadlineSeconds from 120 to 600 to accommodate the wait. Works for all registry types (built-in Quay, embedded OpenShift, BYO) since it uses global.registry.domain. Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: quote boolean override values as strings in values-hub.yaml The clustergroup chart requires all override values to be strings. Bare YAML booleans (true/false) cause Helm template error: "wrong type for value; expected string; got bool" Quote compliance.storage.enabled, app.oidc.enabled, and app.spire.enabled values. Signed-off-by: Min Zhang <minzhang@redhat.com> * docs: update supply-chain.md with new automation features Add documentation for: - First-install image availability (registry-seed-image best-effort job) - ArgoCD PVC health check for WaitForFirstConsumer storage classes - Automatic pipeline trigger via PostSync hook Job with registry readiness check - restart-qtodo finally task that restarts the deployment after a successful pipeline run - Updated Helm template section to reflect Job wrapper change Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: use placeholder repository path for BYO registry option Change BYO registry repository from ztvp/qtodo to your-org/qtodo. quay.io uses org/repo format and users must replace this with their own org. Options 1 and 3 (internal registries) keep ztvp/qtodo since they control the namespace. Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: address PR review feedback - PVC health check: use generic "PVC is pending" message instead of assuming WaitForFirstConsumer binding mode - Disable auto pipeline trigger (pipelinerun.enabled) and seed image mirroring (app.seedImage.enabled) by default; keep templates gated behind flags for future enablement - Guard restart-qtodo task against missing Deployment - Remove auto-trigger and seed image sections from supply-chain docs - Remove pipelinerun/seedImage uncomment logic from gen-byo script Signed-off-by: Min Zhang <minzhang@redhat.com> * fix: pin clustergroup chart to 0.9.47 Signed-off-by: Min Zhang <minzhang@redhat.com> --------- Signed-off-by: Min Zhang <minzhang@redhat.com>
1 parent d78c287 commit 1b56520

31 files changed

Lines changed: 2168 additions & 225 deletions

charts/acs-central/templates/jobs/create-auth-provider.yaml

Lines changed: 95 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -45,51 +45,50 @@ spec:
4545
- |
4646
#!/usr/bin/env bash
4747
48-
echo "🔄 Configuring Keycloak OIDC authentication provider..."
48+
echo "Configuring Keycloak OIDC authentication provider..."
49+
50+
wait_for_central() {
51+
local max_retries=30
52+
local retry_count=0
53+
echo "Waiting for ACS Central API to be available..."
54+
until curl -sk -u "admin:$PASSWORD" https://central/v1/ping > /dev/null 2>&1; do
55+
retry_count=$((retry_count + 1))
56+
if [ $retry_count -ge $max_retries ]; then
57+
echo "ERROR: Timeout waiting for ACS Central API"
58+
return 1
59+
fi
60+
echo " Retry $retry_count/$max_retries..."
61+
sleep 10
62+
done
63+
echo "ACS Central API is ready"
64+
}
4965
50-
# Wait for ACS Central to be ready
51-
echo "⏳ Waiting for ACS Central API to be available..."
52-
max_retries=30
53-
retry_count=0
54-
until curl -sk -u "admin:$PASSWORD" https://central/v1/ping > /dev/null 2>&1; do
55-
retry_count=$((retry_count + 1))
56-
if [ $retry_count -ge $max_retries ]; then
57-
echo "❌ Timeout waiting for ACS Central API"
58-
exit 1
59-
fi
60-
echo " Retry $retry_count/$max_retries..."
61-
sleep 10
62-
done
63-
echo "✅ ACS Central API is ready"
66+
wait_for_central || exit 1
6467
65-
# Wait for Keycloak OIDC discovery endpoint to be available
66-
echo "⏳ Waiting for Keycloak OIDC discovery endpoint..."
68+
echo "Waiting for Keycloak OIDC discovery endpoint..."
6769
max_retries=30
6870
retry_count=0
6971
until curl -sk "$KEYCLOAK_ISSUER/.well-known/openid-configuration" > /dev/null 2>&1; do
7072
retry_count=$((retry_count + 1))
7173
if [ $retry_count -ge $max_retries ]; then
72-
echo " Timeout waiting for Keycloak OIDC discovery endpoint"
73-
echo " Tried: $KEYCLOAK_ISSUER/.well-known/openid-configuration"
74+
echo "ERROR: Timeout waiting for Keycloak OIDC discovery endpoint"
75+
echo " Tried: $KEYCLOAK_ISSUER/.well-known/openid-configuration"
7476
exit 1
7577
fi
7678
echo " Retry $retry_count/$max_retries..."
7779
sleep 10
7880
done
79-
echo "Keycloak OIDC discovery endpoint is ready"
81+
echo "Keycloak OIDC discovery endpoint is ready"
8082
81-
# Check if auth provider already exists
8283
AUTH_PROVIDERS=$(curl -sk -u "admin:$PASSWORD" https://central/v1/authProviders)
8384
if echo "$AUTH_PROVIDERS" | grep -q "OIDC"; then
84-
echo "OIDC provider already configured"
85+
echo "OIDC provider already configured -- nothing to do"
8586
exit 0
8687
fi
8788
88-
# Get ACS Central hostname (without https://)
8989
ACS_CENTRAL_HOSTNAME="$(oc get route central -n stackrox -o jsonpath='{.spec.host}')"
9090
echo "ACS Central hostname: $ACS_CENTRAL_HOSTNAME"
9191
92-
# Create OIDC provider JSON
9392
cat > /tmp/oidc-config.json << 'OIDCEOF'
9493
{
9594
"name": "OIDC",
@@ -111,69 +110,92 @@ spec:
111110
}
112111
OIDCEOF
113112
114-
# Remove leading spaces from JSON
115113
sed -i 's/^ //g' /tmp/oidc-config.json
116114
117-
# Replace placeholders using printf and sed to safely handle special characters
118-
# Escape special sed characters in variables: & \ / and newlines
119-
ACS_CENTRAL_HOSTNAME_ESC=$(printf '%s\n' "$ACS_CENTRAL_HOSTNAME" | sed 's:[&\\/]:\\&:g')
120-
KEYCLOAK_ISSUER_ESC=$(printf '%s\n' "$KEYCLOAK_ISSUER" | sed 's:[&\\/]:\\&:g')
121-
KEYCLOAK_CLIENT_ID_ESC=$(printf '%s\n' "$KEYCLOAK_CLIENT_ID" | sed 's:[&\\/]:\\&:g')
122-
KEYCLOAK_CLIENT_SECRET_ESC=$(printf '%s\n' "$KEYCLOAK_CLIENT_SECRET" | sed 's:[&\\/]:\\&:g')
123-
CLAIM_NAME_ESC=$(printf '%s\n' "$CLAIM_NAME" | sed 's:[&\\/]:\\&:g')
124-
CLAIM_EMAIL_ESC=$(printf '%s\n' "$CLAIM_EMAIL" | sed 's:[&\\/]:\\&:g')
125-
CLAIM_GROUPS_ESC=$(printf '%s\n' "$CLAIM_GROUPS" | sed 's:[&\\/]:\\&:g')
126-
CLAIM_ROLES_ESC=$(printf '%s\n' "$CLAIM_ROLES" | sed 's:[&\\/]:\\&:g')
127-
128-
sed -i "s|UI_ENDPOINT_PLACEHOLDER|$ACS_CENTRAL_HOSTNAME_ESC|g" /tmp/oidc-config.json
129-
sed -i "s|ISSUER_PLACEHOLDER|$KEYCLOAK_ISSUER_ESC|g" /tmp/oidc-config.json
130-
sed -i "s|CLIENT_ID_PLACEHOLDER|$KEYCLOAK_CLIENT_ID_ESC|g" /tmp/oidc-config.json
131-
sed -i "s|CLIENT_SECRET_PLACEHOLDER|$KEYCLOAK_CLIENT_SECRET_ESC|g" /tmp/oidc-config.json
132-
sed -i "s|CLAIM_NAME_PLACEHOLDER|$CLAIM_NAME_ESC|g" /tmp/oidc-config.json
133-
sed -i "s|CLAIM_EMAIL_PLACEHOLDER|$CLAIM_EMAIL_ESC|g" /tmp/oidc-config.json
134-
sed -i "s|CLAIM_GROUPS_PLACEHOLDER|$CLAIM_GROUPS_ESC|g" /tmp/oidc-config.json
135-
sed -i "s|CLAIM_ROLES_PLACEHOLDER|$CLAIM_ROLES_ESC|g" /tmp/oidc-config.json
136-
137-
# Debug: Show the JSON payload
138-
echo "📝 OIDC Configuration JSON:"
115+
escape_sed() { printf '%s\n' "$1" | sed 's:[&\\/]:\\&:g'; }
116+
117+
sed -i "s|UI_ENDPOINT_PLACEHOLDER|$(escape_sed "$ACS_CENTRAL_HOSTNAME")|g" /tmp/oidc-config.json
118+
sed -i "s|ISSUER_PLACEHOLDER|$(escape_sed "$KEYCLOAK_ISSUER")|g" /tmp/oidc-config.json
119+
sed -i "s|CLIENT_ID_PLACEHOLDER|$(escape_sed "$KEYCLOAK_CLIENT_ID")|g" /tmp/oidc-config.json
120+
sed -i "s|CLIENT_SECRET_PLACEHOLDER|$(escape_sed "$KEYCLOAK_CLIENT_SECRET")|g" /tmp/oidc-config.json
121+
sed -i "s|CLAIM_NAME_PLACEHOLDER|$(escape_sed "$CLAIM_NAME")|g" /tmp/oidc-config.json
122+
sed -i "s|CLAIM_EMAIL_PLACEHOLDER|$(escape_sed "$CLAIM_EMAIL")|g" /tmp/oidc-config.json
123+
sed -i "s|CLAIM_GROUPS_PLACEHOLDER|$(escape_sed "$CLAIM_GROUPS")|g" /tmp/oidc-config.json
124+
sed -i "s|CLAIM_ROLES_PLACEHOLDER|$(escape_sed "$CLAIM_ROLES")|g" /tmp/oidc-config.json
125+
126+
echo "OIDC Configuration JSON:"
139127
cat /tmp/oidc-config.json
140128
echo ""
141129
142-
# Verify Keycloak discovery endpoint one more time before creating provider
143-
echo "🔍 Verifying Keycloak discovery endpoint..."
144-
curl -sk "$KEYCLOAK_ISSUER/.well-known/openid-configuration" | head -20
145-
echo ""
130+
# --- Create OIDC auth provider with TLS retry logic ---
131+
# On fresh clusters the proxy trustedCA injection may not have
132+
# propagated to Central's mounted CA bundle yet. If Central
133+
# rejects the Keycloak issuer with "certificate signed by unknown
134+
# authority", restart the Central deployment so it reloads the
135+
# (now-correct) CA bundle, then retry.
136+
create_oidc_provider() {
137+
local http_code
138+
http_code=$(curl -X POST -u "admin:$PASSWORD" -k https://central/v1/authProviders \
139+
-H "Content-Type: application/json" \
140+
--data @/tmp/oidc-config.json \
141+
-w "%{http_code}" \
142+
-o /tmp/output.json)
143+
144+
if [ "$http_code" = "200" ]; then
145+
return 0
146+
fi
146147
147-
echo "📤 Creating auth provider in ACS..."
148-
HTTP_CODE=$(curl -X POST -u "admin:$PASSWORD" -k https://central/v1/authProviders \
149-
-H "Content-Type: application/json" \
150-
--data @/tmp/oidc-config.json \
151-
-w "%{http_code}" \
152-
-o /tmp/output.json)
148+
local body
149+
body=$(cat /tmp/output.json)
150+
echo "Auth provider creation returned HTTP $http_code: $body"
153151
154-
echo "📥 Response HTTP Code: $HTTP_CODE"
155-
echo "📥 Response Body:"
156-
cat /tmp/output.json
157-
echo ""
152+
if echo "$body" | grep -q "certificate signed by unknown authority"; then
153+
return 2
154+
fi
155+
return 1
156+
}
157+
158+
MAX_TLS_RETRIES=3
159+
tls_attempt=0
160+
161+
echo "Creating auth provider in ACS..."
162+
while true; do
163+
create_oidc_provider
164+
rc=$?
158165
159-
if [ "$HTTP_CODE" != "200" ]; then
160-
echo "❌ Failed to create auth provider (HTTP $HTTP_CODE)"
166+
if [ $rc -eq 0 ]; then
167+
break
168+
fi
169+
170+
if [ $rc -eq 2 ]; then
171+
tls_attempt=$((tls_attempt + 1))
172+
if [ $tls_attempt -gt $MAX_TLS_RETRIES ]; then
173+
echo "ERROR: Central still does not trust the ingress CA after $MAX_TLS_RETRIES restart(s)"
174+
exit 1
175+
fi
176+
echo "Central does not trust the ingress CA yet (attempt $tls_attempt/$MAX_TLS_RETRIES)"
177+
echo "Restarting Central to reload CA bundle..."
178+
oc rollout restart deployment/central -n stackrox
179+
oc rollout status deployment/central -n stackrox --timeout=180s
180+
wait_for_central || exit 1
181+
continue
182+
fi
183+
184+
echo "ERROR: Failed to create auth provider"
161185
exit 1
162-
fi
186+
done
163187
164-
# Extract provider ID
165188
AUTH_PROVIDER_ID=$(sed 's/,/\n/g' /tmp/output.json | grep -w id | awk -F\" '{ print $4 }')
166189
167190
if [ -z "$AUTH_PROVIDER_ID" ]; then
168-
echo " Failed to extract auth provider ID"
191+
echo "ERROR: Failed to extract auth provider ID"
169192
cat /tmp/output.json
170193
exit 1
171194
fi
172195
173-
echo "Auth provider created with ID: $AUTH_PROVIDER_ID"
196+
echo "Auth provider created with ID: $AUTH_PROVIDER_ID"
174197
175-
# Create admin role mapping for acs-admin role
176-
echo "📝 Creating role mapping: acs-admin → Admin"
198+
echo "Creating role mapping: acs-admin -> Admin"
177199
JSON_PAYLOAD="{\"roleName\":\"Admin\",\"props\":{\"authProviderId\":\"$AUTH_PROVIDER_ID\",\"key\":\"roles\",\"value\":\"acs-admin\"}}"
178200
179201
HTTP_CODE=$(curl -X POST -u "admin:$PASSWORD" -k https://central/v1/groups \
@@ -182,17 +204,17 @@ spec:
182204
-w "%{http_code}" \
183205
-o /tmp/role-mapping.json)
184206
185-
echo "📥 Role mapping response (HTTP $HTTP_CODE):"
207+
echo "Role mapping response (HTTP $HTTP_CODE):"
186208
cat /tmp/role-mapping.json
187209
echo ""
188210
189211
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "201" ]; then
190-
echo "Admin role mapping created for acs-admin"
212+
echo "Admin role mapping created for acs-admin"
191213
else
192-
echo "⚠️ Warning: Failed to create admin role mapping (HTTP $HTTP_CODE, may already exist)"
214+
echo "WARNING: Failed to create admin role mapping (HTTP $HTTP_CODE, may already exist)"
193215
fi
194216
195-
echo "🎉 Keycloak OIDC configuration complete"
217+
echo "Keycloak OIDC configuration complete"
196218
name: create-auth-provider
197219
dnsPolicy: ClusterFirst
198220
restartPolicy: Never

charts/acs-central/templates/rbac/cluster-init-role.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,13 @@ rules:
3333
- routes
3434
verbs:
3535
- get
36-
- list
36+
- list
37+
- apiGroups:
38+
- apps
39+
resources:
40+
- deployments
41+
verbs:
42+
- get
43+
- list
44+
- watch
45+
- patch
Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
{{/*
2-
Create the image path for the passed in image field
2+
Create the image path for the passed in image field.
3+
When global.registry is enabled with domain and repository, the image
4+
reference is derived from global.registry.domain/repository (e.g.
5+
quay.io/ztvp/qtodo) so no VP --set override is needed.
36
*/}}
47
{{- define "qtodo.image" -}}
8+
{{- $name := tpl .value.name .context -}}
9+
{{- $useRegistry := default false .useRegistry -}}
10+
{{- if and $useRegistry .context.Values.global.registry.enabled .context.Values.global.registry.domain .context.Values.global.registry.repository -}}
11+
{{- $name = printf "%s/%s" (tpl .context.Values.global.registry.domain .context) .context.Values.global.registry.repository -}}
12+
{{- end -}}
513
{{- if eq (substr 0 7 (tpl .value.version .context)) "sha256:" -}}
6-
{{- printf "%s@%s" (tpl .value.name .context) (tpl .value.version .context) -}}
14+
{{- printf "%s@%s" $name (tpl .value.version .context) -}}
715
{{- else -}}
8-
{{- printf "%s:%s" (tpl .value.name .context) (tpl .value.version .context) -}}
16+
{{- printf "%s:%s" $name (tpl .value.version .context) -}}
917
{{- end -}}
1018
{{- end -}}

charts/qtodo/templates/app-deployment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ spec:
193193
readOnly: true
194194
{{- end }}
195195
- name: qtodo
196-
image: {{ template "qtodo.image" (dict "value" .Values.app.images.main "context" $) }}
196+
image: {{ template "qtodo.image" (dict "value" .Values.app.images.main "context" $ "useRegistry" true) }}
197197
imagePullPolicy: {{ .Values.app.images.main.pullPolicy }}
198198
ports:
199199
- containerPort: 8080

charts/qtodo/templates/app-serviceaccount.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
app: qtodo
66
name: qtodo
77
namespace: qtodo
8-
{{- if .Values.app.images.main.registry.auth }}
8+
{{- if or .Values.app.images.main.registry.auth (and .Values.global.registry.enabled .Values.global.registry.vaultPath) }}
99
imagePullSecrets:
1010
- name: {{ .Values.app.images.main.registry.secretName }}
1111
{{- end }}
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
{{- if .Values.app.images.main.registry.auth }}
1+
{{- $regAuth := or .Values.app.images.main.registry.auth (and .Values.global.registry.enabled .Values.global.registry.vaultPath) }}
2+
{{- $regDomain := .Values.app.images.main.registry.domain | default .Values.global.registry.domain }}
3+
{{- $regUser := .Values.app.images.main.registry.user | default .Values.global.registry.user }}
4+
{{- $regVaultPath := .Values.app.images.main.registry.vaultPath | default .Values.global.registry.vaultPath }}
5+
{{- $regPasswordKey := .Values.app.images.main.registry.passwordVaultKey | default .Values.global.registry.passwordVaultKey }}
6+
{{- if $regAuth }}
27
---
38
apiVersion: "external-secrets.io/v1beta1"
49
kind: ExternalSecret
510
metadata:
611
name: {{ .Values.app.images.main.registry.secretName }}
712
namespace: {{ .Release.Namespace | default .Values.global.namespace }}
13+
annotations:
14+
argocd.argoproj.io/sync-wave: "36"
815
spec:
916
refreshInterval: 15s
1017
secretStoreRef:
@@ -18,14 +25,14 @@ spec:
1825
.dockerconfigjson: |
1926
{
2027
"auths": {
21-
"{{ .Values.app.images.main.registry.domain | default (printf "quay-registry-quay-quay-enterprise.%s" .Values.global.hubClusterDomain) }}": {
22-
"auth": "{{ `{{ printf "%s:%s" "` }}{{ .Values.app.images.main.registry.user }}{{ `" .password | b64enc }}` }}"
28+
"{{ tpl (required "registry domain is required (set app.images.main.registry.domain or global.registry.domain)" $regDomain) $ }}": {
29+
"auth": "{{ `{{ printf "%s:%s" "` }}{{ $regUser }}{{ `" .password | b64enc }}` }}"
2330
}
2431
}
2532
}
2633
data:
2734
- secretKey: password
2835
remoteRef:
29-
key: {{ .Values.app.images.main.registry.vaultPath }}
30-
property: {{ .Values.app.images.main.registry.passwordVaultKey }}
31-
{{- end }}
36+
key: {{ required "registry vaultPath is required (set app.images.main.registry.vaultPath or global.registry.vaultPath)" $regVaultPath }}
37+
property: {{ required "registry passwordVaultKey is required (set app.images.main.registry.passwordVaultKey or global.registry.passwordVaultKey)" $regPasswordKey }}
38+
{{- end }}

0 commit comments

Comments
 (0)