@@ -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+
524604func main () {
525605 if err := operatorControllerCmd .Execute (); err != nil {
526606 fmt .Fprintf (os .Stderr , "Error: %v\n " , err )
0 commit comments