Skip to content

fix(security): read FIPS state from HostedCluster on HyperShift#31288

Open
mgencur wants to merge 1 commit into
openshift:mainfrom
mgencur:hypershift_fips
Open

fix(security): read FIPS state from HostedCluster on HyperShift#31288
mgencur wants to merge 1 commit into
openshift:mainfrom
mgencur:hypershift_fips

Conversation

@mgencur

@mgencur mgencur commented Jun 11, 2026

Copy link
Copy Markdown

On HyperShift hosted clusters, the install-config ConfigMap in kube-system does not reflect the actual FIPS configuration. Instead, FIPS is set via .spec.fips on the HostedCluster resource in the management cluster.

Add helpers to discover the HostedCluster and read its FIPS field via the management cluster API. When the management cluster env vars are not set, the test is skipped. Remove unused installConfigName const.

Summary by CodeRabbit

  • Tests
    • Enhanced FIPS compliance validation testing to support HyperShift hosted cluster environments, improving test coverage for externally managed control plane topologies with refined topology detection.

On HyperShift hosted clusters, the install-config ConfigMap in
kube-system does not reflect the actual FIPS configuration. Instead,
FIPS is set via .spec.fips on the HostedCluster resource in the
management cluster.

Add helpers to discover the HostedCluster and read its FIPS field
via the management cluster API. When the management cluster env vars
are not set, the test is skipped. Remove unused installConfigName
const.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@mgencur

mgencur commented Jun 11, 2026

Copy link
Copy Markdown
Author

/hold

@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 11, 2026
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Walkthrough

This PR extends FIPS security testing in OpenShift to support HyperShift-managed external control planes. It adds discovery helpers to query hosted cluster FIPS settings from a management cluster, and refactors the TestFIPS test to conditionally use those helpers when the control plane topology is external.

Changes

HyperShift FIPS External Topology Support

Layer / File(s) Summary
HyperShift discovery helpers and imports
test/extended/security/fips.go
Adds os import for environment-variable checks. Isolates fipsFile constant. Introduces discoverHostedCluster (queries management cluster to find hosted cluster name/namespace by matching HCP namespace) and isHostedClusterFIPS (fetches and parses .spec.fips from the discovered HostedCluster).
TestFIPS external topology mode handling
test/extended/security/fips.go
Restructures TestFIPS to detect ExternalTopologyMode and branch: external mode requires management cluster kubeconfig and namespace, then uses isHostedClusterFIPS to determine expected FIPS state; non-external mode retains existing behavior of computing FIPS with exutil.IsFIPS and validating on the first master node. Removes prior conditional skip of master-node validation for external control planes.

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 13 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning Test lacks meaningful assertion messages on 7 Expect() calls and has unsafe array access: masterNodes.Items[0] accessed without bounds check while workerNodes safely checks length first. Add context messages to all o.Expect(err).NotTo(o.HaveOccurred()) calls. Add bounds check: if len(masterNodes.Items) > 0 before accessing masterNodes.Items[0] to prevent panic.
✅ Passed checks (13 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately reflects the main change: adding logic to read FIPS state from the HostedCluster resource on HyperShift, rather than relying on install-config in kube-system.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed Test titles "[sig-arch] [Conformance] FIPS" and "TestFIPS" are static and deterministic with no dynamic information like pod names, timestamps, UUIDs, node names, or IP addresses.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. The existing test "[sig-arch] [Conformance] FIPS" is refactored to support HyperShift, not created new. The check applies only to new tests being added.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The check applies only to newly added Ginkgo e2e tests. This PR modifies an existing test (TestFIPS), not add new ones, so the check does not apply.
Topology-Aware Scheduling Compatibility ✅ Passed Changes are in a test file (test/extended/security/fips.go), not deployment manifests, operator code, or controllers. The check scope explicitly excludes test files.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes detected. New helper functions isHostedClusterFIPS and discoverHostedCluster are only called within the It() test block (lines 110, 80), not at process initialization...
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The FIPS test file contains no IPv4 assumptions or external connectivity requirements. All test operations are internal cluster API calls (listing nodes, running debug pods) that work transparently...
No-Weak-Crypto ✅ Passed No weak cryptographic algorithms (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or non-constant-time secret comparisons found in the code changes.
Container-Privileges ✅ Passed The PR only modifies test/extended/security/fips.go, a Go test file with no container or K8s manifest definitions containing privileged: true, hostPID/Network/IPC, SYS_ADMIN capabilities, or allowP...
No-Sensitive-Data-In-Logs ✅ Passed The code contains no logging of sensitive data including passwords, tokens, API keys, PII, session IDs, internal hostnames, or customer data. Environment variables are only checked for emptiness, n...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci

openshift-ci Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mgencur
Once this PR has been reviewed and has the lgtm label, please assign petr-muller for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/extended/security/fips.go (1)

61-68: ⚡ Quick win

Consider validating parsed Kubernetes resource names.

The parsed ns and name values from jsonpath output are used in a subsequent CLI call (line 86-87) without validation. While these should be valid DNS labels from the Kubernetes API, defense-in-depth suggests validating the format before use.

🛡️ Add validation for extracted names
 for _, line := range strings.Split(strings.TrimSpace(output), "\n") {
     parts := strings.SplitN(line, ",", 2)
     if len(parts) == 2 {
         ns, name := parts[0], parts[1]
+        // Validate DNS label format (alphanumeric, '-', '.', max 63 chars)
+        if ns == "" || name == "" || len(ns) > 63 || len(name) > 63 {
+            continue
+        }
         if ns+"-"+name == hcpNS {
             return name, ns, nil
         }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/extended/security/fips.go` around lines 61 - 68, The parsed ns and name
extracted from the jsonpath output are used directly; validate they are valid
Kubernetes DNS-1123 labels before using or returning them. Inside the loop that
processes parts (the variables ns and name), add a check using the Kubernetes
DNS-1123 label rules (e.g.,
k8s.io/apimachinery/pkg/util/validation.IsDNS1123Label or equivalent regex:
lowercase alphanumerics and '-' only, start/end with alphanumeric, max 63 chars)
and skip any entries that fail validation; only perform the ns+"-"+name
comparison and return name, ns, nil when both ns and name pass validation.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/extended/security/fips.go`:
- Around line 61-68: The parsed ns and name extracted from the jsonpath output
are used directly; validate they are valid Kubernetes DNS-1123 labels before
using or returning them. Inside the loop that processes parts (the variables ns
and name), add a check using the Kubernetes DNS-1123 label rules (e.g.,
k8s.io/apimachinery/pkg/util/validation.IsDNS1123Label or equivalent regex:
lowercase alphanumerics and '-' only, start/end with alphanumeric, max 63 chars)
and skip any entries that fail validation; only perform the ns+"-"+name
comparison and return name, ns, nil when both ns and name pass validation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 4f2e9246-39f0-4302-9390-b259eb275cdf

📥 Commits

Reviewing files that changed from the base of the PR and between bde16f5 and 905c035.

📒 Files selected for processing (1)
  • test/extended/security/fips.go

@openshift-ci openshift-ci Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jun 11, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e-aws-csi
/test e2e-aws-ovn-fips
/test e2e-aws-ovn-microshift
/test e2e-aws-ovn-microshift-serial
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-gcp-csi
/test e2e-gcp-ovn
/test e2e-gcp-ovn-upgrade
/test e2e-metal-ipi-ovn-ipv6
/test e2e-vsphere-ovn
/test e2e-vsphere-ovn-upi

@mgencur

mgencur commented Jun 11, 2026

Copy link
Copy Markdown
Author

/unhold

Locally it's passing for me with these env variables set and hosted cluster being FIPS-compliant:

KUBECONFIG=/home/mgencur/hypershift/clusters/dev/kubeconfig
HYPERSHIFT_MANAGEMENT_CLUSTER_KUBECONFIG=/home/mgencur/hypershift/clusters/mgmt/kubeconfig
HYPERSHIFT_MANAGEMENT_CLUSTER_NAMESPACE=clusters-mgencur-hc1

Log:

started: 0/1/1 "[sig-arch] [Conformance] FIPS TestFIPS [Suite:openshift/conformance/parallel/minimal]"

  E0611 16:14:49.391226 2597040 reflector.go:204] "Failed to watch" err="failed to list *v1beta1.Machine: the server could not find the requested resource (get machines.machine.openshift.io)" reflector="k8s.io/client-go@v0.35.1/tools/cache/reflector.go:289" type="*v1beta1.Machine"
  E0611 16:14:50.926019 2597040 reflector.go:204] "Failed to watch" err="failed to list *v1beta1.Machine: the server could not find the requested resource (get machines.machine.openshift.io)" reflector="k8s.io/client-go@v0.35.1/tools/cache/reflector.go:289" type="*v1beta1.Machine"
  E0611 16:14:54.012935 2597040 reflector.go:204] "Failed to watch" err="failed to list *v1beta1.Machine: the server could not find the requested resource (get machines.machine.openshift.io)" reflector="k8s.io/client-go@v0.35.1/tools/cache/reflector.go:289" type="*v1beta1.Machine"
  E0611 16:15:00.449071 2597040 reflector.go:204] "Failed to watch" err="failed to list *v1beta1.Machine: the server could not find the requested resource (get machines.machine.openshift.io)" reflector="k8s.io/client-go@v0.35.1/tools/cache/reflector.go:289" type="*v1beta1.Machine"
passed: (10.2s) 2026-06-11T14:15:01 "[sig-arch] [Conformance] FIPS TestFIPS [Suite:openshift/conformance/parallel/minimal]"

INFO[0018] Completed OpenShift test bucket in 12.770622721s 
INFO[0018] Completed MustGather test bucket in 5.478µs  
INFO[0018] Completed Late test bucket in 3.446µs        
Shutting down the monitor
Collecting data.
INFO[0018] Starting CollectData for all monitor tests   
INFO[0018]   Starting CollectData for [Monitor:machine-lifecycle][Jira:"Cluster-Lifecycle / machine-api"] monitor test machine-lifecycle collection 
INFO[0018]   Finished CollectData for [Monitor:machine-lifecycle][Jira:"Cluster-Lifecycle / machine-api"] monitor test machine-lifecycle collection 
INFO[0018] Finished CollectData for all monitor tests   
Computing intervals.
Evaluating tests.
Cleaning up.
INFO[0018] beginning cleanup                             monitorTest=machine-lifecycle
Serializing results.
Writing to storage.
  m.startTime = 2026-06-11 16:14:48.98684515 +0200 CEST m=+5.827097945
  m.stopTime  = 2026-06-11 16:15:01.75883876 +0200 CEST m=+18.599091555
Processing monitorTest: machine-lifecycle
  finalIntervals size = 13
  first interval time: From = 2026-06-11 16:14:48.988032464 +0200 CEST m=+5.828285261; To = 2026-06-11 16:14:48.988036471 +0200 CEST m=+5.828289267
  last interval time: From = 2026-06-11 16:15:01.758760985 +0200 CEST m=+18.599014128; To = 2026-06-11 16:15:01.758764609 +0200 CEST m=+18.599017405
Writing junits.
Writing JUnit report to e2e-monitor-tests__20260611-141448.xml
  I0611 16:15:03.220151 2597040 write_job_run_data.go:41] Error building cluster data: error listing MCPs: the server could not find the requested resource (get machineconfigpools.machineconfiguration.openshift.io)
  I0611 16:15:03.220235 2597040 write_job_run_data.go:43] Ignoring cluster data due to previous errors: {{5.0  aws amd64 ovn external} {{   []}} IPv4 us-east-1 us-east-1a [5.0.0-0.nightly-multi-2026-06-08-075337] }
Writing extension test results.
Writing extension test results JSON to extension_test_result_monitors__20260611-141448.json
Writing extension test results HTML to extension_test_result_monitors__20260611-141448-summary.html
INFO[0020] Mass failure check passed: 0 failures (threshold: 10 failures) 
1 pass, 0 flaky, 0 skip (13s)

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jun 11, 2026
@openshift-ci

openshift-ci Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@mgencur: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-aws-ovn-serial-1of2 905c035 link true /test e2e-aws-ovn-serial-1of2
ci/prow/e2e-aws-ovn-microshift-serial 905c035 link true /test e2e-aws-ovn-microshift-serial
ci/prow/e2e-aws-ovn-microshift 905c035 link true /test e2e-aws-ovn-microshift
ci/prow/e2e-metal-ipi-ovn-ipv6 905c035 link true /test e2e-metal-ipi-ovn-ipv6
ci/prow/e2e-aws-ovn-fips 905c035 link true /test e2e-aws-ovn-fips
ci/prow/e2e-aws-ovn-serial-2of2 905c035 link true /test e2e-aws-ovn-serial-2of2
ci/prow/e2e-gcp-ovn-upgrade 905c035 link true /test e2e-gcp-ovn-upgrade
ci/prow/e2e-vsphere-ovn-upi 905c035 link true /test e2e-vsphere-ovn-upi
ci/prow/e2e-vsphere-ovn 905c035 link true /test e2e-vsphere-ovn
ci/prow/e2e-gcp-ovn 905c035 link true /test e2e-gcp-ovn

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant