Skip to content

Commit 37a4af2

Browse files
committed
feat: improve handling annotations; add e2e test
Signed-off-by: Artur Shad Nik <[email protected]>
1 parent 9308333 commit 37a4af2

File tree

3 files changed

+90
-5
lines changed

3 files changed

+90
-5
lines changed

pkg/cmd/join/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@ func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, stream
8383
cmd.Flags().Int32Var(&o.clientCertExpirationSeconds, "client-cert-expiration-seconds", 31536000, "clientCertExpirationSeconds represents the seconds of a client certificate to expire.")
8484
cmd.Flags().StringVar(&o.registrationAuth, "registration-auth", "", "The type of authentication to use for registering and authenticating with hub")
8585
cmd.Flags().StringVar(&o.hubClusterArn, "hub-cluster-arn", "", "The arn of the hub cluster(i.e. EKS cluster) to which managed-cluster will join")
86-
cmd.Flags().StringArrayVar(&o.klusterletAnnotations, "klusterlet-annotation", []string{}, fmt.Sprintf("Annotations to set on the ManagedCluster, in key=value format. Note: %s will be prepended to each key", operatorv1.ClusterAnnotationsKeyPrefix))
86+
cmd.Flags().StringArrayVar(&o.klusterletAnnotations, "klusterlet-annotation", []string{}, fmt.Sprintf("Annotations to set on the ManagedCluster, in key=value format. Note: each key will be automatically prefixed with '%s/', if not set.", operatorv1.ClusterAnnotationsKeyPrefix))
8787
return cmd
8888
}

pkg/cmd/join/exec.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -753,15 +753,24 @@ func (o *Options) setKlusterletRegistrationAnnotations() {
753753
o.klusterletChartConfig.Klusterlet.RegistrationConfiguration.ClusterAnnotations = map[string]string{}
754754
}
755755

756-
for _, a := range o.klusterletAnnotations {
757-
parts := strings.Split(a, "=")
758-
if len(parts) < 2 {
756+
for _, annotation := range o.klusterletAnnotations {
757+
i := strings.Index(annotation, "=")
758+
if i == -1 {
759+
klog.Warningf("Skipping malformed annotation (missing '='): %s", annotation)
759760
continue
760761
}
761-
k, v := parts[0], parts[1]
762+
763+
k, v := strings.TrimSpace(annotation[:i]), strings.TrimSpace(annotation[i+1:])
764+
765+
if k == "" {
766+
klog.Warningf("Skipping annotation with empty key: %s", annotation)
767+
continue
768+
}
769+
762770
if !strings.HasPrefix(k, operatorv1.ClusterAnnotationsKeyPrefix) {
763771
k = fmt.Sprintf("%s/%s", operatorv1.ClusterAnnotationsKeyPrefix, k)
764772
}
773+
765774
o.klusterletChartConfig.Klusterlet.RegistrationConfiguration.ClusterAnnotations[k] = v
766775
}
767776
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright Contributors to the Open Cluster Management project
2+
package clusteradme2e
3+
4+
import (
5+
"context"
6+
"time"
7+
8+
"github.com/onsi/ginkgo/v2"
9+
"github.com/onsi/gomega"
10+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
11+
operatorv1 "open-cluster-management.io/api/operator/v1"
12+
"open-cluster-management.io/clusteradm/test/e2e/util"
13+
)
14+
15+
var _ = ginkgo.Describe("test clusteradm join with annotations", func() {
16+
ginkgo.BeforeEach(func() {
17+
ginkgo.By("clear e2e environment...")
18+
err := e2e.ClearEnv()
19+
gomega.Expect(err).NotTo(gomega.HaveOccurred())
20+
})
21+
22+
ginkgo.Context("join hub scenario with annotations", func() {
23+
var err error
24+
25+
ginkgo.It("should managedclusters join with annotations and be accepted successfully", func() {
26+
ginkgo.By("init hub")
27+
err = e2e.Clusteradm().Init(
28+
"--context", e2e.Cluster().Hub().Context(),
29+
"--bundle-version=latest",
30+
)
31+
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "clusteradm init error")
32+
33+
ginkgo.By("managedcluster1 join hub with annotations")
34+
err = e2e.Clusteradm().Join(
35+
"--context", e2e.Cluster().ManagedCluster1().Context(),
36+
"--hub-token", e2e.CommandResult().Token(), "--hub-apiserver", e2e.CommandResult().Host(),
37+
"--cluster-name", e2e.Cluster().ManagedCluster1().Name(),
38+
"--wait",
39+
"--bundle-version=latest",
40+
"--force-internal-endpoint-lookup",
41+
"--klusterlet-annotation", "foo=bar",
42+
"--klusterlet-annotation", "test=value",
43+
)
44+
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "managedcluster1 join error")
45+
gomega.Eventually(func() error {
46+
return util.ValidateImagePullSecret(managedClusterKubeClient,
47+
"e30=", "open-cluster-management")
48+
}, time.Second*120, time.Second*2).ShouldNot(gomega.HaveOccurred())
49+
50+
ginkgo.By("hub accept managedcluster1")
51+
err = e2e.Clusteradm().Accept(
52+
"--clusters", e2e.Cluster().ManagedCluster1().Name(),
53+
"--wait",
54+
"--context", e2e.Cluster().Hub().Context(),
55+
)
56+
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "clusteradm accept error")
57+
58+
ginkgo.By("verify managedcluster1 has correct annotations")
59+
gomega.Eventually(func() map[string]string {
60+
managedCluster, err := clusterClient.ClusterV1().ManagedClusters().Get(
61+
context.TODO(), e2e.Cluster().ManagedCluster1().Name(), metav1.GetOptions{})
62+
if err != nil {
63+
return nil
64+
}
65+
return managedCluster.GetAnnotations()
66+
}, time.Second*60, time.Second*2).Should(gomega.HaveKey(operatorv1.ClusterAnnotationsKeyPrefix + "foo"))
67+
managedCluster, err := clusterClient.ClusterV1().ManagedClusters().Get(
68+
context.TODO(), e2e.Cluster().ManagedCluster1().Name(), metav1.GetOptions{})
69+
gomega.Expect(err).NotTo(gomega.HaveOccurred())
70+
annotations := managedCluster.GetAnnotations()
71+
gomega.Expect(annotations).NotTo(gomega.BeNil())
72+
gomega.Expect(annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/foo"]).To(gomega.Equal("bar"))
73+
gomega.Expect(annotations[operatorv1.ClusterAnnotationsKeyPrefix+"/test"]).To(gomega.Equal("value"))
74+
})
75+
})
76+
})

0 commit comments

Comments
 (0)