Skip to content

Commit 1d8e200

Browse files
author
Per Goncalves da Silva
committed
Add Boxcutter runtime to main
Signed-off-by: Per Goncalves da Silva <pegoncal@redhat.com>
1 parent 09f76e6 commit 1d8e200

File tree

2 files changed

+122
-29
lines changed

2 files changed

+122
-29
lines changed

cmd/operator-controller/main.go

Lines changed: 105 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,19 @@ import (
3131
"github.com/containers/image/v5/types"
3232
"github.com/spf13/cobra"
3333
rbacv1 "k8s.io/api/rbac/v1"
34+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3435
apiextensionsv1client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
3536
k8slabels "k8s.io/apimachinery/pkg/labels"
37+
"k8s.io/apimachinery/pkg/selection"
3638
k8stypes "k8s.io/apimachinery/pkg/types"
3739
apimachineryrand "k8s.io/apimachinery/pkg/util/rand"
40+
"k8s.io/client-go/discovery"
3841
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
3942
_ "k8s.io/client-go/plugin/pkg/client/auth"
43+
"k8s.io/client-go/rest"
4044
"k8s.io/klog/v2"
4145
"k8s.io/utils/ptr"
46+
"pkg.package-operator.run/boxcutter/managedcache"
4247
ctrl "sigs.k8s.io/controller-runtime"
4348
crcache "sigs.k8s.io/controller-runtime/pkg/cache"
4449
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
@@ -272,7 +277,8 @@ func run() error {
272277
"Metrics will not be served since the TLS certificate and key file are not provided.")
273278
}
274279

275-
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
280+
restConfig := ctrl.GetConfigOrDie()
281+
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
276282
Scheme: scheme.Scheme,
277283
Metrics: metricsServerOptions,
278284
PprofBindAddress: cfg.pprofAddr,
@@ -427,28 +433,38 @@ func run() error {
427433
preAuth = authorization.NewRBACPreAuthorizer(mgr.GetClient())
428434
}
429435

430-
// determine if a certificate provider should be set in the bundle renderer and feature support for the provider
431-
// based on the feature flag
432-
var certProvider render.CertificateProvider
433-
var isWebhookSupportEnabled bool
434-
if features.OperatorControllerFeatureGate.Enabled(features.WebhookProviderCertManager) {
435-
certProvider = certproviders.CertManagerCertificateProvider{}
436-
isWebhookSupportEnabled = true
437-
} else if features.OperatorControllerFeatureGate.Enabled(features.WebhookProviderOpenshiftServiceCA) {
438-
certProvider = certproviders.OpenshiftServiceCaCertificateProvider{}
439-
isWebhookSupportEnabled = true
440-
}
441-
442-
// now initialize the helmApplier, assigning the potentially nil preAuth
443-
helmApplier := &applier.Helm{
444-
ActionClientGetter: acg,
445-
Preflights: preflights,
446-
BundleToHelmChartConverter: &convert.BundleToHelmChartConverter{
447-
BundleRenderer: registryv1.Renderer,
448-
CertificateProvider: certProvider,
449-
IsWebhookSupportEnabled: isWebhookSupportEnabled,
450-
},
451-
PreAuthorizer: preAuth,
436+
// create applier
437+
var ctrlBuilderOpts []controllers.ControllerBuilderOption
438+
var extApplier controllers.Applier
439+
440+
if features.OperatorControllerFeatureGate.Enabled(features.BoxcutterRuntime) {
441+
// TODO: add support for preflight checks
442+
// TODO: better scheme handling - which types do we want to support?
443+
_ = apiextensionsv1.AddToScheme(mgr.GetScheme())
444+
extApplier = &applier.Boxcutter{
445+
Client: mgr.GetClient(),
446+
Scheme: mgr.GetScheme(),
447+
RevisionGenerator: &applier.SimpleRevisionGenerator{
448+
Scheme: mgr.GetScheme(),
449+
BundleRenderer: &applier.RegistryV1BundleRenderer{
450+
BundleRenderer: registryv1.Renderer,
451+
},
452+
},
453+
}
454+
ctrlBuilderOpts = append(ctrlBuilderOpts, controllers.WithOwns(&ocv1.ClusterExtensionRevision{}))
455+
} else {
456+
// now initialize the helmApplier, assigning the potentially nil preAuth
457+
certProvider := getCertificateProvider()
458+
extApplier = &applier.Helm{
459+
ActionClientGetter: acg,
460+
Preflights: preflights,
461+
BundleToHelmChartConverter: &convert.BundleToHelmChartConverter{
462+
BundleRenderer: registryv1.Renderer,
463+
CertificateProvider: certProvider,
464+
IsWebhookSupportEnabled: certProvider != nil,
465+
},
466+
PreAuthorizer: preAuth,
467+
}
452468
}
453469

454470
cm := contentmanager.NewManager(clientRestConfigMapper, mgr.GetConfig(), mgr.GetRESTMapper())
@@ -467,15 +483,70 @@ func run() error {
467483
Resolver: resolver,
468484
ImageCache: imageCache,
469485
ImagePuller: imagePuller,
470-
Applier: helmApplier,
486+
Applier: extApplier,
471487
InstalledBundleGetter: &controllers.DefaultInstalledBundleGetter{ActionClientGetter: acg},
472488
Finalizers: clusterExtensionFinalizers,
473489
Manager: cm,
474-
}).SetupWithManager(mgr); err != nil {
490+
}).SetupWithManager(mgr, ctrlBuilderOpts...); err != nil {
475491
setupLog.Error(err, "unable to create controller", "controller", "ClusterExtension")
476492
return err
477493
}
478494

495+
if features.OperatorControllerFeatureGate.Enabled(features.BoxcutterRuntime) {
496+
// Boxcutter
497+
discoveryClient, err := discovery.NewDiscoveryClientForConfig(restConfig)
498+
if err != nil {
499+
setupLog.Error(err, "unable to create discovery client")
500+
return err
501+
}
502+
mapFunc := func(ctx context.Context, ce *ocv1.ClusterExtension, c *rest.Config, o crcache.Options) (*rest.Config, crcache.Options, error) {
503+
saKey := client.ObjectKey{
504+
Name: ce.Spec.ServiceAccount.Name,
505+
Namespace: ce.Spec.Namespace,
506+
}
507+
saConfig := rest.AnonymousClientConfig(c)
508+
saConfig.Wrap(func(rt http.RoundTripper) http.RoundTripper {
509+
return &authentication.TokenInjectingRoundTripper{
510+
Tripper: rt,
511+
TokenGetter: tokenGetter,
512+
Key: saKey,
513+
}
514+
})
515+
516+
// Cache scoping
517+
req1, err := k8slabels.NewRequirement(
518+
controllers.ClusterExtensionRevisionOwnerLabel, selection.Equals, []string{ce.Name})
519+
if err != nil {
520+
return nil, o, err
521+
}
522+
o.DefaultLabelSelector = k8slabels.NewSelector().Add(*req1)
523+
524+
return saConfig, o, nil
525+
}
526+
527+
accessManager := managedcache.NewObjectBoundAccessManager(
528+
ctrl.Log.WithName("accessmanager"), mapFunc, restConfig, crcache.Options{
529+
Scheme: mgr.GetScheme(), Mapper: mgr.GetRESTMapper(),
530+
})
531+
if err := mgr.Add(accessManager); err != nil {
532+
setupLog.Error(err, "unable to register AccessManager")
533+
return err
534+
}
535+
536+
if err = (&controllers.ClusterExtensionRevisionReconciler{
537+
Client: cl,
538+
RevisionManager: &controllers.OLMRevisionEngineGetter{
539+
AccessManager: accessManager,
540+
Scheme: mgr.GetScheme(),
541+
RestMapper: mgr.GetRESTMapper(),
542+
DiscoveryClient: discoveryClient,
543+
},
544+
}).SetupWithManager(mgr); err != nil {
545+
setupLog.Error(err, "unable to create controller", "controller", "ClusterExtension")
546+
return err
547+
}
548+
}
549+
479550
if err = (&controllers.ClusterCatalogReconciler{
480551
Client: cl,
481552
CatalogCache: catalogClientBackend,
@@ -521,6 +592,15 @@ func run() error {
521592
return nil
522593
}
523594

595+
func getCertificateProvider() render.CertificateProvider {
596+
if features.OperatorControllerFeatureGate.Enabled(features.WebhookProviderCertManager) {
597+
return certproviders.CertManagerCertificateProvider{}
598+
} else if features.OperatorControllerFeatureGate.Enabled(features.WebhookProviderOpenshiftServiceCA) {
599+
return certproviders.OpenshiftServiceCaCertificateProvider{}
600+
}
601+
return nil
602+
}
603+
524604
func main() {
525605
if err := operatorControllerCmd.Execute(); err != nil {
526606
fmt.Fprintf(os.Stderr, "Error: %v\n", err)

internal/operator-controller/controllers/clusterextension_controller.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,17 @@ func SetDeprecationStatus(ext *ocv1.ClusterExtension, bundleName string, depreca
413413
}
414414
}
415415

416+
type ControllerBuilderOption func(builder *ctrl.Builder)
417+
418+
func WithOwns(obj client.Object) ControllerBuilderOption {
419+
return func(builder *ctrl.Builder) {
420+
builder.Owns(obj)
421+
}
422+
}
423+
416424
// SetupWithManager sets up the controller with the Manager.
417-
func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
418-
controller, err := ctrl.NewControllerManagedBy(mgr).
425+
func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager, opts ...ControllerBuilderOption) error {
426+
ctrlBuilder := ctrl.NewControllerManagedBy(mgr).
419427
For(&ocv1.ClusterExtension{}).
420428
Named("controller-operator-cluster-extension-controller").
421429
Watches(&ocv1.ClusterCatalog{},
@@ -436,8 +444,13 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
436444
}
437445
return true
438446
},
439-
})).
440-
Build(r)
447+
}))
448+
449+
for _, applyOpt := range opts {
450+
applyOpt(ctrlBuilder)
451+
}
452+
453+
controller, err := ctrlBuilder.Build(r)
441454
if err != nil {
442455
return err
443456
}

0 commit comments

Comments
 (0)