From 0f3dbee2b067c56685017d6f4ede24c8f1b629a1 Mon Sep 17 00:00:00 2001 From: valeryia-hurynovich Date: Tue, 31 Mar 2026 15:49:59 +0200 Subject: [PATCH] fixed controller logic due to clarifications --- api/v1alpha1/managedcloudprofile.go | 6 +- api/v1alpha1/zz_generated.deepcopy.go | 10 ++-- controllers/managedcloudprofile_controller.go | 22 +++---- .../managedcloudprofile_controller_test.go | 58 ++++++++++--------- 4 files changed, 50 insertions(+), 46 deletions(-) diff --git a/api/v1alpha1/managedcloudprofile.go b/api/v1alpha1/managedcloudprofile.go index b01264b..4a32218 100644 --- a/api/v1alpha1/managedcloudprofile.go +++ b/api/v1alpha1/managedcloudprofile.go @@ -20,6 +20,9 @@ type ManagedCloudProfileSpec struct { // MachineImageUpdates contains the source and provider information to automate machine images. // +optional MachineImageUpdates []MachineImageUpdate `json:"machineImageUpdates,omitempty"` + // GarbageCollection contains configuration for automated garbage collection + // +optional + GarbageCollection *GarbageCollectionConfig `json:"garbageCollection,omitempty"` } // Copy the cloud profile spec to override some validation @@ -97,9 +100,6 @@ type MachineImageUpdate struct { // ImagesName is the name of the image to maintain automatically ImageName string `json:"imageName"` - // GarbageCollection contains configuration for automated garbage collection - // +optional - GarbageCollection *GarbageCollectionConfig `json:"garbageCollection,omitempty"` } type GarbageCollectionConfig struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index f73ee13..1ee67b6 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -107,11 +107,6 @@ func (in *MachineImageUpdate) DeepCopyInto(out *MachineImageUpdate) { *out = *in in.Source.DeepCopyInto(&out.Source) in.Provider.DeepCopyInto(&out.Provider) - if in.GarbageCollection != nil { - in, out := &in.GarbageCollection, &out.GarbageCollection - *out = new(GarbageCollectionConfig) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineImageUpdate. @@ -265,6 +260,11 @@ func (in *ManagedCloudProfileSpec) DeepCopyInto(out *ManagedCloudProfileSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.GarbageCollection != nil { + in, out := &in.GarbageCollection, &out.GarbageCollection + *out = new(GarbageCollectionConfig) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedCloudProfileSpec. diff --git a/controllers/managedcloudprofile_controller.go b/controllers/managedcloudprofile_controller.go index b6249a3..b4c715d 100644 --- a/controllers/managedcloudprofile_controller.go +++ b/controllers/managedcloudprofile_controller.go @@ -115,21 +115,25 @@ func (r *Reconciler) reconcileCloudProfile(ctx context.Context, log logr.Logger, } func (r *Reconciler) reconcileGarbageCollection(ctx context.Context, log logr.Logger, mcp *v1alpha1.ManagedCloudProfile) error { + if mcp.Spec.GarbageCollection == nil || !mcp.Spec.GarbageCollection.Enabled { + return nil + } + if mcp.Spec.GarbageCollection.MaxAge.Duration < 0 { + return r.failWithStatusUpdate(ctx, mcp, fmt.Errorf("invalid garbage collection maxAge: %s", mcp.Spec.GarbageCollection.MaxAge.String())) + } + + cutoff := time.Now().Add(-mcp.Spec.GarbageCollection.MaxAge.Duration) + for _, updates := range mcp.Spec.MachineImageUpdates { - if updates.GarbageCollection == nil || !updates.GarbageCollection.Enabled { - continue - } - if updates.GarbageCollection.MaxAge.Duration < 0 { - return r.failWithStatusUpdate(ctx, mcp, fmt.Errorf("invalid garbage collection maxAge: %s", updates.GarbageCollection.MaxAge.String())) - } if updates.Source.OCI == nil { continue } - var source cloudprofilesync.Source + password, err := r.getCredential(ctx, updates.Source.OCI.Password) if err != nil { return r.failWithStatusUpdate(ctx, mcp, fmt.Errorf("failed to get credential for garbage collection: %w", err)) } + src, err := r.OCISourceFactory.Create(cloudprofilesync.OCIParams{ Registry: updates.Source.OCI.Registry, Repository: updates.Source.OCI.Repository, @@ -140,9 +144,8 @@ func (r *Reconciler) reconcileGarbageCollection(ctx context.Context, log logr.Lo if err != nil { return r.failWithStatusUpdate(ctx, mcp, fmt.Errorf("failed to initialize OCI source for garbage collection: %w", err)) } - source = src - versions, err := source.GetVersions(ctx) + versions, err := src.GetVersions(ctx) if err != nil { return r.failWithStatusUpdate(ctx, mcp, fmt.Errorf("failed to list source versions for garbage collection: %w", err)) } @@ -152,7 +155,6 @@ func (r *Reconciler) reconcileGarbageCollection(ctx context.Context, log logr.Lo return r.failWithStatusUpdate(ctx, mcp, fmt.Errorf("failed to determine referenced versions for garbage collection: %w", err)) } - cutoff := time.Now().Add(-updates.GarbageCollection.MaxAge.Duration) versionsToDelete := make(map[string]struct{}) for _, v := range versions { if v.CreatedAt.IsZero() { diff --git a/controllers/managedcloudprofile_controller_test.go b/controllers/managedcloudprofile_controller_test.go index f2911d3..5a0ffb5 100644 --- a/controllers/managedcloudprofile_controller_test.go +++ b/controllers/managedcloudprofile_controller_test.go @@ -292,12 +292,13 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { Insecure: true, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 0}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 0}, + } + Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus { @@ -399,12 +400,13 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { Insecure: true, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 0}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 0}, + } + Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus { @@ -487,12 +489,12 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { Insecure: true, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 0}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 0}, + } Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus { @@ -542,12 +544,12 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { }, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 3600000000000}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 3600000000000}, + } Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus { @@ -581,12 +583,12 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { Insecure: true, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 3600000000000}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 3600000000000}, + } Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus { @@ -629,12 +631,12 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { Insecure: true, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 3600000000000}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 3600000000000}, + } Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus { @@ -785,12 +787,12 @@ var _ = Describe("The ManagedCloudProfile reconciler", func() { Insecure: true, }, }, - GarbageCollection: &v1alpha1.GarbageCollectionConfig{ - Enabled: true, - MaxAge: metav1.Duration{Duration: 0}, - }, }, } + mcp.Spec.GarbageCollection = &v1alpha1.GarbageCollectionConfig{ + Enabled: true, + MaxAge: metav1.Duration{Duration: 0}, + } Expect(k8sClient.Create(ctx, &mcp)).To(Succeed()) Eventually(func(g Gomega) v1alpha1.ReconcileStatus {