Skip to content

CNTRLPLANE-2777: feat(resource builder): allow to inject tls configuration into annotated config maps#1322

Open
ingvagabund wants to merge 5 commits intoopenshift:mainfrom
ingvagabund:configmap-tls-injection
Open

CNTRLPLANE-2777: feat(resource builder): allow to inject tls configuration into annotated config maps#1322
ingvagabund wants to merge 5 commits intoopenshift:mainfrom
ingvagabund:configmap-tls-injection

Conversation

@ingvagabund
Copy link
Member

@ingvagabund ingvagabund commented Feb 16, 2026

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

  • provision a cluster with the operator PRs included
  • follow https://access.redhat.com/solutions/6955910 to make the CVO unmanaged + increase log level to 4
  • test 1: change the TLS to Moden (oc edit apiserver cluster):
    spec:
      tlsSecurityProfile:
        modern: {}
        type: Modern
  • reading the CMs:
    oc get cm -n openshift-apiserver-operator openshift-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
    oc get cm -n openshift-controller-manager-operator openshift-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
    oc get cm -n openshift-etcd-operator etcd-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
    oc get cm -n openshift-image-registry image-registry-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
    oc get cm -n openshift-kube-apiserver-operator kube-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
    oc get cm -n openshift-kube-controller-manager-operator kube-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
    oc get cm -n openshift-kube-scheduler-operator openshift-kube-scheduler-operator-config -o json | jq '.data["config.yaml"]' -r | yq '.servingInfo'

Summary by CodeRabbit

  • New Features

    • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.
  • Tests

    • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.
  • Chores

    • Updated dependency declarations to support Kubernetes/OpenShift integrations.

@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 16, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 16, 2026

Walkthrough

Adds a TLS-injection workflow that modifies ConfigMap entries annotated with config.openshift.io/inject-tls by fetching APIServer TLS settings and injecting minTLSVersion and cipherSuites into GenericOperatorConfig YAML blobs; also updates generation script, client types to interfaces, dependencies, and tests.

Changes

Cohort / File(s) Summary
Dependency Management
go.mod
Added direct deps sigs.k8s.io/kustomize/kyaml v0.21.1, sigs.k8s.io/yaml v1.6.0; added indirect deps including github.com/go-errors/errors, github.com/imdario/mergo, and sigs.k8s.io/kube-storage-version-migrator; adjusted require blocks.
Generation Script
hack/generate-lib-resources.py
Introduce interface-aware client type rendering and add a ConfigMap modifier hook mapping for core/v1 ConfigMap.
Resource Builder: core logic
lib/resourcebuilder/core.go
New TLS-injection implementation: ConfigMapInjectTLSAnnotation constant, modifyConfigMap, TLS observation helpers, RNode-based YAML injection, cipher-suite sorting, lister/adapters, and logging/error handling (skips invalid YAML/non-target entries).
Resource Builder: wiring
lib/resourcebuilder/resourcebuilder.go
Builder now holds client interfaces (ConfigV1Interface, CoreV1Interface) and invokes b.modifyConfigMap(...) before applying ConfigMapv1 resources.
Tests
lib/resourcebuilder/core_test.go, lib/resourcebuilder/resourcebuilder_test.go
Extensive tests covering annotation cases, multiple/mixed ConfigMap data, idempotency, YAML preservation, and builder integration using fake clients and helpers.

Sequence Diagram

sequenceDiagram
    participant Builder as Resource Builder
    participant ConfigMap as ConfigMap
    participant APIServer as APIServer Lister
    participant TLS as TLS Observer
    participant YAML as YAML Parser/kuyaml
    participant RNode as RNode Modifier

    Builder->>ConfigMap: Read annotations & data
    ConfigMap-->>Builder: Return data & annotation
    alt annotation == "true"
        Builder->>APIServer: List/Get APIServer resource
        APIServer-->>TLS: Provide servingInfo / securityProfile
        TLS-->>Builder: Return minTLSVersion + cipherSuites
        Builder->>YAML: Parse each data entry (kuyaml)
        YAML-->>Builder: Identify GenericOperatorConfig entries
        Builder->>RNode: Inject minTLSVersion & cipherSuites into nodes
        RNode-->>YAML: Return modified YAML text
        Builder->>ConfigMap: Update data entries and apply resource
        ConfigMap-->>Builder: Persisted
    else annotation missing/false
        Builder-->>ConfigMap: Skip modification
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding TLS configuration injection into annotated ConfigMaps in the resource builder.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Stable And Deterministic Test Names ✅ Passed All test names in added test files use static string literals without dynamic values like timestamps, UUIDs, or generated suffixes.
Test Structure And Quality ✅ Passed Test files demonstrate high quality with clear single responsibility, well-designed helper functions, meaningful failure messages, and adherence to existing codebase patterns using table-driven testing.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 16, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

}

