Skip to content

Commit ad6c027

Browse files
author
Per Goncalves da Silva
committed
Add Boxcutter runtime to main
Signed-off-by: Per Goncalves da Silva <[email protected]>
1 parent 5e004bf commit ad6c027

File tree

2 files changed

+128
-29
lines changed

2 files changed

+128
-29
lines changed

cmd/operator-controller/main.go

Lines changed: 111 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"
@@ -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+
524610
func main() {
525611
if err := operatorControllerCmd.Execute(); err != nil {
526612
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)