Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37
github.com/onsi/ginkgo/v2 v2.32.0
github.com/openshift/api v0.0.0-20260204104751-e09e5a4ebcd0
github.com/openshift/library-go v0.0.0-20260204111611-b7d4fa0e292a
github.com/operator-framework/api v0.44.0
github.com/operator-framework/operator-lifecycle-manager v0.0.0-00010101000000-000000000000
github.com/operator-framework/operator-registry v1.72.0
Expand Down Expand Up @@ -155,7 +156,6 @@ require (
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runtime-spec v1.3.0 // indirect
github.com/openshift/client-go v0.0.0-20260108185524-48f4ccfc4e13 // indirect
github.com/openshift/library-go v0.0.0-20260204111611-b7d4fa0e292a // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down
9 changes: 5 additions & 4 deletions pkg/package-server-manager/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,18 @@ func getTopologyModeFromInfra(infra *configv1.Infrastructure) bool {
// resource matches that of the codified defaults and high availability configurations, where
// codified defaults are defined by the csv returned by the manifests.NewPackageServerCSV
// function.
func ensureCSV(log logr.Logger, image string, interval string, csv *olmv1alpha1.ClusterServiceVersion, highlyAvailableMode bool) (bool, error) {
func ensureCSV(log logr.Logger, image string, interval string, flags []string, csv *olmv1alpha1.ClusterServiceVersion, highlyAvailableMode bool) (bool, error) {

flags := []string{}
runFlags := []string{}
if interval != "" {
flags = append(flags, "--interval", interval)
runFlags = append(runFlags, "--interval", interval)
}
runFlags = append(runFlags, flags...)
expectedCSV, err := manifests.NewPackageServerCSV(
manifests.WithName(csv.Name),
manifests.WithNamespace(csv.Namespace),
manifests.WithImage(image),
manifests.WithRunFlags(flags),
manifests.WithRunFlags(runFlags),
)
if err != nil {
return false, err
Expand Down
42 changes: 39 additions & 3 deletions pkg/package-server-manager/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ package controllers
import (
"context"
"fmt"
"strings"
"sync"

"github.com/go-logr/logr"

configv1 "github.com/openshift/api/config/v1"
libcrypto "github.com/openshift/library-go/pkg/crypto"
"github.com/openshift/operator-framework-olm/pkg/manifests"
olmapiserver "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/apiserver"
olmv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"

corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"

Expand Down Expand Up @@ -85,6 +89,22 @@ func (r *PackageServerCSVReconciler) Reconcile(ctx context.Context, req ctrl.Req
flags = append(flags, "--interval", r.Interval)
}

var apiServer configv1.APIServer
if err := r.Client.Get(ctx, types.NamespacedName{Name: "cluster"}, &apiServer); err != nil {
if !apierrors.IsNotFound(err) {
return ctrl.Result{}, err
}
} else {
minVersion, cipherSuites := olmapiserver.GetSecurityProfileConfig(apiServer.Spec.TLSSecurityProfile)
minVersionStr := libcrypto.TLSVersionToNameOrDie(minVersion)
cipherSuitesStr := strings.Join(libcrypto.CipherSuitesToNamesOrDie(cipherSuites), ",")
flags = append(flags,
"--tls-min-version", minVersionStr,
"--tls-cipher-suites", cipherSuitesStr,
)
log.Info("applying cluster TLS security profile to packageserver", "minVersion", minVersionStr, "cipherSuites", cipherSuitesStr)
}

required, err := manifests.NewPackageServerCSV(
manifests.WithName(r.Name),
manifests.WithNamespace(r.Namespace),
Expand All @@ -96,7 +116,7 @@ func (r *PackageServerCSVReconciler) Reconcile(ctx context.Context, req ctrl.Req
return ctrl.Result{}, err
}
res, err := controllerutil.CreateOrUpdate(ctx, r.Client, required, func() error {
return reconcileCSV(r.Log, r.Image, r.Interval, required, highAvailabilityMode)
return reconcileCSV(r.Log, r.Image, r.Interval, flags, required, highAvailabilityMode)
})

log.Info("reconciliation result", "res", res)
Expand All @@ -123,12 +143,12 @@ func ensureRBAC(client client.Client, ctx context.Context, namespace string, log
return nil
}

func reconcileCSV(log logr.Logger, image string, interval string, csv *olmv1alpha1.ClusterServiceVersion, highAvailabilityMode bool) error {
func reconcileCSV(log logr.Logger, image string, interval string, flags []string, csv *olmv1alpha1.ClusterServiceVersion, highAvailabilityMode bool) error {
if csv.ObjectMeta.CreationTimestamp.IsZero() {
log.Info("attempting to create the packageserver csv")
}

modified, err := ensureCSV(log, image, interval, csv, highAvailabilityMode)
modified, err := ensureCSV(log, image, interval, flags, csv, highAvailabilityMode)
if err != nil {
return fmt.Errorf("error ensuring CSV: %v", err)
}
Expand Down Expand Up @@ -158,10 +178,26 @@ func (r *PackageServerCSVReconciler) infrastructureHandler(_ context.Context, ob
}
}

func (r *PackageServerCSVReconciler) apiServerHandler(_ context.Context, obj client.Object) []reconcile.Request {
if obj.GetName() != "cluster" {
return nil
}
r.Log.Info("requeueing the packageserver deployment after encountering APIServer TLS profile change")
return []reconcile.Request{
{
NamespacedName: types.NamespacedName{
Name: r.Name,
Namespace: r.Namespace,
},
},
}
}

// SetupWithManager sets up the controller with the Manager.
func (r *PackageServerCSVReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&olmv1alpha1.ClusterServiceVersion{}).
Watches(&configv1.Infrastructure{}, handler.EnqueueRequestsFromMapFunc(r.infrastructureHandler)).
Watches(&configv1.APIServer{}, handler.EnqueueRequestsFromMapFunc(r.apiServerHandler)).
Comment on lines +181 to +201

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find RBAC rules referencing apiservers and check verbs / resourceNames
rg -nP -C4 'apiservers' -g '*.yaml' -g '*.yml'
rg -nP -C4 'config\.openshift\.io' -g '*.yaml' -g '*.yml' | rg -nP -C4 'resourceNames|verbs'

Repository: openshift/operator-framework-olm

Length of output: 170


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== files mentioning apiservers =='
rg -n --hidden --glob '!**/vendor/**' 'apiservers|APIServer|resourceNames|cluster' .

echo
echo '== candidate RBAC / manifest files =='
fd -t f -e yaml -e yml -e json -e go . .

Repository: openshift/operator-framework-olm

Length of output: 50389


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== files mentioning apiservers =='
rg -n --hidden --glob '!**/vendor/**' 'apiservers|APIServer|resourceNames|cluster' .

echo
echo '== candidate RBAC / manifest files =='
fd -t f -e yaml -e yml -e json -e go . .

Repository: openshift/operator-framework-olm

Length of output: 50389


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focused search for controller setup, reconciler Get usage, and RBAC annotations/manifests.
rg -n --hidden --glob '!**/vendor/**' 'Watches\(&configv1\.APIServer|apiServerHandler|resourceNames: \[cluster\]|+kubebuilder:rbac|config\.openshift\.io/apiservers|client\.Get\(' pkg

Repository: openshift/operator-framework-olm

Length of output: 458


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== controller file =='
sed -n '1,260p' pkg/package-server-manager/controller.go

echo
echo '== RBAC markers in package-server-manager =='
rg -n --glob 'pkg/package-server-manager/**' '\+kubebuilder:rbac|config\.openshift\.io|APIServer|apiservers|resourceNames|list|watch|get'

echo
echo '== manifest / yaml references to apiservers =='
rg -n --glob '!vendor/**' 'config\.openshift\.io/apiservers|resourceNames: \[cluster\]|resourceNames:.*cluster|verbs:|APIServer' --glob '*.yaml' --glob '*.yml' --glob '*.json'

Repository: openshift/operator-framework-olm

Length of output: 7505


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== non-vendor references to APIServer RBAC / manifests =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io/apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]|APIServer|apiservers|+kubebuilder:rbac' \
  . --glob '*.yaml' --glob '*.yml' --glob '*.json' --glob '*.go'

echo
echo '== package-server-manager tree =='
fd -t f pkg/package-server-manager .

Repository: openshift/operator-framework-olm

Length of output: 531


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== non-vendor references to APIServer RBAC / manifests =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io/apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]|APIServer|apiservers|+kubebuilder:rbac' \
  . --glob '*.yaml' --glob '*.yml' --glob '*.json' --glob '*.go'

echo
echo '== package-server-manager tree =='
fd -t f pkg/package-server-manager .

Repository: openshift/operator-framework-olm

Length of output: 531


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== package-server-manager files =='
fd -t f pkg/package-server-manager .

echo
echo '== kubebuilder RBAC markers for config.openshift.io =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' '\+kubebuilder:rbac:groups=config\.openshift\.io' .

echo
echo '== apiservers RBAC / manifests outside vendor =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io/apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]|apiservers|APIServer' \
  . --glob '*.yaml' --glob '*.yml' --glob '*.json' --glob '*.go'

Repository: openshift/operator-framework-olm

Length of output: 615


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== package-server-manager files =='
fd -t f pkg/package-server-manager .

echo
echo '== kubebuilder RBAC markers for config.openshift.io =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' '\+kubebuilder:rbac:groups=config\.openshift\.io' .

echo
echo '== apiservers RBAC / manifests outside vendor =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io/apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]|apiservers|APIServer' \
  . --glob '*.yaml' --glob '*.yml' --glob '*.json' --glob '*.go'

Repository: openshift/operator-framework-olm

Length of output: 615


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== package-server-manager files =='
fd . pkg/package-server-manager

echo
echo '== kubebuilder RBAC markers for config.openshift.io =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' '\+kubebuilder:rbac:groups=config\.openshift\.io' .

echo
echo '== apiservers RBAC / manifests outside vendor =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io/apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]|apiservers|APIServer' \
  . --glob '*.yaml' --glob '*.yml' --glob '*.json' --glob '*.go'

Repository: openshift/operator-framework-olm

Length of output: 385


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== package-server-manager files =='
fd . pkg/package-server-manager

echo
echo '== kubebuilder RBAC markers for config.openshift.io =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' '\+kubebuilder:rbac:groups=config\.openshift\.io' .

echo
echo '== apiservers RBAC / manifests outside vendor =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io/apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]|apiservers|APIServer' \
  . --glob '*.yaml' --glob '*.yml' --glob '*.json' --glob '*.go'

Repository: openshift/operator-framework-olm

Length of output: 385


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== non-vendor references to config.openshift.io/APIServer =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io|APIServer|apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]' \
  . --glob '*.go' --glob '*.yaml' --glob '*.yml' --glob '*.json'

echo
echo '== package-server-manager controller relevant lines =='
sed -n '1,260p' pkg/package-server-manager/controller.go

Repository: openshift/operator-framework-olm

Length of output: 26323


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== non-vendor references to config.openshift.io/APIServer =='
rg -n --hidden --glob '!vendor/**' --glob '!**/vendor/**' \
  'config\.openshift\.io|APIServer|apiservers|resourceNames:.*cluster|resourceNames: \[cluster\]' \
  . --glob '*.go' --glob '*.yaml' --glob '*.yml' --glob '*.json'

echo
echo '== package-server-manager controller relevant lines =='
sed -n '1,260p' pkg/package-server-manager/controller.go

Repository: openshift/operator-framework-olm

Length of output: 26323


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '60,90p' pkg/manifests/csv.yaml

Repository: openshift/operator-framework-olm

Length of output: 996


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '60,90p' pkg/manifests/csv.yaml

Repository: openshift/operator-framework-olm

Length of output: 996


Grant list/watch on config.openshift.io/apiservers

  • pkg/manifests/csv.yaml only grants get on apiservers with resourceNames: [cluster], but Watches(&configv1.APIServer{}, ...) needs collection access. Add list/watch so the informer can start.
  • Use infrastructureName instead of the "cluster" literal in apiServerHandler for consistency.
🤖 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/package-server-manager/controller.go` around lines 181 - 201, The
APIServer watch in PackageServerCSVReconciler cannot start with only named get
access, so update the CSV RBAC to grant list and watch on
config.openshift.io/apiservers while keeping the existing cluster-specific
access as needed. Also change apiServerHandler to compare against
infrastructureName instead of the hardcoded "cluster" literal, and keep
SetupWithManager’s Watches on configv1.APIServer aligned with that handler.

Complete(r)
}
2 changes: 1 addition & 1 deletion pkg/package-server-manager/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func TestEnsureCSV(t *testing.T) {
tc := tc

t.Run(tc.name, func(t *testing.T) {
gotBool, gotErr := ensureCSV(logger, image, interval, tc.inputCSV, tc.highlyAvailable)
gotBool, gotErr := ensureCSV(logger, image, interval, nil, tc.inputCSV, tc.highlyAvailable)
require.EqualValues(t, tc.want.expectedBool, gotBool)
require.EqualValues(t, tc.want.expectedErr, gotErr)
require.EqualValues(t, tc.inputCSV.Spec, tc.expectedCSV.Spec)
Expand Down