github.com/oam-dev/kubevela@v1.9.11/pkg/utils/k8s_test.go (about) 1 /* 2 Copyright 2021 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package utils 18 19 import ( 20 "context" 21 22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 "k8s.io/apimachinery/pkg/fields" 24 "k8s.io/apimachinery/pkg/runtime" 25 26 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 27 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 28 29 . "github.com/onsi/ginkgo/v2" 30 . "github.com/onsi/gomega" 31 v1 "k8s.io/api/core/v1" 32 rbacv1 "k8s.io/api/rbac/v1" 33 apierror "k8s.io/apimachinery/pkg/api/errors" 34 "sigs.k8s.io/controller-runtime/pkg/client" 35 36 "github.com/oam-dev/kubevela/pkg/utils/errors" 37 ) 38 39 var _ = Describe("Test Create Or Update Namespace functions", func() { 40 41 BeforeEach(func() { 42 }) 43 44 It("Test Create namespace function", func() { 45 46 By("test a normal namespace create case that should be created") 47 namespaceName := "my-test-test1" 48 err := CreateNamespace(context.Background(), k8sClient, namespaceName) 49 Expect(err).Should(BeNil()) 50 var gotNS v1.Namespace 51 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 52 Expect(err).Should(BeNil()) 53 54 By("test a namespace create with no annotations case that should be created") 55 namespaceName = "my-test-test2" 56 var overrideAnn map[string]string 57 var overrideLabels map[string]string 58 err = CreateNamespace(context.Background(), k8sClient, namespaceName, MergeOverrideAnnotations(overrideAnn), MergeOverrideLabels(overrideLabels)) 59 Expect(err).Should(BeNil()) 60 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 61 Expect(err).Should(BeNil()) 62 Expect(gotNS.Annotations).Should(BeNil()) 63 64 By("test a namespace create with annotations case that should be created") 65 namespaceName = "my-test-test3" 66 overrideAnn = map[string]string{"abc": "xyz", "haha": "123"} 67 overrideLabels = map[string]string{"l1": "v1", "l2": "v2"} 68 err = CreateNamespace(context.Background(), k8sClient, namespaceName, MergeOverrideAnnotations(overrideAnn), MergeOverrideLabels(overrideLabels)) 69 Expect(err).Should(BeNil()) 70 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 71 Expect(err).Should(BeNil()) 72 Expect(gotNS.Annotations).Should(BeEquivalentTo(overrideAnn)) 73 for k, v := range overrideLabels { 74 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 75 } 76 77 }) 78 79 It("Test Update namespace function", func() { 80 81 By("test a normal namespace update with no not found error") 82 namespaceName := "updatetest-test1" 83 err := UpdateNamespace(context.Background(), k8sClient, namespaceName) 84 Expect(apierror.IsNotFound(err)).Should(BeTrue()) 85 86 overrideAnn := map[string]string{"abc": "xyz", "haha": "123"} 87 overrideLabels := map[string]string{"l1": "v1", "l2": "v2"} 88 err = CreateNamespace(context.Background(), k8sClient, namespaceName, MergeOverrideAnnotations(overrideAnn), MergeOverrideLabels(overrideLabels)) 89 Expect(err).Should(BeNil()) 90 91 By("test a namespace update with merge labels and annotations case that should be updated") 92 overrideAnn = map[string]string{"haha": "456", "newkey": "newvalue"} 93 overrideLabels = map[string]string{"l2": "v4", "l3": "v3"} 94 err = UpdateNamespace(context.Background(), k8sClient, namespaceName, MergeOverrideAnnotations(overrideAnn), MergeOverrideLabels(overrideLabels)) 95 Expect(err).Should(BeNil()) 96 var gotNS v1.Namespace 97 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 98 Expect(err).Should(BeNil()) 99 Expect(gotNS.Annotations).Should(BeEquivalentTo(map[string]string{"abc": "xyz", "haha": "456", "newkey": "newvalue"})) 100 for k, v := range overrideLabels { 101 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 102 } 103 104 By("test a namespace update with no conflict label key-value case that should be updated") 105 overrideLabels = map[string]string{"l2": "v5"} 106 noconflictLabels := map[string]string{"nc1": "v5"} 107 err = UpdateNamespace(context.Background(), k8sClient, namespaceName, MergeNoConflictLabels(noconflictLabels), MergeOverrideLabels(overrideLabels)) 108 Expect(err).Should(BeNil()) 109 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 110 Expect(err).Should(BeNil()) 111 for k, v := range noconflictLabels { 112 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 113 } 114 for k, v := range overrideLabels { 115 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 116 } 117 118 By("test a namespace update with conflict label that should return error") 119 noconflictLabels = map[string]string{"l2": "v6"} 120 err = UpdateNamespace(context.Background(), k8sClient, namespaceName, MergeNoConflictLabels(noconflictLabels)) 121 Expect(err).ShouldNot(BeNil()) 122 Expect(errors.IsLabelConflict(err)).Should(BeTrue()) 123 124 By("test a namespace update with conflict key but same key should not return error") 125 noconflictLabels = map[string]string{"l2": "v5"} 126 err = UpdateNamespace(context.Background(), k8sClient, namespaceName, MergeNoConflictLabels(noconflictLabels)) 127 Expect(err).Should(BeNil()) 128 129 By("test a namespace update with reset key to be empty") 130 overrideLabels = map[string]string{"l1": "", "l2": ""} 131 err = UpdateNamespace(context.Background(), k8sClient, namespaceName, MergeOverrideLabels(overrideLabels)) 132 Expect(err).Should(BeNil()) 133 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 134 Expect(err).Should(BeNil()) 135 for k, v := range overrideLabels { 136 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 137 } 138 139 By("test a namespace update with conflict label key but the exist value is empty should be able to change") 140 noconflictLabels = map[string]string{"l1": "vx", "l2": "vy"} 141 err = UpdateNamespace(context.Background(), k8sClient, namespaceName, MergeNoConflictLabels(noconflictLabels)) 142 Expect(err).Should(BeNil()) 143 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 144 Expect(err).Should(BeNil()) 145 for k, v := range noconflictLabels { 146 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 147 } 148 }) 149 150 It("Test CreateOrUpdate namespace function", func() { 151 By("test a normal namespace update with no namespace exist") 152 namespaceName := "create-or-update-test1" 153 err := CreateOrUpdateNamespace(context.Background(), k8sClient, namespaceName) 154 Expect(err).Should(BeNil()) 155 156 By("test update namespace with functions") 157 overrideAnn := map[string]string{"abc": "xyz", "haha": "123"} 158 overrideLabels := map[string]string{"l1": "v1", "l2": "v2"} 159 noconflictLabels := map[string]string{"c1": "v1", "c2": "v2"} 160 err = CreateOrUpdateNamespace(context.Background(), k8sClient, namespaceName, MergeOverrideAnnotations(overrideAnn), MergeOverrideLabels(overrideLabels), MergeNoConflictLabels(noconflictLabels)) 161 Expect(err).Should(BeNil()) 162 var gotNS v1.Namespace 163 err = k8sClient.Get(context.Background(), client.ObjectKey{Name: namespaceName}, &gotNS) 164 Expect(err).Should(BeNil()) 165 Expect(gotNS.Annotations).Should(BeEquivalentTo(overrideAnn)) 166 for k, v := range overrideLabels { 167 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 168 } 169 for k, v := range noconflictLabels { 170 Expect(gotNS.Labels).Should(HaveKeyWithValue(k, v)) 171 } 172 }) 173 174 It("Test IsClusterScope", func() { 175 ok, err := IsClusterScope(v1.SchemeGroupVersion.WithKind("ConfigMap"), k8sClient.RESTMapper()) 176 Expect(err).Should(Succeed()) 177 Expect(ok).Should(BeFalse()) 178 ok, err = IsClusterScope(rbacv1.SchemeGroupVersion.WithKind("ClusterRole"), k8sClient.RESTMapper()) 179 Expect(err).Should(Succeed()) 180 Expect(ok).Should(BeTrue()) 181 }) 182 183 It("Test FilterObjectsByFieldSelector function", func() { 184 var componentSpec = v1beta1.ApplicationSpec{ 185 Components: []common.ApplicationComponent{ 186 { 187 Name: "test1-component", 188 Type: "worker", 189 Properties: &runtime.RawExtension{Raw: []byte(`{"cmd":["sleep","1000"],"image":"busybox"}`)}, 190 }, 191 }, 192 } 193 var componentStatus = common.AppStatus{ 194 Services: []common.ApplicationComponentStatus{ 195 { 196 Name: "test1-component", 197 Message: "test1-component applied", 198 Healthy: true, 199 }, 200 }, 201 Phase: common.ApplicationRunning, 202 } 203 apps := []*v1beta1.Application{ 204 { 205 ObjectMeta: metav1.ObjectMeta{ 206 Name: "app1", 207 Namespace: "test2", 208 }, 209 Spec: componentSpec, 210 Status: componentStatus, 211 }, 212 { 213 ObjectMeta: metav1.ObjectMeta{ 214 Name: "app2", 215 Namespace: "test2", 216 }, 217 Spec: componentSpec, 218 Status: componentStatus, 219 }, 220 } 221 222 var objects []runtime.Object 223 for i := range apps { 224 objects = append(objects, apps[i]) 225 } 226 fieldSelector, err := fields.ParseSelector("metadata.name=app2,metadata.namespace=test2") 227 Expect(err).Should(BeNil()) 228 filteredObjects := FilterObjectsByFieldSelector(objects, fieldSelector) 229 Expect(filteredObjects).Should(ContainElements(objects[1])) 230 }) 231 })