@@ -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"
@@ -219,6 +224,12 @@ func run() error {
219224 DefaultLabelSelector : k8slabels .Nothing (),
220225 }
221226
227+ if features .OperatorControllerFeatureGate .Enabled (features .BoxcutterRuntime ) {
228+ cacheOptions .ByObject [& ocv1.ClusterExtensionRevision {}] = crcache.ByObject {
229+ Label : k8slabels .Everything (),
230+ }
231+ }
232+
222233 saKey , err := sautil .GetServiceAccount ()
223234 if err != nil {
224235 setupLog .Error (err , "Failed to extract serviceaccount from JWT" )
@@ -272,7 +283,8 @@ func run() error {
272283 "Metrics will not be served since the TLS certificate and key file are not provided." )
273284 }
274285
275- mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), ctrl.Options {
286+ restConfig := ctrl .GetConfigOrDie ()
287+ mgr , err := ctrl .NewManager (restConfig , ctrl.Options {
276288 Scheme : scheme .Scheme ,
277289 Metrics : metricsServerOptions ,
278290 PprofBindAddress : cfg .pprofAddr ,
@@ -427,28 +439,38 @@ func run() error {
427439 preAuth = authorization .NewRBACPreAuthorizer (mgr .GetClient ())
428440 }
429441
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 ,
442+ // create applier
443+ var ctrlBuilderOpts []controllers.ControllerBuilderOption
444+ var extApplier controllers.Applier
445+
446+ if features .OperatorControllerFeatureGate .Enabled (features .BoxcutterRuntime ) {
447+ // TODO: add support for preflight checks
448+ // TODO: better scheme handling - which types do we want to support?
449+ _ = apiextensionsv1 .AddToScheme (mgr .GetScheme ())
450+ extApplier = & applier.Boxcutter {
451+ Client : mgr .GetClient (),
452+ Scheme : mgr .GetScheme (),
453+ RevisionGenerator : & applier.SimpleRevisionGenerator {
454+ Scheme : mgr .GetScheme (),
455+ BundleRenderer : & applier.RegistryV1BundleRenderer {
456+ BundleRenderer : registryv1 .Renderer ,
457+ },
458+ },
459+ }
460+ ctrlBuilderOpts = append (ctrlBuilderOpts , controllers .WithOwns (& ocv1.ClusterExtensionRevision {}))
461+ } else {
462+ // now initialize the helmApplier, assigning the potentially nil preAuth
463+ certProvider := getCertificateProvider ()
464+ extApplier = & applier.Helm {
465+ ActionClientGetter : acg ,
466+ Preflights : preflights ,
467+ BundleToHelmChartConverter : & convert.BundleToHelmChartConverter {
468+ BundleRenderer : registryv1 .Renderer ,
469+ CertificateProvider : certProvider ,
470+ IsWebhookSupportEnabled : certProvider != nil ,
471+ },
472+ PreAuthorizer : preAuth ,
473+ }
452474 }
453475
454476 cm := contentmanager .NewManager (clientRestConfigMapper , mgr .GetConfig (), mgr .GetRESTMapper ())
@@ -467,15 +489,70 @@ func run() error {
467489 Resolver : resolver ,
468490 ImageCache : imageCache ,
469491 ImagePuller : imagePuller ,
470- Applier : helmApplier ,
492+ Applier : extApplier ,
471493 InstalledBundleGetter : & controllers.DefaultInstalledBundleGetter {ActionClientGetter : acg },
472494 Finalizers : clusterExtensionFinalizers ,
473495 Manager : cm ,
474- }).SetupWithManager (mgr ); err != nil {
496+ }).SetupWithManager (mgr , ctrlBuilderOpts ... ); err != nil {
475497 setupLog .Error (err , "unable to create controller" , "controller" , "ClusterExtension" )
476498 return err
477499 }
478500
501+ if features .OperatorControllerFeatureGate .Enabled (features .BoxcutterRuntime ) {
502+ // Boxcutter
503+ discoveryClient , err := discovery .NewDiscoveryClientForConfig (restConfig )
504+ if err != nil {
505+ setupLog .Error (err , "unable to create discovery client" )
506+ return err
507+ }
508+ mapFunc := func (ctx context.Context , ce * ocv1.ClusterExtension , c * rest.Config , o crcache.Options ) (* rest.Config , crcache.Options , error ) {
509+ saKey := client.ObjectKey {
510+ Name : ce .Spec .ServiceAccount .Name ,
511+ Namespace : ce .Spec .Namespace ,
512+ }
513+ saConfig := rest .AnonymousClientConfig (c )
514+ saConfig .Wrap (func (rt http.RoundTripper ) http.RoundTripper {
515+ return & authentication.TokenInjectingRoundTripper {
516+ Tripper : rt ,
517+ TokenGetter : tokenGetter ,
518+ Key : saKey ,
519+ }
520+ })
521+
522+ // Cache scoping
523+ req1 , err := k8slabels .NewRequirement (
524+ controllers .ClusterExtensionRevisionOwnerLabel , selection .Equals , []string {ce .Name })
525+ if err != nil {
526+ return nil , o , err
527+ }
528+ o .DefaultLabelSelector = k8slabels .NewSelector ().Add (* req1 )
529+
530+ return saConfig , o , nil
531+ }
532+
533+ accessManager := managedcache .NewObjectBoundAccessManager (
534+ ctrl .Log .WithName ("accessmanager" ), mapFunc , restConfig , crcache.Options {
535+ Scheme : mgr .GetScheme (), Mapper : mgr .GetRESTMapper (),
536+ })
537+ if err := mgr .Add (accessManager ); err != nil {
538+ setupLog .Error (err , "unable to register AccessManager" )
539+ return err
540+ }
541+
542+ if err = (& controllers.ClusterExtensionRevisionReconciler {
543+ Client : cl ,
544+ RevisionManager : & controllers.OLMRevisionEngineGetter {
545+ AccessManager : accessManager ,
546+ Scheme : mgr .GetScheme (),
547+ RestMapper : mgr .GetRESTMapper (),
548+ DiscoveryClient : discoveryClient ,
549+ },
550+ }).SetupWithManager (mgr ); err != nil {
551+ setupLog .Error (err , "unable to create controller" , "controller" , "ClusterExtension" )
552+ return err
553+ }
554+ }
555+
479556 if err = (& controllers.ClusterCatalogReconciler {
480557 Client : cl ,
481558 CatalogCache : catalogClientBackend ,
@@ -521,6 +598,15 @@ func run() error {
521598 return nil
522599}
523600
601+ func getCertificateProvider () render.CertificateProvider {
602+ if features .OperatorControllerFeatureGate .Enabled (features .WebhookProviderCertManager ) {
603+ return certproviders.CertManagerCertificateProvider {}
604+ } else if features .OperatorControllerFeatureGate .Enabled (features .WebhookProviderOpenshiftServiceCA ) {
605+ return certproviders.OpenshiftServiceCaCertificateProvider {}
606+ }
607+ return nil
608+ }
609+
524610func main () {
525611 if err := operatorControllerCmd .Execute (); err != nil {
526612 fmt .Fprintf (os .Stderr , "Error: %v\n " , err )
0 commit comments