Skip to content

TRT-2761: Undo revert and fix applyClusterTLSProfile()#1335

Open
tmshort wants to merge 2 commits into
openshift:mainfrom
tmshort:synchronize
Open

TRT-2761: Undo revert and fix applyClusterTLSProfile()#1335
tmshort wants to merge 2 commits into
openshift:mainfrom
tmshort:synchronize

Conversation

@tmshort

@tmshort tmshort commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

This undoes the revert #1334 (which reverted #1330). The downstream sync is pulled back in, and the fix operator-framework/operator-lifecycle-manager#3860 is downstreamed in. This should be the only necessary fix, and the only commit that needs to be downstreamed.

This has to be a manual downstream due to the revert. Following this, subsequent automatic syncing should succeed.

Alternative to #1333

Summary by CodeRabbit

  • New Features

    • Package server now can automatically adopt the cluster’s TLS security profile when no custom TLS minimum is set.
    • Added permission to read the cluster APIServer configuration needed for this startup behavior.
  • Bug Fixes

    • Improved handling so existing TLS settings provided by users continue to take precedence.
    • Added broader compatibility and stability updates through dependency and workflow upgrades.

tmshort and others added 2 commits June 29, 2026 10:46
…-1330-1782684731"

This reverts commit 93e5a5c, reversing
changes made to 0adff33.
…up (#3860)

In HyperShift hosted clusters the API server is not ready during initial
packageserver startup, causing applyClusterTLSProfile() to timeout and
return a fatal error, crash-looping the packageserver.

Change error handling to warn-and-continue so packageserver starts with
secure TLS defaults. The PSM will inject the correct --tls-min-version /
--tls-cipher-suites flags via the CSV once the API becomes available,
triggering a clean restart with the cluster-configured profile.

Signed-off-by: Todd Short <tshort@redhat.com>
Upstream-repository: operator-lifecycle-manager
Upstream-commit: 601f296cf140af32c687109b065df1dbdcd2943d
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 29, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 29, 2026

Copy link
Copy Markdown

@tmshort: This pull request references TRT-2761 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 bug to target the "5.0.0" version, but no target version was set.

Details

In response to this:

This undoes the revert #1334 (which reverted #1330). The downstream sync is pulled back in, and the fix operator-framework/operator-lifecycle-manager#3860 is downstreamed in. This should be the only necessary fix, and the only commit that needs to be downstreamed.

This has to be a manual downstream due to the revert. Following this, subsequent automatic syncing should succeed.

Alternative to #1333

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Walkthrough

Adds cluster TLS profile auto-detection to the package-server: at startup, if --tls-min-version is unset, the server fetches the OpenShift APIServer CR and applies the cluster TLS profile to SecureServing. Corresponding RBAC rules are added to all manifests. Additionally, mapstructure is migrated to go-viper/mapstructure/v2, hashstructure to v2 with FormatV2, and several dependencies are bumped.

Changes

Cluster TLS Profile Auto-Detection

Layer / File(s) Summary
RBAC grants for APIServer CR read
pkg/manifests/csv.yaml, staging/operator-lifecycle-manager/deploy/chart/templates/_packageserver.clusterserviceversion.yaml, staging/operator-lifecycle-manager/deploy/upstream/quickstart/olm.yaml
Adds get permission on config.openshift.io apiservers resource named cluster to packageserver clusterPermissions in all manifests.
applyClusterTLSProfile implementation
staging/operator-lifecycle-manager/pkg/package-server/server/server.go
Expands imports, builds rest.Config earlier in Run, conditionally calls applyClusterTLSProfile when MinTLSVersion is unset (warning on error), and implements applyClusterTLSProfile + applyClusterTLSProfileWithClients helpers that check OpenShift availability, fetch APIServer/cluster, and set MinTLSVersion/CipherSuites only when not already set by flags.
Unit tests for applyClusterTLSProfileWithClients
staging/operator-lifecycle-manager/pkg/package-server/server/server_test.go
Adds six test cases covering non-OpenShift no-op, Intermediate/Modern TLS profile mapping, flag precedence, missing CR error, and error leaving SecureServingOptions unchanged.

Dependency and mapstructure/hashstructure migration

Layer / File(s) Summary
go.mod dependency bumps
go.mod, staging/operator-lifecycle-manager/go.mod
Adds go-viper/mapstructure/v2, replaces mitchellh/hashstructure v1 with v2, bumps k8s.io/* modules from v0.36.1 to v0.36.2, containerd to v1.7.33, ginkgo/v2 to v2.32.0, and prometheus/common to v0.69.0.
mapstructure and hashstructure import migration
staging/operator-lifecycle-manager/pkg/controller/operators/decorators/operator.go, staging/operator-lifecycle-manager/pkg/lib/codec/mapstructure.go, staging/operator-lifecycle-manager/pkg/lib/comparison/equal.go
Replaces mitchellh/mapstructure imports with go-viper/mapstructure/v2 and updates hashstructure calls to use FormatV2.

CI actions/checkout v7 upgrade

Layer / File(s) Summary
actions/checkout bump to v7
staging/operator-lifecycle-manager/.github/workflows/*
Upgrades actions/checkout from @v6 to @v7 across all six workflows (e2e-tests, go-verdiff, goreleaser, quickstart, sanity, unit).

Sequence Diagram(s)

sequenceDiagram
  participant Run as PackageServerOptions.Run
  participant applyClusterTLSProfile
  participant applyClusterTLSProfileWithClients
  participant DiscoveryClient
  participant ConfigV1Client as ConfigV1Client (OpenShift)

  Run->>Run: build rest.Config from kubeconfig/in-cluster
  alt MinTLSVersion unset
    Run->>applyClusterTLSProfile: rest.Config
    applyClusterTLSProfile->>applyClusterTLSProfileWithClients: k8s + configv1 clients (10s timeout)
    applyClusterTLSProfileWithClients->>DiscoveryClient: check config.openshift.io API group
    alt API group absent (non-OpenShift)
      applyClusterTLSProfileWithClients-->>Run: no-op, no error
    else API group present
      applyClusterTLSProfileWithClients->>ConfigV1Client: get APIServer/cluster
      ConfigV1Client-->>applyClusterTLSProfileWithClients: TLS security profile
      applyClusterTLSProfileWithClients->>Run: set MinTLSVersion + CipherSuites on SecureServing
    end
  end
  Run->>Run: o.Config(ctx), EnableMetrics, start API server
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: reverting the revert and fixing applyClusterTLSProfile().
Docstring Coverage ✅ Passed Docstring coverage is 91.67% 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 The added tests use static Go test function names; no Ginkgo It/Describe/Context titles or dynamic data appear in changed files.
Test Structure And Quality ✅ Passed These are isolated unit tests with fake clients, meaningful failure messages, no cleanup/timeouts needed, and they match local test style.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the new server tests are plain Go unit tests, so MicroShift API compatibility isn’t applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Added tests are plain unit tests in server_test.go, not Ginkgo e2e tests, and they contain no multi-node/SNO assumptions or missing skip guards.
Topology-Aware Scheduling Compatibility ✅ Passed The PR only adds TLS-profile logic, RBAC, and checkout/version bumps; no new node selectors, affinity, spread, replica, or PDB changes were introduced.
Ote Binary Stdout Contract ✅ Passed No touched process-level code writes to stdout; the modified Go files contain no fmt.Print/Println/Printf, os.Stdout, log.SetOutput, or suite setup entrypoints.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the new tests are standard unit tests using fakes and contain no IPv4 or external-network assumptions.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/ECB, custom crypto, or secret/token compares were added; TLS changes use OpenShift security-profile mapping and secure defaults.
Container-Privileges ✅ Passed No added privileged settings were found; changed manifests only add RBAC, and existing securityContexts remain non-root with allowPrivilegeEscalation:false.
No-Sensitive-Data-In-Logs ✅ Passed New logs only report TLS profile metadata and generic startup errors; I found no logging of secrets, tokens, PII, or customer data.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci

openshift-ci Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: tmshort

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

The pull request process is described here

Details Needs approval from an approver in each of these files:

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@staging/operator-lifecycle-manager/pkg/package-server/server/server.go`:
- Around line 225-236: The fallback guard in server.go only checks
o.SecureServing.MinTLSVersion, but applyClusterTLSProfile merges MinTLSVersion
and CipherSuites independently, so the cluster profile is skipped when only
--tls-cipher-suites is missing. Update the condition in the package-server
startup path to run the fallback whenever either SecureServing.MinTLSVersion or
SecureServing.CipherSuites is unset, while keeping the
applyClusterTLSProfile(ctx, clientConfig, o.SecureServing) call and its warning
handling unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 4d6dcd6e-0c78-4dc4-8a50-35ade49e7fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 93e5a5c and a6faf7e.

⛔ Files ignored due to path filters (53)
  • go.sum is excluded by !**/*.sum
  • staging/operator-lifecycle-manager/go.sum is excluded by !**/*.sum
  • vendor/github.com/containerd/containerd/labels/labels.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/containerd/containerd/labels/validate.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/containerd/containerd/version/version.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/.editorconfig is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/.envrc is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/.gitignore is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/.golangci.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/CHANGELOG.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/decode_hooks.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/devenv.lock is excluded by !**/*.lock, !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/devenv.nix is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/devenv.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/errors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/internal/errors/errors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/internal/errors/join.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/internal/errors/join_go1_19.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/mapstructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/reflect_go1_19.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/go-viper/mapstructure/v2/reflect_go1_20.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/hashstructure/v2/LICENSE is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/hashstructure/v2/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/hashstructure/v2/errors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/hashstructure/v2/hashstructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/hashstructure/v2/include.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/mapstructure/README.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/mapstructure/decode_hooks.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/mitchellh/mapstructure/error.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/ginkgo/v2/ginkgo/run/run_command.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/ginkgo/v2/ginkgo/watch/watch_command.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/ginkgo/v2/reporters/default_reporter.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/ginkgo/v2/types/config.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/ginkgo/v2/types/errors.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/onsi/ginkgo/v2/types/version.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/decorators/operator.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/codec/mapstructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/lib/comparison/equal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/server/server.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/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/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_float.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/prometheus/common/model/value_histogram.go is excluded by !**/vendor/**, !vendor/**
  • vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (16)
  • go.mod
  • pkg/manifests/csv.yaml
  • staging/operator-lifecycle-manager/.github/workflows/e2e-tests.yml
  • staging/operator-lifecycle-manager/.github/workflows/go-verdiff.yaml
  • staging/operator-lifecycle-manager/.github/workflows/goreleaser.yaml
  • staging/operator-lifecycle-manager/.github/workflows/quickstart.yml
  • staging/operator-lifecycle-manager/.github/workflows/sanity.yaml
  • staging/operator-lifecycle-manager/.github/workflows/unit.yml
  • staging/operator-lifecycle-manager/deploy/chart/templates/_packageserver.clusterserviceversion.yaml
  • staging/operator-lifecycle-manager/deploy/upstream/quickstart/olm.yaml
  • staging/operator-lifecycle-manager/go.mod
  • staging/operator-lifecycle-manager/pkg/controller/operators/decorators/operator.go
  • staging/operator-lifecycle-manager/pkg/lib/codec/mapstructure.go
  • staging/operator-lifecycle-manager/pkg/lib/comparison/equal.go
  • staging/operator-lifecycle-manager/pkg/package-server/server/server.go
  • staging/operator-lifecycle-manager/pkg/package-server/server/server_test.go

Comment on lines +225 to +236
// If --tls-min-version was not supplied (e.g. no PSM-injected flags yet), fall
// back to a direct GET of the cluster APIServer CR so the packageserver still
// honours the cluster TLS security profile on first boot or during upgrades.
if o.SecureServing.MinTLSVersion == "" {
// Warn and continue on failure: the API server may not be reachable
// during initial startup (e.g. cluster bootstrap). Packageserver starts
// with secure TLS defaults; operators can supply --tls-min-version and
// --tls-cipher-suites flags to override the profile on a later restart.
if err := applyClusterTLSProfile(ctx, clientConfig, o.SecureServing); err != nil {
log.WithError(err).Warn("Failed to apply cluster TLS profile to serving options, using defaults")
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Call the fallback when either TLS field is unset.

This guard only looks at MinTLSVersion, but the helper below merges MinTLSVersion and CipherSuites independently. If someone supplies --tls-min-version and leaves --tls-cipher-suites unset, we skip the fallback entirely and never pick up the cluster profile's cipher suites.

Suggested fix
-	if o.SecureServing.MinTLSVersion == "" {
+	if o.SecureServing.MinTLSVersion == "" || len(o.SecureServing.CipherSuites) == 0 {
 		// Warn and continue on failure: the API server may not be reachable
 		// during initial startup (e.g. cluster bootstrap). Packageserver starts
 		// with secure TLS defaults; operators can supply --tls-min-version and
📝 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 --tls-min-version was not supplied (e.g. no PSM-injected flags yet), fall
// back to a direct GET of the cluster APIServer CR so the packageserver still
// honours the cluster TLS security profile on first boot or during upgrades.
if o.SecureServing.MinTLSVersion == "" {
// Warn and continue on failure: the API server may not be reachable
// during initial startup (e.g. cluster bootstrap). Packageserver starts
// with secure TLS defaults; operators can supply --tls-min-version and
// --tls-cipher-suites flags to override the profile on a later restart.
if err := applyClusterTLSProfile(ctx, clientConfig, o.SecureServing); err != nil {
log.WithError(err).Warn("Failed to apply cluster TLS profile to serving options, using defaults")
}
}
// If --tls-min-version was not supplied (e.g. no PSM-injected flags yet), fall
// back to a direct GET of the cluster APIServer CR so the packageserver still
// honours the cluster TLS security profile on first boot or during upgrades.
if o.SecureServing.MinTLSVersion == "" || len(o.SecureServing.CipherSuites) == 0 {
// Warn and continue on failure: the API server may not be reachable
// during initial startup (e.g. cluster bootstrap). Packageserver starts
// with secure TLS defaults; operators can supply --tls-min-version and
// --tls-cipher-suites flags to override the profile on a later restart.
if err := applyClusterTLSProfile(ctx, clientConfig, o.SecureServing); err != nil {
log.WithError(err).Warn("Failed to apply cluster TLS profile to serving options, using defaults")
}
}
🤖 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 `@staging/operator-lifecycle-manager/pkg/package-server/server/server.go`
around lines 225 - 236, The fallback guard in server.go only checks
o.SecureServing.MinTLSVersion, but applyClusterTLSProfile merges MinTLSVersion
and CipherSuites independently, so the cluster profile is skipped when only
--tls-cipher-suites is missing. Update the condition in the package-server
startup path to run the fallback whenever either SecureServing.MinTLSVersion or
SecureServing.CipherSuites is unset, while keeping the
applyClusterTLSProfile(ctx, clientConfig, o.SecureServing) call and its warning
handling unchanged.

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants