Skip to content
Draft
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
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,6 @@ lint-custom: custom-linter-build #EXHELP Call custom linter for the project
lint-api-diff: $(GOLANGCI_LINT) #HELP Validate API changes using kube-api-linter with diff-aware analysis
hack/api-lint-diff/run.sh

.PHONY: k8s-pin
k8s-pin: #EXHELP Pin k8s staging modules based on k8s.io/kubernetes version (in go.mod or from K8S_IO_K8S_VERSION env var) and run go mod tidy.
K8S_IO_K8S_VERSION='$(K8S_IO_K8S_VERSION)' go run hack/tools/k8smaintainer/main.go

.PHONY: tidy #HELP Run go mod tidy.
tidy:
go mod tidy
Expand Down Expand Up @@ -204,7 +200,7 @@ generate: $(CONTROLLER_GEN) #EXHELP Generate code containing DeepCopy, DeepCopyI
$(CONTROLLER_GEN) --load-build-tags=$(GO_BUILD_TAGS) object:headerFile="hack/boilerplate.go.txt" paths="./..."

.PHONY: verify
verify: k8s-pin kind-verify-versions fmt generate manifests update-tls-profiles crd-ref-docs update-registryv1-bundle-schema verify-bingo #HELP Verify all generated code is up-to-date. Runs k8s-pin instead of just tidy.
verify: tidy kind-verify-versions fmt generate manifests update-tls-profiles crd-ref-docs update-registryv1-bundle-schema verify-bingo #HELP Verify all generated code is up-to-date.
git diff --exit-code

.PHONY: verify-bingo
Expand Down
19 changes: 11 additions & 8 deletions api/v1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ type ClusterExtensionSpec struct {
// +required
Namespace string `json:"namespace"`

// serviceAccount specifies a ServiceAccount used to perform all interactions with the cluster
// that are required to manage the extension.
// The ServiceAccount must be configured with the necessary permissions to perform these interactions.
// The ServiceAccount must exist in the namespace referenced in the spec.
// The serviceAccount field is required.
// serviceAccount was previously used to specify a ServiceAccount for managing the extension.
// This field is now deprecated and ignored. operator-controller uses its own ServiceAccount
// for all Kubernetes API interactions.
//
// +required
ServiceAccount ServiceAccountReference `json:"serviceAccount"`
// Deprecated: This field is ignored. It will be removed in a future API version.
//
// +optional
ServiceAccount ServiceAccountReference `json:"serviceAccount,omitzero"`

// source is required and selects the installation source of content for this ClusterExtension.
// Set the sourceType field to perform the selection.
Expand Down Expand Up @@ -376,7 +376,10 @@ type CatalogFilter struct {
UpgradeConstraintPolicy UpgradeConstraintPolicy `json:"upgradeConstraintPolicy,omitempty"`
}

// ServiceAccountReference identifies the serviceAccount used fo install a ClusterExtension.
// ServiceAccountReference identifies the serviceAccount used to install a ClusterExtension.
//
// Deprecated: This type is deprecated and will be removed in a future API version.
// operator-controller now uses its own ServiceAccount for all operations.
type ServiceAccountReference struct {
// name is a required, immutable reference to the name of the ServiceAccount used for installation
// and management of the content for the package specified in the packageName field.
Expand Down
3 changes: 0 additions & 3 deletions api/v1/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ func TestValidate(t *testing.T) {
}
defaultExtensionSpec := func(s *ClusterExtensionSpec) *ClusterExtensionSpec {
s.Namespace = "ns"
s.ServiceAccount = ServiceAccountReference{
Name: "sa",
}
s.Source = SourceConfig{
SourceType: SourceTypeCatalog,
Catalog: &CatalogFilter{
Expand Down
10 changes: 5 additions & 5 deletions applyconfigurations/api/v1/clusterextensionspec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion applyconfigurations/api/v1/serviceaccountreference.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 15 additions & 52 deletions cmd/operator-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ import (
ocv1 "github.com/operator-framework/operator-controller/api/v1"
"github.com/operator-framework/operator-controller/internal/operator-controller/action"
"github.com/operator-framework/operator-controller/internal/operator-controller/applier"
"github.com/operator-framework/operator-controller/internal/operator-controller/authentication"
"github.com/operator-framework/operator-controller/internal/operator-controller/authorization"
"github.com/operator-framework/operator-controller/internal/operator-controller/catalogmetadata/cache"
catalogclient "github.com/operator-framework/operator-controller/internal/operator-controller/catalogmetadata/client"
"github.com/operator-framework/operator-controller/internal/operator-controller/contentmanager"
Expand Down Expand Up @@ -475,11 +473,10 @@ func run() error {

certProvider := getCertificateProvider()
regv1ManifestProvider := &applier.RegistryV1ManifestProvider{
BundleRenderer: registryv1.Renderer,
CertificateProvider: certProvider,
IsWebhookSupportEnabled: certProvider != nil,
IsSingleOwnNamespaceEnabled: features.OperatorControllerFeatureGate.Enabled(features.SingleOwnNamespaceInstallSupport),
IsDeploymentConfigEnabled: features.OperatorControllerFeatureGate.Enabled(features.DeploymentConfig),
BundleRenderer: registryv1.Renderer,
CertificateProvider: certProvider,
IsWebhookSupportEnabled: certProvider != nil,
IsDeploymentConfigEnabled: features.OperatorControllerFeatureGate.Enabled(features.DeploymentConfig),
}
var cerCfg reconcilerConfigurator
if features.OperatorControllerFeatureGate.Enabled(features.BoxcutterRuntime) {
Expand Down Expand Up @@ -599,12 +596,6 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
return err
}

// determine if PreAuthorizer should be enabled based on feature gate
var preAuth authorization.PreAuthorizer
if features.OperatorControllerFeatureGate.Enabled(features.PreflightPermissions) {
preAuth = authorization.NewRBACPreAuthorizer(c.mgr.GetClient())
}

// TODO: better scheme handling - which types do we want to support?
_ = apiextensionsv1.AddToScheme(c.mgr.GetScheme())
rg := &applier.SimpleRevisionGenerator{
Expand All @@ -617,7 +608,6 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
Scheme: c.mgr.GetScheme(),
RevisionGenerator: rg,
Preflights: c.preflights,
PreAuthorizer: preAuth,
FieldOwner: fieldOwner,
}
revisionStatesGetter := &controllers.BoxcutterRevisionStatesGetter{Reader: c.mgr.GetClient()}
Expand All @@ -630,9 +620,6 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
}
ceReconciler.ReconcileSteps = []controllers.ReconcileStepFunc{
controllers.HandleFinalizers(c.finalizers),
controllers.ValidateClusterExtension(
controllers.ServiceAccountValidator(coreClient),
),
controllers.MigrateStorage(storageMigrator),
controllers.RetrieveRevisionStates(revisionStatesGetter),
controllers.ResolveBundle(c.resolver, c.mgr.GetClient()),
Expand Down Expand Up @@ -662,29 +649,19 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
return fmt.Errorf("unable to add tracking cache to manager: %v", err)
}

cerCoreClient, err := corev1client.NewForConfig(c.mgr.GetConfig())
if err != nil {
return fmt.Errorf("unable to create client for ClusterExtensionRevision controller: %w", err)
}
cerTokenGetter := authentication.NewTokenGetter(cerCoreClient, authentication.WithExpirationDuration(1*time.Hour))

revisionEngineFactory, err := controllers.NewDefaultRevisionEngineFactory(
revisionEngine := controllers.NewRevisionEngine(
c.mgr.GetScheme(),
trackingCache,
discoveryClient,
c.mgr.GetRESTMapper(),
fieldOwnerPrefix,
c.mgr.GetConfig(),
cerTokenGetter,
c.mgr.GetClient(),
)
if err != nil {
return fmt.Errorf("unable to create revision engine factory: %w", err)
}

if err = (&controllers.ClusterExtensionRevisionReconciler{
Client: c.mgr.GetClient(),
RevisionEngineFactory: revisionEngineFactory,
TrackingCache: trackingCache,
Client: c.mgr.GetClient(),
RevisionEngine: revisionEngine,
TrackingCache: trackingCache,
}).SetupWithManager(c.mgr); err != nil {
return fmt.Errorf("unable to setup ClusterExtensionRevision controller: %w", err)
}
Expand All @@ -696,19 +673,13 @@ func (c *helmReconcilerConfigurator) Configure(ceReconciler *controllers.Cluster
if err != nil {
return fmt.Errorf("unable to create core client: %w", err)
}
tokenGetter := authentication.NewTokenGetter(coreClient, authentication.WithExpirationDuration(1*time.Hour))
clientRestConfigMapper := action.ServiceAccountRestConfigMapper(tokenGetter)
if features.OperatorControllerFeatureGate.Enabled(features.SyntheticPermissions) {
clientRestConfigMapper = action.SyntheticUserRestConfigMapper(clientRestConfigMapper)
}

cfgGetter, err := helmclient.NewActionConfigGetter(c.mgr.GetConfig(), c.mgr.GetRESTMapper(),
helmclient.StorageDriverMapper(action.ChunkedStorageDriverMapper(coreClient, c.mgr.GetAPIReader(), cfg.systemNamespace)),
helmclient.ClientNamespaceMapper(func(obj client.Object) (string, error) {
ext := obj.(*ocv1.ClusterExtension)
return ext.Spec.Namespace, nil
}),
helmclient.ClientRestConfigMapper(clientRestConfigMapper),
)
if err != nil {
return fmt.Errorf("unable to create helm action config getter: %w", err)
Expand All @@ -721,41 +692,33 @@ func (c *helmReconcilerConfigurator) Configure(ceReconciler *controllers.Cluster
return fmt.Errorf("unable to create helm action client getter: %w", err)
}

// determine if PreAuthorizer should be enabled based on feature gate
var preAuth authorization.PreAuthorizer
if features.OperatorControllerFeatureGate.Enabled(features.PreflightPermissions) {
preAuth = authorization.NewRBACPreAuthorizer(c.mgr.GetClient())
cm, err := contentmanager.NewManager(c.mgr.GetConfig(), c.mgr.GetRESTMapper())
if err != nil {
setupLog.Error(err, "unable to create content manager")
return err
}

cm := contentmanager.NewManager(clientRestConfigMapper, c.mgr.GetConfig(), c.mgr.GetRESTMapper())
err = c.finalizers.Register(controllers.ClusterExtensionCleanupContentManagerCacheFinalizer, finalizers.FinalizerFunc(func(ctx context.Context, obj client.Object) (crfinalizer.Result, error) {
ext := obj.(*ocv1.ClusterExtension)
err := cm.Delete(ext)
return crfinalizer.Result{}, err
cm.Delete(ctx, obj.GetName())
return crfinalizer.Result{}, nil
}))
if err != nil {
setupLog.Error(err, "unable to register content manager cleanup finalizer")
return err
}

// now initialize the helmApplier, assigning the potentially nil preAuth
appl := &applier.Helm{
ActionClientGetter: acg,
Preflights: c.preflights,
HelmChartProvider: &applier.RegistryV1HelmChartProvider{
ManifestProvider: c.regv1ManifestProvider,
},
HelmReleaseToObjectsConverter: &applier.HelmReleaseToObjectsConverter{},
PreAuthorizer: preAuth,
Watcher: c.watcher,
Manager: cm,
}
revisionStatesGetter := &controllers.HelmRevisionStatesGetter{ActionClientGetter: acg}
ceReconciler.ReconcileSteps = []controllers.ReconcileStepFunc{
controllers.HandleFinalizers(c.finalizers),
controllers.ValidateClusterExtension(
controllers.ServiceAccountValidator(coreClient),
),
controllers.RetrieveRevisionStates(revisionStatesGetter),
controllers.ResolveBundle(c.resolver, c.mgr.GetClient()),
controllers.UnpackBundle(c.imagePuller, c.imageCache),
Expand Down
Loading
Loading