Skip to content

Add E2E test for the TLSAdherence openshift/api field#31309

Open
richardsonnick wants to merge 1 commit into
openshift:mainfrom
richardsonnick:tls-adherence-e2e
Open

Add E2E test for the TLSAdherence openshift/api field#31309
richardsonnick wants to merge 1 commit into
openshift:mainfrom
richardsonnick:tls-adherence-e2e

Conversation

@richardsonnick

@richardsonnick richardsonnick commented Jun 16, 2026

Copy link
Copy Markdown

Adds E2E tests for the TLSAdherence openshift/api field. This is a requirement for GA.

Summary by CodeRabbit

  • Tests
    • Added integration tests for TLSAdherence feature gate behavior and cluster API server validation
    • Tests verify API server accepts and reflects different TLSAdherence policy configurations
    • Tests confirm TLSAdherence feature gate status is properly reported in cluster configuration
    • Tests validate cluster operators are not degraded during configuration updates

@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

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Walkthrough

A new Ginkgo test file is added under test/extended/apiserver/ that validates TLSAdherence feature gate behavior. It skips for MicroShift/HyperShift or when the gate is disabled, then asserts feature gate presence in status, dry-run spec field updates, policy enum validity, and no degraded cluster operators.

Changes

TLSAdherence Integration Tests

Layer / File(s) Summary
Package, helper, and suite skip guards
test/extended/apiserver/tls_adherence.go
Declares imports and the TLSAdherence feature gate name constant. Adds a helper that queries featuregate/cluster status to check if TLSAdherence is in the enabled list. Defines the Ginkgo Describe suite with a BeforeEach that skips the entire suite on MicroShift/HyperShift or when the feature gate is not enabled.
Feature gate presence, dry-run spec updates, and enum validation
test/extended/apiserver/tls_adherence.go
Asserts TLSAdherence appears in featuregate/cluster .status.featureGates[].enabled[].name. Dry-run updates apiservers/cluster.spec.tlsAdherence to StrictAllComponents and LegacyAdheringComponentsOnly, asserting each reflected value matches. Validates the live spec.tlsAdherence is one of the defined TLSAdherencePolicy enum values.
Cluster operator degradation check
test/extended/apiserver/tls_adherence.go
Lists all cluster operators and fails the test if any operator has Type=OperatorDegraded with Status=True, reporting reason and message in the failure output.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning BeforeEach block (lines 48, 50, 56) contains 3 assertions without meaningful failure messages (e.g., o.Expect(err).NotTo(o.HaveOccurred())), violating custom check requirement #4. Test code itsel... Add failure messages to BeforeEach assertions: e.g., change line 48 to o.Expect(err).NotTo(o.HaveOccurred(), "failed to check if cluster is MicroShift")
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and concisely describes the main change: adding E2E tests for the TLSAdherence openshift/api field, which matches the file added and PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 All test names in tls_adherence.go are stable and deterministic. All It() and Describe() declarations use static strings without dynamic information (no timestamps, UUIDs, pod/namespace names, or g...
Microshift Test Compatibility ✅ Passed All 5 test cases have [apigroup:config.openshift.io] tags and BeforeEach runtime skip check protecting them from MicroShift execution, per the check's allowed protection mechanisms.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The tests are API-level configuration checks using OpenShift APIs (featuregate/cluster, apiservers/cluster, ClusterOperators) with dry-run operations. They make no assumptions about cluster topolog...
Topology-Aware Scheduling Compatibility ✅ Passed This PR adds only integration test code with no deployment manifests, operator code, or controllers. No scheduling constraints are introduced; the check is not applicable.
Ote Binary Stdout Contract ✅ Passed File contains no stdout writes at process level. fmt.Errorf and fmt.Sprintf are used only for error/message formatting, not stdout. No klog, Print, Println, or Printf calls found. All code is withi...
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Test file contains no IPv4 assumptions, hardcoded IPv4 addresses, or external connectivity requirements. All operations use cluster-internal API calls only.
No-Weak-Crypto ✅ Passed No weak cryptography patterns found. File contains only test code for TLSAdherence feature gate validation with no crypto algorithms, custom implementations, or secret comparisons.
Container-Privileges ✅ Passed PR adds only Go test code (test/extended/apiserver/tls_adherence.go) with no container manifests, Kubernetes definitions, or privileged container settings.
No-Sensitive-Data-In-Logs ✅ Passed No sensitive data (passwords, tokens, API keys, PII, session IDs) found in logging. The single g.Fail statement logs cluster operator names, condition reasons, and messages—standard Kubernetes diag...

✏️ 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 16, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: richardsonnick
Once this PR has been reviewed and has the lgtm label, please assign smg247 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

@openshift-ci openshift-ci Bot requested review from p0lyn0mial and sjenning June 16, 2026 18:08

@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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@test/extended/apiserver/tls_adherence.go`:
- Around line 120-131: The test assertion in the It block does not account for
the optional spec.tlsAdherence field being unset. Since the field is marked as
optional with omitempty and the test comment acknowledges "when set", the
apiServer.Spec.TLSAdherence value may be nil, causing the BeElementOf assertion
to fail even when the state is valid. Either guard the assertion with a nil
check that conditionally validates only when the field is set, or add the
nil/zero value to the validValues slice so that an unset field is considered a
valid state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 328d6dfb-fe5e-4dfc-a5f3-811d6c04d0e2

📥 Commits

Reviewing files that changed from the base of the PR and between b3b98a0 and 1f5851c.

📒 Files selected for processing (1)
  • test/extended/apiserver/tls_adherence.go

Comment on lines +120 to +131
g.It("[FeatureGate:TLSAdherence] should have a valid spec.tlsAdherence value on apiservers/cluster [apigroup:config.openshift.io]", func(ctx context.Context) {
apiServer, err := oc.AdminConfigClient().ConfigV1().APIServers().Get(ctx, "cluster", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred(), "failed to get apiservers/cluster")

validValues := []configv1.TLSAdherencePolicy{
configv1.TLSAdherencePolicyNoOpinion,
configv1.TLSAdherencePolicyLegacyAdheringComponentsOnly,
configv1.TLSAdherencePolicyStrictAllComponents,
}
o.Expect(apiServer.Spec.TLSAdherence).To(
o.BeElementOf(validValues),
"apiservers/cluster spec.tlsAdherence must be one of the defined TLSAdherencePolicy values")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify TLSAdherence field type/default semantics and whether empty value is a valid persisted state.

set -euo pipefail

echo "== Locate APIServerSpec TLSAdherence definition =="
rg -n --type=go -C4 '\bTLSAdherence\b' 

echo
echo "== Look for defaulting markers or comments tied to TLSAdherence =="
rg -n --type=go -C3 'default|omitempty|TLSAdherencePolicyNoOpinion|tlsAdherence'

echo
echo "== Check if existing tests treat empty/unset tlsAdherence as valid =="
rg -n --type=go -C3 'spec\.tlsAdherence|TLSAdherencePolicy|BeElementOf'

Repository: openshift/origin

Length of output: 50375


Add a guard to check if spec.tlsAdherence is set before asserting it matches a valid value.

Line 129 asserts apiServer.Spec.TLSAdherence is one of three explicit enum values, but the field is optional (marked omitempty) and can be unset. The test comment on line 119 says "when set," acknowledging that the field may not always be populated. If the field is unset on the cluster, the BeElementOf assertion will fail even though the state is valid. Guard the assertion with a check for whether the field is set, or include the zero/unset value in the valid values list.

🤖 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/apiserver/tls_adherence.go` around lines 120 - 131, The test
assertion in the It block does not account for the optional spec.tlsAdherence
field being unset. Since the field is marked as optional with omitempty and the
test comment acknowledges "when set", the apiServer.Spec.TLSAdherence value may
be nil, causing the BeElementOf assertion to fail even when the state is valid.
Either guard the assertion with a nil check that conditionally validates only
when the field is set, or add the nil/zero value to the validValues slice so
that an unset field is considered a valid state.

Comment on lines +51 to +53
if isMicroShift || isHyperShift {
g.Skip("TLSAdherence is not applicable to MicroShift or HyperShift clusters")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not true, right? I think it is applicable in both, though it may make sense to have a separate test for Hypershift since it has a split apiserver and a HyperShift-specific configuration API for configuring the TLS profile of the hosted cluster.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

oh sorry yes no this is not true. removing.

Comment on lines +63 to +81
g.It("[FeatureGate:TLSAdherence] should have TLSAdherence listed as enabled in featuregate/cluster status [apigroup:config.openshift.io]", func(ctx context.Context) {
fg, err := oc.AdminConfigClient().ConfigV1().FeatureGates().Get(ctx, "cluster", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred(), "failed to get featuregate/cluster")

found := false
for _, featureGateValues := range fg.Status.FeatureGates {
for _, enabledGate := range featureGateValues.Enabled {
if enabledGate.Name == tlsAdherenceFeatureGateName {
found = true
break
}
}
if found {
break
}
}
o.Expect(found).To(o.BeTrue(),
"TLSAdherence must appear in featuregate/cluster .status.featureGates[].enabled[].name")
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can't hurt to verify this, but I don't think this should count toward the 5 tests, the intent of which are more functional rather than verifying assumptions.

Comment on lines +134 to +147
// Test 5 – verify that no cluster operator is degraded when the TLSAdherence feature gate is active.
g.It("[FeatureGate:TLSAdherence] should not have any degraded cluster operators [apigroup:config.openshift.io]", func(ctx context.Context) {
coList, err := oc.AdminConfigClient().ConfigV1().ClusterOperators().List(ctx, metav1.ListOptions{})
o.Expect(err).NotTo(o.HaveOccurred(), "failed to list clusteroperators")

for _, co := range coList.Items {
for _, condition := range co.Status.Conditions {
if condition.Type == configv1.OperatorDegraded && condition.Status == configv1.ConditionTrue {
g.Fail(fmt.Sprintf("cluster operator %q is degraded: %s: %s",
co.Name, condition.Reason, condition.Message))
}
}
}
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think there is a different kind of test that we can implement that essentially continuously monitors the cluster to verify an invariant is never violated. The way this test is implemented, you'll only get a point in time verification, which would likely result in false negatives.

@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

Comment on lines +83 to +117
// Test 2 – verify the API server accepts and reflects StrictAllComponents via dry-run.
g.It("[FeatureGate:TLSAdherence] should accept and reflect spec.tlsAdherence StrictAllComponents on apiservers/cluster [apigroup:config.openshift.io]", func(ctx context.Context) {
current, err := oc.AdminConfigClient().ConfigV1().APIServers().Get(ctx, "cluster", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred(), "failed to get apiservers/cluster")

desired := current.DeepCopy()
desired.Spec.TLSAdherence = configv1.TLSAdherencePolicyStrictAllComponents

result, err := oc.AdminConfigClient().ConfigV1().APIServers().Update(ctx, desired, metav1.UpdateOptions{
DryRun: []string{metav1.DryRunAll},
})
o.Expect(err).NotTo(o.HaveOccurred(),
"apiservers/cluster should accept spec.tlsAdherence=StrictAllComponents")
o.Expect(result.Spec.TLSAdherence).To(
o.Equal(configv1.TLSAdherencePolicyStrictAllComponents),
"apiservers/cluster should reflect spec.tlsAdherence=StrictAllComponents")
})

// Test 3 – verify the API server accepts and reflects LegacyAdheringComponentsOnly via dry-run.
g.It("[FeatureGate:TLSAdherence] should accept and reflect spec.tlsAdherence LegacyAdheringComponentsOnly on apiservers/cluster [apigroup:config.openshift.io]", func(ctx context.Context) {
current, err := oc.AdminConfigClient().ConfigV1().APIServers().Get(ctx, "cluster", metav1.GetOptions{})
o.Expect(err).NotTo(o.HaveOccurred(), "failed to get apiservers/cluster")

desired := current.DeepCopy()
desired.Spec.TLSAdherence = configv1.TLSAdherencePolicyLegacyAdheringComponentsOnly

result, err := oc.AdminConfigClient().ConfigV1().APIServers().Update(ctx, desired, metav1.UpdateOptions{
DryRun: []string{metav1.DryRunAll},
})
o.Expect(err).NotTo(o.HaveOccurred(),
"apiservers/cluster should accept spec.tlsAdherence=LegacyAdheringComponentsOnly")
o.Expect(result.Spec.TLSAdherence).To(
o.Equal(configv1.TLSAdherencePolicyLegacyAdheringComponentsOnly),
"apiservers/cluster should reflect spec.tlsAdherence=LegacyAdheringComponentsOnly")
})

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it's a stretch to make these two separate tests. But I think a single test that verifies that all valid values can be successfully dry-run updated is a reasonable single test to run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it possible to test to make sure this can only be set by cluster-admins? Is there an RBAC in place to test?

@openshift-ci

openshift-ci Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@richardsonnick: 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-vsphere-ovn 1f5851c link true /test e2e-vsphere-ovn
ci/prow/e2e-metal-ipi-ovn-ipv6 1f5851c link true /test e2e-metal-ipi-ovn-ipv6
ci/prow/e2e-gcp-ovn 1f5851c link true /test e2e-gcp-ovn
ci/prow/e2e-aws-ovn-fips 1f5851c link true /test e2e-aws-ovn-fips

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants