Skip to content

CNTRLPLANE-3616: e2e tests for TLS profile change of konnectivity-server - #8886

Open
kaleemsiddiqu wants to merge 1 commit into
openshift:mainfrom
kaleemsiddiqu:test-cntrlplane-3616
Open

CNTRLPLANE-3616: e2e tests for TLS profile change of konnectivity-server#8886
kaleemsiddiqu wants to merge 1 commit into
openshift:mainfrom
kaleemsiddiqu:test-cntrlplane-3616

Conversation

@kaleemsiddiqu

@kaleemsiddiqu kaleemsiddiqu commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

e2e tests added for konnectivity-server to verify that TLS profile propagation is respected correctly after this new flag addition

test for changes done in #8866

Summary by CodeRabbit

  • Tests
    • Added new end-to-end coverage for konnectivity server TLS configuration on the management cluster.
    • Verifies the server reflects HostedCluster API server TLS security profile changes, including minimum TLS version updates.
    • Confirms handshake behavior: default/intermediate allows TLS 1.2 and TLS 1.3, while Modern allows TLS 1.3 and rejects TLS 1.2.
    • Restores the original TLS profile after test execution.

@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: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 1, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 1, 2026

Copy link
Copy Markdown

@kaleemsiddiqu: This pull request references CNTRLPLANE-3616 which is a valid jira issue.

Details

In response to this:

e2e tests added for konnectivity-server to verify that TLS profile propagation is respected correctly after this new flag addition

test for changes done in #8866

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 openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 606cc58d-ed8f-4e4d-b04c-495fc63ceead

📥 Commits

Reviewing files that changed from the base of the PR and between 5304af1 and 7ea7e6e.

📒 Files selected for processing (1)
  • test/e2e/v2/tests/konnectivity_server_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/e2e/v2/tests/konnectivity_server_test.go

📝 Walkthrough

Walkthrough

This PR adds a new Go e2e v2 test suite for konnectivity-server TLS configuration. It registers VerifyKonnectivityServerTLSConfigTest, checks the --tls-min-version argument on the konnectivity-server container in the kube-apiserver deployment, and runs openssl s_client from a kube-apiserver pod to verify TLS 1.2 and TLS 1.3 behavior across default/intermediate and Modern HostedCluster APIServer TLS profiles. It also updates the HostedCluster profile during the test, waits for rollout changes, and restores the original configuration in cleanup.

Sequence Diagram(s)

sequenceDiagram
  participant Test as VerifyKonnectivityServerTLSConfigTest
  participant HostedCluster
  participant KubeAPIServerPod as kube-apiserver pod
  participant Konnectivity as konnectivity-server

  Test->>HostedCluster: capture original APIServer TLS profile
  Test->>KubeAPIServerPod: inspect konnectivity-server args
  Test->>KubeAPIServerPod: exec openssl s_client for TLS 1.2 and TLS 1.3
  KubeAPIServerPod->>Konnectivity: handshake attempts
  Konnectivity-->>KubeAPIServerPod: accept both versions

  Test->>HostedCluster: update profile to Modern
  Test->>KubeAPIServerPod: wait for VersionTLS13
  Test->>KubeAPIServerPod: exec openssl s_client for TLS 1.3 and TLS 1.2
  KubeAPIServerPod->>Konnectivity: handshake attempts
  Konnectivity-->>KubeAPIServerPod: accept TLS 1.3, reject TLS 1.2

  Test->>HostedCluster: remove Modern profile
  Test->>KubeAPIServerPod: wait for VersionTLS12
  Test->>KubeAPIServerPod: exec openssl s_client for TLS 1.2 and TLS 1.3
  KubeAPIServerPod->>Konnectivity: handshake attempts
  Konnectivity-->>KubeAPIServerPod: accept both versions again

  Test->>HostedCluster: restore original profile
Loading

Related PRs: None identified.

Suggested labels: e2e, test, konnectivity, tls

Suggested reviewers: enxebre

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: new e2e tests covering konnectivity-server TLS profile changes.
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 Ginkgo titles in the new test file are static strings; none include generated or runtime-changing values.
Test Structure And Quality ✅ Passed PASS: Focused It blocks, explicit timeouts on waits/Eventually, meaningful assertion messages, and AfterAll cleanup restoring the HostedCluster; pattern matches other ordered e2e tests.
Topology-Aware Scheduling Compatibility ✅ Passed Only a new e2e test file was added; it contains no manifests, replicas, affinity, nodeSelectors, PDBs, or topology-dependent scheduling logic.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Tests use cluster-internal localhost via pod exec; no hardcoded IPv4 addresses, IP parsing, or external/public connectivity found.
No-Weak-Crypto ✅ Passed Only TLS-version checks via openssl s_client; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token compares found.
Container-Privileges ✅ Passed The only changed file is an e2e Go test and it contains no privileged/hostPID/hostNetwork/hostIPC/SYS_ADMIN/allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed The new test only logs generic progress plus a pod name/error on restore failure; no passwords, tokens, API keys, PII, or customer data are printed.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci
openshift-ci Bot requested review from csrwng and sjenning July 1, 2026 12:36
@openshift-ci openshift-ci Bot added area/testing Indicates the PR includes changes for e2e testing and removed do-not-merge/needs-area labels Jul 1, 2026
@openshift-ci

openshift-ci Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
test/e2e/v2/tests/konnectivity_server_test.go (1)

623-623: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use plain v2 Ginkgo names instead of legacy string annotations.

The current v2 convention is to keep Describe names plain and express filtering/classification via labels.

Suggested fix
-var _ = Describe("[sig-hypershift][Jira:Hypershift][Feature:KonnectivityServer] Konnectivity Server TLS Configuration", Label("konnectivity-server"), func() {
+var _ = Describe("Konnectivity Server TLS Configuration", Label("konnectivity-server"), func() {

Based on learnings, v2 E2E tests should not include legacy [sig-hypershift], [Jira:Hypershift], or [Feature:XYZ] annotations in Ginkgo Describe names.

🤖 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/e2e/v2/tests/konnectivity_server_test.go` at line 623, The Describe in
konnectivity_server_test.go still uses legacy Ginkgo v1-style annotations in the
test title. Update the Describe name in the konnectivity server test to a plain
v2 name and keep classification in the existing Label("konnectivity-server")
(and any other labels if needed) instead of embedding [sig-hypershift],
[Jira:Hypershift], or [Feature:...] in the string.

Source: Learnings

🤖 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/e2e/v2/tests/konnectivity_server_test.go`:
- Around line 112-114: The konnectivity server test is only checking
kasPodList.Items[0], so an HA control plane can hide stale kube-apiserver pods.
Update the affected assertions in konnectivity_server_test.go to iterate over
all kube-apiserver pods returned by the list, or use a deterministic selector
only after confirming the full replica set is updated. Apply this to the
repeated kasPodList.Items[0] checks in the relevant test blocks so each pod’s
phase, args, and TLS behavior are validated consistently.
- Around line 278-285: The polling block in Eventually for kube-apiserver pod
discovery should not return early on mgmtClient.List errors, because that makes
the poll succeed without validating anything. In the konnectivity_server_test.go
checks that use mgmtClient.List with kasPodList and MatchingLabels{"app":
"kube-apiserver"}, replace the silent return with a failed Gomega expectation or
explicit failure so the Eventually retry fails loudly. Apply the same fix in
both affected polling sections so listing failures cannot be masked.
- Around line 349-352: The readiness checks over kasPod.Status.ContainerStatuses
can pass vacuously when the slice is empty, so add an explicit non-empty
assertion before the per-container loop in the konnectivity server test. Update
both ContainerStatuses iterations in this test to first verify the list has at
least one entry, then keep the existing container-by-container Ready assertions.
Use the existing kasPod.Status.ContainerStatuses and containerStatus.Ready
checks as the place to apply the fix.
- Around line 77-90: The cleanup for the HostedCluster state only restores the
TLSSecurityProfile, so it can leave empty Spec.Configuration or APIServer
structs behind when they were originally nil. In konnectivity_server_test.go,
update the BeforeAll capture logic around the
hostedCluster.Spec.Configuration.APIServer.TLSSecurityProfile snapshot to also
record whether Spec.Configuration and APIServer existed before mutation. Then
restore the exact original shape in the cleanup path using those captured flags,
not just the TLS profile.

---

Nitpick comments:
In `@test/e2e/v2/tests/konnectivity_server_test.go`:
- Line 623: The Describe in konnectivity_server_test.go still uses legacy Ginkgo
v1-style annotations in the test title. Update the Describe name in the
konnectivity server test to a plain v2 name and keep classification in the
existing Label("konnectivity-server") (and any other labels if needed) instead
of embedding [sig-hypershift], [Jira:Hypershift], or [Feature:...] in the
string.
🪄 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: 8d835ec8-e5fc-4bb8-a4cb-f644c4b39fb2

📥 Commits

Reviewing files that changed from the base of the PR and between ca3d347 and 5304af1.

📒 Files selected for processing (1)
  • test/e2e/v2/tests/konnectivity_server_test.go

Comment thread test/e2e/v2/tests/konnectivity_server_test.go Outdated
Comment on lines +112 to +114
kasPod := &kasPodList.Items[0]
Expect(kasPod.Status.Phase).To(Equal(corev1.PodRunning),
"kube-apiserver pod should be running")

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Avoid validating only the first kube-apiserver pod.

The test repeatedly uses kasPodList.Items[0], so an HA control plane can pass while another kube-apiserver pod still has stale konnectivity args or TLS behavior. Iterate all listed pods, or select deterministically only after proving the intended replica set is fully updated.

Also applies to: 170-185, 215-239, 288-303, 333-352, 369-380, 395-409, 460-475, 506-525, 542-579

🤖 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/e2e/v2/tests/konnectivity_server_test.go` around lines 112 - 114, The
konnectivity server test is only checking kasPodList.Items[0], so an HA control
plane can hide stale kube-apiserver pods. Update the affected assertions in
konnectivity_server_test.go to iterate over all kube-apiserver pods returned by
the list, or use a deterministic selector only after confirming the full replica
set is updated. Apply this to the repeated kasPodList.Items[0] checks in the
relevant test blocks so each pod’s phase, args, and TLS behavior are validated
consistently.

Source: Path instructions

Comment on lines +278 to +285
err := mgmtClient.List(tc.Context, kasPodList,
crclient.InNamespace(tc.ControlPlaneNamespace),
crclient.MatchingLabels{"app": "kube-apiserver"},
)

if err != nil {
return
}

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not silently pass Eventually when pod listing fails.

In Eventually(func(g Gomega)), returning without a failed expectation makes that poll successful. These branches can let propagation checks pass without ever listing kube-apiserver pods.

Suggested fix
-				if err != nil {
-					return
-				}
+				g.Expect(err).NotTo(HaveOccurred(), "failed to list kube-apiserver pods")

As per path instructions, framework paths should fail loudly rather than silently swallow errors.

Also applies to: 449-457

🤖 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/e2e/v2/tests/konnectivity_server_test.go` around lines 278 - 285, The
polling block in Eventually for kube-apiserver pod discovery should not return
early on mgmtClient.List errors, because that makes the poll succeed without
validating anything. In the konnectivity_server_test.go checks that use
mgmtClient.List with kasPodList and MatchingLabels{"app": "kube-apiserver"},
replace the silent return with a failed Gomega expectation or explicit failure
so the Eventually retry fails loudly. Apply the same fix in both affected
polling sections so listing failures cannot be masked.

Source: Path instructions

Comment on lines +349 to +352
for _, containerStatus := range kasPod.Status.ContainerStatuses {
g.Expect(containerStatus.Ready).To(BeTrue(),
"container %s should be ready in pod %s", containerStatus.Name, kasPod.Name)
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert container statuses are present before per-container checks.

If ContainerStatuses is empty, these readiness loops pass vacuously. Add a non-empty assertion before iterating.

Suggested fix
+				g.Expect(kasPod.Status.ContainerStatuses).NotTo(BeEmpty(),
+					"expected container statuses on pod %s", kasPod.Name)
 				for _, containerStatus := range kasPod.Status.ContainerStatuses {

As per path instructions, before iterating a list and asserting on each item, assert the list is non-empty.

Also applies to: 522-525

🤖 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/e2e/v2/tests/konnectivity_server_test.go` around lines 349 - 352, The
readiness checks over kasPod.Status.ContainerStatuses can pass vacuously when
the slice is empty, so add an explicit non-empty assertion before the
per-container loop in the konnectivity server test. Update both
ContainerStatuses iterations in this test to first verify the list has at least
one entry, then keep the existing container-by-container Ready assertions. Use
the existing kasPod.Status.ContainerStatuses and containerStatus.Ready checks as
the place to apply the fix.

Source: Path instructions

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 43.26%. Comparing base (dda6055) to head (5304af1).

⚠️ Current head 5304af1 differs from pull request most recent head 7ea7e6e

Please upload reports for the commit 7ea7e6e to get more accurate results.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8886      +/-   ##
==========================================
- Coverage   43.45%   43.26%   -0.20%     
==========================================
  Files         771      770       -1     
  Lines       95718    95479     -239     
==========================================
- Hits        41597    41311     -286     
- Misses      51234    51284      +50     
+ Partials     2887     2884       -3     

see 15 files with indirect coverage changes

Flag Coverage Δ
cmd-support 36.62% <ø> (-0.51%) ⬇️
cpo-hostedcontrolplane 45.31% <ø> (+0.10%) ⬆️
cpo-other 45.10% <ø> (ø)
hypershift-operator 53.59% <ø> (-0.07%) ⬇️
other 31.69% <ø> (-0.39%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

e2e tests added for konnectivity-server to verify that TLS profile
propagation is respected correctly after this new flag addition

Signed-off-by: Kaleemullah Siddiqui <ksiddiqu@redhat.com>
@kaleemsiddiqu
kaleemsiddiqu force-pushed the test-cntrlplane-3616 branch from 5304af1 to 7ea7e6e Compare July 7, 2026 11:36
@kaleemsiddiqu

Copy link
Copy Markdown
Contributor Author

/retest

@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@kaleemsiddiqu: The following test 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/images 7ea7e6e link true /test images

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.

@hypershift-jira-solve-ci

hypershift-jira-solve-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

The diff's +51 maps to file line 45 (accounting for the file starting at line 1 in the diff with header offset), which matches the error exactly: konnectivity_server_test.go:45:6: hostedClusterHasTLSProfileType redeclared in this block.

Now I have all the evidence. Here's the complete analysis:

Test Failure Analysis Complete

Job Information

Test Failure Analysis

Error

GO111MODULE=on GOWORK=off GOFLAGS=-mod=vendor go vet -tags integration,e2e,reqserving,e2ev2,backuprestore ./...
# github.com/openshift/hypershift/test/e2e/v2/tests
# [github.com/openshift/hypershift/test/e2e/v2/tests]
vet: test/e2e/v2/tests/konnectivity_server_test.go:45:6: hostedClusterHasTLSProfileType redeclared in this block
make: *** [Makefile:533: vet] Error 1

Summary

The make vet step fails because the new file test/e2e/v2/tests/konnectivity_server_test.go (added by this PR) declares a function hostedClusterHasTLSProfileType that is already defined in test/e2e/v2/tests/control_plane_pki_operator_test.go in the same Go package (tests). Since both files share the //go:build e2ev2 build tag and belong to the same package, go vet (run with -tags e2ev2) sees two identical top-level function declarations and reports a compilation error.

Root Cause

The function hostedClusterHasTLSProfileType is defined identically in two files within the same Go package tests:

  1. Existing: test/e2e/v2/tests/control_plane_pki_operator_test.go (line 48) — already present on main
  2. New (this PR): test/e2e/v2/tests/konnectivity_server_test.go (line 45) — added by this PR

Both files use the //go:build e2ev2 build constraint. The CI make vet command runs with -tags integration,e2e,reqserving,e2ev2,backuprestore, so both files are included in compilation, and Go detects the duplicate function declaration.

The function has the same signature and implementation in both files:

func hostedClusterHasTLSProfileType(hc *hyperv1.HostedCluster, profileType configv1.TLSProfileType) bool {
    return hc.Spec.Configuration != nil &&
        hc.Spec.Configuration.APIServer != nil &&
        hc.Spec.Configuration.APIServer.TLSSecurityProfile != nil &&
        hc.Spec.Configuration.APIServer.TLSSecurityProfile.Type == profileType
}

This is a straightforward Go compilation rule — a package-scoped identifier cannot be declared twice within the same package. The author likely copied helper functions from control_plane_pki_operator_test.go (which tests similar TLS profile functionality for the PKI operator) into the new konnectivity-server test file without removing the duplicate.

Recommendations
  1. Remove the duplicate declaration from konnectivity_server_test.go — delete the hostedClusterHasTLSProfileType function definition (lines 44–49) since it already exists in control_plane_pki_operator_test.go. The function is package-scoped, so the new test file can use it directly without re-declaring it.

  2. Consider extracting shared helpers — both control_plane_pki_operator_test.go and konnectivity_server_test.go test TLS profile behavior and share similar patterns (checking TLS profile type, getting kube-apiserver deployment, waiting for rollout, exec-ing into pods). Consider moving shared helpers like hostedClusterHasTLSProfileType, getTLSMinVersionFromArgs, getKubeAPIServerDeployment, waitForKubeAPIServerRollout, and getReadyKubeAPIServerPod into a common helpers file (e.g., test/e2e/v2/tests/helpers_test.go) to avoid future duplication.

  3. Verify no other functions will conflict — the other helper functions (getTLSMinVersionFromArgs, getKubeAPIServerDeployment, waitForKubeAPIServerRollout, getReadyKubeAPIServerPod) are currently only defined in the new file and do not conflict, but may be candidates for sharing in the future.

Evidence
Evidence Detail
Failing step make vet (go vet -tags integration,e2e,reqserving,e2ev2,backuprestore ./...)
Error message vet: test/e2e/v2/tests/konnectivity_server_test.go:45:6: hostedClusterHasTLSProfileType redeclared in this block
Duplicate location 1 test/e2e/v2/tests/control_plane_pki_operator_test.go:48 (existing on main)
Duplicate location 2 test/e2e/v2/tests/konnectivity_server_test.go:45 (added by PR #8886)
Build tag Both files use //go:build e2ev2, so both compile under the vet tags
Go package Both files are in package tests (test/e2e/v2/tests/)
PR files changed Only test/e2e/v2/tests/konnectivity_server_test.go (new file, 558 lines)
Fix complexity Trivial — remove 6 lines (the duplicate function definition)

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

Labels

area/testing Indicates the PR includes changes for e2e testing jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants