From f46e05a05d6b7d84026da94347df731733edbe88 Mon Sep 17 00:00:00 2001 From: Raul Hernandez Date: Mon, 20 Jul 2026 16:57:40 +0200 Subject: [PATCH 01/10] oran-o2ims: add tls scanner Signed-off-by: Raul Hernandez --- .../openshift-kni-oran-o2ims-main.yaml | 19 ++++ ...nshift-kni-oran-o2ims-main-presubmits.yaml | 87 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml index f5c4e1988b1d2..2f8b123ce5b80 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml @@ -3,6 +3,10 @@ base_images: name: cli-operator-sdk namespace: ocp tag: v1.31.0 + tls-scanner-tool: + name: tls-scanner + namespace: tls-scanner + tag: tls-scanner-tool ubi-min9: name: ubi-minimal namespace: ocp @@ -106,6 +110,21 @@ tests: cpu: 100m memory: 200Mi workflow: optional-operators-ci-operator-sdk-aws +- always_run: false + as: install-bundle-tls-scan + optional: true + steps: + cluster_profile: openshift-org-aws + dependencies: + OO_BUNDLE: operator-bundle + env: + COMPUTE_NODE_TYPE: m5.2xlarge + OO_INSTALL_NAMESPACE: oran-o2ims + SCAN_NAMESPACE: oran-o2ims + test: + - ref: optional-operators-operator-sdk + - ref: tls-scanner-run + workflow: ipi-aws - always_run: false as: markdownlint commands: | diff --git a/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-presubmits.yaml b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-presubmits.yaml index 5da5362f3911e..a28a94cc7ebe0 100644 --- a/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-presubmits.yaml +++ b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-presubmits.yaml @@ -255,6 +255,93 @@ presubmits: secret: secretName: result-aggregator trigger: (?m)^/test( | .* )images,?($|\s.*) + - agent: kubernetes + always_run: false + branches: + - ^main$ + - ^main- + cluster: build09 + context: ci/prow/install-bundle-tls-scan + decorate: true + decoration_config: + sparse_checkout_files: + - .ci-operator.yaml + - Dockerfile + - Dockerfile.must-gather + - bundle.Dockerfile + labels: + ci-operator.openshift.io/cloud: aws + ci-operator.openshift.io/cloud-cluster-profile: openshift-org-aws + ci.openshift.io/generator: prowgen + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: pull-ci-openshift-kni-oran-o2ims-main-install-bundle-tls-scan + optional: true + rerun_command: /test install-bundle-tls-scan + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --secret-dir=/secrets/ci-pull-credentials + - --target=install-bundle-tls-scan + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/ci-pull-credentials + name: ci-pull-credentials + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: ci-pull-credentials + secret: + secretName: ci-pull-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator + trigger: (?m)^/test( | .* )install-bundle-tls-scan,?($|\s.*) - agent: kubernetes always_run: false branches: From 5cc24330f5280859d18ac2124ad01f57295d2f3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Fri, 24 Jul 2026 15:40:10 +0200 Subject: [PATCH 02/10] oran-o2ims: add wait-for-server-pods step and fix bundle substitutions - Add a wait-for-server-pods inline step to the install-bundle-tls-scan test that dynamically discovers TLS-serving services via the service.beta.openshift.io/serving-cert-secret-name annotation, waits for their backing pods to become Ready, and verifies that service-ca TLS secrets exist before the tls-scanner runs. This avoids hardcoding server names. - Move operator.substitutions under the bundle item where it belongs, making the pullspec override explicitly scoped to the operator-bundle. --- .../openshift-kni-oran-o2ims-main.yaml | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml index 2f8b123ce5b80..9efdf541910b5 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml @@ -123,6 +123,77 @@ tests: SCAN_NAMESPACE: oran-o2ims test: - ref: optional-operators-operator-sdk + - as: wait-for-server-pods + cli: latest + commands: | + NAMESPACE=oran-o2ims + echo "Waiting for Inventory CR to be auto-created..." + for i in $(seq 1 60); do + if oc get inventory default -n "$NAMESPACE" &>/dev/null; then + echo "Inventory CR 'default' found." + break + fi + echo " attempt $i/60..." + sleep 5 + done + + echo "" + echo "Discovering services with TLS serving certs..." + TLS_SERVICES=$(oc get services -n "$NAMESPACE" \ + -o jsonpath='{range .items[?(@.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name)]}{.metadata.name}{"\n"}{end}') + + echo "TLS services found:" + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + echo " $svc -> secret: $SECRET" + done + + echo "" + echo "Waiting for TLS service pods to be ready..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SELECTOR=$(oc get service "$svc" -n "$NAMESPACE" \ + -o go-template='{{range $k,$v := .spec.selector}}{{$k}}={{$v}},{{end}}' | sed 's/,$//') + if [ -z "$SELECTOR" ]; then + echo " SKIP: $svc has no selector" + continue + fi + echo " $svc (selector: $SELECTOR)..." + if ! oc wait pods -l "$SELECTOR" -n "$NAMESPACE" \ + --for=condition=Ready --timeout=5m; then + echo " WARNING: pods for $svc did not become ready within 5m" + echo " Pod status:" + oc get pods -l "$SELECTOR" -n "$NAMESPACE" --no-headers | sed 's/^/ /' + echo " Recent events:" + oc get events -n "$NAMESPACE" --field-selector reason!=Pulling,reason!=Pulled \ + --sort-by='.lastTimestamp' 2>/dev/null | grep "$svc" | tail -5 | sed 's/^/ /' \ + || echo " (no events found)" + fi + done + + echo "" + echo "Verifying TLS secrets from service-ca..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + if oc get secret "$SECRET" -n "$NAMESPACE" &>/dev/null; then + echo " $SECRET exists" + else + echo " WARNING: $SECRET not found" + fi + done + + echo "" + echo "Final pod status in $NAMESPACE:" + oc get pods -n "$NAMESPACE" + from: cli + resources: + requests: + cpu: 100m + memory: 200Mi - ref: tls-scanner-run workflow: ipi-aws - always_run: false From c4d36cd620c55723d93c969ea3ac3728d3143214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Tue, 28 Jul 2026 15:50:32 +0200 Subject: [PATCH 03/10] tls-scanner: add SCANNER_NAMESPACE to deploy scanner into target namespace The scanner always runs in a dedicated tls-scanner namespace. When scanning pods with NetworkPolicies restricting ingress to same-namespace traffic (e.g. oran-o2ims servers), the TLS handshake probes are blocked, producing false NO_TLS results. Add a SCANNER_NAMESPACE env var that deploys the scanner pod into an existing namespace instead, reusing the OWNS_NAMESPACE=false pattern already used by the HyperShift management-cluster path. Set SCANNER_NAMESPACE=oran-o2ims in the install-bundle-tls-scan test so the scanner satisfies the oran-o2ims NetworkPolicy rules. --- .../tls/scanner/run/tls-scanner-run-commands.sh | 8 +++++++- .../tls/scanner/run/tls-scanner-run-ref.yaml | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh index eb48bac978faa..cf89d9e816d48 100644 --- a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh +++ b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh @@ -6,8 +6,14 @@ set -o pipefail run_tls_scan() { # TLS Scanner - scans TLS configurations of all pods in the cluster - local NAMESPACE="tls-scanner" + local NAMESPACE="${SCANNER_NAMESPACE:-tls-scanner}" local OWNS_NAMESPACE=true + # When SCANNER_NAMESPACE is explicitly set, deploy into an existing namespace + # (do not create/delete it). Check the variable itself, not the resolved value, + # so that SCANNER_NAMESPACE=tls-scanner is also treated as externally owned. + if [[ -n "${SCANNER_NAMESPACE:-}" ]]; then + OWNS_NAMESPACE=false + fi local SCANNER_IMAGE="${PULL_SPEC_TLS_SCANNER_TOOL}" local ARTIFACT_DIR="${ARTIFACT_DIR:-/tmp/artifacts}" diff --git a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-ref.yaml b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-ref.yaml index 37072ca16a889..f45025cb6f064 100644 --- a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-ref.yaml +++ b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-ref.yaml @@ -7,6 +7,12 @@ ref: - name: SCAN_NAMESPACE default: "" documentation: "Comma-separated list of namespaces to scan. Empty means scan all namespaces." + - name: SCANNER_NAMESPACE + default: "" + documentation: |- + Namespace where the scanner pod is deployed. When set, the scanner runs + in this existing namespace instead of creating a dedicated 'tls-scanner' + namespace. - name: PQC_CHECK default: "false" documentation: "Set to 'true' to check post-quantum cryptography readiness (scanner will only check TLS 1.3 and mlkem/mlkem25519 support)." From f93e695370b392a3d5b8e6ab91fe3149ebbc2edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Thu, 30 Jul 2026 16:09:50 +0200 Subject: [PATCH 04/10] tls-scanner: fix unbound variable in cleanup trap on scan failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the scanner pod fails (e.g. TLS compliance violations), the script exits before reaching the trap unregistration at the end of run_tls_scan. The EXIT trap fires the cleanup function, but bash unwinds the function call stack before running the trap handler. Since NAMESPACE and OWNS_NAMESPACE were declared local to run_tls_scan, they no longer exist in the trap handler's scope, causing a fatal "unbound variable" error under set -o nounset. Fix by removing the local qualifier from both variables. They are safe as globals: the non-HyperShift path calls the function once, and the HyperShift path runs each invocation in a subshell that isolates variable state. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Raúl Hernández --- .../tls/scanner/run/tls-scanner-run-commands.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh index cf89d9e816d48..1f4621680799a 100644 --- a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh +++ b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh @@ -6,8 +6,8 @@ set -o pipefail run_tls_scan() { # TLS Scanner - scans TLS configurations of all pods in the cluster - local NAMESPACE="${SCANNER_NAMESPACE:-tls-scanner}" - local OWNS_NAMESPACE=true + NAMESPACE="${SCANNER_NAMESPACE:-tls-scanner}" + OWNS_NAMESPACE=true # When SCANNER_NAMESPACE is explicitly set, deploy into an existing namespace # (do not create/delete it). Check the variable itself, not the resolved value, # so that SCANNER_NAMESPACE=tls-scanner is also treated as externally owned. @@ -318,8 +318,7 @@ EOF echo "Artifacts saved to: ${SCANNER_ARTIFACT_DIR}" ls -la "${SCANNER_ARTIFACT_DIR}" || true - # Unregister the trap so it doesn't fire after the function returns (local - # variables NAMESPACE/OWNS_NAMESPACE would be unbound at that point). + # Unregister the trap so it doesn't fire after the function returns. trap - EXIT } From 29aeba66ac70ef19bbdccc7afcd03118297b3a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Wed, 5 Aug 2026 15:53:10 +0200 Subject: [PATCH 05/10] tls-scanner: restore local scope for NAMESPACE/OWNS_NAMESPACE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream PR #82522 fixed the cleanup trap crash by snapshotting locals into _CLEANUP_* globals. Restore NAMESPACE and OWNS_NAMESPACE to local (matching upstream) while keeping the SCANNER_NAMESPACE logic from our earlier commits. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Raúl Hernández --- .../tls/scanner/run/tls-scanner-run-commands.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh index 1f4621680799a..cf89d9e816d48 100644 --- a/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh +++ b/ci-operator/step-registry/tls/scanner/run/tls-scanner-run-commands.sh @@ -6,8 +6,8 @@ set -o pipefail run_tls_scan() { # TLS Scanner - scans TLS configurations of all pods in the cluster - NAMESPACE="${SCANNER_NAMESPACE:-tls-scanner}" - OWNS_NAMESPACE=true + local NAMESPACE="${SCANNER_NAMESPACE:-tls-scanner}" + local OWNS_NAMESPACE=true # When SCANNER_NAMESPACE is explicitly set, deploy into an existing namespace # (do not create/delete it). Check the variable itself, not the resolved value, # so that SCANNER_NAMESPACE=tls-scanner is also treated as externally owned. @@ -318,7 +318,8 @@ EOF echo "Artifacts saved to: ${SCANNER_ARTIFACT_DIR}" ls -la "${SCANNER_ARTIFACT_DIR}" || true - # Unregister the trap so it doesn't fire after the function returns. + # Unregister the trap so it doesn't fire after the function returns (local + # variables NAMESPACE/OWNS_NAMESPACE would be unbound at that point). trap - EXIT } From 932cb6f842105b2f1ba1e066d2a895ffdaa6bfad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Tue, 28 Jul 2026 15:50:54 +0200 Subject: [PATCH 06/10] oran-o2ims: set SCANNER_NAMESPACE --- .../openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml index 9efdf541910b5..a43265ce90149 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml @@ -121,6 +121,7 @@ tests: COMPUTE_NODE_TYPE: m5.2xlarge OO_INSTALL_NAMESPACE: oran-o2ims SCAN_NAMESPACE: oran-o2ims + SCANNER_NAMESPACE: oran-o2ims test: - ref: optional-operators-operator-sdk - as: wait-for-server-pods From 769c2b6e1bafa38f158e1e6e620ff380001144e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Thu, 30 Jul 2026 12:08:51 +0200 Subject: [PATCH 07/10] oran-o2ims: apply TLS Adherence (tls-13) --- .../oran-o2ims/openshift-kni-oran-o2ims-main.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml index a43265ce90149..8991d7d4abb3d 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml @@ -122,6 +122,8 @@ tests: OO_INSTALL_NAMESPACE: oran-o2ims SCAN_NAMESPACE: oran-o2ims SCANNER_NAMESPACE: oran-o2ims + TLS_13_ENABLE_TLS_ADHERENCE: "true" + TLS_13_TLS_ADHERENCE_POLICY: StrictAllComponents test: - ref: optional-operators-operator-sdk - as: wait-for-server-pods @@ -195,6 +197,7 @@ tests: requests: cpu: 100m memory: 200Mi + - ref: tls-13 - ref: tls-scanner-run workflow: ipi-aws - always_run: false From 986fc9677eea63b5a7132409d7cb6d1586ba36ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Wed, 5 Aug 2026 16:00:48 +0200 Subject: [PATCH 08/10] oran-o2ims: add TLS scan job to release-4.22 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the install-bundle-tls-scan test with TLS Adherence (StrictAllComponents) and tls-scanner to the release-4.22 config, matching the main branch configuration. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Raúl Hernández --- ...openshift-kni-oran-o2ims-release-4.22.yaml | 94 +++++++++++++++++++ ...ni-oran-o2ims-release-4.22-presubmits.yaml | 87 +++++++++++++++++ 2 files changed, 181 insertions(+) diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml index 755cd30caf648..e6415258c81a2 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml @@ -3,6 +3,10 @@ base_images: name: cli-operator-sdk namespace: ocp tag: v1.31.0 + tls-scanner-tool: + name: tls-scanner + namespace: tls-scanner + tag: tls-scanner-tool ubi-min9: name: ubi-minimal namespace: ocp @@ -106,6 +110,96 @@ tests: cpu: 100m memory: 200Mi workflow: optional-operators-ci-operator-sdk-aws +- always_run: false + as: install-bundle-tls-scan + optional: true + steps: + cluster_profile: openshift-org-aws + dependencies: + OO_BUNDLE: operator-bundle + env: + COMPUTE_NODE_TYPE: m5.2xlarge + OO_INSTALL_NAMESPACE: oran-o2ims + SCAN_NAMESPACE: oran-o2ims + SCANNER_NAMESPACE: oran-o2ims + TLS_13_ENABLE_TLS_ADHERENCE: "true" + TLS_13_TLS_ADHERENCE_POLICY: StrictAllComponents + test: + - ref: optional-operators-operator-sdk + - as: wait-for-server-pods + cli: latest + commands: | + NAMESPACE=oran-o2ims + echo "Waiting for Inventory CR to be auto-created..." + for i in $(seq 1 60); do + if oc get inventory default -n "$NAMESPACE" &>/dev/null; then + echo "Inventory CR 'default' found." + break + fi + echo " attempt $i/60..." + sleep 5 + done + + echo "" + echo "Discovering services with TLS serving certs..." + TLS_SERVICES=$(oc get services -n "$NAMESPACE" \ + -o jsonpath='{range .items[?(@.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name)]}{.metadata.name}{"\n"}{end}') + + echo "TLS services found:" + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + echo " $svc -> secret: $SECRET" + done + + echo "" + echo "Waiting for TLS service pods to be ready..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SELECTOR=$(oc get service "$svc" -n "$NAMESPACE" \ + -o go-template='{{range $k,$v := .spec.selector}}{{$k}}={{$v}},{{end}}' | sed 's/,$//') + if [ -z "$SELECTOR" ]; then + echo " SKIP: $svc has no selector" + continue + fi + echo " $svc (selector: $SELECTOR)..." + if ! oc wait pods -l "$SELECTOR" -n "$NAMESPACE" \ + --for=condition=Ready --timeout=5m; then + echo " WARNING: pods for $svc did not become ready within 5m" + echo " Pod status:" + oc get pods -l "$SELECTOR" -n "$NAMESPACE" --no-headers | sed 's/^/ /' + echo " Recent events:" + oc get events -n "$NAMESPACE" --field-selector reason!=Pulling,reason!=Pulled \ + --sort-by='.lastTimestamp' 2>/dev/null | grep "$svc" | tail -5 | sed 's/^/ /' \ + || echo " (no events found)" + fi + done + + echo "" + echo "Verifying TLS secrets from service-ca..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + if oc get secret "$SECRET" -n "$NAMESPACE" &>/dev/null; then + echo " $SECRET exists" + else + echo " WARNING: $SECRET not found" + fi + done + + echo "" + echo "Final pod status in $NAMESPACE:" + oc get pods -n "$NAMESPACE" + from: cli + resources: + requests: + cpu: 100m + memory: 200Mi + - ref: tls-13 + - ref: tls-scanner-run + workflow: ipi-aws - always_run: false as: markdownlint commands: | diff --git a/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-presubmits.yaml b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-presubmits.yaml index e9bceba46507a..987ec7227c6a9 100644 --- a/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-presubmits.yaml +++ b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-presubmits.yaml @@ -255,6 +255,93 @@ presubmits: secret: secretName: result-aggregator trigger: (?m)^/test( | .* )images,?($|\s.*) + - agent: kubernetes + always_run: false + branches: + - ^release-4\.22$ + - ^release-4\.22- + cluster: build09 + context: ci/prow/install-bundle-tls-scan + decorate: true + decoration_config: + sparse_checkout_files: + - .ci-operator.yaml + - Dockerfile + - Dockerfile.must-gather + - bundle.Dockerfile + labels: + ci-operator.openshift.io/cloud: aws + ci-operator.openshift.io/cloud-cluster-profile: openshift-org-aws + ci.openshift.io/generator: prowgen + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: pull-ci-openshift-kni-oran-o2ims-release-4.22-install-bundle-tls-scan + optional: true + rerun_command: /test install-bundle-tls-scan + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --secret-dir=/secrets/ci-pull-credentials + - --target=install-bundle-tls-scan + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/ci-pull-credentials + name: ci-pull-credentials + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: ci-pull-credentials + secret: + secretName: ci-pull-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator + trigger: (?m)^/test( | .* )install-bundle-tls-scan,?($|\s.*) - agent: kubernetes always_run: false branches: From e2190d8b6bf0863eff44eaf366f5e6bd829d0bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Wed, 5 Aug 2026 16:12:29 +0200 Subject: [PATCH 09/10] oran-o2ims: add periodic TLS scan jobs for main and release-4.22 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add install-bundle-tls-scan-periodic to both main (Fridays 03:00 UTC) and release-4.22 (Mondays 03:00 UTC) configurations. The periodic jobs are identical to the on-demand variants but run on a cron schedule. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Raúl Hernández --- .../openshift-kni-oran-o2ims-main.yaml | 89 ++++++++++++++++++ ...openshift-kni-oran-o2ims-release-4.22.yaml | 89 ++++++++++++++++++ ...enshift-kni-oran-o2ims-main-periodics.yaml | 90 +++++++++++++++++++ ...kni-oran-o2ims-release-4.22-periodics.yaml | 90 +++++++++++++++++++ 4 files changed, 358 insertions(+) create mode 100644 ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-periodics.yaml create mode 100644 ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-periodics.yaml diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml index 8991d7d4abb3d..647228cbfaa33 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml @@ -200,6 +200,95 @@ tests: - ref: tls-13 - ref: tls-scanner-run workflow: ipi-aws +- as: install-bundle-tls-scan-periodic + cron: 0 3 * * 5 + steps: + cluster_profile: openshift-org-aws + dependencies: + OO_BUNDLE: operator-bundle + env: + COMPUTE_NODE_TYPE: m5.2xlarge + OO_INSTALL_NAMESPACE: oran-o2ims + SCAN_NAMESPACE: oran-o2ims + SCANNER_NAMESPACE: oran-o2ims + TLS_13_ENABLE_TLS_ADHERENCE: "true" + TLS_13_TLS_ADHERENCE_POLICY: StrictAllComponents + test: + - ref: optional-operators-operator-sdk + - as: wait-for-server-pods + cli: latest + commands: | + NAMESPACE=oran-o2ims + echo "Waiting for Inventory CR to be auto-created..." + for i in $(seq 1 60); do + if oc get inventory default -n "$NAMESPACE" &>/dev/null; then + echo "Inventory CR 'default' found." + break + fi + echo " attempt $i/60..." + sleep 5 + done + + echo "" + echo "Discovering services with TLS serving certs..." + TLS_SERVICES=$(oc get services -n "$NAMESPACE" \ + -o jsonpath='{range .items[?(@.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name)]}{.metadata.name}{"\n"}{end}') + + echo "TLS services found:" + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + echo " $svc -> secret: $SECRET" + done + + echo "" + echo "Waiting for TLS service pods to be ready..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SELECTOR=$(oc get service "$svc" -n "$NAMESPACE" \ + -o go-template='{{range $k,$v := .spec.selector}}{{$k}}={{$v}},{{end}}' | sed 's/,$//') + if [ -z "$SELECTOR" ]; then + echo " SKIP: $svc has no selector" + continue + fi + echo " $svc (selector: $SELECTOR)..." + if ! oc wait pods -l "$SELECTOR" -n "$NAMESPACE" \ + --for=condition=Ready --timeout=5m; then + echo " WARNING: pods for $svc did not become ready within 5m" + echo " Pod status:" + oc get pods -l "$SELECTOR" -n "$NAMESPACE" --no-headers | sed 's/^/ /' + echo " Recent events:" + oc get events -n "$NAMESPACE" --field-selector reason!=Pulling,reason!=Pulled \ + --sort-by='.lastTimestamp' 2>/dev/null | grep "$svc" | tail -5 | sed 's/^/ /' \ + || echo " (no events found)" + fi + done + + echo "" + echo "Verifying TLS secrets from service-ca..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + if oc get secret "$SECRET" -n "$NAMESPACE" &>/dev/null; then + echo " $SECRET exists" + else + echo " WARNING: $SECRET not found" + fi + done + + echo "" + echo "Final pod status in $NAMESPACE:" + oc get pods -n "$NAMESPACE" + from: cli + resources: + requests: + cpu: 100m + memory: 200Mi + - ref: tls-13 + - ref: tls-scanner-run + workflow: ipi-aws - always_run: false as: markdownlint commands: | diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml index e6415258c81a2..fd0045f698cb4 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml @@ -200,6 +200,95 @@ tests: - ref: tls-13 - ref: tls-scanner-run workflow: ipi-aws +- as: install-bundle-tls-scan-periodic + cron: 0 3 * * 1 + steps: + cluster_profile: openshift-org-aws + dependencies: + OO_BUNDLE: operator-bundle + env: + COMPUTE_NODE_TYPE: m5.2xlarge + OO_INSTALL_NAMESPACE: oran-o2ims + SCAN_NAMESPACE: oran-o2ims + SCANNER_NAMESPACE: oran-o2ims + TLS_13_ENABLE_TLS_ADHERENCE: "true" + TLS_13_TLS_ADHERENCE_POLICY: StrictAllComponents + test: + - ref: optional-operators-operator-sdk + - as: wait-for-server-pods + cli: latest + commands: | + NAMESPACE=oran-o2ims + echo "Waiting for Inventory CR to be auto-created..." + for i in $(seq 1 60); do + if oc get inventory default -n "$NAMESPACE" &>/dev/null; then + echo "Inventory CR 'default' found." + break + fi + echo " attempt $i/60..." + sleep 5 + done + + echo "" + echo "Discovering services with TLS serving certs..." + TLS_SERVICES=$(oc get services -n "$NAMESPACE" \ + -o jsonpath='{range .items[?(@.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name)]}{.metadata.name}{"\n"}{end}') + + echo "TLS services found:" + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + echo " $svc -> secret: $SECRET" + done + + echo "" + echo "Waiting for TLS service pods to be ready..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SELECTOR=$(oc get service "$svc" -n "$NAMESPACE" \ + -o go-template='{{range $k,$v := .spec.selector}}{{$k}}={{$v}},{{end}}' | sed 's/,$//') + if [ -z "$SELECTOR" ]; then + echo " SKIP: $svc has no selector" + continue + fi + echo " $svc (selector: $SELECTOR)..." + if ! oc wait pods -l "$SELECTOR" -n "$NAMESPACE" \ + --for=condition=Ready --timeout=5m; then + echo " WARNING: pods for $svc did not become ready within 5m" + echo " Pod status:" + oc get pods -l "$SELECTOR" -n "$NAMESPACE" --no-headers | sed 's/^/ /' + echo " Recent events:" + oc get events -n "$NAMESPACE" --field-selector reason!=Pulling,reason!=Pulled \ + --sort-by='.lastTimestamp' 2>/dev/null | grep "$svc" | tail -5 | sed 's/^/ /' \ + || echo " (no events found)" + fi + done + + echo "" + echo "Verifying TLS secrets from service-ca..." + echo "$TLS_SERVICES" | while read -r svc; do + [ -z "$svc" ] && continue + SECRET=$(oc get service "$svc" -n "$NAMESPACE" \ + -o jsonpath='{.metadata.annotations.service\.beta\.openshift\.io/serving-cert-secret-name}') + if oc get secret "$SECRET" -n "$NAMESPACE" &>/dev/null; then + echo " $SECRET exists" + else + echo " WARNING: $SECRET not found" + fi + done + + echo "" + echo "Final pod status in $NAMESPACE:" + oc get pods -n "$NAMESPACE" + from: cli + resources: + requests: + cpu: 100m + memory: 200Mi + - ref: tls-13 + - ref: tls-scanner-run + workflow: ipi-aws - always_run: false as: markdownlint commands: | diff --git a/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-periodics.yaml b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-periodics.yaml new file mode 100644 index 0000000000000..9c7bc0f810bf4 --- /dev/null +++ b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main-periodics.yaml @@ -0,0 +1,90 @@ +periodics: +- agent: kubernetes + cluster: build07 + cron: 0 3 * * 5 + decorate: true + decoration_config: + sparse_checkout_files: + - .ci-operator.yaml + - Dockerfile + - Dockerfile.must-gather + - bundle.Dockerfile + extra_refs: + - base_ref: main + org: openshift-kni + repo: oran-o2ims + sparse_checkout_files: + - .ci-operator.yaml + - Dockerfile + - Dockerfile.must-gather + - bundle.Dockerfile + labels: + ci-operator.openshift.io/cloud: aws + ci-operator.openshift.io/cloud-cluster-profile: openshift-org-aws + ci.openshift.io/generator: prowgen + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: periodic-ci-openshift-kni-oran-o2ims-main-install-bundle-tls-scan-periodic + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --secret-dir=/secrets/ci-pull-credentials + - --target=install-bundle-tls-scan-periodic + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/ci-pull-credentials + name: ci-pull-credentials + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: ci-pull-credentials + secret: + secretName: ci-pull-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator diff --git a/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-periodics.yaml b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-periodics.yaml new file mode 100644 index 0000000000000..7a86f99988522 --- /dev/null +++ b/ci-operator/jobs/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22-periodics.yaml @@ -0,0 +1,90 @@ +periodics: +- agent: kubernetes + cluster: build07 + cron: 0 3 * * 1 + decorate: true + decoration_config: + sparse_checkout_files: + - .ci-operator.yaml + - Dockerfile + - Dockerfile.must-gather + - bundle.Dockerfile + extra_refs: + - base_ref: release-4.22 + org: openshift-kni + repo: oran-o2ims + sparse_checkout_files: + - .ci-operator.yaml + - Dockerfile + - Dockerfile.must-gather + - bundle.Dockerfile + labels: + ci-operator.openshift.io/cloud: aws + ci-operator.openshift.io/cloud-cluster-profile: openshift-org-aws + ci.openshift.io/generator: prowgen + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: periodic-ci-openshift-kni-oran-o2ims-release-4.22-install-bundle-tls-scan-periodic + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --secret-dir=/secrets/ci-pull-credentials + - --target=install-bundle-tls-scan-periodic + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/ci-pull-credentials + name: ci-pull-credentials + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: ci-pull-credentials + secret: + secretName: ci-pull-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator From ec0708a3c60d090e149ac19a2c816a255f58bd9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Hern=C3=A1ndez?= Date: Sun, 9 Aug 2026 10:50:42 +0200 Subject: [PATCH 10/10] oran-o2ims: enable PQC readiness check in TLS scan jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set PQC_CHECK=true across all TLS scan pipelines (on-demand and periodic) for main and release-4.22. This enables post-quantum cryptography readiness checks (TLS 1.3 + mlkem/mlkem25519 support). Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Raúl Hernández --- .../openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml | 2 ++ .../oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml index 647228cbfaa33..fff9ed8207fdb 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-main.yaml @@ -120,6 +120,7 @@ tests: env: COMPUTE_NODE_TYPE: m5.2xlarge OO_INSTALL_NAMESPACE: oran-o2ims + PQC_CHECK: "true" SCAN_NAMESPACE: oran-o2ims SCANNER_NAMESPACE: oran-o2ims TLS_13_ENABLE_TLS_ADHERENCE: "true" @@ -209,6 +210,7 @@ tests: env: COMPUTE_NODE_TYPE: m5.2xlarge OO_INSTALL_NAMESPACE: oran-o2ims + PQC_CHECK: "true" SCAN_NAMESPACE: oran-o2ims SCANNER_NAMESPACE: oran-o2ims TLS_13_ENABLE_TLS_ADHERENCE: "true" diff --git a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml index fd0045f698cb4..9bdcc253d28fa 100644 --- a/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml +++ b/ci-operator/config/openshift-kni/oran-o2ims/openshift-kni-oran-o2ims-release-4.22.yaml @@ -120,6 +120,7 @@ tests: env: COMPUTE_NODE_TYPE: m5.2xlarge OO_INSTALL_NAMESPACE: oran-o2ims + PQC_CHECK: "true" SCAN_NAMESPACE: oran-o2ims SCANNER_NAMESPACE: oran-o2ims TLS_13_ENABLE_TLS_ADHERENCE: "true" @@ -209,6 +210,7 @@ tests: env: COMPUTE_NODE_TYPE: m5.2xlarge OO_INSTALL_NAMESPACE: oran-o2ims + PQC_CHECK: "true" SCAN_NAMESPACE: oran-o2ims SCANNER_NAMESPACE: oran-o2ims TLS_13_ENABLE_TLS_ADHERENCE: "true"