From 33ced6cc343e90217d276d45a83d11e8f590367d Mon Sep 17 00:00:00 2001 From: tcondeixa Date: Tue, 18 Aug 2026 17:59:26 +0200 Subject: [PATCH 1/4] clean the kube2iam annotations when the role is empty --- pkg/cluster/sync.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index 664c67b7e..6a83b0a46 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -1793,6 +1793,28 @@ func (c *Cluster) syncLogicalBackupJob() error { return fmt.Errorf("could not patch annotations of the logical backup job %q: %v", jobName, err) } } + + if c.OpConfig.KubeIAMRole == "" { + patch, err := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]*string{constants.KubeIAmAnnotation: nil}, + }, + "spec": map[string]interface{}{ + "jobTemplate": map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]*string{constants.KubeIAmAnnotation: nil}, + }, + }, + }, + }) + if err != nil { + return fmt.Errorf("could not marshal kube2iam annotation removal patch for logical backup job %q: %v", jobName, err) + } + _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.StrategicMergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + return fmt.Errorf("could not remove kube2iam annotation from logical backup job %q: %v", jobName, err) + } + } c.LogicalBackupJob = desiredJob return nil } From 0e4b4616fc82909fa79f84842f64a8461c151ced Mon Sep 17 00:00:00 2001 From: tcondeixa Date: Wed, 19 Aug 2026 09:33:34 +0200 Subject: [PATCH 2/4] reuse existing block that define the annotations --- pkg/cluster/sync.go | 54 +++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index 6a83b0a46..db5800ea3 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -1783,36 +1783,46 @@ func (c *Cluster) syncLogicalBackupJob() error { return fmt.Errorf("could not patch labels of the logical backup job %q: %v", jobName, err) } } - if changed, _ := c.compareAnnotations(job.Annotations, desiredJob.Annotations, nil); changed { - patchData, err := metaAnnotationsPatch(desiredJob.Annotations) + _, kubeIamInCurrent := job.Annotations[constants.KubeIAmAnnotation] + _, kubeIamInDesired := desiredJob.Annotations[constants.KubeIAmAnnotation] + kubeIamNeedsRemoval := kubeIamInCurrent && !kubeIamInDesired + if changed, _ := c.compareAnnotations(job.Annotations, desiredJob.Annotations, nil); changed || kubeIamNeedsRemoval { + patchAnnotations := make(map[string]interface{}) + for k, v := range desiredJob.Annotations { + patchAnnotations[k] = v + } + if kubeIamNeedsRemoval { + patchAnnotations[constants.KubeIAmAnnotation] = nil + } + patchData, err := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{"annotations": patchAnnotations}, + }) if err != nil { - return fmt.Errorf("could not form patch for the logical backup job %q: %v", jobName, err) + return fmt.Errorf("could not form patch for the logical backup job %q annotations: %v", jobName, err) } - _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.MergePatchType, []byte(patchData), metav1.PatchOptions{}) + _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.MergePatchType, patchData, metav1.PatchOptions{}) if err != nil { return fmt.Errorf("could not patch annotations of the logical backup job %q: %v", jobName, err) } } - - if c.OpConfig.KubeIAMRole == "" { - patch, err := json.Marshal(map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]*string{constants.KubeIAmAnnotation: nil}, - }, - "spec": map[string]interface{}{ - "jobTemplate": map[string]interface{}{ - "metadata": map[string]interface{}{ - "annotations": map[string]*string{constants.KubeIAmAnnotation: nil}, + if _, ok := job.Spec.JobTemplate.Annotations[constants.KubeIAmAnnotation]; ok { + if _, exists := desiredJob.Spec.JobTemplate.Annotations[constants.KubeIAmAnnotation]; !exists { + patchData, err := json.Marshal(map[string]interface{}{ + "spec": map[string]interface{}{ + "jobTemplate": map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]*string{constants.KubeIAmAnnotation: nil}, + }, }, }, - }, - }) - if err != nil { - return fmt.Errorf("could not marshal kube2iam annotation removal patch for logical backup job %q: %v", jobName, err) - } - _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.StrategicMergePatchType, patch, metav1.PatchOptions{}) - if err != nil { - return fmt.Errorf("could not remove kube2iam annotation from logical backup job %q: %v", jobName, err) + }) + if err != nil { + return fmt.Errorf("could not form patch for the logical backup job %q job template annotations: %v", jobName, err) + } + _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.MergePatchType, patchData, metav1.PatchOptions{}) + if err != nil { + return fmt.Errorf("could not remove kube2iam annotation from logical backup job %q job template: %v", jobName, err) + } } } c.LogicalBackupJob = desiredJob From 23c2bc0ba08386f37cec1c3f266256289d06dd92 Mon Sep 17 00:00:00 2001 From: tcondeixa Date: Wed, 19 Aug 2026 09:41:25 +0200 Subject: [PATCH 3/4] keep a single api call --- pkg/cluster/sync.go | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index db5800ea3..eeb3d3aee 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -1783,31 +1783,22 @@ func (c *Cluster) syncLogicalBackupJob() error { return fmt.Errorf("could not patch labels of the logical backup job %q: %v", jobName, err) } } - _, kubeIamInCurrent := job.Annotations[constants.KubeIAmAnnotation] - _, kubeIamInDesired := desiredJob.Annotations[constants.KubeIAmAnnotation] - kubeIamNeedsRemoval := kubeIamInCurrent && !kubeIamInDesired - if changed, _ := c.compareAnnotations(job.Annotations, desiredJob.Annotations, nil); changed || kubeIamNeedsRemoval { - patchAnnotations := make(map[string]interface{}) - for k, v := range desiredJob.Annotations { - patchAnnotations[k] = v - } - if kubeIamNeedsRemoval { - patchAnnotations[constants.KubeIAmAnnotation] = nil - } - patchData, err := json.Marshal(map[string]interface{}{ - "metadata": map[string]interface{}{"annotations": patchAnnotations}, - }) + if changed, _ := c.compareAnnotations(job.Annotations, desiredJob.Annotations, nil); changed { + patchData, err := metaAnnotationsPatch(desiredJob.Annotations) if err != nil { - return fmt.Errorf("could not form patch for the logical backup job %q annotations: %v", jobName, err) + return fmt.Errorf("could not form patch for the logical backup job %q: %v", jobName, err) } - _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.MergePatchType, patchData, metav1.PatchOptions{}) + _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.MergePatchType, []byte(patchData), metav1.PatchOptions{}) if err != nil { return fmt.Errorf("could not patch annotations of the logical backup job %q: %v", jobName, err) } } - if _, ok := job.Spec.JobTemplate.Annotations[constants.KubeIAmAnnotation]; ok { - if _, exists := desiredJob.Spec.JobTemplate.Annotations[constants.KubeIAmAnnotation]; !exists { + if _, ok := job.Annotations[constants.KubeIAmAnnotation]; ok { + if _, exists := desiredJob.Annotations[constants.KubeIAmAnnotation]; !exists { patchData, err := json.Marshal(map[string]interface{}{ + "metadata": map[string]interface{}{ + "annotations": map[string]*string{constants.KubeIAmAnnotation: nil}, + }, "spec": map[string]interface{}{ "jobTemplate": map[string]interface{}{ "metadata": map[string]interface{}{ @@ -1817,11 +1808,11 @@ func (c *Cluster) syncLogicalBackupJob() error { }, }) if err != nil { - return fmt.Errorf("could not form patch for the logical backup job %q job template annotations: %v", jobName, err) + return fmt.Errorf("could not form patch to remove kube2iam annotation from logical backup job %q: %v", jobName, err) } _, err = c.KubeClient.CronJobs(c.Namespace).Patch(context.TODO(), jobName, types.MergePatchType, patchData, metav1.PatchOptions{}) if err != nil { - return fmt.Errorf("could not remove kube2iam annotation from logical backup job %q job template: %v", jobName, err) + return fmt.Errorf("could not remove kube2iam annotation from logical backup job %q: %v", jobName, err) } } } From 952dce08518fc50b30f9ba9f965e520d33181262 Mon Sep 17 00:00:00 2001 From: tcondeixa Date: Wed, 19 Aug 2026 09:46:29 +0200 Subject: [PATCH 4/4] check also job annotation to trigger deletion --- pkg/cluster/sync.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index eeb3d3aee..482e41b1b 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -1793,7 +1793,9 @@ func (c *Cluster) syncLogicalBackupJob() error { return fmt.Errorf("could not patch annotations of the logical backup job %q: %v", jobName, err) } } - if _, ok := job.Annotations[constants.KubeIAmAnnotation]; ok { + _, kubeIamInCronJob := job.Annotations[constants.KubeIAmAnnotation] + _, kubeIamInTemplate := job.Spec.JobTemplate.Annotations[constants.KubeIAmAnnotation] + if kubeIamInCronJob || kubeIamInTemplate { if _, exists := desiredJob.Annotations[constants.KubeIAmAnnotation]; !exists { patchData, err := json.Marshal(map[string]interface{}{ "metadata": map[string]interface{}{