Skip to content

NO-JIRA: Moving auth and oas helper funcs to library-go#2333

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift:masterfrom
gangwgr:combine-func
Jun 29, 2026
Merged

NO-JIRA: Moving auth and oas helper funcs to library-go#2333
openshift-merge-bot[bot] merged 1 commit into
openshift:masterfrom
gangwgr:combine-func

Conversation

@gangwgr

@gangwgr gangwgr commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Expanded encryption test coverage for OAuth “token of life” and OpenShift “route of life” resources.
    • Added helper utilities to create these resources and read their raw stored values directly from etcd to confirm encrypted vs plaintext behavior.
    • Introduced assertions that validate both access/authorize token encryption state and that the latest migrated key is recorded for the relevant encryption targets.
    • Enhanced the test client setup with dynamic Kubernetes access to support these helpers.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a shared dynamic client for encryption test helpers, plus OAuth token and OpenShift Route helpers and assertions that create resources, inspect raw etcd values, and verify encryption state.

Changes

Auth & OAS Encryption Test Helpers

Layer / File(s) Summary
Dynamic client wiring
test/library/encryption/helpers.go
Adds dynamic.Interface to ClientSet and initializes it in GetClients.
OAuth token helpers
test/library/encryption/helpers_auth.go
Defines OAuth token-of-life creation and raw etcd reads using the shared dynamic client and etcd key lookup.
OAuth token assertions
test/library/encryption/assertion_auth.go
Defines OAuth access/authorize targets and asserts encrypted or unencrypted token state plus migrated-key tracking.
Route helpers and assertions
test/library/encryption/helpers_oas.go, test/library/encryption/assertion_oas.go
Defines route creation and raw etcd reads, then asserts encrypted or unencrypted route state plus migrated-key tracking.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately summarizes the main change: moving auth and OAS helper functions into library-go.
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 No Ginkgo title calls were added/changed in the diff; touched tests use static native test names only.
Test Structure And Quality ✅ Passed Changed files are helper-only; no _test.go files or Ginkgo blocks were added, so the Ginkgo test-quality check is not applicable.
Microshift Test Compatibility ✅ Passed Helper-only changes; no new Ginkgo It/Describe/Context/When specs were added, and the added OpenShift API usage in helpers includes Route, which MicroShift supports.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The PR only adds/updates encryption helper functions; no new Ginkgo It/Describe/Context/When tests or multi-node assumptions are present.
Topology-Aware Scheduling Compatibility ✅ Passed Only test helper code changed; no deployment, controller, replica, affinity, nodeSelector, or PDB logic was added.
Ote Binary Stdout Contract ✅ Passed The changed files add only test helper functions and t.Log/t.Errorf calls; no main/init/TestMain/RunSpecs or top-level stdout writes were introduced.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo specs were added in the touched files; the new helpers use cluster clients/etcd only and contain no IPv4-only or public-internet assumptions.
No-Weak-Crypto ✅ Passed No weak crypto algorithms or custom crypto code were added; the new strings.Contains checks only inspect plaintext markers in test helpers, not secret comparisons.
Container-Privileges ✅ Passed Only Go test helpers changed; no container/K8s manifests or privilege/securityContext fields were added, so the check is not applicable.
No-Sensitive-Data-In-Logs ✅ Passed Added logs only mention resource names, namespaces, and counts; no passwords, tokens, API keys, PII, or raw etcd values are logged.
✨ 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 bertinatto and dgrisonnet June 25, 2026 12:28

@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: 3

