@@ -8,9 +8,11 @@ import (
88 "slices"
99 "strings"
1010
11+ "github.com/pkg/errors"
1112 corev1 "k8s.io/api/core/v1"
1213 kerrs "k8s.io/apimachinery/pkg/api/errors"
1314 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
1416 "k8s.io/apimachinery/pkg/types"
1517 addonapi "open-cluster-management.io/api/client/addon/clientset/versioned"
1618 "sigs.k8s.io/controller-runtime/pkg/client"
@@ -19,7 +21,6 @@ import (
1921 "github.com/open-cluster-management-io/lab/fleetconfig-controller/api/v1alpha1"
2022 exec_utils "github.com/open-cluster-management-io/lab/fleetconfig-controller/internal/exec"
2123 "github.com/open-cluster-management-io/lab/fleetconfig-controller/internal/file"
22- "github.com/pkg/errors"
2324)
2425
2526const (
@@ -34,7 +35,7 @@ func handleAddonConfig(ctx context.Context, kClient client.Client, addonC *addon
3435 logger .V (0 ).Info ("handleAddOnConfig" , "fleetconfig" , fc .Name )
3536
3637 // get existing addons
37- createdAddOns , err := addonC .AddonV1alpha1 ().AddOnTemplates ().List (ctx , metav1.ListOptions {})
38+ createdAddOns , err := addonC .AddonV1alpha1 ().AddOnTemplates ().List (ctx , metav1.ListOptions {LabelSelector : v1alpha1 . ManagedBySelector . String () })
3839 if err != nil {
3940 return err
4041 }
@@ -80,15 +81,15 @@ func handleAddonConfig(ctx context.Context, kClient client.Client, addonC *addon
8081 return err
8182 }
8283
83- err = handleAddonCreate (ctx , kClient , fc , addonsToCreate )
84+ err = handleAddonCreate (ctx , kClient , addonC , fc , addonsToCreate )
8485 if err != nil {
8586 return err
8687 }
8788
8889 return nil
8990}
9091
91- func handleAddonCreate (ctx context.Context , kClient client.Client , fc * v1alpha1.FleetConfig , addons []v1alpha1.AddOnConfig ) error {
92+ func handleAddonCreate (ctx context.Context , kClient client.Client , addonC * addonapi. Clientset , fc * v1alpha1.FleetConfig , addons []v1alpha1.AddOnConfig ) error {
9293 if len (addons ) == 0 {
9394 return nil
9495 }
@@ -159,7 +160,61 @@ func handleAddonCreate(ctx context.Context, kClient client.Client, fc *v1alpha1.
159160 return fmt .Errorf ("failed to create addon: %v, output: %s" , err , string (out ))
160161 }
161162 logger .V (0 ).Info ("created addon" , "AddOnTemplate" , a .Name , "output" , string (stdout ))
163+
164+ // label created resources
165+ err = labelConfigurationResources (ctx , addonC , a )
166+ if err != nil {
167+ logger .V (0 ).Error (err , "failed to label addon resources" , "addon" , a .Name , "version" , a .Version )
168+ }
169+ }
170+ return nil
171+ }
172+
173+ // labelConfigurationResources labels the AddOnTemplate and ClusterManagementAddOn resources created for an addon
174+ func labelConfigurationResources (ctx context.Context , addonC * addonapi.Clientset , addon v1alpha1.AddOnConfig ) error {
175+ logger := log .FromContext (ctx )
176+
177+ // Label AddOnTemplate with a.Name-a.Version
178+ addonTemplateName := fmt .Sprintf ("%s-%s" , addon .Name , addon .Version )
179+ addonTemplate , err := addonC .AddonV1alpha1 ().AddOnTemplates ().Get (ctx , addonTemplateName , metav1.GetOptions {})
180+ if err != nil {
181+ return fmt .Errorf ("failed to get AddOnTemplate %s: %v" , addonTemplateName , err )
182+ }
183+
184+ // Add managedBy label to AddOnTemplate
185+ if addonTemplate .Labels == nil {
186+ addonTemplate .Labels = make (map [string ]string )
187+ }
188+ for k , v := range v1alpha1 .ManagedByLabels {
189+ addonTemplate .Labels [k ] = v
190+ }
191+
192+ _ , err = addonC .AddonV1alpha1 ().AddOnTemplates ().Update (ctx , addonTemplate , metav1.UpdateOptions {})
193+ if err != nil {
194+ return fmt .Errorf ("failed to update AddOnTemplate %s with labels: %v" , addonTemplateName , err )
195+ }
196+ logger .V (2 ).Info ("labeled AddOnTemplate" , "name" , addonTemplateName , "label" , v1alpha1 .LabelAddOnManagedBy )
197+
198+ // Label ClusterManagementAddOn with a.Name
199+ clusterMgmtAddOn , err := addonC .AddonV1alpha1 ().ClusterManagementAddOns ().Get (ctx , addon .Name , metav1.GetOptions {})
200+ if err != nil {
201+ return fmt .Errorf ("failed to get ClusterManagementAddOn %s: %v" , addon .Name , err )
202+ }
203+
204+ // Add managedBy label to ClusterManagementAddOn
205+ if clusterMgmtAddOn .Labels == nil {
206+ clusterMgmtAddOn .Labels = make (map [string ]string )
207+ }
208+ for k , v := range v1alpha1 .ManagedByLabels {
209+ clusterMgmtAddOn .Labels [k ] = v
210+ }
211+
212+ _ , err = addonC .AddonV1alpha1 ().ClusterManagementAddOns ().Update (ctx , clusterMgmtAddOn , metav1.UpdateOptions {})
213+ if err != nil {
214+ return fmt .Errorf ("failed to update ClusterManagementAddOn %s with labels: %v" , addon .Name , err )
162215 }
216+ logger .V (2 ).Info ("labeled ClusterManagementAddOn" , "name" , addon .Name , "label" , v1alpha1 .LabelAddOnManagedBy )
217+
163218 return nil
164219}
165220
@@ -198,6 +253,8 @@ func handleAddonDelete(ctx context.Context, addonC *addonapi.Clientset, fc *v1al
198253 }
199254
200255 // check if there are any remaining addon templates for the same addon names as what was just deleted (different versions of the same addon)
256+ // dont use a label selector here - in case an addon with the same name was created out of band, and it is the last remaining version, we dont want
257+ // to delete its ClusterManagementAddOn
201258 allAddons , err := addonC .AddonV1alpha1 ().AddOnTemplates ().List (ctx , metav1.ListOptions {})
202259 if err != nil && ! kerrs .IsNotFound (err ) {
203260 return fmt .Errorf ("failed to clean up addons %v: %v" , purgeList , err )
@@ -231,7 +288,7 @@ func handleAddonDelete(ctx context.Context, addonC *addonapi.Clientset, fc *v1al
231288 return nil
232289}
233290
234- func handleSpokeAddons (ctx context.Context , spoke v1alpha1.Spoke , fc * v1alpha1.FleetConfig ) ([]string , error ) {
291+ func handleSpokeAddons (ctx context.Context , addonC * addonapi. Clientset , spoke v1alpha1.Spoke , fc * v1alpha1.FleetConfig ) ([]string , error ) {
235292 var enabledAddons []string
236293
237294 addons := spoke .AddOns
@@ -294,7 +351,7 @@ func handleSpokeAddons(ctx context.Context, spoke v1alpha1.Spoke, fc *v1alpha1.F
294351 }
295352
296353 // Enable new addons and updated addons
297- newEnabledAddons , err := handleAddonEnable (ctx , spoke .Name , addonsToEnable )
354+ newEnabledAddons , err := handleAddonEnable (ctx , addonC , spoke .Name , addonsToEnable )
298355 // even if an error is returned, any addon which was successfully enabled is tracked, so append before returning
299356 enabledAddons = append (enabledAddons , newEnabledAddons ... )
300357 if err != nil {
@@ -304,7 +361,7 @@ func handleSpokeAddons(ctx context.Context, spoke v1alpha1.Spoke, fc *v1alpha1.F
304361 return enabledAddons , nil
305362}
306363
307- func handleAddonEnable (ctx context.Context , spokeName string , addons []v1alpha1.AddOn ) ([]string , error ) {
364+ func handleAddonEnable (ctx context.Context , addonC * addonapi. Clientset , spokeName string , addons []v1alpha1.AddOn ) ([]string , error ) {
308365 if len (addons ) == 0 {
309366 return nil , nil
310367 }
@@ -343,6 +400,11 @@ func handleAddonEnable(ctx context.Context, spokeName string, addons []v1alpha1.
343400 enableErrs = append (enableErrs , fmt .Errorf ("failed to enable addon: %v, output: %s" , err , string (out )))
344401 continue
345402 }
403+ err = labelManagedClusterAddOn (ctx , addonC , spokeName , a .ConfigName )
404+ if err != nil {
405+ enableErrs = append (enableErrs , err )
406+ continue
407+ }
346408 enabledAddons = append (enabledAddons , a .ConfigName )
347409 logger .V (1 ).Info ("enabled addon" , "managedcluster" , spokeName , "addon" , a .ConfigName , "output" , string (stdout ))
348410 }
@@ -353,6 +415,30 @@ func handleAddonEnable(ctx context.Context, spokeName string, addons []v1alpha1.
353415 return enabledAddons , nil
354416}
355417
418+ func labelManagedClusterAddOn (ctx context.Context , addonC * addonapi.Clientset , spokeName , addonName string ) error {
419+ logger := log .FromContext (ctx )
420+
421+ mcao , err := addonC .AddonV1alpha1 ().ManagedClusterAddOns (spokeName ).Get (ctx , addonName , metav1.GetOptions {})
422+ if err != nil {
423+ return fmt .Errorf ("failed to get ManagedClusterAddOn %s for spoke %s: %v" , addonName , spokeName , err )
424+ }
425+
426+ if mcao .Labels == nil {
427+ mcao .Labels = make (map [string ]string )
428+ }
429+ for k , v := range v1alpha1 .ManagedByLabels {
430+ mcao .Labels [k ] = v
431+ }
432+
433+ _ , err = addonC .AddonV1alpha1 ().ManagedClusterAddOns (spokeName ).Update (ctx , mcao , metav1.UpdateOptions {})
434+ if err != nil {
435+ return fmt .Errorf ("failed to update ManagedClusterAddOn %s for spoke %s with labels: %v" , addonName , spokeName , err )
436+ }
437+ logger .V (2 ).Info ("labeled ManagedClusterAddOn" , "name" , addonName , "spoke" , spokeName , "label" , v1alpha1 .LabelAddOnManagedBy )
438+
439+ return nil
440+ }
441+
356442func handleAddonDisable (ctx context.Context , spokeName string , addons []string ) error {
357443 if len (addons ) == 0 {
358444 return nil
0 commit comments