package bootstrapping import ( "context" "encoding/json" "os" kustomizeApi "github.com/fluxcd/kustomize-controller/api/v1" "github.com/go-logr/logr" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "edge-infra.dev/pkg/edge/api/services" ) func CleanUpKustomizations(ctx context.Context, path string, bucketName, clusterVersion string, log logr.Logger, cl client.Client) error { mapKustomizations := map[string]string{} ks, err := services.CreateKustomizations(ctx, bucketName, path, clusterVersion) if err != nil { return err } for _, kustomization := range ks { fluxKustomization := &kustomizeApi.Kustomization{} if err := json.Unmarshal([]byte(kustomization), fluxKustomization); err != nil { log.Error(err, "failed to marshall kustomizations") continue } log.Info("Installing Flux Kustomize resource!!") existingKustomization := &kustomizeApi.Kustomization{} if err := cl.Get(ctx, types.NamespacedName{ Name: fluxKustomization.Name, Namespace: fluxKustomization.Namespace, }, existingKustomization); err != nil { if apierrors.IsNotFound(err) { if err := cl.Create(ctx, fluxKustomization); err != nil { log.Error(err, "unable to create flux kustomization", "name", fluxKustomization.Name, "namespace", fluxKustomization.Namespace) return err } return nil } log.Error(err, "failed to get existing kustomization", "name", fluxKustomization.Name, "namespace", fluxKustomization.Namespace) return err } existingKustomization.TypeMeta = fluxKustomization.TypeMeta existingKustomization.ObjectMeta.Name = fluxKustomization.ObjectMeta.Name existingKustomization.ObjectMeta.Namespace = fluxKustomization.ObjectMeta.Namespace existingKustomization.Spec = fluxKustomization.Spec existingKustomization.Status = fluxKustomization.Status if err := cl.Update(ctx, existingKustomization); err != nil { log.Error(err, "failed to update existing kustomization", "name", existingKustomization.Name, "namespace", existingKustomization.Namespace) return err } log.Info("kustomization applied") mapKustomizations[existingKustomization.Name] = "" } badKustosRemoved := false for !badKustosRemoved { badKustosRemoved = true listKustomizations := &kustomizeApi.KustomizationList{} if err = cl.List(ctx, listKustomizations); err != nil { log.Error(err, "failed to get all kustomizations") os.Exit(1) } for _, existingKustomization := range listKustomizations.Items { if !isExpectedKustomization(mapKustomizations, existingKustomization.Name) { badKustosRemoved = badKustosRemoved && removeUnexpectKustomizations(ctx, existingKustomization, cl, log) } } } return err } func isExpectedKustomization(existing map[string]string, checkKustomization string) bool { _, ok := existing[checkKustomization] return ok } func removeUnexpectKustomizations(ctx context.Context, existingKustomization kustomizeApi.Kustomization, cl client.Client, log logr.Logger) bool { if _, ok := existingKustomization.Labels["kustomize.toolkit.fluxcd.io/name"]; !ok { //only delete if kustomization not synced by flux badKustomization := existingKustomization.DeepCopy() if badKustomization.Spec.Prune { if _, err := controllerutil.CreateOrUpdate(ctx, cl, badKustomization, func() error { badKustomization.Spec.Prune = false return nil }); err != nil { log.Error(err, "failed to update bad kustomization") os.Exit(1) } return false } if err := cl.Delete(ctx, badKustomization); err != nil { log.Error(err, "failed to delete bad kustomization") os.Exit(1) } return true } return true }