🤖 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/library/encryption/assertion.go`:
- Around line 232-242: The etcd assertion failure messages in
AssertTokenOfLifeNotEncrypted (and the related token-check helper nearby) are
logging sensitive token material by printing the refresh token marker and raw
payload. Update these tests to keep logs redacted: remove the plain-text token
value and raw etcd content from t.Errorf calls, and replace them with generic
failure text that references the assertion name without exposing token data.

In `@test/library/encryption/helpers.go`:
- Around line 523-530: In the helper that calls clientSet.Etcd.Get and then
indexes resp.Kvs[0], stop execution immediately when the returned key count is
not exactly one by replacing the non-fatal t.Errorf path with a fatal assertion
or equivalent early return before indexing. Also switch the lookup from a
prefix-based Get with routeOfLifeEtcdPrefix to an exact key fetch in the
affected helper(s) so similarly named objects do not collide and resp.Kvs[0] is
only accessed when a single result is guaranteed.
- Around line 536-545: The token pre-cleanup in the helper continues into the
create path even when the existing-token lookup or deletion fails, which can
hide the real setup error. Update the logic around
cs.TokenClient.OAuthAccessTokens().Get and Delete to fail fast instead of only
logging, and return immediately on any unexpected error so the helper never
proceeds to Create with an uncertain state. Keep the fix localized to the
existing cleanup flow in the token helper so the failure is surfaced before
later steps run.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 98c693e0-71d6-458c-9707-533c0617919f

📥 Commits

Reviewing files that changed from the base of the PR and between d80d43d and e3c9fbb.

⛔ Files ignored due to path filters (19)
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/internal/internal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/clusterrolescoperestriction.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthauthorizetoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthclient.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthclientauthorization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/scoperestriction.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/useroauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/scheme/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/scheme/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/generated_expansion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauth_client.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthauthorizetoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthclient.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthclientauthorization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/useroauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (2)
  • test/library/encryption/assertion.go
  • test/library/encryption/helpers.go

Comment thread test/library/encryption/assertion.go Outdated
Comment on lines +232 to +242
if strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token not encrypted, token received from etcd have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)
}
}

func AssertTokenOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, rawTokenOfLife runtime.Object) {
t.Helper()
tokenOfLife := rawTokenOfLife.(*oauthapiv1.OAuthAccessToken)
rawTokenValue := GetRawTokenOfLife(t, clientSet)
if !strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token received from etcd doesnt have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)

@coderabbitai coderabbitai Bot Jun 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Avoid logging token material from etcd assertions.

These failure messages include both the refresh token marker and raw etcd payload. Even in test helpers, OAuth token payloads should stay redacted in logs.

Proposed fix
 	rawTokenValue := GetRawTokenOfLife(t, clientSet)
 	if strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
-		t.Errorf("access token not encrypted, token received from etcd have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)
+		t.Errorf("access token not encrypted: raw etcd payload contains the plaintext refresh token marker")
 	}
 }
@@
 	rawTokenValue := GetRawTokenOfLife(t, clientSet)
 	if !strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
-		t.Errorf("access token received from etcd doesnt have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)
+		t.Errorf("access token received from etcd does not contain the expected plaintext refresh token marker")
 	}
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token not encrypted, token received from etcd have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)
}
}
func AssertTokenOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, rawTokenOfLife runtime.Object) {
t.Helper()
tokenOfLife := rawTokenOfLife.(*oauthapiv1.OAuthAccessToken)
rawTokenValue := GetRawTokenOfLife(t, clientSet)
if !strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token received from etcd doesnt have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)
if strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token not encrypted: raw etcd payload contains the plaintext refresh token marker")
}
}
func AssertTokenOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, rawTokenOfLife runtime.Object) {
t.Helper()
tokenOfLife := rawTokenOfLife.(*oauthapiv1.OAuthAccessToken)
rawTokenValue := GetRawTokenOfLife(t, clientSet)
if !strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token received from etcd does not contain the expected plaintext refresh token marker")
}
}
🤖 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/library/encryption/assertion.go` around lines 232 - 242, The etcd
assertion failure messages in AssertTokenOfLifeNotEncrypted (and the related
token-check helper nearby) are logging sensitive token material by printing the
refresh token marker and raw payload. Update these tests to keep logs redacted:
remove the plain-text token value and raw etcd content from t.Errorf calls, and
replace them with generic failure text that references the assertion name
without exposing token data.

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.

Valid concern

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ardaguclu Thanks for confirming — keeping those assertion messages redacted is the right fix here.

Comment thread test/library/encryption/helpers.go Outdated
Comment on lines +523 to +530
resp, err := clientSet.Etcd.Get(timeout, routeOfLifeEtcdPrefix, clientv3.WithPrefix())
require.NoError(t, err)

if len(resp.Kvs) != 1 {
t.Errorf("Expected to get a single key from etcd, got %d", len(resp.Kvs))
}

return string(resp.Kvs[0].Value)

@coderabbitai coderabbitai Bot Jun 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Stop before indexing when etcd returns the wrong number of keys.

After t.Errorf, execution continues and resp.Kvs[0] panics when no key is returned. Use a fatal assertion before indexing; an exact Get also avoids prefix collisions with similarly named objects.

Proposed fix
-	resp, err := clientSet.Etcd.Get(timeout, routeOfLifeEtcdPrefix, clientv3.WithPrefix())
+	resp, err := clientSet.Etcd.Get(timeout, routeOfLifeEtcdPrefix)
 	require.NoError(t, err)
