@@ -36,7 +36,6 @@ import (
36
36
"helm.sh/helm/v3/pkg/postrender"
37
37
"helm.sh/helm/v3/pkg/release"
38
38
"helm.sh/helm/v3/pkg/storage/driver"
39
- corev1 "k8s.io/api/core/v1"
40
39
"k8s.io/apimachinery/pkg/api/equality"
41
40
apimeta "k8s.io/apimachinery/pkg/api/meta"
42
41
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -48,9 +47,9 @@ import (
48
47
ctrl "sigs.k8s.io/controller-runtime"
49
48
"sigs.k8s.io/controller-runtime/pkg/cache"
50
49
"sigs.k8s.io/controller-runtime/pkg/client"
51
- "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
52
50
crcontroller "sigs.k8s.io/controller-runtime/pkg/controller"
53
51
"sigs.k8s.io/controller-runtime/pkg/event"
52
+ crfinalizer "sigs.k8s.io/controller-runtime/pkg/finalizer"
54
53
crhandler "sigs.k8s.io/controller-runtime/pkg/handler"
55
54
"sigs.k8s.io/controller-runtime/pkg/log"
56
55
"sigs.k8s.io/controller-runtime/pkg/predicate"
@@ -80,7 +79,6 @@ import (
80
79
// ClusterExtensionReconciler reconciles a ClusterExtension object
81
80
type ClusterExtensionReconciler struct {
82
81
client.Client
83
- ReleaseNamespace string
84
82
BundleProvider BundleProvider
85
83
Unpacker rukpaksource.Unpacker
86
84
ActionClientGetter helmclient.ActionClientGetter
@@ -91,6 +89,7 @@ type ClusterExtensionReconciler struct {
91
89
controller crcontroller.Controller
92
90
cache cache.Cache
93
91
InstalledBundleGetter InstalledBundleGetter
92
+ Finalizers crfinalizer.Finalizers
94
93
}
95
94
96
95
type InstalledBundleGetter interface {
@@ -104,9 +103,7 @@ const (
104
103
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions,verbs=get;list;watch
105
104
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions/status,verbs=update;patch
106
105
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clusterextensions/finalizers,verbs=update
107
- //+kubebuilder:rbac:groups=core,resources=pods,verbs=list;watch;create;delete
108
- //+kubebuilder:rbac:groups=core,resources=configmaps,verbs=list;watch
109
- //+kubebuilder:rbac:groups=core,resources=pods/log,verbs=get
106
+ //+kubebuilder:rbac:groups=core,resources=secrets,verbs=create;update;patch;delete;get;list;watch
110
107
//+kubebuilder:rbac:groups=*,resources=*,verbs=*
111
108
112
109
//+kubebuilder:rbac:groups=catalogd.operatorframework.io,resources=clustercatalogs,verbs=list;watch
@@ -196,6 +193,25 @@ func checkForUnexpectedFieldChange(a, b ocv1alpha1.ClusterExtension) bool {
196
193
*/
197
194
//nolint:unparam
198
195
func (r * ClusterExtensionReconciler ) reconcile (ctx context.Context , ext * ocv1alpha1.ClusterExtension ) (ctrl.Result , error ) {
196
+ finalizeResult , err := r .Finalizers .Finalize (ctx , ext )
197
+ if err != nil {
198
+ // TODO: For now, this error handling follows the pattern of other error handling.
199
+ // Namely: zero just about everything out, throw our hands up, and return an error.
200
+ // This is not ideal, and we should consider a more nuanced approach that resolves
201
+ // as much status as possible before returning, or at least keeps previous state if
202
+ // it is properly labeled with its observed generation.
203
+ ext .Status .ResolvedBundle = nil
204
+ ext .Status .InstalledBundle = nil
205
+ setResolvedStatusConditionFailed (ext , err .Error ())
206
+ ensureAllConditionsWithReason (ext , ocv1alpha1 .ReasonResolutionFailed , err .Error ())
207
+ return ctrl.Result {}, err
208
+ }
209
+ if finalizeResult .Updated || finalizeResult .StatusUpdated {
210
+ // On create: make sure the finalizer is applied before we do anything
211
+ // On delete: make sure we do nothing after the finalizer is removed
212
+ return ctrl.Result {}, nil
213
+ }
214
+
199
215
// run resolution
200
216
bundle , err := r .resolve (ctx , * ext )
201
217
if err != nil {
@@ -300,7 +316,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
300
316
301
317
switch state {
302
318
case stateNeedsInstall :
303
- rel , err = ac .Install (ext .GetName (), r . ReleaseNamespace , chrt , values , func (install * action.Install ) error {
319
+ rel , err = ac .Install (ext .GetName (), ext . Spec . InstallNamespace , chrt , values , func (install * action.Install ) error {
304
320
install .CreateNamespace = false
305
321
install .Labels = map [string ]string {labels .BundleNameKey : bundle .Name , labels .PackageNameKey : bundle .Package , labels .BundleVersionKey : bundleVersion .String ()}
306
322
return nil
@@ -310,7 +326,7 @@ func (r *ClusterExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alp
310
326
return ctrl.Result {}, err
311
327
}
312
328
case stateNeedsUpgrade :
313
- rel , err = ac .Upgrade (ext .GetName (), r . ReleaseNamespace , chrt , values , helmclient .AppendUpgradePostRenderer (post ))
329
+ rel , err = ac .Upgrade (ext .GetName (), ext . Spec . InstallNamespace , chrt , values , helmclient .AppendUpgradePostRenderer (post ))
314
330
if err != nil {
315
331
setInstalledStatusConditionFailed (ext , fmt .Sprintf ("%s:%v" , ocv1alpha1 .ReasonUpgradeFailed , err ))
316
332
return ctrl.Result {}, err
@@ -574,7 +590,6 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
574
590
return true
575
591
},
576
592
}).
577
- Watches (& corev1.Pod {}, mapOwneeToOwnerHandler (mgr .GetClient (), mgr .GetLogger (), & ocv1alpha1.ClusterExtension {})).
578
593
Build (r )
579
594
580
595
if err != nil {
@@ -587,47 +602,12 @@ func (r *ClusterExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
587
602
return nil
588
603
}
589
604
590
- func mapOwneeToOwnerHandler (cl client.Client , log logr.Logger , owner client.Object ) crhandler.EventHandler {
591
- return crhandler .EnqueueRequestsFromMapFunc (func (ctx context.Context , obj client.Object ) []reconcile.Request {
592
- ownerGVK , err := apiutil .GVKForObject (owner , cl .Scheme ())
593
- if err != nil {
594
- log .Error (err , "map ownee to owner: lookup GVK for owner" )
595
- return nil
596
- }
597
-
598
- type ownerInfo struct {
599
- key types.NamespacedName
600
- gvk schema.GroupVersionKind
601
- }
602
- var oi * ownerInfo
603
-
604
- for _ , ref := range obj .GetOwnerReferences () {
605
- gv , err := schema .ParseGroupVersion (ref .APIVersion )
606
- if err != nil {
607
- log .Error (err , fmt .Sprintf ("map ownee to owner: parse ownee's owner reference group version %q" , ref .APIVersion ))
608
- return nil
609
- }
610
- refGVK := gv .WithKind (ref .Kind )
611
- if refGVK == ownerGVK && ref .Controller != nil && * ref .Controller {
612
- oi = & ownerInfo {
613
- key : types.NamespacedName {Name : ref .Name },
614
- gvk : ownerGVK ,
615
- }
616
- break
617
- }
618
- }
619
- if oi == nil {
620
- return nil
621
- }
622
- return []reconcile.Request {{NamespacedName : oi .key }}
623
- })
624
- }
625
-
626
605
// Generate reconcile requests for all cluster extensions affected by a catalog change
627
606
func clusterExtensionRequestsForCatalog (c client.Reader , logger logr.Logger ) crhandler.MapFunc {
628
607
return func (ctx context.Context , _ client.Object ) []reconcile.Request {
629
608
// no way of associating an extension to a catalog so create reconcile requests for everything
630
- clusterExtensions := ocv1alpha1.ClusterExtensionList {}
609
+ clusterExtensions := metav1.PartialObjectMetadataList {}
610
+ clusterExtensions .SetGroupVersionKind (ocv1alpha1 .GroupVersion .WithKind ("ClusterExtensionList" ))
631
611
err := c .List (ctx , & clusterExtensions )
632
612
if err != nil {
633
613
logger .Error (err , "unable to enqueue cluster extensions for catalog reconcile" )
@@ -655,16 +635,16 @@ const (
655
635
stateError releaseState = "Error"
656
636
)
657
637
658
- func (r * ClusterExtensionReconciler ) getReleaseState (cl helmclient.ActionInterface , obj metav1. Object , chrt * chart.Chart , values chartutil.Values , post * postrenderer ) (* release.Release , releaseState , error ) {
659
- currentRelease , err := cl .Get (obj .GetName ())
638
+ func (r * ClusterExtensionReconciler ) getReleaseState (cl helmclient.ActionInterface , ext * ocv1alpha1. ClusterExtension , chrt * chart.Chart , values chartutil.Values , post * postrenderer ) (* release.Release , releaseState , error ) {
639
+ currentRelease , err := cl .Get (ext .GetName ())
660
640
if err != nil && ! errors .Is (err , driver .ErrReleaseNotFound ) {
661
641
return nil , stateError , err
662
642
}
663
643
if errors .Is (err , driver .ErrReleaseNotFound ) {
664
644
return nil , stateNeedsInstall , nil
665
645
}
666
646
667
- desiredRelease , err := cl .Upgrade (obj .GetName (), r . ReleaseNamespace , chrt , values , func (upgrade * action.Upgrade ) error {
647
+ desiredRelease , err := cl .Upgrade (ext .GetName (), ext . Spec . InstallNamespace , chrt , values , func (upgrade * action.Upgrade ) error {
668
648
upgrade .DryRun = true
669
649
return nil
670
650
}, helmclient .AppendUpgradePostRenderer (post ))
0 commit comments