1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package manifest_test
16
17 import (
18 "context"
19 "path"
20 "reflect"
21 "strings"
22 "testing"
23
24 corev1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/apis/core/v1beta1"
25 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/k8s"
26 "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/manifest"
27 testpaths "github.com/GoogleCloudPlatform/k8s-config-connector/operator/pkg/test/util/paths"
28
29 "github.com/google/go-cmp/cmp"
30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31 "sigs.k8s.io/kubebuilder-declarative-pattern/pkg/patterns/addon/pkg/loaders"
32 )
33
34 var clusterModeWIManifest = `# Copyright 2022 Google LLC
35 #
36 # Licensed under the Apache License, Version 2.0 (the "License");
37 # you may not use this file except in compliance with the License.
38 # You may obtain a copy of the License at
39 #
40 # http://www.apache.org/licenses/LICENSE-2.0
41 #
42 # Unless required by applicable law or agreed to in writing, software
43 # distributed under the License is distributed on an "AS IS" BASIS,
44 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 # See the License for the specific language governing permissions and
46 # limitations under the License.
47
48 apiVersion: apiextensions.k8s.io/v1
49 kind: CustomResourceDefinition
50 metadata:
51 name: foos.test.cnrm.cloud.google.com
52 labels:
53 cnrm.cloud.google.com/system: "true"
54 cnrm.cloud.google.com/managed-by-kcc: "true"
55 spec:
56 scope: Namespaced
57 group: test.cnrm.cloud.google.com
58 names:
59 kind: foo
60 plural: foos
61 versions:
62 - name: v1alpha1
63 schema:
64 openAPIV3Schema:
65 type: object
66 served: true
67 storage: true
68 ---
69 apiVersion: apiextensions.k8s.io/v1
70 kind: CustomResourceDefinition
71 metadata:
72 name: bars.test.cnrm.cloud.google.com
73 labels:
74 cnrm.cloud.google.com/system: "true"
75 cnrm.cloud.google.com/managed-by-kcc: "true"
76 spec:
77 scope: Namespaced
78 group: test.cnrm.cloud.google.com
79 names:
80 kind: bar
81 plural: bars
82 versions:
83 - name: v1alpha1
84 schema:
85 openAPIV3Schema:
86 type: object
87 served: true
88 storage: true
89 ---
90 # Copyright 2022 Google LLC
91 #
92 # Licensed under the Apache License, Version 2.0 (the "License");
93 # you may not use this file except in compliance with the License.
94 # You may obtain a copy of the License at
95 #
96 # http://www.apache.org/licenses/LICENSE-2.0
97 #
98 # Unless required by applicable law or agreed to in writing, software
99 # distributed under the License is distributed on an "AS IS" BASIS,
100 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
101 # See the License for the specific language governing permissions and
102 # limitations under the License.
103
104 apiVersion: v1
105 kind: Namespace
106 metadata:
107 name: cnrm-system
108 ---
109 apiVersion: v1
110 kind: ServiceAccount
111 metadata:
112 annotations:
113 iam.gke.io/gcp-service-account: cnrm-system@${PROJECT_ID?}.iam.gserviceaccount.com
114 name: cnrm-controller-manager
115 namespace: cnrm-system
116 ---
117 apiVersion: v1
118 kind: Service
119 metadata:
120 name: cnrm-manager
121 namespace: cnrm-system
122 spec:
123 ports:
124 - name: controller-manager
125 port: 443
126 - name: metrics
127 port: 8888
128 selector:
129 cnrm.cloud.google.com/component: cnrm-controller-manager
130 cnrm.cloud.google.com/system: "true"
131 ---
132 apiVersion: apps/v1
133 kind: StatefulSet
134 metadata:
135 labels:
136 cnrm.cloud.google.com/component: cnrm-controller-manager
137 cnrm.cloud.google.com/system: "true"
138 name: cnrm-controller-manager
139 namespace: cnrm-system
140 spec:
141 selector:
142 matchLabels:
143 cnrm.cloud.google.com/component: cnrm-controller-manager
144 cnrm.cloud.google.com/system: "true"
145 serviceName: cnrm-manager
146 template:
147 metadata:
148 labels:
149 cnrm.cloud.google.com/component: cnrm-controller-manager
150 cnrm.cloud.google.com/system: "true"
151 `
152
153 var clusterModeGcpManifest = `# Copyright 2022 Google LLC
154 #
155 # Licensed under the Apache License, Version 2.0 (the "License");
156 # you may not use this file except in compliance with the License.
157 # You may obtain a copy of the License at
158 #
159 # http://www.apache.org/licenses/LICENSE-2.0
160 #
161 # Unless required by applicable law or agreed to in writing, software
162 # distributed under the License is distributed on an "AS IS" BASIS,
163 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
164 # See the License for the specific language governing permissions and
165 # limitations under the License.
166
167 apiVersion: apiextensions.k8s.io/v1
168 kind: CustomResourceDefinition
169 metadata:
170 name: foos.test.cnrm.cloud.google.com
171 labels:
172 cnrm.cloud.google.com/system: "true"
173 cnrm.cloud.google.com/managed-by-kcc: "true"
174 spec:
175 scope: Namespaced
176 group: test.cnrm.cloud.google.com
177 names:
178 kind: foo
179 plural: foos
180 versions:
181 - name: v1alpha1
182 schema:
183 openAPIV3Schema:
184 type: object
185 served: true
186 storage: true
187 ---
188 apiVersion: apiextensions.k8s.io/v1
189 kind: CustomResourceDefinition
190 metadata:
191 name: bars.test.cnrm.cloud.google.com
192 labels:
193 cnrm.cloud.google.com/system: "true"
194 cnrm.cloud.google.com/managed-by-kcc: "true"
195 spec:
196 scope: Namespaced
197 group: test.cnrm.cloud.google.com
198 names:
199 kind: bar
200 plural: bars
201 versions:
202 - name: v1alpha1
203 schema:
204 openAPIV3Schema:
205 type: object
206 served: true
207 storage: true
208 ---
209 # Copyright 2022 Google LLC
210 #
211 # Licensed under the Apache License, Version 2.0 (the "License");
212 # you may not use this file except in compliance with the License.
213 # You may obtain a copy of the License at
214 #
215 # http://www.apache.org/licenses/LICENSE-2.0
216 #
217 # Unless required by applicable law or agreed to in writing, software
218 # distributed under the License is distributed on an "AS IS" BASIS,
219 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
220 # See the License for the specific language governing permissions and
221 # limitations under the License.
222
223 apiVersion: v1
224 kind: Namespace
225 metadata:
226 name: cnrm-system
227 ---
228 apiVersion: v1
229 kind: ServiceAccount
230 metadata:
231 name: cnrm-controller-manager
232 namespace: cnrm-system
233 ---
234 apiVersion: v1
235 kind: Service
236 metadata:
237 name: cnrm-manager
238 namespace: cnrm-system
239 spec:
240 ports:
241 - name: controller-manager
242 port: 443
243 - name: metrics
244 port: 8888
245 selector:
246 cnrm.cloud.google.com/component: cnrm-controller-manager
247 cnrm.cloud.google.com/system: "true"
248 ---
249 apiVersion: apps/v1
250 kind: StatefulSet
251 metadata:
252 labels:
253 cnrm.cloud.google.com/component: cnrm-controller-manager
254 cnrm.cloud.google.com/system: "true"
255 name: cnrm-controller-manager
256 namespace: cnrm-system
257 spec:
258 selector:
259 matchLabels:
260 cnrm.cloud.google.com/component: cnrm-controller-manager
261 cnrm.cloud.google.com/system: "true"
262 serviceName: cnrm-manager
263 template:
264 metadata:
265 labels:
266 cnrm.cloud.google.com/component: cnrm-controller-manager
267 cnrm.cloud.google.com/system: "true"
268 spec:
269 volumes:
270 - name: gcp-service-account
271 secret:
272 secretName: gcp-key
273 `
274
275 var namespacedManifest = `# Copyright 2022 Google LLC
276 #
277 # Licensed under the Apache License, Version 2.0 (the "License");
278 # you may not use this file except in compliance with the License.
279 # You may obtain a copy of the License at
280 #
281 # http://www.apache.org/licenses/LICENSE-2.0
282 #
283 # Unless required by applicable law or agreed to in writing, software
284 # distributed under the License is distributed on an "AS IS" BASIS,
285 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286 # See the License for the specific language governing permissions and
287 # limitations under the License.
288
289 apiVersion: apiextensions.k8s.io/v1
290 kind: CustomResourceDefinition
291 metadata:
292 name: foos.test.cnrm.cloud.google.com
293 labels:
294 cnrm.cloud.google.com/system: "true"
295 cnrm.cloud.google.com/managed-by-kcc: "true"
296 spec:
297 scope: Namespaced
298 group: test.cnrm.cloud.google.com
299 names:
300 kind: foo
301 plural: foos
302 versions:
303 - name: v1alpha1
304 schema:
305 openAPIV3Schema:
306 type: object
307 served: true
308 storage: true
309 ---
310 apiVersion: apiextensions.k8s.io/v1
311 kind: CustomResourceDefinition
312 metadata:
313 name: bars.test.cnrm.cloud.google.com
314 labels:
315 cnrm.cloud.google.com/system: "true"
316 cnrm.cloud.google.com/managed-by-kcc: "true"
317 spec:
318 scope: Namespaced
319 group: test.cnrm.cloud.google.com
320 names:
321 kind: bar
322 plural: bars
323 versions:
324 - name: v1alpha1
325 schema:
326 openAPIV3Schema:
327 type: object
328 served: true
329 storage: true
330 ---
331 # Copyright 2022 Google LLC
332 #
333 # Licensed under the Apache License, Version 2.0 (the "License");
334 # you may not use this file except in compliance with the License.
335 # You may obtain a copy of the License at
336 #
337 # http://www.apache.org/licenses/LICENSE-2.0
338 #
339 # Unless required by applicable law or agreed to in writing, software
340 # distributed under the License is distributed on an "AS IS" BASIS,
341 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
342 # See the License for the specific language governing permissions and
343 # limitations under the License.
344
345 apiVersion: v1
346 kind: Namespace
347 metadata:
348 name: cnrm-system
349 `
350
351 var namespacedComponentsOnly = `# Copyright 2022 Google LLC
352 #
353 # Licensed under the Apache License, Version 2.0 (the "License");
354 # you may not use this file except in compliance with the License.
355 # You may obtain a copy of the License at
356 #
357 # http://www.apache.org/licenses/LICENSE-2.0
358 #
359 # Unless required by applicable law or agreed to in writing, software
360 # distributed under the License is distributed on an "AS IS" BASIS,
361 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
362 # See the License for the specific language governing permissions and
363 # limitations under the License.
364
365 apiVersion: v1
366 kind: ServiceAccount
367 metadata:
368 annotations:
369 iam.gke.io/gcp-service-account: cnrm-system-${NAMESPACE?}@${PROJECT_ID?}.iam.gserviceaccount.com
370 labels:
371 cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
372 cnrm.cloud.google.com/system: "true"
373 name: cnrm-controller-manager-${NAMESPACE?}
374 namespace: cnrm-system
375 ---
376 apiVersion: v1
377 kind: Service
378 metadata:
379 name: cnrm-manager-${NAMESPACE?}
380 namespace: cnrm-system
381 spec:
382 ports:
383 - name: controller-manager
384 port: 443
385 - name: metrics
386 port: 8888
387 selector:
388 cnrm.cloud.google.com/component: cnrm-controller-manager
389 cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
390 cnrm.cloud.google.com/system: "true"
391 ---
392 apiVersion: apps/v1
393 kind: StatefulSet
394 metadata:
395 labels:
396 cnrm.cloud.google.com/component: cnrm-controller-manager
397 cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
398 cnrm.cloud.google.com/system: "true"
399 name: cnrm-controller-manager-${NAMESPACE?}
400 namespace: cnrm-system
401 spec:
402 selector:
403 matchLabels:
404 cnrm.cloud.google.com/component: cnrm-controller-manager
405 cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
406 cnrm.cloud.google.com/system: "true"
407 serviceName: cnrm-manager-${NAMESPACE?}
408 template:
409 metadata:
410 labels:
411 cnrm.cloud.google.com/component: cnrm-controller-manager
412 cnrm.cloud.google.com/scoped-namespace: ${NAMESPACE?}
413 cnrm.cloud.google.com/system: "true"
414 `
415
416 func TestNewLocalRepository_LoadManifest(t *testing.T) {
417 t.Parallel()
418 basedir, repo := newTestNewLocalRepository(t)
419 tests := []struct {
420 name string
421 cc *corev1beta1.ConfigConnector
422 result map[string]string
423 }{
424 {
425 name: "cluster mode, workload identity",
426 cc: &corev1beta1.ConfigConnector{
427 ObjectMeta: metav1.ObjectMeta{
428 Name: k8s.ConfigConnectorAllowedName,
429 },
430 Spec: corev1beta1.ConfigConnectorSpec{
431 GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
432 Mode: "cluster",
433 },
434 },
435 result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "cluster", "workload-identity"}, "/"): clusterModeWIManifest},
436 },
437 {
438 name: "cluster mode, gcp identity",
439 cc: &corev1beta1.ConfigConnector{
440 ObjectMeta: metav1.ObjectMeta{
441 Name: k8s.ConfigConnectorAllowedName,
442 },
443 Spec: corev1beta1.ConfigConnectorSpec{
444 CredentialSecretName: "my-key",
445 Mode: "cluster",
446 },
447 },
448 result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "cluster", "gcp-identity"}, "/"): clusterModeGcpManifest},
449 },
450 {
451 name: "namespaced mode",
452 cc: &corev1beta1.ConfigConnector{
453 ObjectMeta: metav1.ObjectMeta{
454 Name: k8s.ConfigConnectorAllowedName,
455 },
456 Spec: corev1beta1.ConfigConnectorSpec{
457 GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
458 Mode: "namespaced",
459 },
460 },
461 result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "namespaced"}, "/"): namespacedManifest},
462 },
463 {
464 name: "namespaced mode by default",
465 cc: &corev1beta1.ConfigConnector{
466 ObjectMeta: metav1.ObjectMeta{
467 Name: k8s.ConfigConnectorAllowedName,
468 },
469 Spec: corev1beta1.ConfigConnectorSpec{
470 GoogleServiceAccount: "foo@bar.iam.gserviceaccount.com",
471 },
472 },
473 result: map[string]string{strings.Join([]string{basedir, "packages", "configconnector", "0.0.0-test", "namespaced"}, "/"): namespacedManifest},
474 },
475 }
476
477 for _, test := range tests {
478 tc := test
479 t.Run(tc.name, func(t *testing.T) {
480 manifestStrs, err := repo.LoadManifest(context.TODO(), "configconnector", "0.0.0-test", tc.cc)
481 if err != nil {
482 t.Fatalf("unexpected error while loadding the manifest: %v", err)
483 }
484 if !reflect.DeepEqual(manifestStrs, tc.result) {
485 t.Fatalf("unexpected diff: %v", cmp.Diff(manifestStrs, tc.result))
486 }
487 })
488 }
489 }
490
491 func TestNewLocalRepository_LoadNamespacedComponents(t *testing.T) {
492 t.Parallel()
493 baseDir, repo := newTestNewLocalRepository(t)
494 manifestPath := path.Join(baseDir, "packages/configconnector/0.0.0-test/namespaced/per-namespace-components.yaml")
495 tests := []struct {
496 name string
497 result map[string]string
498 }{
499 {
500 name: "load namespaced component",
501 result: map[string]string{manifestPath: namespacedComponentsOnly},
502 },
503 }
504 for _, test := range tests {
505 tc := test
506 t.Run(tc.name, func(t *testing.T) {
507 t.Parallel()
508 manifests, err := repo.LoadNamespacedComponents(context.TODO(), "configconnector", "0.0.0-test")
509 if err != nil {
510 t.Fatalf("unexpected error while loadding the manifest for namespaced components: %v", err)
511 }
512 if !reflect.DeepEqual(manifests, tc.result) {
513 t.Fatalf("unexpected diff: %v", cmp.Diff(manifests, tc.result))
514 }
515 })
516 }
517 }
518
519 func TestNewLocalRepository_LoadChannel(t *testing.T) {
520 t.Parallel()
521 _, repo := newTestNewLocalRepository(t)
522 res, err := repo.LoadChannel(context.TODO(), "stable")
523 if err != nil {
524 t.Fatalf("unexpected error: %v", err)
525 }
526 expected := &loaders.Channel{
527 Manifests: []loaders.Version{
528 {
529 Version: "0.0.0-test",
530 },
531 },
532 }
533 if !reflect.DeepEqual(res, expected) {
534 t.Fatalf("unexpected diff: %v", cmp.Diff(res, expected))
535 }
536 }
537
538 func newTestNewLocalRepository(t *testing.T) (string, manifest.Repository) {
539 root := testpaths.GetOperatorSrcRootOrLogFatal()
540 basedir := root + "/" + "pkg/manifest/testchannel"
541 return basedir, manifest.NewLocalRepository(basedir)
542 }
543
View as plain text