// Process each data entry that contains GenericOperatorConfig
for key, value := range cm.Data {

Choose a reason for hiding this comment

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

have you considered going for a single config.yaml entry ?

Copy link
Member Author

Choose a reason for hiding this comment

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

@ingvagabund ingvagabund force-pushed the configmap-tls-injection branch 5 times, most recently from 938cef8 to bea8cc6 Compare February 18, 2026 16:35
Copy link

@ricardomaraschini ricardomaraschini left a comment

Choose a reason for hiding this comment

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

I assume that the hash of the configmap will be automatically added to the deployment for rollouts.

edit: we don't yet, a similar mechanism is still to be implemented

@DavidHurta
Copy link
Contributor

/cc

@openshift-ci openshift-ci bot requested a review from DavidHurta February 19, 2026 13:36
@ingvagabund ingvagabund changed the title wip: feat(resource builder): allow to inject tls configuration into annotated config maps CNTRLPLANE-2777: wip: feat(resource builder): allow to inject tls configuration into annotated config maps Feb 19, 2026
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 19, 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 Feb 19, 2026
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 19, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

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.

@ingvagabund ingvagabund changed the title CNTRLPLANE-2777: wip: feat(resource builder): allow to inject tls configuration into annotated config maps CNTRLPLANE-2777: feat(resource builder): allow to inject tls configuration into annotated config maps Feb 24, 2026
@ingvagabund
Copy link
Member Author

@DavidHurta the high level functionality design is finished. Is the current implementation in the right direction that is aligned with how CVO is expected to reconcile?

@ingvagabund ingvagabund force-pushed the configmap-tls-injection branch from bea8cc6 to 4ae1b14 Compare February 25, 2026 11:41
@ingvagabund
Copy link
Member Author

ingvagabund commented Feb 25, 2026

I assume that the hash of the configmap will be automatically added to the deployment for rollouts.

As you suggested we can either:

  1. use --terminate-on-files so each operator gets terminated and restarted. Or,
  2. the resource builder could be extended with another annotation for saying which CMs/Secrets are dependencies and where a hash is expected to be computed. E.g.:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: NS
      name: operator
      annotations:
        ...
        config.openshift.io/depends-on-configmap-NAME: ""
        config.openshift.io/depends-on-secret-NAME: ""
    Where configmap/secret are scoped within NS. The resource builder will compute a hash of each listed CM/Secret and updates the corresponding annotation with it. The deployment controller will do the rest if the annotation hash changes.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Feb 25, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Summary by CodeRabbit

  • New Features

  • ConfigMaps can now be automatically configured with TLS settings via annotation, allowing security profiles to be injected into application configurations while preserving existing data.

  • Tests

  • Added comprehensive test suite for ConfigMap modification behavior, covering annotation states, mixed data formats, and TLS field validation.

  • Chores

  • Updated and added dependencies for Kubernetes support.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
lib/resourcebuilder/core_test.go (1)

64-84: Ignored error from json.Marshal in test helper.

While marshalling a simple Pod struct should never fail, silently discarding the error at Line 82 is a test smell. Consider using t parameter or must-style helper.

♻️ Suggested fix

Since this is a package-level helper without access to *testing.T, a simple panic is acceptable in test code:

-func makePodJSON() string {
+func makePodJSON(t *testing.T) string {
+	t.Helper()
 	pod := &corev1.Pod{
 		...
 	}
-	data, _ := json.Marshal(pod)
+	data, err := json.Marshal(pod)
+	if err != nil {
+		t.Fatalf("Failed to marshal Pod: %v", err)
+	}
 	return string(data)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core_test.go` around lines 64 - 84, The helper
makePodJSON ignores the error returned by json.Marshal; change it to fail loudly
in tests by checking the error from json.Marshal(pod) and panicking (or using a
must-style behavior) if err != nil so test failures are obvious; update the
function makePodJSON to capture the error from json.Marshal and call panic with
that error (or wrap a descriptive message) instead of discarding it.
hack/generate-lib-resources.py (1)

127-127: Avoid equality comparison to True; use truthiness check instead.

Per Ruff E712, use client['interface'] instead of client['interface'] == True.

♻️ Suggested fix
-            'type': '{}{}.{}'.format("" if 'interface' in client and client['interface'] == True else "*", client_short_name, client['type']),
+            'type': '{}{}.{}'.format("" if client.get('interface') else "*", client_short_name, client['type']),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hack/generate-lib-resources.py` at line 127, Replace the explicit equality
check client['interface'] == True with a truthiness check so the 'type' dict
entry uses if client.get('interface') or client['interface'] (truthy) instead of
comparing to True; update the expression that builds the 'type' value (the dict
entry using '{}{}.{}'.format(...)) to use a truthy test on client['interface']
to decide whether to include the empty string or "*" (reference the 'client'
variable and the 'type' dict entry in the generator).
lib/resourcebuilder/core.go (4)

98-104: Redundant API call: APIServers().Get() is called twice per ConfigMap.

Line 100 fetches the APIServer resource to check existence, and then ObserveTLSSecurityProfile (via the apiServerListerAdapter.Get at Line 212) fetches it again. This doubles the API server load for every annotated ConfigMap on each reconciliation cycle. Consider removing the pre-check and relying solely on the errors returned by ObserveTLSSecurityProfile.

♻️ Suggested simplification
 func (b *builder) observeTLSConfiguration(ctx context.Context, cm *corev1.ConfigMap) (minTLSVersion string, minTLSFound bool, cipherSuites []string, ciphersFound bool) {
-	// First check if the APIServer cluster resource exists
-	_, err := b.configClientv1.APIServers().Get(ctx, "cluster", metav1.GetOptions{})
-	if err != nil {
-		klog.V(2).Infof("ConfigMap %s/%s: APIServer cluster resource not found, skipping TLS injection: %v", cm.Namespace, cm.Name, err)
-		return "", false, nil, false
-	}
-
 	// Create a lister adapter for ObserveTLSSecurityProfile
 	lister := &apiServerListerAdapter{
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 98 - 104, The initial APIServer
existence check in builder.observeTLSConfiguration that calls
b.configClientv1.APIServers().Get should be removed to avoid duplicate API
calls; instead, rely on ObserveTLSSecurityProfile (and the
apiServerListerAdapter.Get it uses) to return appropriate errors if the
APIServer is missing. Edit observeTLSConfiguration to delete the pre-check block
(the call to b.configClientv1.APIServers().Get and its early return/log) and let
the subsequent call to ObserveTLSSecurityProfile handle not-found or error
cases, preserving existing logging where ObserveTLSSecurityProfile reports
failures.

29-41: Empty (non-nil) Data map silently passes through without logging.

Line 38 checks cm.Data == nil but logs "empty data". If Data is an empty map (map[string]string{}), it won't be logged as "empty" and the loop at Line 52 will simply not iterate. Consider also checking len(cm.Data) == 0 for consistency with the log message.

♻️ Minor fix
 	// Empty data, nothing to inject into
-	if cm.Data == nil {
+	if len(cm.Data) == 0 {
 		klog.V(2).Infof("ConfigMap %s/%s has empty data, skipping", cm.Namespace, cm.Name)
 		return nil
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 29 - 41, In modifyConfigMap on
builder, the current check only tests cm.Data == nil but the log says "empty
data" while an empty (non-nil) map will silently pass through; change the
condition to treat both nil and zero-length maps as empty (e.g., if cm.Data ==
nil || len(cm.Data) == 0) and keep the klog message, or adjust the message to
reflect nil vs empty; update the early-return branch so the range loop that
follows (the iteration over cm.Data) isn't relied on to detect emptiness.

86-93: Log at Line 91 is misleading: it prints even when no entries were modified.

The "APIServer config available for ConfigMap ... TLS injection" message is emitted unconditionally after the loop, even if no GenericOperatorConfig entries were found or updated. Consider moving it inside the loop (where updates happen) or tracking whether any modification occurred.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 86 - 93, The log "APIServer config
available for ConfigMap ... TLS injection" is emitted unconditionally; update
the code in the routine that iterates cm.Data and updates GenericOperatorConfig
entries (the block that sets cm.Data[key] = modifiedYAML and calls
klog.V(2).Infof about updated ciphers/minTLSVersion) to only emit the
APIServer-config-available message when at least one entry was actually
modified—either move that klog.V(2).Infof into the modification branch or
introduce a boolean modified flag (e.g., modified := false; set to true when you
change cm.Data[key]) and emit the message only if modified is true, referencing
cm.Namespace and cm.Name as currently done.

141-166: servingInfo is unconditionally created even when neither TLS field needs updating.

LookupCreate(yaml.MappingNode, "servingInfo") at Line 142 will create a servingInfo mapping if it doesn't exist. If both ciphersFound and minTLSFound are false (shouldn't reach here given the caller check, but defensively), this would inject an empty servingInfo node. The current caller guards against this, so this is a minor defensive-coding note.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 141 - 166, The function
updateRNodeWithTLSSettings unconditionally creates servingInfo via
yaml.LookupCreate which can add an empty mapping when neither TLS value needs
updating; change the logic to only obtain/create servingInfo when needed: check
ciphersFound and minTLSFound first, and for cipherSuites call
yaml.Lookup(servingInfoParent, "servingInfo") to see if it exists (and only
create with yaml.SetField("servingInfo", yaml.NewMapRNode(...)) or
yaml.LookupCreate when actually about to set fields), and similarly only create
servingInfo when setting minTLSVersion; update the code paths in
updateRNodeWithTLSSettings so servingInfo is created lazily (use yaml.Lookup
instead of yaml.LookupCreate or defer yaml.LookupCreate until just before PipeE
calls) while keeping the existing comparisons with getSortedCipherSuites and
slices.Equal.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/resourcebuilder/core_test.go`:
- Around line 536-541: The table-driven test includes a shouldCallAPI boolean
that is never asserted in the test loop; either remove the unused shouldCallAPI
field from the tests slice or add an assertion inside the test loop that
inspects the fake client's recorded actions and compares whether an API call
occurred to tests[i].shouldCallAPI (e.g., check
fakeClient.Actions()/RecordedActions length or presence of a specific verb) so
the table entry is validated; update the tests slice entry points and the test
loop where the resource builder is exercised to perform this check.
- Around line 226-235: The test declares expectModified in TestModifyConfigMap
but never asserts it; update the test loop in TestModifyConfigMap to verify
expectModified for each case by comparing the original and returned/modified
*corev1.ConfigMap (or by using a boolean return if ModifyConfigMap returns one):
after calling the function under test, add an assertion that when
tc.expectModified is true the modified ConfigMap differs (use reflect.DeepEqual
or cmp.Diff) from the original, and when false they are equal; reference the
existing test case variable tc.expectModified and the test helper
validateConfigMap to keep behavior checks consistent.

In `@lib/resourcebuilder/core.go`:
- Around line 224-232: configObserverListers currently returns nil from
ResourceSyncer() and PreRunHasSynced(), violating the configobserver.Listers
contract and risking a panic in callers like listersToInformer() or
NewNestedConfigObserver(); fix by returning concrete no-op implementations: have
PreRunHasSynced() return an empty slice (e.g. return []cache.InformerSynced{}),
and implement a small noop ResourceSyncer type that satisfies
resourcesynccontroller.ResourceSyncer (methods are no-ops) and return an
instance from ResourceSyncer(); update core.go's configObserverListers methods
accordingly (referencing configObserverListers, ResourceSyncer(),
PreRunHasSynced(), ObserveTLSSecurityProfile, APIServerLister(),
listersToInformer(), NewNestedConfigObserver()) or, if you choose not to add a
noop, add a clear comment on configObserverListers' type header stating it must
never be passed to code paths that call these methods.

---

Nitpick comments:
In `@hack/generate-lib-resources.py`:
- Line 127: Replace the explicit equality check client['interface'] == True with
a truthiness check so the 'type' dict entry uses if client.get('interface') or
client['interface'] (truthy) instead of comparing to True; update the expression
that builds the 'type' value (the dict entry using '{}{}.{}'.format(...)) to use
a truthy test on client['interface'] to decide whether to include the empty
string or "*" (reference the 'client' variable and the 'type' dict entry in the
generator).

In `@lib/resourcebuilder/core_test.go`:
- Around line 64-84: The helper makePodJSON ignores the error returned by
json.Marshal; change it to fail loudly in tests by checking the error from
json.Marshal(pod) and panicking (or using a must-style behavior) if err != nil
so test failures are obvious; update the function makePodJSON to capture the
error from json.Marshal and call panic with that error (or wrap a descriptive
message) instead of discarding it.

In `@lib/resourcebuilder/core.go`:
- Around line 98-104: The initial APIServer existence check in
builder.observeTLSConfiguration that calls b.configClientv1.APIServers().Get
should be removed to avoid duplicate API calls; instead, rely on
ObserveTLSSecurityProfile (and the apiServerListerAdapter.Get it uses) to return
appropriate errors if the APIServer is missing. Edit observeTLSConfiguration to
delete the pre-check block (the call to b.configClientv1.APIServers().Get and
its early return/log) and let the subsequent call to ObserveTLSSecurityProfile
handle not-found or error cases, preserving existing logging where
ObserveTLSSecurityProfile reports failures.
- Around line 29-41: In modifyConfigMap on builder, the current check only tests
cm.Data == nil but the log says "empty data" while an empty (non-nil) map will
silently pass through; change the condition to treat both nil and zero-length
maps as empty (e.g., if cm.Data == nil || len(cm.Data) == 0) and keep the klog
message, or adjust the message to reflect nil vs empty; update the early-return
branch so the range loop that follows (the iteration over cm.Data) isn't relied
on to detect emptiness.
- Around line 86-93: The log "APIServer config available for ConfigMap ... TLS
injection" is emitted unconditionally; update the code in the routine that
iterates cm.Data and updates GenericOperatorConfig entries (the block that sets
cm.Data[key] = modifiedYAML and calls klog.V(2).Infof about updated
ciphers/minTLSVersion) to only emit the APIServer-config-available message when
at least one entry was actually modified—either move that klog.V(2).Infof into
the modification branch or introduce a boolean modified flag (e.g., modified :=
false; set to true when you change cm.Data[key]) and emit the message only if
modified is true, referencing cm.Namespace and cm.Name as currently done.
- Around line 141-166: The function updateRNodeWithTLSSettings unconditionally
creates servingInfo via yaml.LookupCreate which can add an empty mapping when
neither TLS value needs updating; change the logic to only obtain/create
servingInfo when needed: check ciphersFound and minTLSFound first, and for
cipherSuites call yaml.Lookup(servingInfoParent, "servingInfo") to see if it
exists (and only create with yaml.SetField("servingInfo", yaml.NewMapRNode(...))
or yaml.LookupCreate when actually about to set fields), and similarly only
create servingInfo when setting minTLSVersion; update the code paths in
updateRNodeWithTLSSettings so servingInfo is created lazily (use yaml.Lookup
instead of yaml.LookupCreate or defer yaml.LookupCreate until just before PipeE
calls) while keeping the existing comparisons with getSortedCipherSuites and
slices.Equal.

ℹ️ Review info

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

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 9a401d5 and 4ae1b14.

⛔ Files ignored due to path filters (294)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/go-errors/errors/.travis.yml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/LICENSE.MIT is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/error.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/error_1_13.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/error_backward.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/parse_panic.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-errors/errors/stackframe.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/.deepsource.toml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/.gitignore is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/.travis.yml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/map.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/imdario/mergo/mergo.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.ci-operator.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.coderabbit.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.gitattributes is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.gitignore is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.golangci.go-validated.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/AGENTS.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/Dockerfile.ocp is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/annotations/annotations.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/types_compatibilityrequirement.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiextensions/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiserver/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/types_apirequestcount.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apiserver/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiserver/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apiserver/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apps/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/deprecated_consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/apps/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apps/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/apps/v1/zz_prerelease_lifecycle_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/codec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/authorization/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/authorization/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/authorization/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/build/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/consts.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/build/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/build/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/cloudnetwork/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/cloudnetwork/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/cloudnetwork/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/cloudnetwork/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/console/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_cli_download.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_external_log_links.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_link.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_notification.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_plugin.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_quick_start.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_sample.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types_console_yaml_sample.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/console/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/envtest-releases.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/types_helm_chart_repository.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/types_project_helm_chart_repository.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/helm/v1beta1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/helm/v1beta1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/helm/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/image/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/image/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/types_imagepruner.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/imageregistry/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/imageregistry/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/imageregistry/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/kubecontrolplane/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/legacyconfig/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/serialization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/stringsource.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/legacyconfig/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/common.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/types_alibabaprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/types_aws.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/types_controlplanemachineset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/types_nutanixprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/types_powervsprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/types_openstack.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1beta1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_azureprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_gcpprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machine.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machinehealthcheck.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_provider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_vsphereprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/monitoring/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/monitoring/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/monitoring/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/monitoring/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/constants.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1alpha1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/types_dnsnameresolver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/network/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/network/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/networkoperator/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/types_egressrouter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/networkoperator/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/networkoperator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/networkoperator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/oauth/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/oauth/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/oauth/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/openshiftcontrolplane/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/openshiftcontrolplane/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/openshiftcontrolplane/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/openshiftcontrolplane/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/openshiftcontrolplane/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/openshiftcontrolplane/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/openshiftcontrolplane/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/types_conditioncheck.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operatorcontrolplane/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/osin/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/osin/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/osin/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/osin/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/osin/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/osin/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/pkg/serialization/serialization.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/project/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/project/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/quota/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/legacy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/quota/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/quota/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/quota/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/route/.codegen.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/route/OWNERS is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/route/install.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/route/v1/Makefile is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/route/v1/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/route/v1/generated.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/route/v1/generated.proto is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (6)
  • go.mod
  • hack/generate-lib-resources.py
  • lib/resourcebuilder/core.go
  • lib/resourcebuilder/core_test.go
  • lib/resourcebuilder/resourcebuilder.go
  • lib/resourcebuilder/resourcebuilder_test.go

Comment on lines +224 to +232
func (l *configObserverListers) ResourceSyncer() resourcesynccontroller.ResourceSyncer {
// Not needed for TLS observation
return nil
}

func (l *configObserverListers) PreRunHasSynced() []cache.InformerSynced {
// Not needed for TLS observation
return nil
}
Copy link

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:

# First, let's understand the repo structure and find the relevant files
git ls-files | grep -E "(resourcebuilder|configobserver)" | head -20

Repository: openshift/cluster-version-operator

Length of output: 1188


🏁 Script executed:

# Read the core.go file to see the full context
cat -n lib/resourcebuilder/core.go | sed -n '220,240p'

# Also check the interface definition
cat -n lib/resourcebuilder/interface.go | head -50

# Look at the observe_tlssecurityprofile implementation
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/apiserver/observe_tlssecurityprofile.go

Repository: openshift/cluster-version-operator

Length of output: 8005


🏁 Script executed:

# Find the APIServerLister interface definition
rg -n "type APIServerLister" --type go

# Search for all uses of ResourceSyncer in the codebase
rg -n "ResourceSyncer" --type go

# Search for all uses of PreRunHasSynced in the codebase
rg -n "PreRunHasSynced" --type go

# Find where configObserverListers is instantiated
rg -n "configObserverListers{" --type go

Repository: openshift/cluster-version-operator

Length of output: 2179


🏁 Script executed:

# Read the config_observer_controller.go around the lines that call PreRunHasSynced
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/config_observer_controller.go | sed -n '35,45p'

# Read the context around lines 255-257 where PreRunHasSynced is called
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/config_observer_controller.go | sed -n '250,270p'

# Look at the full Listers interface definition
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/config_observer_controller.go | sed -n '33,50p'

# Check the apiserver listers.go to understand the interface
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/apiserver/listers.go

Repository: openshift/cluster-version-operator

Length of output: 3078


🏁 Script executed:

# Find where listersToInformer is called
rg -n "listersToInformer" --type go

# Look for the Run method or startup code that uses this
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/config_observer_controller.go | sed -n '200,250p'

# Check how configObserverListers is initialized and used in lib/resourcebuilder/core.go
cat -n lib/resourcebuilder/core.go | sed -n '1,50p'

# Look for where configObserverListers is created/instantiated
rg -n "New.*configObserverListers\|&configObserverListers" --type go

Repository: openshift/cluster-version-operator

Length of output: 6154


🏁 Script executed:

# Look at the code around line 126 in config_observer_controller.go
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/config_observer_controller.go | sed -n '100,140p'

# Search for any calls to ResourceSyncer() in the codebase
rg -n "\.ResourceSyncer\(\)" --type go -A 2

# Check if the configObserverListers is actually used with the config observer controller
grep -r "configObserverListers\|NewConfigObserverListers" lib/ --include="*.go"

Repository: openshift/cluster-version-operator

Length of output: 2578


🏁 Script executed:

# Find where configObserverListers is used
rg -n "configObserverListers" lib/resourcebuilder/core.go -B 5 -A 10

# Check if it's passed to NewNestedConfigObserver or similar
rg -n "NewNestedConfigObserver\|NewConfigObserver" lib/ --include="*.go" -B 2 -A 2

Repository: openshift/cluster-version-operator

Length of output: 2026


🏁 Script executed:

# Double-check the current usage is safe by seeing what ObserveTLSSecurityProfile actually does
cat -n vendor/github.com/openshift/library-go/pkg/operator/configobserver/apiserver/observe_tlssecurityprofile.go | sed -n '35,80p'

Repository: openshift/cluster-version-operator

Length of output: 2460


Return proper implementations instead of nil for ResourceSyncer() and PreRunHasSynced(), or document that configObserverListers must never be passed to code paths that invoke these methods.

ObserveTLSSecurityProfile currently only calls APIServerLister() and never invokes ResourceSyncer() or PreRunHasSynced(), so the current usage is safe. However, configObserverListers implements the configobserver.Listers interface, which requires both methods. The listersToInformer() function in library-go's config_observer_controller.go (lines 255–257) iterates over the result of PreRunHasSynced() without nil-checking, which would panic if this lister is ever passed to NewNestedConfigObserver() or similar code paths. This pattern violates the interface contract and creates a landmine for future refactoring. Either return empty slices/objects instead of nil, or add a clear comment that this lister is only for TLS observation and must never be used with the config observer controller.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 224 - 232, configObserverListers
currently returns nil from ResourceSyncer() and PreRunHasSynced(), violating the
configobserver.Listers contract and risking a panic in callers like
listersToInformer() or NewNestedConfigObserver(); fix by returning concrete
no-op implementations: have PreRunHasSynced() return an empty slice (e.g. return
[]cache.InformerSynced{}), and implement a small noop ResourceSyncer type that
satisfies resourcesynccontroller.ResourceSyncer (methods are no-ops) and return
an instance from ResourceSyncer(); update core.go's configObserverListers
methods accordingly (referencing configObserverListers, ResourceSyncer(),
PreRunHasSynced(), ObserveTLSSecurityProfile, APIServerLister(),
listersToInformer(), NewNestedConfigObserver()) or, if you choose not to add a
noop, add a clear comment on configObserverListers' type header stating it must
never be passed to code paths that call these methods.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Feb 25, 2026

@ingvagabund: 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-agnostic-ovn-techpreview-serial 4ae1b14 link true /test e2e-agnostic-ovn-techpreview-serial
ci/prow/e2e-hypershift 4ae1b14 link true /test e2e-hypershift
ci/prow/e2e-hypershift-conformance 4ae1b14 link true /test e2e-hypershift-conformance

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.

@DavidHurta
Copy link
Contributor

@DavidHurta the high level functionality design is finished. Is the current implementation in the right direction that is aligned with how CVO is expected to reconcile?

Hello, @ingvagabund. The high-level design looks good on my end. From quickly going through the code, the implementation looks good.

I have reserved some time for myself to properly review the PR. Thanks for creating some tests, that's always appreciated!

I see the openshift/cluster-image-registry-operator#1297 PR, which is great. We can leverage it to verify the PR before merging, if possible.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
lib/resourcebuilder/core.go (2)

163-168: Consider checking if minTLSVersion needs updating.

Unlike cipherSuites (which compares current vs. new values before updating), minTLSVersion is always set without checking the current value. While kyaml preserves YAML structure when setting the same value, adding a comparison would make the idempotency intent explicit and consistent with the cipher handling.

 	// Update minTLSVersion if found
 	if minTLSFound && minTLSVersion != "" {
+		currentMinTLS, err := servingInfo.GetString("minTLSVersion")
+		if err != nil || currentMinTLS != minTLSVersion {
 			if err := servingInfo.PipeE(yaml.SetField("minTLSVersion", yaml.NewStringRNode(minTLSVersion))); err != nil {
 				return err
 			}
+		}
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 163 - 168, The code unconditionally
sets minTLSVersion when minTLSFound is true, unlike the cipherSuites logic which
first compares existing vs new value; update the block around
minTLSFound/minTLSVersion and servingInfo.PipeE to read the current
"minTLSVersion" (via yaml.Field/Get or the same helper used for cipherSuites),
compare it to minTLSVersion, and only call
servingInfo.PipeE(yaml.SetField("minTLSVersion",
yaml.NewStringRNode(minTLSVersion))) when they differ so the update is
idempotent and consistent with cipher handling.

104-109: Minor: Redundant APIServer fetch.

The APIServer is fetched twice: once explicitly at Line 105, then again inside ObserveTLSSecurityProfile via the lister adapter. Consider removing the explicit check since ObserveTLSSecurityProfile already handles missing config gracefully.

 func (b *builder) observeTLSConfiguration(ctx context.Context, cm *corev1.ConfigMap) (minTLSVersion string, minTLSFound bool, cipherSuites []string, ciphersFound bool) {
-	// First check if the APIServer cluster resource exists
-	_, err := b.configClientv1.APIServers().Get(ctx, "cluster", metav1.GetOptions{})
-	if err != nil {
-		klog.V(2).Infof("ConfigMap %s/%s: APIServer cluster resource not found, skipping TLS injection: %v", cm.Namespace, cm.Name, err)
-		return "", false, nil, false
-	}
-
 	// Create a lister adapter for ObserveTLSSecurityProfile
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 104 - 109, Remove the redundant
explicit APIServer fetch block that calls b.configClientv1.APIServers().Get and
its error handling/klog/return; rely on ObserveTLSSecurityProfile (and its
lister adapter) to detect a missing APIServer and handle it gracefully.
Specifically, delete the lines invoking b.configClientv1.APIServers().Get(ctx,
"cluster", metav1.GetOptions{}) and the subsequent if err != nil { ... return
... } block so the function flow continues to ObserveTLSSecurityProfile without
an extra fetch.
lib/resourcebuilder/core_test.go (1)

177-193: Minor: Variable shadowing reduces readability.

The inner found variable at Line 183 shadows the outer found from Line 173. While not a bug, consider renaming to cipherFound for clarity.

-	for _, expectedCipher := range expectedCiphers {
-		found := false
-		for _, cipher := range cipherSuites {
-			if cipher == expectedCipher {
-				found = true
-				break
-			}
-		}
-		if !found {
+	for _, expectedCipher := range expectedCiphers {
+		cipherFound := false
+		for _, cipher := range cipherSuites {
+			if cipher == expectedCipher {
+				cipherFound = true
+				break
+			}
+		}
+		if !cipherFound {

Alternatively, use slices.Contains:

if !slices.Contains(cipherSuites, expectedCipher) {
    return fmt.Errorf("expected cipher %s not found in cipherSuites: %v", expectedCipher, cipherSuites)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core_test.go` around lines 177 - 193, The inner loop uses
a variable named "found" which shadows the outer "found" (from the outer scope)
and reduces readability; rename the inner boolean to "cipherFound" (or similar)
in the loop that iterates over cipherSuites to avoid shadowing, or replace the
whole inner loop by calling slices.Contains(cipherSuites, expectedCipher) to
check presence and simplify the logic in the test that iterates over
expectedCiphers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/resourcebuilder/core.go`:
- Around line 70-72: The log message in the ConfigMap handling branch (where
kind != "GenericOperatorConfig") contains a typo ("skiping"); update the
klog.V(4).Infof call string in the code path that checks kind (the conditional
using variable kind) to correct "skiping" to "skipping" so the message logged by
klog.V(4).Infof accurately reads "skipping this entry".

---

Nitpick comments:
In `@lib/resourcebuilder/core_test.go`:
- Around line 177-193: The inner loop uses a variable named "found" which
shadows the outer "found" (from the outer scope) and reduces readability; rename
the inner boolean to "cipherFound" (or similar) in the loop that iterates over
cipherSuites to avoid shadowing, or replace the whole inner loop by calling
slices.Contains(cipherSuites, expectedCipher) to check presence and simplify the
logic in the test that iterates over expectedCiphers.

In `@lib/resourcebuilder/core.go`:
- Around line 163-168: The code unconditionally sets minTLSVersion when
minTLSFound is true, unlike the cipherSuites logic which first compares existing
vs new value; update the block around minTLSFound/minTLSVersion and
servingInfo.PipeE to read the current "minTLSVersion" (via yaml.Field/Get or the
same helper used for cipherSuites), compare it to minTLSVersion, and only call
servingInfo.PipeE(yaml.SetField("minTLSVersion",
yaml.NewStringRNode(minTLSVersion))) when they differ so the update is
idempotent and consistent with cipher handling.
- Around line 104-109: Remove the redundant explicit APIServer fetch block that
calls b.configClientv1.APIServers().Get and its error handling/klog/return; rely
on ObserveTLSSecurityProfile (and its lister adapter) to detect a missing
APIServer and handle it gracefully. Specifically, delete the lines invoking
b.configClientv1.APIServers().Get(ctx, "cluster", metav1.GetOptions{}) and the
subsequent if err != nil { ... return ... } block so the function flow continues
to ObserveTLSSecurityProfile without an extra fetch.

ℹ️ Review info

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

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 4ae1b14 and 1718c36.

📒 Files selected for processing (2)
  • lib/resourcebuilder/core.go
  • lib/resourcebuilder/core_test.go

Comment on lines +70 to +72
if kind != "GenericOperatorConfig" {
klog.V(4).Infof("ConfigMap's %q entry is not a GenericOperatorConfig, skiping this entry", key)
continue
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Typo: "skiping" → "skipping".

 		if kind != "GenericOperatorConfig" {
-			klog.V(4).Infof("ConfigMap's %q entry is not a GenericOperatorConfig, skiping this entry", key)
+			klog.V(4).Infof("ConfigMap's %q entry is not a GenericOperatorConfig, skipping this entry", key)
 			continue
 		}
📝 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 kind != "GenericOperatorConfig" {
klog.V(4).Infof("ConfigMap's %q entry is not a GenericOperatorConfig, skiping this entry", key)
continue
if kind != "GenericOperatorConfig" {
klog.V(4).Infof("ConfigMap's %q entry is not a GenericOperatorConfig, skipping this entry", key)
continue
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/resourcebuilder/core.go` around lines 70 - 72, The log message in the
ConfigMap handling branch (where kind != "GenericOperatorConfig") contains a
typo ("skiping"); update the klog.V(4).Infof call string in the code path that
checks kind (the conditional using variable kind) to correct "skiping" to
"skipping" so the message logged by klog.V(4).Infof accurately reads "skipping
this entry".

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

spec:
audit:
  profile: Default
tlsSecurityProfile:
  modern: {}
  type: Modern

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

  • provision a cluster with the operator PRs included
  • follow https://access.redhat.com/solutions/6955910 to make the CVO unmanaged + increase log level to 4
  • test 1: change the TLS to Moden (oc edit apiserver cluster):
spec:
tlsSecurityProfile:
  modern: {}
  type: Modern

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

  • provision a cluster with the operator PRs included
  • follow https://access.redhat.com/solutions/6955910 to make the CVO unmanaged + increase log level to 4
  • test 1: change the TLS to Moden (oc edit apiserver cluster):
spec:
  tlsSecurityProfile:
    modern: {}
    type: Modern

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

  • provision a cluster with the operator PRs included
  • follow https://access.redhat.com/solutions/6955910 to make the CVO unmanaged + increase log level to 4
  • test 1: change the TLS to Moden (oc edit apiserver cluster):
spec:
  tlsSecurityProfile:
    modern: {}
    type: Modern
  • reading the CMs:
oc get cm -n openshift-apiserver-operator openshift-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'

oc get cm -n openshift-controller-manager-operator openshift-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'

oc get cm -n openshift-etcd-operator etcd-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'

oc get cm -n openshift-image-registry image-registry-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'

oc get cm -n openshift-kube-apiserver-operator kube-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'

oc get cm -n openshift-kube-controller-manager-operator kube-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'

oc get cm -n openshift-kube-scheduler-operator openshift-kube-scheduler-operator-config -o json | jq '.data["config.yaml"]' -r | yq '.servingInfo'

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

  • provision a cluster with the operator PRs included
  • follow https://access.redhat.com/solutions/6955910 to make the CVO unmanaged + increase log level to 4
  • test 1: change the TLS to Moden (oc edit apiserver cluster):
spec:
  tlsSecurityProfile:
    modern: {}
    type: Modern
  • reading the CMs:
oc get cm -n openshift-apiserver-operator openshift-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-controller-manager-operator openshift-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-etcd-operator etcd-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-image-registry image-registry-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-kube-apiserver-operator kube-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-kube-controller-manager-operator kube-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-kube-scheduler-operator openshift-kube-scheduler-operator-config -o json | jq '.data["config.yaml"]' -r | yq '.servingInfo'

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Mar 2, 2026

@ingvagabund: This pull request references CNTRLPLANE-2777 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the epic to target the "4.22.0" version, but no target version was set.

Details

In response to this:

Design notes:

  • any operator built on top of library-go's NewControllerCommandConfig gets --config flag where operatorv1alpha1.GenericOperatorConfig manifest is expected.
  • operatorv1alpha1.GenericOperatorConfig has a .servingInfo.minTLSVersion and .servingInfo.cipherSuites where CVO can inject the centralized TLS configuration.
  • example: https://github.com/openshift/cluster-etcd-operator/blob/main/manifests/0000_20_etcd-operator_03_configmap.yaml#L14-L21
  • CVO's lib/resourcebuilder.builder can be extended to inject the tls configuration the same way as proxy injection is.
  • CVO is expected to reconcile every 2 minutes? So eventually all CM's annotated with config.openshift.io/inject-tls can be injected with the TLS configuration.

Operators with the tls-inject annotation:

How to test it:

  • provision a cluster with the operator PRs included
  • follow https://access.redhat.com/solutions/6955910 to make the CVO unmanaged + increase log level to 4
  • test 1: change the TLS to Moden (oc edit apiserver cluster):
spec:
  tlsSecurityProfile:
    modern: {}
    type: Modern
  • reading the CMs:
oc get cm -n openshift-apiserver-operator openshift-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-controller-manager-operator openshift-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-etcd-operator etcd-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-image-registry image-registry-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-kube-apiserver-operator kube-apiserver-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-kube-controller-manager-operator kube-controller-manager-operator-config -o json | jq -r '.data["config.yaml"]' | yq '.servingInfo'
oc get cm -n openshift-kube-scheduler-operator openshift-kube-scheduler-operator-config -o json | jq '.data["config.yaml"]' -r | yq '.servingInfo'

Summary by CodeRabbit

  • New Features

  • ConfigMaps can be annotated to automatically receive TLS settings (min TLS version and cipher suites) injected from cluster security profile, preserving other data.

  • Tests

  • Added comprehensive tests covering annotation states, mixed data formats, idempotence, and TLS field validation.

  • Chores

  • Updated dependency declarations to support Kubernetes/OpenShift integrations.

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.

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

Labels

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.

4 participants