-
-	if len(resp.Kvs) != 1 {
-		t.Errorf("Expected to get a single key from etcd, got %d", len(resp.Kvs))
-	}
+	require.Len(t, resp.Kvs, 1, "Expected to get a single key from etcd")
 
 	return string(resp.Kvs[0].Value)
-	resp, err := clientSet.Etcd.Get(timeout, tokenOfLifeEtcdPrefix, clientv3.WithPrefix())
+	resp, err := clientSet.Etcd.Get(timeout, tokenOfLifeEtcdPrefix)
 	require.NoError(t, err)
-
-	if len(resp.Kvs) != 1 {
-		t.Errorf("Expected to get a single key from etcd, got %d", len(resp.Kvs))
-	}
+	require.Len(t, resp.Kvs, 1, "Expected to get a single key from etcd")
 
 	return string(resp.Kvs[0].Value)

Also applies to: 576-583

🤖 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/library/encryption/helpers.go` around lines 523 - 530, In the helper
that calls clientSet.Etcd.Get and then indexes resp.Kvs[0], stop execution
immediately when the returned key count is not exactly one by replacing the
non-fatal t.Errorf path with a fatal assertion or equivalent early return before
indexing. Also switch the lookup from a prefix-based Get with
routeOfLifeEtcdPrefix to an exact key fetch in the affected helper(s) so
similarly named objects do not collide and resp.Kvs[0] is only accessed when a
single result is guaranteed.

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 concern is valid.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ardaguclu Thanks for confirming — agreed. The helper should fail before indexing resp.Kvs[0], and using an exact etcd key lookup here is the safer choice to avoid prefix collisions.

Comment thread test/library/encryption/helpers.go Outdated
Comment thread test/library/encryption/helpers.go Outdated
t.Helper()
t.Logf("Creating %q in %q namespace", "route-of-life", ns)
rawRouteOfLife := RouteOfLife(t, ns)
routeOfLife, err := cs.RouteClient.Routes(ns).Create(ctx, rawRouteOfLife.(*routev1.Route), metav1.CreateOptions{})

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.

Instead of importing typed client, maybe we can use dynamicclient. So that we would have less dependency;

 func CreateAndStoreRouteOfLife(ctx context.Context, t testing.TB, cs ClientSet, ns string) *routev1.Route {
        t.Helper()
        obj, err := cs.DynamicClient.Resource(routeGVR).Namespace(ns).Create(ctx, RouteOfLife(ns), metav1.CreateOptions{})
        require.NoError(t, err)

        var route routev1.Route
        err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &route)
        require.NoError(t, err)
        return &route
  }

Comment thread test/library/encryption/helpers.go Outdated
return routeOfLife
}

func RouteOfLife(t testing.TB, ns string) runtime.Object {

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.

With dynamicclient, this can be?

 func RouteOfLife(ns string) *unstructured.Unstructured {
        return &unstructured.Unstructured{
                Object: map[string]interface{}{
                        "apiVersion": "route.openshift.io/v1",
                        "kind":       "Route",
                        "metadata": map[string]interface{}{
                                "name":      "route-of-life",
                                "namespace": ns,
                        },
                        "spec": map[string]interface{}{
                                "host": "devcluster.openshift.io",
                                "port": map[string]interface{}{
                                        "targetPort": 2014,
                                },
                                "to": map[string]interface{}{
                                        "name": "dummyroute",
                                },
                        },
                },
        }
  }

Comment thread test/library/encryption/helpers.go Outdated
Comment on lines +523 to +530
resp, err := clientSet.Etcd.Get(timeout, routeOfLifeEtcdPrefix, clientv3.WithPrefix())
require.NoError(t, err)

if len(resp.Kvs) != 1 {
t.Errorf("Expected to get a single key from etcd, got %d", len(resp.Kvs))
}

return string(resp.Kvs[0].Value)

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 concern is valid.

Comment thread test/library/encryption/assertion.go Outdated
}
}

func AssertRoutes(t testing.TB, clientSet ClientSet, expectedMode configv1.EncryptionType, namespace, labelSelector string) {

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.

What about moving this to assertion_auth.go. OAS related ones can be moved under assertion_oas.go.

Comment thread test/library/encryption/helpers.go Outdated
}
}

func CreateAndStoreRouteOfLife(ctx context.Context, t testing.TB, cs ClientSet, ns string) runtime.Object {

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 can go under helpers_oas.go

Comment thread test/library/encryption/helpers.go Outdated
return string(resp.Kvs[0].Value)
}

func CreateAndStoreTokenOfLife(ctx context.Context, t testing.TB, cs ClientSet) runtime.Object {

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 can go under helpers_auth.go

Comment thread test/library/encryption/assertion.go Outdated
Comment on lines +232 to +242
if strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token not encrypted, token received from etcd have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)
}
}

func AssertTokenOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, rawTokenOfLife runtime.Object) {
t.Helper()
tokenOfLife := rawTokenOfLife.(*oauthapiv1.OAuthAccessToken)
rawTokenValue := GetRawTokenOfLife(t, clientSet)
if !strings.Contains(rawTokenValue, tokenOfLife.RefreshToken) {
t.Errorf("access token received from etcd doesnt have %q (plain text), raw content in etcd is %s", tokenOfLife.RefreshToken, rawTokenValue)

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.

Valid concern

@ardaguclu

Copy link
Copy Markdown
Member

@gangwgr our plan can be like this;

  • Move helper functions in library-go (basically this PR covers this)
  • Update openshift-apiserver-operator, cluster-authentication-operator to use these functions
  • Update kube-apiserver-operator to assert oas, auth.

@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/library/encryption/assertion_oas.go`:
- Around line 19-24: Update the route encryption assertions so malformed route
objects fail fast instead of treating a missing spec.to.name as an empty string.
In extractRouteToName, detect when the expected name field is absent or invalid
and return an error or otherwise trigger a test failure, then have
AssertRouteOfLifeEncrypted and the related not-encrypted assertion use that
result before calling strings.Contains on the raw etcd value. This should
surface bad payloads explicitly instead of producing misleading pass/fail
behavior.
🪄 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: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b28f5f02-de1f-478b-95da-70e0b2245ff5

📥 Commits

Reviewing files that changed from the base of the PR and between e3c9fbb and 73ed196.

⛔ Files ignored due to path filters (19)
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/internal/internal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/clusterrolescoperestriction.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthauthorizetoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthclient.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/oauthclientauthorization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/scoperestriction.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/applyconfigurations/oauth/v1/useroauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/scheme/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/scheme/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/generated_expansion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauth_client.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthauthorizetoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthclient.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/oauthclientauthorization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/oauth/clientset/versioned/typed/oauth/v1/useroauthaccesstoken.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (5)
  • test/library/encryption/assertion_auth.go
  • test/library/encryption/assertion_oas.go
  • test/library/encryption/helpers.go
  • test/library/encryption/helpers_auth.go
  • test/library/encryption/helpers_oas.go

Comment thread test/library/encryption/assertion_oas.go Outdated
@@ -0,0 +1,407 @@
// Code generated by applyconfiguration-gen. DO NOT EDIT.

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.

Why do we still have these imports?. Since we use dynamiclient, we shouldn't import these.

@gangwgr gangwgr force-pushed the combine-func branch 2 times, most recently from c2fe187 to 5a27cd2 Compare June 29, 2026 08:29
Comment thread test/library/encryption/helpers.go Outdated
etcdClient := NewEtcdClient(kubeClient)

return ClientSet{Etcd: etcdClient, ApiServerConfig: apiServerConfigClient, Kube: kubeClient}
dynClient, err := dynamic.NewForConfig(kubeConfig)

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.

Suggested change
dynClient, err := dynamic.NewForConfig(kubeConfig)
dynamicClient, err := dynamic.NewForConfig(kubeConfig)

Comment thread test/library/encryption/helpers_auth.go Outdated

