From 77ac51b528af955b16c2a847575ab3412ae7cec5 Mon Sep 17 00:00:00 2001 From: Kevin McDermott Date: Thu, 12 Oct 2023 14:40:22 +0100 Subject: [PATCH] Add managed-by label to generated resources. This also adds "origin" labels to indicate which cluster-discovery resource created the clusters and secrets. --- .../automatedclusterdiscovery_controller.go | 14 +++ ...tomatedclusterdiscovery_controller_test.go | 21 +++++ internal/controller/suite_test.go | 90 ------------------- 3 files changed, 35 insertions(+), 90 deletions(-) delete mode 100644 internal/controller/suite_test.go diff --git a/internal/controller/automatedclusterdiscovery_controller.go b/internal/controller/automatedclusterdiscovery_controller.go index c523a24..e82ae1a 100644 --- a/internal/controller/automatedclusterdiscovery_controller.go +++ b/internal/controller/automatedclusterdiscovery_controller.go @@ -41,6 +41,8 @@ import ( "k8s.io/client-go/tools/clientcmd/api" ) +const k8sManagedByLabel = "app.kubernetes.io/managed-by" + // AutomatedClusterDiscoveryReconciler reconciles a AutomatedClusterDiscovery object type AutomatedClusterDiscoveryReconciler struct { client.Client @@ -159,6 +161,7 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont if err := controllerutil.SetOwnerReference(cd, gitopsCluster, r.Scheme); err != nil { return inventoryResources, fmt.Errorf("failed to set ownership on created GitopsCluster: %w", err) } + gitopsCluster.SetLabels(labelsForResource(*cd)) if err := r.Client.Create(ctx, gitopsCluster); err != nil { return inventoryResources, err } @@ -182,6 +185,8 @@ func (r *AutomatedClusterDiscoveryReconciler) reconcileClusters(ctx context.Cont if err := controllerutil.SetOwnerReference(cd, secret, r.Scheme); err != nil { return inventoryResources, fmt.Errorf("failed to set ownership on created Secret: %w", err) } + secret.SetLabels(labelsForResource(*cd)) + if err := r.Client.Create(ctx, secret); err != nil { return inventoryResources, err } @@ -321,3 +326,12 @@ func clustersToMapping(clusters []*providers.ProviderCluster) map[string]*provid return names } + +func labelsForResource(acd clustersv1alpha1.AutomatedClusterDiscovery) map[string]string { + return map[string]string{ + k8sManagedByLabel: "cluster-reflector-controller", + "clusters.weave.works/origin-name": acd.GetName(), + "clusters.weave.works/origin-namespace": acd.GetNamespace(), + "clusters.weave.works/origin-type": acd.Spec.Type, + } +} diff --git a/internal/controller/automatedclusterdiscovery_controller_test.go b/internal/controller/automatedclusterdiscovery_controller_test.go index 0a61bf9..2813e1a 100644 --- a/internal/controller/automatedclusterdiscovery_controller_test.go +++ b/internal/controller/automatedclusterdiscovery_controller_test.go @@ -110,16 +110,25 @@ func TestAutomatedClusterDiscoveryReconciler(t *testing.T) { assert.NoError(t, err) assert.Equal(t, ctrl.Result{RequeueAfter: time.Minute}, result) + wantLabels := map[string]string{ + "app.kubernetes.io/managed-by": "cluster-reflector-controller", + "clusters.weave.works/origin-name": "test-aks", + "clusters.weave.works/origin-namespace": "default", + "clusters.weave.works/origin-type": "aks", + } + gitopsCluster := &gitopsv1alpha1.GitopsCluster{} err = k8sClient.Get(ctx, types.NamespacedName{Name: "cluster-1", Namespace: aksCluster.Namespace}, gitopsCluster) assert.NoError(t, err) assert.Equal(t, gitopsv1alpha1.GitopsClusterSpec{ SecretRef: &meta.LocalObjectReference{Name: "cluster-1-kubeconfig"}, }, gitopsCluster.Spec) + assertHasLabels(t, gitopsCluster, wantLabels) secret := &corev1.Secret{} err = k8sClient.Get(ctx, types.NamespacedName{Name: "cluster-1-kubeconfig", Namespace: aksCluster.Namespace}, secret) assert.NoError(t, err) + assertHasLabels(t, secret, wantLabels) value, err := clientcmd.Write(*testProvider.response[0].KubeConfig) assert.NoError(t, err) @@ -350,6 +359,18 @@ func assertHasOwnerReference(t *testing.T, obj metav1.Object, ownerRef metav1.Ow t.Fatalf("%s %s does not have OwnerReference %s", obj.GetResourceVersion(), obj.GetName(), &ownerRef) } +func assertHasLabels(t *testing.T, o client.Object, want map[string]string) { + labels := o.GetLabels() + for k, v := range want { + kv, ok := labels[k] + if !ok { + t.Errorf("%s %s/%s is missing label %q with value %q", o.GetObjectKind().GroupVersionKind().Kind, o.GetNamespace(), o.GetName(), k, v) + continue + } + assert.Equal(t, v, kv) + } +} + func isOwnerReferenceEqual(a, b metav1.OwnerReference) bool { return (a.APIVersion == b.APIVersion) && (a.Kind == b.Kind) && diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go deleted file mode 100644 index 0ecf7d7..0000000 --- a/internal/controller/suite_test.go +++ /dev/null @@ -1,90 +0,0 @@ -/* -Copyright 2023. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "fmt" - "path/filepath" - "runtime" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - clustersv1alpha1 "github.com/weaveworks/cluster-reflector-controller/api/v1alpha1" - //+kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment - -func TestControllers(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - - // The BinaryAssetsDirectory is only required if you want to run the tests directly - // without call the makefile target test. If not informed it will look for the - // default path defined in controller-runtime which is /usr/local/kubebuilder/. - // Note that you must have the required binaries setup under the bin directory to perform - // the tests directly. When we run make test it will be setup and used automatically. - BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", - fmt.Sprintf("1.28.0-%s-%s", runtime.GOOS, runtime.GOARCH)), - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = clustersv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -})