From 3a2e7d33119b080c0a1cd4167d851f3ce9c59e4c Mon Sep 17 00:00:00 2001 From: Shafeeque E S Date: Wed, 16 Aug 2023 22:46:16 +0530 Subject: [PATCH] Add `reconcile` operation for Seed, Reconcile backupbuckets on seed reconciliation (#8347) * Increase seed generation on Reconcile operation annotation. * Reconcile backupbucket on seed reconciliation * Inject backup-secret hash into the gardenlet pod annotations * Address PR review feedback --- pkg/apis/core/validation/seed.go | 1 + .../controller/managedseed/actuator.go | 14 ++++++++++++- .../seed/seed/reconciler_reconcile.go | 1 + pkg/registry/core/seed/strategy.go | 3 +++ pkg/registry/core/seed/strategy_test.go | 9 ++++++++ .../gardenlet/managedseed/managedseed_test.go | 21 +++++++++++++++---- 6 files changed, 44 insertions(+), 5 deletions(-) diff --git a/pkg/apis/core/validation/seed.go b/pkg/apis/core/validation/seed.go index 4304cd50ec7..b9066ec542d 100644 --- a/pkg/apis/core/validation/seed.go +++ b/pkg/apis/core/validation/seed.go @@ -39,6 +39,7 @@ var ( ) availableSeedOperations = sets.New( v1beta1constants.SeedOperationRenewGardenAccessSecrets, + v1beta1constants.GardenerOperationReconcile, ) ) diff --git a/pkg/gardenlet/controller/managedseed/actuator.go b/pkg/gardenlet/controller/managedseed/actuator.go index f54a87c69ea..e5a8cb48a89 100644 --- a/pkg/gardenlet/controller/managedseed/actuator.go +++ b/pkg/gardenlet/controller/managedseed/actuator.go @@ -45,6 +45,7 @@ import ( "github.com/gardener/gardener/pkg/controllerutils" gardenletv1alpha1 "github.com/gardener/gardener/pkg/gardenlet/apis/config/v1alpha1" gardenletbootstraputil "github.com/gardener/gardener/pkg/gardenlet/bootstrap/util" + "github.com/gardener/gardener/pkg/utils" gardenerutils "github.com/gardener/gardener/pkg/utils/gardener" kubernetesutils "github.com/gardener/gardener/pkg/utils/kubernetes" ) @@ -487,9 +488,13 @@ func (a *actuator) reconcileSeedSecrets(ctx context.Context, log logr.Logger, sp // If backup is specified, create or update the backup secret if it doesn't exist or is owned by the managed seed if spec.Backup != nil { + var checksum string + // Get backup secret backupSecret, err := kubernetesutils.GetSecretByReference(ctx, a.gardenClient, &spec.Backup.SecretRef) - if client.IgnoreNotFound(err) != nil { + if err == nil { + checksum = utils.ComputeSecretChecksum(backupSecret.Data)[:8] + } else if client.IgnoreNotFound(err) != nil { return err } @@ -508,7 +513,14 @@ func (a *actuator) reconcileSeedSecrets(ctx context.Context, log logr.Logger, sp }); err != nil { return err } + + checksum = utils.ComputeSecretChecksum(secret.Data)[:8] } + + // Inject backup-secret hash into the pod annotations + managedSeed.Spec.Gardenlet.Deployment.PodAnnotations = utils.MergeStringMaps[string](managedSeed.Spec.Gardenlet.Deployment.PodAnnotations, map[string]string{ + "checksum/seed-backup-secret": spec.Backup.SecretRef.Name + "-" + checksum, + }) } // If secret reference is specified and the static token kubeconfig is enabled, diff --git a/pkg/gardenlet/controller/seed/seed/reconciler_reconcile.go b/pkg/gardenlet/controller/seed/seed/reconciler_reconcile.go index 262d5ea9b7f..a34beccf4d1 100644 --- a/pkg/gardenlet/controller/seed/seed/reconciler_reconcile.go +++ b/pkg/gardenlet/controller/seed/seed/reconciler_reconcile.go @@ -696,6 +696,7 @@ func deployBackupBucketInGarden(ctx context.Context, k8sGardenClient client.Clie ownerRef := metav1.NewControllerRef(seed, gardencorev1beta1.SchemeGroupVersion.WithKind("Seed")) _, err := controllerutils.CreateOrGetAndStrategicMergePatch(ctx, k8sGardenClient, backupBucket, func() error { + metav1.SetMetaDataAnnotation(&backupBucket.ObjectMeta, v1beta1constants.GardenerOperation, v1beta1constants.GardenerOperationReconcile) backupBucket.OwnerReferences = []metav1.OwnerReference{*ownerRef} backupBucket.Spec = gardencorev1beta1.BackupBucketSpec{ Provider: gardencorev1beta1.BackupBucketProvider{ diff --git a/pkg/registry/core/seed/strategy.go b/pkg/registry/core/seed/strategy.go index 50bac0a71f6..7c39ab0a8e3 100644 --- a/pkg/registry/core/seed/strategy.go +++ b/pkg/registry/core/seed/strategy.go @@ -84,6 +84,9 @@ func mustIncreaseGeneration(oldSeed, newSeed *core.Seed) bool { switch newSeed.Annotations[v1beta1constants.GardenerOperation] { case v1beta1constants.SeedOperationRenewGardenAccessSecrets: return true + case v1beta1constants.GardenerOperationReconcile: + delete(newSeed.Annotations, v1beta1constants.GardenerOperation) + return true } } diff --git a/pkg/registry/core/seed/strategy_test.go b/pkg/registry/core/seed/strategy_test.go index a6efb198e4a..00bb8898332 100644 --- a/pkg/registry/core/seed/strategy_test.go +++ b/pkg/registry/core/seed/strategy_test.go @@ -88,6 +88,15 @@ var _ = Describe("Strategy", func() { Expect(newSeed.Generation).To(Equal(oldSeed.Generation + 1)) }) + It("should bump the generation and remove the annotation if the operation annotation was set to reconcile", func() { + metav1.SetMetaDataAnnotation(&newSeed.ObjectMeta, "gardener.cloud/operation", "reconcile") + + strategy.PrepareForUpdate(ctx, newSeed, oldSeed) + + Expect(newSeed.Generation).To(Equal(oldSeed.Generation + 1)) + Expect(newSeed.Annotations).NotTo(ContainElement("gardener.cloud/operation")) + }) + It("should not bump the generation if the operation annotation didn't change", func() { metav1.SetMetaDataAnnotation(&oldSeed.ObjectMeta, "gardener.cloud/operation", "renew-garden-access-secrets") metav1.SetMetaDataAnnotation(&newSeed.ObjectMeta, "gardener.cloud/operation", "renew-garden-access-secrets") diff --git a/test/integration/gardenlet/managedseed/managedseed_test.go b/test/integration/gardenlet/managedseed/managedseed_test.go index 8e7135ac6e1..aad5de5ad29 100644 --- a/test/integration/gardenlet/managedseed/managedseed_test.go +++ b/test/integration/gardenlet/managedseed/managedseed_test.go @@ -42,6 +42,7 @@ var _ = Describe("ManagedSeed controller test", func() { shootKubeconfigSecret *corev1.Secret shootSecretBinding *gardencorev1beta1.SecretBinding shootCloudProviderSecret *corev1.Secret + backupSecret *corev1.Secret backupSecretName, seedSecretName string reconcileShoot = func() { @@ -58,7 +59,7 @@ var _ = Describe("ManagedSeed controller test", func() { By("Verify if seed secrets are created") EventuallyWithOffset(1, func(g Gomega) { g.Expect(testClient.Get(ctx, client.ObjectKeyFromObject(managedSeed), managedSeed)).To(Succeed()) - g.Expect(testClient.Get(ctx, client.ObjectKey{Name: backupSecretName, Namespace: gardenNamespaceGarden.Name}, &corev1.Secret{})).To(Succeed()) + g.Expect(testClient.Get(ctx, client.ObjectKeyFromObject(backupSecret), backupSecret)).To(Succeed()) g.Expect(testClient.Get(ctx, client.ObjectKey{Name: seedSecretName, Namespace: gardenNamespaceGarden.Name}, &corev1.Secret{})).To(Succeed()) }).Should(Succeed()) } @@ -79,7 +80,12 @@ var _ = Describe("ManagedSeed controller test", func() { g.Expect(testClient.Get(ctx, client.ObjectKey{Name: "gardenlet-kubeconfig-bootstrap", Namespace: gardenNamespaceShoot}, &corev1.Secret{})).To(Succeed()) g.Expect(testClient.Get(ctx, client.ObjectKey{Name: "gardenlet", Namespace: gardenNamespaceShoot}, &corev1.Service{})).To(Succeed()) g.Expect(testClient.Get(ctx, client.ObjectKey{Name: "gardenlet", Namespace: gardenNamespaceShoot}, &corev1.ServiceAccount{})).To(Succeed()) - g.Expect(testClient.Get(ctx, client.ObjectKey{Name: "gardenlet", Namespace: gardenNamespaceShoot}, &appsv1.Deployment{})).To(Succeed()) + + gardenletDeployment := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Name: "gardenlet", Namespace: gardenNamespaceShoot}} + g.Expect(testClient.Get(ctx, client.ObjectKeyFromObject(gardenletDeployment), gardenletDeployment)).To(Succeed()) + g.Expect(gardenletDeployment.Spec.Template.Annotations).To(HaveKeyWithValue( + "checksum/seed-backup-secret", backupSecret.Name+"-"+utils.ComputeSecretChecksum(backupSecret.Data)[:8], + )) }).Should(Succeed()) } ) @@ -92,6 +98,13 @@ var _ = Describe("ManagedSeed controller test", func() { backupSecretName = "backup-" + utils.ComputeSHA256Hex([]byte(uuid.NewUUID()))[:8] seedSecretName = "seed-" + utils.ComputeSHA256Hex([]byte(uuid.NewUUID()))[:8] + backupSecret = &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: backupSecretName, + Namespace: gardenNamespaceGarden.Name, + }, + } + gardenletConfig, err := encoding.EncodeGardenletConfiguration(&gardenletv1alpha1.GardenletConfiguration{ TypeMeta: metav1.TypeMeta{ APIVersion: gardenletv1alpha1.SchemeGroupVersion.String(), @@ -115,8 +128,8 @@ var _ = Describe("ManagedSeed controller test", func() { Provider: "test", Region: pointer.String("bar"), SecretRef: corev1.SecretReference{ - Name: backupSecretName, - Namespace: gardenNamespaceGarden.Name, + Name: backupSecret.Name, + Namespace: backupSecret.Namespace, }, }, SecretRef: &corev1.SecretReference{