Skip to content

Commit a3d694e

Browse files
authored
✨ allow labeling resources created during addon create and enable (#509)
* feat: allow labeling resources created during addon create and enable Signed-off-by: Artur Shad Nik <[email protected]> * refactor: label parser helper Signed-off-by: Artur Shad Nik <[email protected]> * test: add labels to addon lifecycle e2e suite Signed-off-by: Artur Shad Nik <[email protected]> * fix: use version in template name Signed-off-by: Artur Shad Nik <[email protected]> --------- Signed-off-by: Artur Shad Nik <[email protected]>
1 parent f196c46 commit a3d694e

File tree

8 files changed

+108
-5
lines changed

8 files changed

+108
-5
lines changed

pkg/cmd/addon/create/cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, stream
5151
cmd.Flags().BoolVar(&o.EnableHubRegistration, "hub-registration", false, "Enable the agent to register to the hub cluster")
5252
cmd.Flags().StringVar(&o.ClusterRoleBindingRef, "cluster-role-bind", "", "The rolebinding to the clusterrole in "+
5353
"the cluster namespace for the addon agent")
54+
cmd.Flags().StringSliceVar(&o.Labels, "labels", []string{}, "Labels to add to the ClusterManagementAddOn and AddOnTemplate resources (eg. key1=value1,key2=value2)")
5455
o.FileNameFlags.AddFlags(cmd.Flags())
5556

5657
return cmd

pkg/cmd/addon/create/exec.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,26 @@ import (
1313
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
1414
addonclientset "open-cluster-management.io/api/client/addon/clientset/versioned"
1515
workapiv1 "open-cluster-management.io/api/work/v1"
16+
17+
"open-cluster-management.io/clusteradm/pkg/helpers/parse"
1618
)
1719

1820
func newAddonTemplate(o *Options) (*addonv1alpha1.AddOnTemplate, error) {
1921
manifests, err := o.readManifests()
2022
if err != nil {
2123
return nil, err
2224
}
25+
26+
// Parse labels
27+
labels, err := o.parseLabels()
28+
if err != nil {
29+
return nil, err
30+
}
31+
2332
addon := &addonv1alpha1.AddOnTemplate{
2433
ObjectMeta: metav1.ObjectMeta{
25-
Name: o.templateName(),
34+
Name: o.templateName(),
35+
Labels: labels,
2636
},
2737
Spec: addonv1alpha1.AddOnTemplateSpec{
2838
AddonName: o.Name,
@@ -59,10 +69,17 @@ func newAddonTemplate(o *Options) (*addonv1alpha1.AddOnTemplate, error) {
5969
return addon, nil
6070
}
6171

62-
func newClusterManagementAddon(o *Options) *addonv1alpha1.ClusterManagementAddOn {
72+
func newClusterManagementAddon(o *Options) (*addonv1alpha1.ClusterManagementAddOn, error) {
73+
// Parse labels
74+
labels, err := o.parseLabels()
75+
if err != nil {
76+
return nil, err
77+
}
78+
6379
cma := &addonv1alpha1.ClusterManagementAddOn{
6480
ObjectMeta: metav1.ObjectMeta{
65-
Name: o.Name,
81+
Name: o.Name,
82+
Labels: labels,
6683
Annotations: map[string]string{
6784
"addon.open-cluster-management.io/lifecycle": "addon-manager",
6885
},
@@ -85,7 +102,7 @@ func newClusterManagementAddon(o *Options) *addonv1alpha1.ClusterManagementAddOn
85102
},
86103
}
87104

88-
return cma
105+
return cma, nil
89106
}
90107

91108
func (o *Options) complete(cmd *cobra.Command, args []string) (err error) {
@@ -142,7 +159,10 @@ func (o *Options) templateName() string {
142159
}
143160

144161
func (o *Options) applyCMA(addonClient addonclientset.Interface) error {
145-
cma := newClusterManagementAddon(o)
162+
cma, err := newClusterManagementAddon(o)
163+
if err != nil {
164+
return err
165+
}
146166

147167
// apply cma at first
148168
originalCMA, err := addonClient.AddonV1alpha1().ClusterManagementAddOns().Get(context.TODO(), o.Name, metav1.GetOptions{})
@@ -224,3 +244,8 @@ func (o *Options) readManifests() ([]workapiv1.Manifest, error) {
224244

225245
return manifests, nil
226246
}
247+
248+
// parseLabels parses the labels flag and returns a map of labels
249+
func (o *Options) parseLabels() (map[string]string, error) {
250+
return parse.ParseLabels(o.Labels)
251+
}

pkg/cmd/addon/create/options.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ type Options struct {
2424
// registration only supports clusterRoleBinding with cluster namespace
2525
ClusterRoleBindingRef string
2626

27+
//Labels to add to created resources
28+
Labels []string
29+
2730
FileNameFlags genericclioptions.FileNameFlags
2831
//
2932
Streams genericiooptions.IOStreams

pkg/cmd/addon/enable/cmd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func NewCmd(clusteradmFlags *genericclioptionsclusteradm.ClusteradmFlags, stream
6969
cmd.Flags().StringVarP(&o.Namespace, "namespace", "n", "open-cluster-management-agent-addon", "Specified namespace to deploy addon")
7070
cmd.Flags().StringVar(&o.OutputFile, "output-file", "", "The generated resources will be copied in the specified file")
7171
cmd.Flags().StringSliceVar(&o.Annotate, "annotate", []string{}, "Annotations to add to the ManagedClusterAddon (eg. key1=value1,key2=value2)")
72+
cmd.Flags().StringSliceVar(&o.Labels, "labels", []string{}, "Labels to add to the ManagedClusterAddon (eg. key1=value1,key2=value2)")
7273

7374
return cmd
7475
}

pkg/cmd/addon/enable/exec.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
addonv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
1515
addonclientset "open-cluster-management.io/api/client/addon/clientset/versioned"
1616
clusterclientset "open-cluster-management.io/api/client/cluster/clientset/versioned"
17+
"open-cluster-management.io/clusteradm/pkg/helpers/parse"
1718
)
1819

1920
type ClusterAddonInfo struct {
@@ -34,11 +35,19 @@ func NewClusterAddonInfo(cn string, o *Options, an string) (*addonv1alpha1.Manag
3435
}
3536
annos[annoSlice[0]] = annoSlice[1]
3637
}
38+
39+
// Parse provided labels
40+
labels, err := parse.ParseLabels(o.Labels)
41+
if err != nil {
42+
return nil, err
43+
}
44+
3745
return &addonv1alpha1.ManagedClusterAddOn{
3846
ObjectMeta: metav1.ObjectMeta{
3947
Name: an,
4048
Namespace: cn,
4149
Annotations: annos,
50+
Labels: labels,
4251
},
4352
Spec: addonv1alpha1.ManagedClusterAddOnSpec{
4453
InstallNamespace: o.Namespace,
@@ -144,6 +153,7 @@ func ApplyAddon(addonClient addonclientset.Interface, addon *addonv1alpha1.Manag
144153
}
145154

146155
originalAddon.Annotations = addon.Annotations
156+
originalAddon.Labels = addon.Labels
147157
originalAddon.Spec.InstallNamespace = addon.Spec.InstallNamespace
148158
_, err = addonClient.AddonV1alpha1().ManagedClusterAddOns(addon.Namespace).Update(context.TODO(), originalAddon, metav1.UpdateOptions{})
149159
return err

pkg/cmd/addon/enable/options.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ type Options struct {
1919
OutputFile string
2020
//Annotations to add to the addon
2121
Annotate []string
22+
//Labels to add to the addon
23+
Labels []string
2224
//
2325
Streams genericiooptions.IOStreams
2426
}

pkg/helpers/parse/parse.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright Contributors to the Open Cluster Management project
2+
package parse
3+
4+
import (
5+
"fmt"
6+
"strings"
7+
)
8+
9+
func ParseLabels(labels []string) (map[string]string, error) {
10+
labelMap := make(map[string]string)
11+
for _, labelString := range labels {
12+
labelSlice := strings.Split(labelString, "=")
13+
if len(labelSlice) != 2 {
14+
return nil, fmt.Errorf("error parsing label '%s'. Expected to be of the form: key=value", labelString)
15+
}
16+
labelMap[labelSlice[0]] = labelSlice[1]
17+
}
18+
return labelMap, nil
19+
}

test/e2e/clusteradm/addon_create_test.go renamed to test/e2e/clusteradm/addon_lifecycle_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package clusteradme2e
44
import (
55
"context"
66
"fmt"
7+
"reflect"
8+
"strings"
79
"time"
810

911
"open-cluster-management.io/clusteradm/test/e2e/util"
@@ -18,6 +20,11 @@ import (
1820
"k8s.io/apimachinery/pkg/runtime/schema"
1921
)
2022

23+
var addonLabels = map[string]string{
24+
"foo.example.com/created-by": "clusteradm",
25+
"foo": "bar",
26+
}
27+
2128
var _ = ginkgo.Describe("test clusteradm with addon create", ginkgo.Label("addon-create"), func() {
2229
ginkgo.BeforeEach(func() {
2330
ginkgo.By("clear e2e environment...")
@@ -76,6 +83,12 @@ var _ = ginkgo.Describe("test clusteradm with addon create", ginkgo.Label("addon
7683
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "create configmap-reader clusterrole error")
7784
}
7885

86+
var pairs []string
87+
for k, v := range addonLabels {
88+
pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
89+
}
90+
labelsString := strings.Join(pairs, ",")
91+
7992
ginkgo.By("hub create addon")
8093
err = e2e.Clusteradm().Addon(
8194
"create",
@@ -85,9 +98,33 @@ var _ = ginkgo.Describe("test clusteradm with addon create", ginkgo.Label("addon
8598
"--hub-registration",
8699
"--cluster-role-bind",
87100
"configmap-reader",
101+
"--labels",
102+
labelsString,
88103
)
89104
gomega.Expect(err).NotTo(gomega.HaveOccurred())
90105

106+
gomega.Eventually(func() error {
107+
cma, err := addonClient.AddonV1alpha1().ClusterManagementAddOns().Get(
108+
context.TODO(), "test-nginx", metav1.GetOptions{})
109+
if err != nil {
110+
return err
111+
}
112+
if !reflect.DeepEqual(cma.Labels, addonLabels) {
113+
return fmt.Errorf("clusterManagementAddOns does not have expected labels. have: %v, want: %v", cma.Labels, addonLabels)
114+
}
115+
116+
addonT, err := addonClient.AddonV1alpha1().AddOnTemplates().Get(
117+
context.TODO(), "test-nginx-0.0.1", metav1.GetOptions{})
118+
if err != nil {
119+
return err
120+
}
121+
if !reflect.DeepEqual(addonT.Labels, addonLabels) {
122+
return fmt.Errorf("addOnTemplate does not have expected labels. have: %v, want: %v", addonT.Labels, addonLabels)
123+
}
124+
125+
return nil
126+
}, 120*time.Second, 1*time.Second).ShouldNot(gomega.HaveOccurred())
127+
91128
ginkgo.By("hub enable addon")
92129
err = e2e.Clusteradm().Addon(
93130
"enable",
@@ -96,6 +133,8 @@ var _ = ginkgo.Describe("test clusteradm with addon create", ginkgo.Label("addon
96133
"test-nginx",
97134
"--clusters",
98135
e2e.Cluster().ManagedCluster1().Name(),
136+
"--labels",
137+
labelsString,
99138
)
100139
gomega.Expect(err).NotTo(gomega.HaveOccurred())
101140

@@ -105,6 +144,9 @@ var _ = ginkgo.Describe("test clusteradm with addon create", ginkgo.Label("addon
105144
if err != nil {
106145
return err
107146
}
147+
if !reflect.DeepEqual(mca.Labels, addonLabels) {
148+
return fmt.Errorf("managedClusterAddOn does not have expected labels. have: %v, want: %v", mca.Labels, addonLabels)
149+
}
108150

109151
if meta.IsStatusConditionTrue(mca.Status.Conditions, "Available") {
110152
return nil

0 commit comments

Comments
 (0)