func CreateAndStoreTokenOfLife(ctx context.Context, t testing.TB, cs ClientSet) *unstructured.Unstructured {
t.Helper()
dynTokens := cs.DynamicClient.Resource(oauthAccessTokenGVR)

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.

Suggested change
dynTokens := cs.DynamicClient.Resource(oauthAccessTokenGVR)
tokens := cs.DynamicClient.Resource(oauthAccessTokenGVR)

Comment thread test/library/encryption/helpers_oas.go Outdated

var routeGVR = schema.GroupVersionResource{Group: "route.openshift.io", Version: "v1", Resource: "routes"}

func CreateAndStoreRouteOfLife(ctx context.Context, t testing.TB, cs ClientSet, ns string) *unstructured.Unstructured {

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.

Why don't we return runtime.Object?

{Group: "route.openshift.io", Resource: "routes"},
}

func AssertRouteOfLifeEncrypted(t testing.TB, clientSet ClientSet, routeOfLife *unstructured.Unstructured) {

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.

Why don't we pass runtime.Object?

t.Helper()
name, found, err := unstructured.NestedString(route.Object, "spec", "to", "name")
require.NoError(t, err)
require.True(t, found && len(name) > 0, "route spec.to.name is missing")

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.

We should have 2 separate require.True


func AssertRouteOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, routeOfLife *unstructured.Unstructured) {
t.Helper()
toName := extractRouteToName(t, routeOfLife)

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.

Instead of dealing with unstructured object, we can use Route by converting unstructured to Route.

@ardaguclu

Copy link
Copy Markdown
Member

/retitle NO-JIRA: Moving auth and oas helper funcs to library-go

@openshift-ci openshift-ci Bot changed the title Moving auth and oas helper funcs to library-go NO-JIRA: Moving auth and oas helper funcs to library-go Jun 29, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 29, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@gangwgr: This pull request explicitly references no jira issue.

Details

In response to this:

Summary by CodeRabbit

  • New Features
  • Expanded encryption test coverage for OAuth “token of life” and OpenShift “route of life” resources.
  • Added utilities to create these resources and read their raw stored values directly from etcd.
  • Introduced assertions to verify expected encrypted vs plaintext behavior based on the configured encryption mode.
  • Added checks that the latest migrated key is recorded for the relevant targets.
  • Enhanced the test client setup with dynamic Kubernetes access for these helpers.

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

♻️ Duplicate comments (1)
test/library/encryption/assertion_oas.go (1)

20-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fail fast on the runtime.Object contract before asserting encryption state.

These helpers still assume resource is always a *routev1.Route and that Spec.To.Name is populated. A wrong object now panics at the type assertion, and an empty target name makes strings.Contains(..., "") produce misleading results. Please add require.IsType/checked assertion plus a require.NotEmpty guard before the plaintext check.

Suggested fix
 func AssertRouteOfLifeEncrypted(t testing.TB, clientSet ClientSet, resource runtime.Object) {
 	t.Helper()
-	routeOfLife := resource.(*routev1.Route)
+	routeOfLife, ok := resource.(*routev1.Route)
+	require.True(t, ok, "expected *routev1.Route, got %T", resource)
+	require.NotEmpty(t, routeOfLife.Spec.To.Name, "route spec.to.name is missing")
 	rawRouteValue := GetRawRouteOfLife(t, clientSet, routeOfLife.Namespace)
 	if strings.Contains(rawRouteValue, routeOfLife.Spec.To.Name) {
 		t.Errorf("route not encrypted, etcd value contains target name %q in plain text", routeOfLife.Spec.To.Name)
 	}
 }

 func AssertRouteOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, resource runtime.Object) {
 	t.Helper()
-	routeOfLife := resource.(*routev1.Route)
+	routeOfLife, ok := resource.(*routev1.Route)
+	require.True(t, ok, "expected *routev1.Route, got %T", resource)
+	require.NotEmpty(t, routeOfLife.Spec.To.Name, "route spec.to.name is missing")
 	rawRouteValue := GetRawRouteOfLife(t, clientSet, routeOfLife.Namespace)
 	if !strings.Contains(rawRouteValue, routeOfLife.Spec.To.Name) {
 		t.Errorf("route not decrypted, etcd value does not contain target name %q in plain text", routeOfLife.Spec.To.Name)
 	}
 }

Also applies to: 29-34

🤖 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/library/encryption/assertion_oas.go` around lines 20 - 25, In
AssertRouteOfLifeEncrypted (and the similar helper at the other referenced
block), fail fast before checking etcd plaintext by validating the
runtime.Object is actually a *routev1.Route and that routeOfLife.Spec.To.Name is
not empty. Replace the direct type assertion with a checked
assertion/require.IsType-style guard, add a require.NotEmpty guard for the
target name, and only then call GetRawRouteOfLife and strings.Contains.
🤖 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.

Duplicate comments:
In `@test/library/encryption/assertion_oas.go`:
- Around line 20-25: In AssertRouteOfLifeEncrypted (and the similar helper at
the other referenced block), fail fast before checking etcd plaintext by
validating the runtime.Object is actually a *routev1.Route and that
routeOfLife.Spec.To.Name is not empty. Replace the direct type assertion with a
checked assertion/require.IsType-style guard, add a require.NotEmpty guard for
the target name, and only then call GetRawRouteOfLife and strings.Contains.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ab32daf6-e579-423f-a134-bfd22b314955

📥 Commits

Reviewing files that changed from the base of the PR and between 5a27cd2 and 0bc160b.

📒 Files selected for processing (5)
  • test/library/encryption/assertion_auth.go
  • test/library/encryption/assertion_oas.go
  • test/library/encryption/helpers.go
  • test/library/encryption/helpers_auth.go
  • test/library/encryption/helpers_oas.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/library/encryption/helpers.go
  • test/library/encryption/helpers_auth.go
  • test/library/encryption/assertion_auth.go


func AssertRouteOfLifeEncrypted(t testing.TB, clientSet ClientSet, resource runtime.Object) {
t.Helper()
routeOfLife := resource.(*routev1.Route)

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.

Suggested change
routeOfLife := resource.(*routev1.Route)
routeOfLife, ok := resource.(*routev1.Route)
if !ok {
t.Fatalf...
}


func AssertRouteOfLifeNotEncrypted(t testing.TB, clientSet ClientSet, resource runtime.Object) {
t.Helper()
routeOfLife := resource.(*routev1.Route)

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.

Suggested change
routeOfLife := resource.(*routev1.Route)
routeOfLife, ok := resource.(*routev1.Route)

Comment thread test/library/encryption/helpers_auth.go Outdated

const tokenOfLifeName = "sha256~token-aaaaaaaa-of-aaaaaaaa-life-aaaaaaaa"

func CreateAndStoreTokenOfLife(ctx context.Context, t testing.TB, cs ClientSet) *unstructured.Unstructured {

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 we return runtime.Object? or Route?

Comment thread test/library/encryption/helpers_auth.go Outdated
return obj
}

func TokenOfLife() *unstructured.Unstructured {

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 we have Route object and convert it to unstructured just before applying it?

Comment thread test/library/encryption/helpers_oas.go Outdated
return &route
}

func RouteOfLife(ns string) *unstructured.Unstructured {

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 we return as runtime.Object or Route?

@ardaguclu

ardaguclu commented Jun 29, 2026

Copy link
Copy Markdown
Member

Changes look good to me. We just need fake PRs on cluster-openshift-apiserver-operator, cluster-authentication-operator to prove that changes are working.

@gangwgr

gangwgr commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

Changes look good to me. We just need fake PRs on cluster-openshift-apiserver-operator, cluster-authentication-operator to prove that changes are working.

ok checking

@ardaguclu

Copy link
Copy Markdown
Member

/approve

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 29, 2026
@gangwgr

gangwgr commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

/hold
testing with ci

@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 29, 2026
Comment thread test/library/encryption/helpers_auth.go Outdated
return &result
}

func TokenOfLifeAsResource(_ testing.TB, _ string) runtime.Object {

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.

What is the purpose of this function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is a wrapper around TokenOfLife() that matches the ResourceFunc field signature func(testing.TB, string) runtime.Object in the encryption test scenarios (OnOffScenario, ProvidersMigrationScenario, KMSToKMSMigrationScenario). It allows consumers like cluster-authentication-operator to directly assign library.TokenOfLifeAsResource instead of writing an inline adapter:

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.

Why don't we directly update TokenOfLife with that signature?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated

Comment thread test/library/encryption/helpers_auth.go Outdated
return newTokenOfLife()
}

func newTokenOfLife() *oauthapiv1.OAuthAccessToken {

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.

Suggested change
func newTokenOfLife() *oauthapiv1.OAuthAccessToken {
func TokenOfLife(_ testing.TB, _ string) runtime.Object {

Comment thread test/library/encryption/helpers_oas.go Outdated
return &result
}

func RouteOfLife(ns string) *routev1.Route {

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.

Suggested change
func RouteOfLife(ns string) *routev1.Route {
func RouteOfLife(t testing.TB, ns string) runtime.Object {

?

@ardaguclu

Copy link
Copy Markdown
Member

/lgtm
/hold
let's see what will happen on CI

@openshift-ci

openshift-ci Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ardaguclu, gangwgr

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

The pull request process is described 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 added the lgtm Indicates that a PR is ready to be merged. label Jun 29, 2026
@gangwgr

gangwgr commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

@gangwgr

gangwgr commented Jun 29, 2026

Copy link
Copy Markdown
Contributor Author

/unhold

@ardaguclu

Copy link
Copy Markdown
Member

/hold cancel

@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 29, 2026
@openshift-ci

openshift-ci Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

@gangwgr: all tests passed!

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.

@openshift-merge-bot openshift-merge-bot Bot merged commit f7f45e2 into openshift:master Jun 29, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants