Skip to content

OTA-1836: Honor the centralized TLS configuration#1338

Open
DavidHurta wants to merge 16 commits into
openshift:mainfrom
DavidHurta:central-tls-profile
Open

OTA-1836: Honor the centralized TLS configuration#1338
DavidHurta wants to merge 16 commits into
openshift:mainfrom
DavidHurta:central-tls-profile

Conversation

@DavidHurta
Copy link
Copy Markdown
Contributor

@DavidHurta DavidHurta commented Mar 7, 2026

Honor the centralized TLS configuration.

A follow-up PR openshift/hypershift#8013 after this one merges.

Summary by CodeRabbit

  • New Features

    • Central TLS profile manager for metrics: APIServer-driven TLS settings are applied at runtime and can be overridden via CLI. Startup validates overrides and waits for APIServer cache sync.
  • Tests

    • Extensive tests for profile selection, override precedence, informer-driven updates, error recovery, and adherence policy behavior.
  • Chores

    • Updated test frameworks and refreshed multiple indirect dependencies.

@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 Mar 7, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Mar 7, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test ?

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 7, 2026

Note

Reviews paused

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

Use the following commands to manage reviews:

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

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds APIServer-driven TLS profile management for the metrics server: new pkg/tls ProfileManager, CLI overrides, operator informer wiring, metrics integration applying profile+overrides per-handshake, tests, and dependency bumps.

Changes

APIServer-driven TLS Profile for Metrics

Layer / File(s) Summary
Dependency updates
go.mod
Test frameworks and OpenShift/Kubernetes indirects updated; k8s.io/component-base promoted to direct require.
CLI flags for TLS overrides
cmd/cluster-version-operator/start.go
Adds --tls-min-version and --tls-cipher-suites persistent flags and supporting imports for dynamic help text.
Start options & controller-context wiring
pkg/start/start.go
Adds TLSOptions to startup Options, validates/parses overrides at startup, waits for config informer caches, initializes CVO ProfileManager during run, and passes APIServer informer + overrides into controller context.
CVO APIServer informer wiring and API
pkg/cvo/cvo.go
Operator stores APIServer informer/lister and TLS override state, includes informer in cache sync, exposes InitializeProfileManager() and ApplySettings(), and updates constructor signature.
Metrics server TLS integration
pkg/cvo/metrics.go
RunMetrics accepts an applySettings callback and invokes it on each dynamically generated *tls.Config before use.
TLS profile manager implementation
pkg/tls/tls.go
New ProfileManager, Settings, Options, resolver and informer event handlers, ApplySettings, and override parsing/validation.
TLS profile manager test coverage
pkg/tls/tls_test.go
Tests for profile application across profiles, override validation/precedence, informer-driven updates, initialization fallback, and error recovery.

Sequence Diagram

sequenceDiagram
  participant OperatorStart as Operator Startup
  participant APIServerInf as APIServer Informer
  participant ProfileMgr as TLS ProfileManager
  participant MetricsServer as Metrics Server
  participant ClientTLS as Client TLS Handshake
  OperatorStart->>APIServerInf: create and sync informer
  OperatorStart->>ProfileMgr: NewProfileManager(informer, overrides)
  ProfileMgr->>APIServerInf: register add/update/delete handlers
  ProfileMgr->>ProfileMgr: resolve initial TLS profile
  OperatorStart->>MetricsServer: RunMetrics(informer)
  ClientTLS->>MetricsServer: initiate connection
  MetricsServer->>ProfileMgr: ApplySettings(tls.Config)
  ProfileMgr->>ProfileMgr: apply secure defaults -> central profile -> overrides
  MetricsServer-->>ClientTLS: TLS config ready
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Container-Privileges ❌ Error Bootstrap pod manifest contains privileged: true and hostNetwork: true without documented justification for cluster-version-operator initialization. Add comments documenting why CVO bootstrap pod requires full privilege escalation and host network access, or reduce privileges if possible.
Test Structure And Quality ⚠️ Warning Test_tlsProfileManager_EventHandlers violates single responsibility via nested t.Run(). Tests use time.Sleep() instead of polling for async events. Missing test coverage for CreateOverrides() bug. Split EventHandlers test into 5 separate test functions; replace sleep waits with polling; add test for reused Options clearing previous overrides.
✅ Passed checks (13 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'OTA-1836: Honor the centralized TLS configuration' directly and clearly summarizes the main objective of the changeset, which adds support for respecting cluster-wide TLS profiles from the APIServer resource.
Docstring Coverage ✅ Passed Docstring coverage is 92.86% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed PR uses standard Go testing (not Ginkgo). All tests in pkg/tls/tls_test.go are table-driven with static test names containing no dynamic content, timestamps, UUIDs, or generated identifiers.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests added in this PR. The 965-line test file (pkg/tls/tls_test.go) contains only standard Go unit tests using testing.T, not Ginkgo e2e tests, so the check does not apply.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR adds no Ginkgo e2e tests. Only new test file is pkg/tls/tls_test.go containing 8 standard Go unit tests, not Ginkgo e2e tests. SNO check not applicable to unit tests.
Topology-Aware Scheduling Compatibility ✅ Passed PR only modifies TLS configuration code, not deployment manifests or scheduling logic. No pod affinity, anti-affinity, nodeSelectors, replica scaling, or topology-dependent constraints are added.
Ote Binary Stdout Contract ✅ Passed All modified files comply with OTE Binary Stdout Contract: klog redirected to stderr via alsologtostderr flag, no fmt.Print* or os.Stdout at process level.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests were added in this PR. Only standard Go unit tests in pkg/tls/tls_test.go using fake clients, with no IPv4 assumptions or external connectivity requirements. Check not applicable.
No-Weak-Crypto ✅ Passed No weak crypto algorithms, custom implementations, or insecure comparisons detected. All cryptographic operations use standard Go library or approved OpenShift/Kubernetes libraries.
No-Sensitive-Data-In-Logs ✅ Passed PR logs only public TLS constants/identifiers and error objects; no passwords, tokens, keys, PII, hostnames, or customer data exposed in logs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 7, 2026
@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test e2e-agnostic-operator
/test e2e-agnostic-ovn
/test e2e-hypershift
/test gofmt
/test images
/test lint
/test unit
/test verify-update
/test verify-yaml

Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
pkg/start/start.go (1)

358-363: ⚠️ Potential issue | 🟠 Major

Wait for the APIServer informer before starting metrics.

RunMetrics now reads the TLS profile through controllerCtx.CVO.APIServerLister(), but this path still only blocks on ClusterVersionInformerFactory.WaitForCacheSync above. The APIServer informer is created later in NewControllerContext, so on a fresh leader transition its cache can still be cold here and the first handshakes will race an empty/NotFound profile. Please gate metrics startup on the APIServer informer, or the full ConfigInformerFactory, being synced when RespectCentralTLSProfile is enabled.

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

In `@pkg/start/start.go` around lines 358 - 363, The metrics server is started
without ensuring the APIServer informer (or the full ConfigInformerFactory) has
synced, causing races when RunMetrics reads TLS profiles via
controllerCtx.CVO.APIServerLister(); update the metrics startup to, when
RespectCentralTLSProfile is enabled, wait for the APIServer informer (or
controllerCtx.ConfigInformerFactory) to be synced before spawning the goroutine
that calls cvo.RunMetrics (check o.MetricsOptions.ListenAddress and
o.RespectCentralTLSProfile, then call the appropriate WaitForCacheSync on the
APIServer informer or ConfigInformerFactory from controllerCtx and only start
the metrics goroutine after that returns true).
pkg/cvo/metrics.go (2)

353-360: ⚠️ Potential issue | 🟠 Major

Reject missing apiServerLister at startup.

If RespectCentralTLSProfile is true and apiServerLister is nil, the process won't fail until Line 485, where the first handshake dereferences it. Please turn that into an early configuration error.

Suggested fix
 func RunMetrics(runContext context.Context, shutdownContext context.Context, restConfig *rest.Config, apiServerLister configlistersv1.APIServerLister, options MetricsOptions) error {
 	if options.ListenAddress == "" {
 		return errors.New("listen address is required to serve metrics")
 	}
 
 	if options.DisableAuthentication && !options.DisableAuthorization {
 		return errors.New("invalid configuration: cannot enable authorization without authentication")
 	}
+	if options.RespectCentralTLSProfile && apiServerLister == nil {
+		return errors.New("apiServerLister is required when RespectCentralTLSProfile is enabled")
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cvo/metrics.go` around lines 353 - 360, Add an early validation in
RunMetrics to reject a nil apiServerLister when options.RespectCentralTLSProfile
is true: after the existing ListenAddress and auth checks, check if
options.RespectCentralTLSProfile && apiServerLister == nil and return a clear
configuration error (e.g. "apiServerLister is required when
RespectCentralTLSProfile is true"). This prevents the later nil dereference in
TLS handshake code that relies on apiServerLister.

467-490: ⚠️ Potential issue | 🔴 Critical

Synchronize lastValidProfile in the TLS callback.

lastValidProfile is captured by GetConfigForClient and then read and overwritten on each handshake without synchronization. That is a data race, and concurrent handshakes can also write back an older snapshot after a profile change.

Suggested fix
 import (
 	"context"
 	"crypto/tls"
 	"crypto/x509"
 	"errors"
 	"fmt"
 	"net"
 	"net/http"
 	"slices"
+	"sync"
 	"time"
@@
-	var lastValidProfile *cachedTLSProfile
+	var (
+		lastValidProfile   *cachedTLSProfile
+		lastValidProfileMu sync.Mutex
+	)
@@
 			if options.RespectCentralTLSProfile {
+				lastValidProfileMu.Lock()
 				profile, err := getAPIServerTLSProfile(apiServerLister, lastValidProfile)
+				if err == nil {
+					lastValidProfile = profile
+				}
+				lastValidProfileMu.Unlock()
 				if err != nil {
 					return nil, fmt.Errorf("failed to get TLS profile for metrics server: %w", err)
 				}
-				lastValidProfile = profile
 				profile.apply(config)
 			}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cvo/metrics.go` around lines 467 - 490, The TLS callback captures and
mutates lastValidProfile unsafely; add synchronization (e.g., a package-local
sync.RWMutex like lastValidProfileMu) and use RLock when reading and Lock when
updating to prevent data races and stale overwrites in GetConfigForClient; wrap
the call to getAPIServerTLSProfile and the assignment lastValidProfile = profile
(and the subsequent profile.apply(config) if it relies on the stored state)
inside the mutex so readers/writers are serialized and the cachedTLSProfile is
updated atomically.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/cvo/metrics.go`:
- Around line 176-180: The log at the klog.Infof call prints profile.Ciphers
using %s which causes invalid formatting; update the klog.Infof in the TLS
profile change block (after tlsprofile.NewTLSConfigFromProfile and the
unsupportedCiphers check) to format the cipher list correctly by using a verbs
that match the type (e.g., %v) or join the slice into a string (e.g.,
strings.Join(profile.Ciphers, ",")). Ensure you import strings if you choose
Join and keep the rest of the message unchanged.

---

Outside diff comments:
In `@pkg/cvo/metrics.go`:
- Around line 353-360: Add an early validation in RunMetrics to reject a nil
apiServerLister when options.RespectCentralTLSProfile is true: after the
existing ListenAddress and auth checks, check if
options.RespectCentralTLSProfile && apiServerLister == nil and return a clear
configuration error (e.g. "apiServerLister is required when
RespectCentralTLSProfile is true"). This prevents the later nil dereference in
TLS handshake code that relies on apiServerLister.
- Around line 467-490: The TLS callback captures and mutates lastValidProfile
unsafely; add synchronization (e.g., a package-local sync.RWMutex like
lastValidProfileMu) and use RLock when reading and Lock when updating to prevent
data races and stale overwrites in GetConfigForClient; wrap the call to
getAPIServerTLSProfile and the assignment lastValidProfile = profile (and the
subsequent profile.apply(config) if it relies on the stored state) inside the
mutex so readers/writers are serialized and the cachedTLSProfile is updated
atomically.

In `@pkg/start/start.go`:
- Around line 358-363: The metrics server is started without ensuring the
APIServer informer (or the full ConfigInformerFactory) has synced, causing races
when RunMetrics reads TLS profiles via controllerCtx.CVO.APIServerLister();
update the metrics startup to, when RespectCentralTLSProfile is enabled, wait
for the APIServer informer (or controllerCtx.ConfigInformerFactory) to be synced
before spawning the goroutine that calls cvo.RunMetrics (check
o.MetricsOptions.ListenAddress and o.RespectCentralTLSProfile, then call the
appropriate WaitForCacheSync on the APIServer informer or ConfigInformerFactory
from controllerCtx and only start the metrics goroutine after that returns
true).

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 4b2ebb59-479e-4c67-b71f-fec6dbcfc90e

📥 Commits

Reviewing files that changed from the base of the PR and between 7092376 and 3f595e0.

⛔ Files ignored due to path filters (291)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/evanphx/json-patch/v5/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/errors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/fold.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/fuzz.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/indent.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/scanner.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/stream.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/tables.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/tags.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/evanphx/json-patch/v5/patch.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-logr/logr/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-logr/logr/funcr/funcr.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/btree/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/btree/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/btree/btree.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/btree/btree_generic.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/pprof/profile/merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/pprof/profile/profile.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/pprof/profile/proto.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/google/pprof/profile/prune.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/CHANGELOG.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/format/format.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/gomega_dsl.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/assertion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/async_assertion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/duration_bundle.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/gomega.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/polling_signal_error.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/internal/vetoptdesc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/and.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_directory.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_element_of_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_false_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_identical_to.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_true_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/consist_of.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/equal_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_each_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_exact_elements.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_field.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_len_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_value.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_json_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/not.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/or.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/panic_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/receive_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/satisfy_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/semi_structured_data_support.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/succeed_matcher.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/type_support.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/matchers/with_transform.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/gomega/types/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_backup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_crio_credential_provider_config.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1alpha2/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha2/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/legacyfeaturegates.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_network.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/types_clusterapi.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.crd-manifests/0000_30_cluster-api_01_clusterapis-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1alpha1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/controller-runtime-common/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/controller-runtime-common/pkg/tls/controller.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/controller-runtime-common/pkg/tls/tls.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/library-go/pkg/crypto/crypto.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/library-go/pkg/manifest/manifest.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/api/client.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/desc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/labels.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/metric.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/process_collector_darwin.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/process_collector_mem_nocgo_darwin.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/process_collector_procfsenabled.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/vec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/client_golang/prometheus/wrap.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/config/config.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/config/headers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/config/http_config.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/decode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/encode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/expfmt.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/fuzz.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/openmetrics_create.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/text_create.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/expfmt/text_parse.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/alert.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/labels.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/labelset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/metric.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/time.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/value.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/value_histogram.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/value_type.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/.golangci.yml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/Makefile.common is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/arp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/fs.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/fs_statfs_notype.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/fscache.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/internal/fs/fs.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/internal/util/parse.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/mountstats.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/net_dev_snmp6.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/net_ip_socket.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/net_protocols.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/net_tcp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/net_unix.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_cgroup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_io.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_netstat.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_smaps.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_snmp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_snmp6.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_status.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/proc_sys.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/procfs/softirqs.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/bool_func.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/count.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/errors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/flag.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/func.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/golangflag.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/ipnet_slice.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/string_to_string.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/text.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/spf13/pflag/time.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/net/http2/transport.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/net/http2/writesched_priority_rfc9218.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/net/trace/events.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/internal/doc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/internal/oauth2.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/internal/token.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/internal/transport.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/oauth2.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/pkce.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/token.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/oauth2/transport.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sync/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sync/PATENTS is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sync/errgroup/errgroup.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/mkerrors.sh is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_386.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_arm.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_mips.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/sys/unix/ztypes_netbsd_arm.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/term/terminal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/japanese/eucjp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/japanese/iso2022jp.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/japanese/shiftjis.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/korean/euckr.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/simplifiedchinese/gbk.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/simplifiedchinese/hzgb2312.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/traditionalchinese/big5.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/text/encoding/unicode/unicode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/golang.org/x/tools/go/ast/inspector/cursor.go is excluded by !**/vendor/**, !vendor/**
  • vendor/gomodules.xyz/jsonpatch/v2/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/gomodules.xyz/jsonpatch/v2/jsonpatch.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/encoding/protowire/wire.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/filedesc/editions.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/filedesc/presence.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/genid/api_gen.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/impl/codec_message_opaque.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/impl/message_opaque.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/impl/presence.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/strs/strings_unsafe_go120.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/internal/version/version.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/proto/merge.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/reflect/protoreflect/source_gen.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe_go120.go is excluded by !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/gofeaturespb/go_features.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/known/emptypb/empty.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/known/structpb/struct.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/google.golang.org/protobuf/types/known/wrapperspb/wrappers.pb.go is excluded by !**/*.pb.go, !**/vendor/**, !vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/evanphx/json-patch.v4/patch.go is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/yaml.v2/.travis.yml is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/yaml.v2/LICENSE.libyaml is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/yaml.v2/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/yaml.v2/apic.go is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/yaml.v2/decode.go is excluded by !**/vendor/**, !vendor/**
  • vendor/gopkg.in/yaml.v2/emitterc.go is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (9)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/metrics.go
  • pkg/cvo/sync_worker.go
  • pkg/payload/payload.go
  • pkg/payload/render.go
  • pkg/start/start.go

Comment thread pkg/cvo/metrics.go Outdated
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 11, 2026
@DavidHurta DavidHurta force-pushed the central-tls-profile branch from 3f595e0 to 1362d3f Compare March 17, 2026 00:23
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 17, 2026
@DavidHurta DavidHurta changed the title WIP: Central tls profile OTA-1764: Respect Central TLS Profile in Standalone Mar 17, 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 Mar 17, 2026
@openshift-ci-robot
Copy link
Copy Markdown
Contributor

openshift-ci-robot commented Mar 17, 2026

@DavidHurta: This pull request references OTA-1764 which is a valid jira issue.

Details

In response to this:

Summary by CodeRabbit

  • New Features

  • Added support for dynamic TLS profile handling in the metrics server, enabling centralized TLS configuration management from the cluster's APIServer.

  • Introduced a new configuration option to control TLS profile synchronization behavior.

  • Chores

  • Updated multiple Go module dependencies to newer versions, including logging, testing, Kubernetes, Prometheus, and related utilities.

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.

@DavidHurta DavidHurta force-pushed the central-tls-profile branch 2 times, most recently from 9990e0a to f9d748d Compare March 17, 2026 01:27
@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test all

@DavidHurta
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
pkg/cvo/metrics.go (1)

164-170: Remove or clarify the dead code block.

The if false block with the TODO comment is unreachable and will never execute. If this is a placeholder for future API changes, consider using a build tag or feature flag instead, or remove it entirely until the API changes are ready.

♻️ Suggested approach

Either remove the dead code block entirely:

-	if false { // TODO: Add TLS adherence logic when API changes merge
-		return &cachedTLSProfile{
-			spec:       nil,
-			apply:      func(config *tls.Config) {}, // do nothing
-			generation: apiServer.Generation,
-		}, nil
-	}
-

Or if keeping it as a placeholder, add a clearer skip mechanism:

+	// TODO(OTA-XXXX): Add TLS adherence logic when API changes merge
+	// When implemented, check apiServer.Spec.TLSSecurityProfile adherence field here
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/cvo/metrics.go` around lines 164 - 170, The unreachable "if false" block
should be removed or replaced with a proper toggle; delete the dead branch that
returns a cachedTLSProfile with spec nil/apply noop (references:
cachedTLSProfile, apiServer.Generation, tls.Config) or, if you need a
placeholder, replace it with a clear feature flag/build-tag guard (not "if
false") and document the intent; ensure any retained placeholder still compiles
and preserves the intended return shape for the surrounding function.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@go.mod`:
- Around line 29-36: The go.mod shows a mismatch: most k8s modules are v0.35.1
while k8s.io/kube-aggregator remains v0.34.1; verify compatibility and align
versions by either upgrading k8s.io/kube-aggregator to a v0.35.x release if
available, or downgrade the other k8s modules to the kube-aggregator compatible
version (e.g., v0.34.x), or add a go.mod replace to force a tested compatible
commit; update the k8s module entries (k8s.io/kube-aggregator and the other
k8s.io/* lines) so all Kubernetes component modules use a mutually compatible
version set and run go mod tidy and go test to ensure no API/type mismatches.
- Line 3: The go.mod contains an invalid Go version "go 1.25.0"; update the
module's go directive to a valid released version (e.g., "go 1.25.8" or "go
1.26.1") by replacing the current go directive value so the go directive in
go.mod reflects an actual Go release.

---

Nitpick comments:
In `@pkg/cvo/metrics.go`:
- Around line 164-170: The unreachable "if false" block should be removed or
replaced with a proper toggle; delete the dead branch that returns a
cachedTLSProfile with spec nil/apply noop (references: cachedTLSProfile,
apiServer.Generation, tls.Config) or, if you need a placeholder, replace it with
a clear feature flag/build-tag guard (not "if false") and document the intent;
ensure any retained placeholder still compiles and preserves the intended return
shape for the surrounding function.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b19eb2ef-b766-4f59-b7e5-9d3710e2fd62

📥 Commits

Reviewing files that changed from the base of the PR and between 3f595e0 and f9d748d.

⛔ Files ignored due to path filters (113)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/evanphx/json-patch/v5/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/errors.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/decode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/encode.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/fold.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/fuzz.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/indent.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/scanner.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/stream.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/tables.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/internal/json/tags.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/merge.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/evanphx/json-patch/v5/patch.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/btree/LICENSE is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/btree/README.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/btree/btree.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/btree/btree_generic.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/pprof/profile/merge.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/pprof/profile/profile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/pprof/profile/proto.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/google/pprof/profile/prune.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/CHANGELOG.md is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/format/format.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/gomega_dsl.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/async_assertion.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/duration_bundle.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/gomega.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/polling_signal_error.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/internal/vetoptdesc.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/and.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_directory.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_comparable_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_element_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_false_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_identical_to.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_key_of_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_true_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/consist_of.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/equal_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_each_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_exact_elements.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_existing_field_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_field.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_body_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_header_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_http_status_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_len_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/have_value.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_error_strictly_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_json_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/not.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/or.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/panic_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/receive_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/satisfy_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/semi_structured_data_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/succeed_matcher.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/type_support.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/matchers/with_transform.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/onsi/gomega/types/types.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_apiserver.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_authentication.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_network.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/types_tlssecurityprofile.go is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-CustomNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-Default.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-DevPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-OKD.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_apiservers-TechPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-Default.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-OKD.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-OKD.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-CustomNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-DevPreviewNoUpgrade.crd.yaml is excluded by !vendor/**, !**/vendor/**
📒 Files selected for processing (9)
  • go.mod
  • lib/manifest/manifest.go
  • pkg/cvo/cvo.go
  • pkg/cvo/featuregate_integration_test.go
  • pkg/cvo/metrics.go
  • pkg/cvo/sync_worker.go
  • pkg/payload/payload.go
  • pkg/payload/render.go
  • pkg/start/start.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/cvo/featuregate_integration_test.go
  • lib/manifest/manifest.go
  • pkg/payload/render.go

Comment thread go.mod Outdated
Comment thread go.mod Outdated
@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test ?

@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test tls-scanner
/test all

@DavidHurta DavidHurta force-pushed the central-tls-profile branch from 8553636 to 7b9c98f Compare March 18, 2026 00:29
@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test tls-scanner
/test all

@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test tls-scanner

@DavidHurta DavidHurta changed the title OTA-1764: Respect Central TLS Profile in Standalone OTA-1764: Support centralized TLS configuration Mar 19, 2026
@DavidHurta DavidHurta force-pushed the central-tls-profile branch from 70099c9 to 29e1401 Compare March 19, 2026 02:30
@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test tls-scanner
/test all

hongkailiu and others added 10 commits May 29, 2026 01:46
Implements comprehensive test coverage for ProfileManager's event handlers
including Add, Update, and Delete events. Tests verify:
- Initial profile application from Add event
- Profile updates via Update events
- Error recovery when invalid profiles are received
- TLSAdherence policy changes
- Fallback to safe defaults on Delete events

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Extracts the repeated pattern of creating and starting an APIServer
informer into helper functions to reduce code duplication.

Changes:
- Add setupInformer helper for simple test cases
- Add setupInformerWithClient helper for tests that need the fake
  client (e.g., for updating APIServer resources in event tests)
- Both helpers accept variadic apiServers and custom timeout
- Update all tests to use the new helpers, reducing ~80 lines of
  boilerplate code

The helpers use t.Helper() for better test failure reporting.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Initializing ProfileManager before the APIServer informer syncs causes
the lister to be empty, forcing CVO to use library default TLS settings
instead of the cluster's configured TLS profile from the APIServer resource.
This creates inconsistency where CVO starts with different TLS settings
than what the cluster administrator configured, potentially causing
connection issues or security policy violations.

Move ProfileManager initialization to after informer sync in start.go
to ensure the cluster's actual TLS profile is applied from the start.

Co-authored-by: Claude Code <claude@anthropic.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
@DavidHurta DavidHurta force-pushed the central-tls-profile branch from b60de52 to b9518b4 Compare May 29, 2026 00:15
Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/cvo/metrics.go (1)

279-286: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast when applySettings is nil.

GetConfigForClient calls the callback unconditionally. A nil callback turns the first scrape into a process panic instead of a startup error.

Suggested fix
 func RunMetrics(runContext context.Context, shutdownContext context.Context, restConfig *rest.Config, applySettings func(config *tls.Config), options MetricsOptions) error {
+	if applySettings == nil {
+		return errors.New("applySettings is required")
+	}
+
 	if options.ListenAddress == "" {
 		return errors.New("listen address is required to serve metrics")
 	}

Also applies to: 392-405

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

In `@pkg/cvo/metrics.go` around lines 279 - 286, RunMetrics must fail fast if
applySettings is nil because GetConfigForClient calls that callback
unconditionally; add a nil-check at the start of RunMetrics (and the other
initialization path noted around lines 392-405) and return an explicit error
like "applySettings callback is required" when applySettings == nil so startup
errors occur instead of a panic; update both the RunMetrics function and the
other initialization site that constructs a client via GetConfigForClient to
validate the callback before proceeding, referencing the applySettings parameter
and the GetConfigForClient call sites.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/tls/tls.go`:
- Around line 178-205: The method CreateOverrides leaves o.settings intact on
the early-return path, causing stale overrides to persist; modify
CreateOverrides (on type Options) to clear the cached overrides before returning
when no overrides are configured (e.g., set o.settings = nil before the early
return) so that a reused Options instance does not retain previous TLS settings;
keep the existing parsing and assignment to o.settings = validated for the
non-empty cases.

---

Outside diff comments:
In `@pkg/cvo/metrics.go`:
- Around line 279-286: RunMetrics must fail fast if applySettings is nil because
GetConfigForClient calls that callback unconditionally; add a nil-check at the
start of RunMetrics (and the other initialization path noted around lines
392-405) and return an explicit error like "applySettings callback is required"
when applySettings == nil so startup errors occur instead of a panic; update
both the RunMetrics function and the other initialization site that constructs a
client via GetConfigForClient to validate the callback before proceeding,
referencing the applySettings parameter and the GetConfigForClient call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: b4079a36-1e0c-4307-bbb8-73f1af317b83

📥 Commits

Reviewing files that changed from the base of the PR and between 1517c65 and b60de52.

📒 Files selected for processing (6)
  • cmd/cluster-version-operator/start.go
  • pkg/cvo/cvo.go
  • pkg/cvo/metrics.go
  • pkg/start/start.go
  • pkg/tls/tls.go
  • pkg/tls/tls_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/cluster-version-operator/start.go
  • pkg/tls/tls_test.go

Comment thread pkg/tls/tls.go
Comment on lines +178 to +205
// CreateOverrides creates the TLS override options and returns parsed values.
// Returns nil if no overrides are configured.
func (o *Options) CreateOverrides() error {
// If no overrides, return nil (central profile or defaults will be used)
if o.MinVersionOverride == "" && len(o.CipherSuitesOverride) == 0 {
return nil
}

validated := &Settings{}

if o.MinVersionOverride != "" {
minVersion, err := cliflag.TLSVersion(o.MinVersionOverride)
if err != nil {
return fmt.Errorf("invalid --tls-min-version %q: %w (valid values: %v)", o.MinVersionOverride, err, cliflag.TLSPossibleVersions())
}
validated.MinVersion = minVersion
}

if len(o.CipherSuitesOverride) > 0 {
cipherSuites, err := cliflag.TLSCipherSuites(o.CipherSuitesOverride)
if err != nil {
return fmt.Errorf("invalid --tls-cipher-suites: %w", err)
}
validated.CipherSuites = cipherSuites
}

o.settings = validated
return nil
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reset cached overrides before reparsing.

CreateOverrides() leaves o.settings untouched on the early-return path, so a reused Options instance keeps applying the previous TLS overrides after the flags are cleared. Reset the cached settings before parsing so “no overrides” really becomes nil.

Suggested fix
 func (o *Options) CreateOverrides() error {
+	o.settings = nil
+
 	// If no overrides, return nil (central profile or defaults will be used)
 	if o.MinVersionOverride == "" && len(o.CipherSuitesOverride) == 0 {
 		return nil
 	}
@@
-	o.settings = validated
+	o.settings = validated
 	return nil
 }
📝 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
// CreateOverrides creates the TLS override options and returns parsed values.
// Returns nil if no overrides are configured.
func (o *Options) CreateOverrides() error {
// If no overrides, return nil (central profile or defaults will be used)
if o.MinVersionOverride == "" && len(o.CipherSuitesOverride) == 0 {
return nil
}
validated := &Settings{}
if o.MinVersionOverride != "" {
minVersion, err := cliflag.TLSVersion(o.MinVersionOverride)
if err != nil {
return fmt.Errorf("invalid --tls-min-version %q: %w (valid values: %v)", o.MinVersionOverride, err, cliflag.TLSPossibleVersions())
}
validated.MinVersion = minVersion
}
if len(o.CipherSuitesOverride) > 0 {
cipherSuites, err := cliflag.TLSCipherSuites(o.CipherSuitesOverride)
if err != nil {
return fmt.Errorf("invalid --tls-cipher-suites: %w", err)
}
validated.CipherSuites = cipherSuites
}
o.settings = validated
return nil
// CreateOverrides creates the TLS override options and returns parsed values.
// Returns nil if no overrides are configured.
func (o *Options) CreateOverrides() error {
o.settings = nil
// If no overrides, return nil (central profile or defaults will be used)
if o.MinVersionOverride == "" && len(o.CipherSuitesOverride) == 0 {
return nil
}
validated := &Settings{}
if o.MinVersionOverride != "" {
minVersion, err := cliflag.TLSVersion(o.MinVersionOverride)
if err != nil {
return fmt.Errorf("invalid --tls-min-version %q: %w (valid values: %v)", o.MinVersionOverride, err, cliflag.TLSPossibleVersions())
}
validated.MinVersion = minVersion
}
if len(o.CipherSuitesOverride) > 0 {
cipherSuites, err := cliflag.TLSCipherSuites(o.CipherSuitesOverride)
if err != nil {
return fmt.Errorf("invalid --tls-cipher-suites: %w", err)
}
validated.CipherSuites = cipherSuites
}
o.settings = validated
return nil
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/tls/tls.go` around lines 178 - 205, The method CreateOverrides leaves
o.settings intact on the early-return path, causing stale overrides to persist;
modify CreateOverrides (on type Options) to clear the cached overrides before
returning when no overrides are configured (e.g., set o.settings = nil before
the early return) so that a reused Options instance does not retain previous TLS
settings; keep the existing parsing and assignment to o.settings = validated for
the non-empty cases.

@DavidHurta
Copy link
Copy Markdown
Contributor Author

DavidHurta commented May 29, 2026

I have tried to make your review more straightforward. I have directly cherry-picked your commits (only minor merge conflict resolution needed for the Move things around commit).

Furthermore, I have added a new 97a5bd2 commit to resolve that one minor mentioned issue. PTAL. Please let me know if the description is not clear enough or is incorrect. I am happy to follow up.

@hongkailiu
Copy link
Copy Markdown
Member

I have added a new 97a5bd2 commit to resolve that one minor mentioned issue.

Thanks for catching it up. It saved us lots of troubles of fixing it.

I should not have made that mistake in the first place given that it took me 2 hours to fix the same issue in test.
https://github.com/openshift/cluster-version-operator/pull/1338/changes#diff-92c83cc60428f2d2d8fc8055c7de208fc9fc40de60ed134df861ba0ee01af18eR39

apiServerInformer.Lister() // we have to call this before Start

@hongkailiu
Copy link
Copy Markdown
Member

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label May 29, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 29, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: DavidHurta, hongkailiu

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

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [DavidHurta,hongkailiu]

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

@hongkailiu
Copy link
Copy Markdown
Member

/retest-required

@hongkailiu
Copy link
Copy Markdown
Member

Initializing ProfileManager before the APIServer informer syncs causes
the lister to be empty

The above from 97a5bd2

Yesterday I thought about it and led to #1338 (comment) but now I am thinking maybe the claim "the lister to be empty" is not true.

Did you get the conclusion by testing it on a cluster?

I am going to do some testing otherwise.

This is NOT a blocker to merge the current pull. I can bring this up with a follow up pull if needed.

@hongkailiu
Copy link
Copy Markdown
Member

hongkailiu commented May 31, 2026

share some e2e testing result: #1393 (comment)

It shows the e2e running against the current pull.
The testing result has nothing to do with #1338 (comment).

@DavidHurta
Copy link
Copy Markdown
Contributor Author

DavidHurta commented Jun 1, 2026

Did you get the conclusion by testing it on a cluster?

No testing. Static analysis (prone to misunderstanding the code, of course).

The wording of the commit could be more technically correct. It is a data race issue. It may or may not occur depending on when informers are started and when the caches sync.

The CVO can sometimes make these things (initialization, passing down only the needed structs, etc.) a bit awkward due to its architecture. Thus, why I always double-check my code in this area.

Previously, the profile manager wanted to fetch the APIServer before the underlying informer was even started.

Start is described as:

	// Start initializes all requested informers. They are handled in goroutines
	// which run until the stop channel gets closed.
	// Warning: Start does not block. When run in a go-routine, it will race with a later WaitForCacheSync.
	Start(stopCh <-chan struct{})

Thus, here we should get a clear error. I have checked the past CI, and we can see such CVO logs in https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results/pr-logs/pull/openshift_cluster-version-operator/1393/pull-ci-openshift-cluster-version-operator-main-e2e-agnostic-operator/2058900598811529216/artifacts/e2e-agnostic-operator/gather-extra/artifacts/pods/openshift-cluster-version_cluster-version-operator-867dc65658-nxxj2_cluster-version-operator.log:

$ curl -s https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results/pr-logs/pull/openshift_cluster-version-operator/1393/pull-ci-openshift-cluster-version-operator-main-e2e-agnostic-operator/2058900598811529216/artifacts/e2e-agnostic-operator/gather-extra/artifacts/pods/openshift-cluster-version_cluster-version-operator-867dc65658-nxxj2_cluster-version-operator.log | grep tls.go | head
W0525 13:56:44.993892       1 tls.go:41] APIServer resource not available at startup: apiserver.config.openshift.io "cluster" not found, using fallback defaults
I0525 13:56:44.993935       1 tls.go:92] Updated cached TLS profile
I0525 13:56:45.002808       1 tls.go:92] Updated cached TLS profile
I0525 13:59:03.710753       1 tls.go:92] Updated cached TLS profile
I0525 14:01:22.418936       1 tls.go:92] Updated cached TLS profile
I0525 14:03:41.126518       1 tls.go:92] Updated cached TLS profile
I0525 14:05:59.834533       1 tls.go:92] Updated cached TLS profile
I0525 14:08:18.543529       1 tls.go:92] Updated cached TLS profile
I0525 14:09:43.475549       1 tls.go:92] Updated cached TLS profile
I0525 14:12:02.183322       1 tls.go:92] Updated cached TLS profile

That's a CI run for 6a8c607 from #1393, which at the time contained the CVO changes, if I understand correctly.

@hongkailiu
Copy link
Copy Markdown
Member

$ curl -s https://gcsweb-ci.apps.ci.l2s4.p1.openshiftapps.com/gcs/test-platform-results/pr-logs/pull/openshift_cluster-version-operator/1393/pull-ci-openshift-cluster-version-operator-main-e2e-agnostic-operator/2058900598811529216/artifacts/e2e-agnostic-operator/gather-extra/artifacts/pods/openshift-cluster-version_cluster-version-operator-867dc65658-nxxj2_cluster-version-operator.log | grep tls.go | head
W0525 13:56:44.993892 1 tls.go:41] APIServer resource not available at startup: apiserver.config.openshift.io "cluster" not found, using fallback defaults

Great. You have a solid proof from CI.
Thanks.

I will dig a bit about it (still no blockers for this pull).

@DavidHurta
Copy link
Copy Markdown
Contributor Author

/test tls-scanner-modern-profile
/test tls-scanner-default-profile

@DavidHurta
Copy link
Copy Markdown
Contributor Author

/unhold

Intentionally not marking as verified at the moment.

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

openshift-ci Bot commented Jun 1, 2026

@DavidHurta: 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/tls-scanner-modern-profile b9518b4 link false /test tls-scanner-modern-profile
ci/prow/tls-scanner-default-profile b9518b4 link false /test tls-scanner-default-profile

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.

hongkailiu added a commit to hongkailiu/cluster-version-operator that referenced this pull request Jun 1, 2026
Follow up the issue from openshift#1338 (comment):

The right way to call things out for `InformerFactory`: e.g., [processInitialFeatureGate](https://github.com/openshift/cluster-version-operator/blob/c1dc3e8f0b7c366d45177af391c4f888059b446d/pkg/start/start.go#L269-L280),

* `Lister()` such as `configInformerFactory.Config().V1().FeatureGates().Lister()`
* `Start()` such as `configInformerFactory.Start(ctx.Done())`
* `WaitForCacheSync*()` such as `configInformerFactory.WaitForCacheSync(ctx.Done())`

The lister is ready to retrieve instance, e.g., via `Get()`.

```console
$ git --no-pager log --pretty=oneline -1
6a8c607 (HEAD -> pr1338-e2e-6a8c6072b2f4e45fe5ab9269b4efa96d4608b0d0) make update
```

The issue with the commit above:

```
start.go: Line 190
func (o *Options) Run(ctx context.Context) error

* Line 216
  o.NewControllerContext()
	* Line 650
      cvo, err := cvo.New() where Lister() and cvotls.NewProfileManager(apiServerInformer, tlsOverrides) are called where apiServerInformer.Lister().Get(tlsprofile.APIServerName) is called

* Line 221
  o.run()
	* start and sync
```

The issue is that `get()` is called in the wrong order: `Lister()`, `Get()`, `Start()` and `Sync()`. It explains `apiserver.config.openshift.io "cluster" not found` from openshift#1338 (comment). In short, we need the informer factory is ready before initializing the TLS profile manager.

The fix is moving `NewProfileManager()` from `cvo.go` to `start.go` and the instance passes to `cvo.go`.

Note that the same `configInformerFactory` instance is started and synced in `o.processInitialFeatureGate`. The only thing missing is invoking its `List()` ahead of it.
Once it is done, we do not need to do those again in `cvo.go`.
hongkailiu added a commit to hongkailiu/cluster-version-operator that referenced this pull request Jun 1, 2026
Follow up the issue from openshift#1338 (comment):

The right way to call things out for `InformerFactory`: e.g., [processInitialFeatureGate](https://github.com/openshift/cluster-version-operator/blob/c1dc3e8f0b7c366d45177af391c4f888059b446d/pkg/start/start.go#L269-L280),

* `Lister()` such as `configInformerFactory.Config().V1().FeatureGates().Lister()`
* `Start()` such as `configInformerFactory.Start(ctx.Done())`
* `WaitForCacheSync*()` such as `configInformerFactory.WaitForCacheSync(ctx.Done())`

The lister is ready to retrieve instance, e.g., via `Get()`.

```console
$ git --no-pager log --pretty=oneline -1
6a8c607 (HEAD -> pr1338-e2e-6a8c6072b2f4e45fe5ab9269b4efa96d4608b0d0) make update
```

The issue with the commit above:

```
start.go: Line 190
func (o *Options) Run(ctx context.Context) error

* Line 216
  o.NewControllerContext()
	* Line 650
      cvo, err := cvo.New() where Lister() and cvotls.NewProfileManager(apiServerInformer, tlsOverrides) are called where apiServerInformer.Lister().Get(tlsprofile.APIServerName) is called

* Line 221
  o.run()
	* start and sync
```

The issue is that `get()` is called in the wrong order: `Lister()`, `Get()`, `Start()` and `Sync()`. It explains `apiserver.config.openshift.io "cluster" not found` from openshift#1338 (comment). In short, we need the informer factory is ready before initializing the TLS profile manager.

The fix is moving `NewProfileManager()` from `cvo.go` to `start.go` and the instance passes to `cvo.go`.

Note that the same `configInformerFactory` instance is started and synced in `o.processInitialFeatureGate`. The only thing missing is invoking its `List()` ahead of it.
Once it is done, we do not need to do those again in `cvo.go`.

I prefer the current fix over the reverted one because the code is simpler this way. `cvo` does not need to have the fields such as the informer and the overrides that actually belong to the TLS profile manager.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants