crossplane

Форк
0
610 строк · 15.4 Кб
1
/*
2
Copyright 2023 The Crossplane 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 xrd
18

19
import (
20
	"context"
21
	"testing"
22

23
	"github.com/google/go-cmp/cmp"
24
	"github.com/google/go-cmp/cmp/cmpopts"
25
	extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
26
	kerrors "k8s.io/apimachinery/pkg/api/errors"
27
	"k8s.io/apimachinery/pkg/runtime"
28
	"k8s.io/apimachinery/pkg/runtime/schema"
29
	"k8s.io/apimachinery/pkg/util/validation/field"
30
	"sigs.k8s.io/controller-runtime/pkg/client"
31
	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
32

33
	"github.com/crossplane/crossplane-runtime/pkg/errors"
34
	"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
35
	"github.com/crossplane/crossplane-runtime/pkg/test"
36

37
	v1 "github.com/crossplane/crossplane/apis/apiextensions/v1"
38
)
39

40
var _ admission.CustomValidator = &validator{}
41

42
func TestValidateUpdate(t *testing.T) {
43
	errBoom := errors.New("boom")
44

45
	type args struct {
46
		old    runtime.Object
47
		new    *v1.CompositeResourceDefinition
48
		client client.Client
49
	}
50
	cases := map[string]struct {
51
		args
52
		warns admission.Warnings
53
		err   error
54
	}{
55
		"UnexpectedType": {
56
			args: args{
57
				old: &extv1.CustomResourceDefinition{},
58
				new: &v1.CompositeResourceDefinition{},
59
			},
60
			err: errors.New(errUnexpectedType),
61
		},
62
		"SuccessNoClaimCreate": {
63
			args: args{
64
				old: &v1.CompositeResourceDefinition{
65
					Spec: v1.CompositeResourceDefinitionSpec{
66
						Names: extv1.CustomResourceDefinitionNames{
67
							Kind: "a",
68
						},
69
					},
70
				},
71
				new: &v1.CompositeResourceDefinition{
72
					Spec: v1.CompositeResourceDefinitionSpec{
73
						Names: extv1.CustomResourceDefinitionNames{
74
							Kind: "a",
75
						},
76
					},
77
				},
78
				client: &test.MockClient{
79
					MockGet:    test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
80
					MockCreate: test.NewMockCreateFn(nil),
81
				},
82
			},
83
		},
84
		"SuccessWithClaimCreate": {
85
			args: args{
86
				old: &v1.CompositeResourceDefinition{
87
					Spec: v1.CompositeResourceDefinitionSpec{
88
						Names: extv1.CustomResourceDefinitionNames{
89
							Kind:     "A",
90
							Plural:   "as",
91
							Singular: "a",
92
							ListKind: "AList",
93
						},
94
						ClaimNames: &extv1.CustomResourceDefinitionNames{
95
							Kind:     "B",
96
							Plural:   "bs",
97
							Singular: "b",
98
							ListKind: "BList",
99
						},
100
					},
101
				},
102
				new: &v1.CompositeResourceDefinition{
103
					Spec: v1.CompositeResourceDefinitionSpec{
104
						Names: extv1.CustomResourceDefinitionNames{
105
							Kind:     "A",
106
							Plural:   "as",
107
							Singular: "a",
108
							ListKind: "AList",
109
						},
110
						ClaimNames: &extv1.CustomResourceDefinitionNames{
111
							Kind:     "B",
112
							Plural:   "bs",
113
							Singular: "b",
114
							ListKind: "BList",
115
						},
116
					},
117
				},
118
				client: &test.MockClient{
119
					MockGet:    test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
120
					MockCreate: test.NewMockCreateFn(nil),
121
				},
122
			},
123
		},
124

125
		"SuccessNoClaimUpdate": {
126
			args: args{
127
				old: &v1.CompositeResourceDefinition{
128
					Spec: v1.CompositeResourceDefinitionSpec{
129
						Names: extv1.CustomResourceDefinitionNames{
130
							Kind: "a",
131
						},
132
					},
133
				},
134
				new: &v1.CompositeResourceDefinition{
135
					Spec: v1.CompositeResourceDefinitionSpec{
136
						Names: extv1.CustomResourceDefinitionNames{
137
							Kind: "a",
138
						},
139
					},
140
				},
141
				client: &test.MockClient{
142
					MockGet:    test.NewMockGetFn(nil),
143
					MockUpdate: test.NewMockUpdateFn(nil),
144
				},
145
			},
146
		},
147
		"SuccessWithClaimUpdate": {
148
			args: args{
149
				old: &v1.CompositeResourceDefinition{
150
					Spec: v1.CompositeResourceDefinitionSpec{
151
						Names: extv1.CustomResourceDefinitionNames{
152
							Kind:     "A",
153
							Plural:   "as",
154
							Singular: "a",
155
							ListKind: "AList",
156
						},
157
						ClaimNames: &extv1.CustomResourceDefinitionNames{
158
							Kind:     "B",
159
							Plural:   "bs",
160
							Singular: "b",
161
							ListKind: "BList",
162
						},
163
					},
164
				},
165
				new: &v1.CompositeResourceDefinition{
166
					Spec: v1.CompositeResourceDefinitionSpec{
167
						Names: extv1.CustomResourceDefinitionNames{
168
							Kind:     "A",
169
							Plural:   "as",
170
							Singular: "a",
171
							ListKind: "AList",
172
						},
173
						ClaimNames: &extv1.CustomResourceDefinitionNames{
174
							Kind:     "B",
175
							Plural:   "bs",
176
							Singular: "b",
177
							ListKind: "BList",
178
						},
179
					},
180
				},
181
				client: &test.MockClient{
182
					MockGet:    test.NewMockGetFn(nil),
183
					MockUpdate: test.NewMockUpdateFn(nil),
184
				},
185
			},
186
		},
187
		"FailChangeClaimKind": {
188
			args: args{
189
				old: &v1.CompositeResourceDefinition{
190
					Spec: v1.CompositeResourceDefinitionSpec{
191
						Names: extv1.CustomResourceDefinitionNames{
192
							Kind:     "A",
193
							Plural:   "as",
194
							Singular: "a",
195
							ListKind: "AList",
196
						},
197
						ClaimNames: &extv1.CustomResourceDefinitionNames{
198
							Kind:     "B",
199
							Plural:   "bs",
200
							Singular: "b",
201
							ListKind: "BList",
202
						},
203
					},
204
				},
205
				new: &v1.CompositeResourceDefinition{
206
					Spec: v1.CompositeResourceDefinitionSpec{
207
						Names: extv1.CustomResourceDefinitionNames{
208
							Kind:     "A",
209
							Plural:   "as",
210
							Singular: "a",
211
							ListKind: "AList",
212
						},
213
						ClaimNames: &extv1.CustomResourceDefinitionNames{
214
							Kind:     "C",
215
							Plural:   "cs",
216
							Singular: "c",
217
							ListKind: "CList",
218
						},
219
					},
220
				},
221
				client: &test.MockClient{
222
					MockGet:    test.NewMockGetFn(nil),
223
					MockUpdate: test.NewMockUpdateFn(nil),
224
				},
225
			},
226
			// WARN: brittle test, depends on the sorting of the field.ErrorList
227
			err: field.ErrorList{
228
				field.Invalid(field.NewPath("spec", "claimNames", "plural"), "cs", "field is immutable"),
229
				field.Invalid(field.NewPath("spec", "claimNames", "kind"), "C", "field is immutable"),
230
			}.ToAggregate(),
231
		},
232
		"FailOnClaimNotFound": {
233
			args: args{
234
				old: &v1.CompositeResourceDefinition{
235
					Spec: v1.CompositeResourceDefinitionSpec{
236
						Names: extv1.CustomResourceDefinitionNames{
237
							Kind:     "A",
238
							Plural:   "as",
239
							Singular: "a",
240
							ListKind: "AList",
241
						},
242
						ClaimNames: &extv1.CustomResourceDefinitionNames{
243
							Kind:     "B",
244
							Plural:   "bs",
245
							Singular: "b",
246
							ListKind: "BList",
247
						},
248
					},
249
				},
250
				new: &v1.CompositeResourceDefinition{
251
					Spec: v1.CompositeResourceDefinitionSpec{
252
						Names: extv1.CustomResourceDefinitionNames{
253
							Kind:     "A",
254
							Plural:   "as",
255
							Singular: "a",
256
							ListKind: "AList",
257
						},
258
						ClaimNames: &extv1.CustomResourceDefinitionNames{
259
							Kind:     "B",
260
							Plural:   "bs",
261
							Singular: "b",
262
							ListKind: "BList",
263
						},
264
					},
265
				},
266
				client: &test.MockClient{
267
					MockGet: test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
268
					MockCreate: test.NewMockCreateFn(nil, func(obj client.Object) error {
269
						p, err := fieldpath.PaveObject(obj)
270
						if err != nil {
271
							return err
272
						}
273
						s, err := p.GetString("spec.names.kind")
274
						if err != nil {
275
							return err
276
						}
277
						if s == "B" {
278
							return errBoom
279
						}
280
						return nil
281
					}),
282
				},
283
			},
284
			err: errBoom,
285
		},
286
		"FailOnClaimFound": {
287
			args: args{
288
				old: &v1.CompositeResourceDefinition{
289
					Spec: v1.CompositeResourceDefinitionSpec{
290
						Names: extv1.CustomResourceDefinitionNames{
291
							Kind:     "A",
292
							Plural:   "as",
293
							Singular: "a",
294
							ListKind: "AList",
295
						},
296
						ClaimNames: &extv1.CustomResourceDefinitionNames{
297
							Kind:     "B",
298
							Plural:   "bs",
299
							Singular: "b",
300
							ListKind: "BList",
301
						},
302
					},
303
				},
304
				new: &v1.CompositeResourceDefinition{
305
					Spec: v1.CompositeResourceDefinitionSpec{
306
						Names: extv1.CustomResourceDefinitionNames{
307
							Kind:     "A",
308
							Plural:   "as",
309
							Singular: "a",
310
							ListKind: "AList",
311
						},
312
						ClaimNames: &extv1.CustomResourceDefinitionNames{
313
							Kind:     "B",
314
							Plural:   "bs",
315
							Singular: "b",
316
							ListKind: "BList",
317
						},
318
					},
319
				},
320
				client: &test.MockClient{
321
					MockGet: test.NewMockGetFn(nil),
322
					MockUpdate: test.NewMockUpdateFn(nil, func(obj client.Object) error {
323
						p, err := fieldpath.PaveObject(obj)
324
						if err != nil {
325
							return err
326
						}
327
						s, err := p.GetString("spec.names.kind")
328
						if err != nil {
329
							return err
330
						}
331
						if s == "B" {
332
							return errBoom
333
						}
334
						return nil
335
					}),
336
				},
337
			},
338
			err: errBoom,
339
		},
340
		"FailOnCompositeNotFound": {
341
			args: args{
342
				old: &v1.CompositeResourceDefinition{
343
					Spec: v1.CompositeResourceDefinitionSpec{
344
						Names: extv1.CustomResourceDefinitionNames{
345
							Kind:     "A",
346
							Plural:   "as",
347
							Singular: "a",
348
							ListKind: "AList",
349
						},
350
						ClaimNames: &extv1.CustomResourceDefinitionNames{
351
							Kind:     "B",
352
							Plural:   "bs",
353
							Singular: "b",
354
							ListKind: "BList",
355
						},
356
					},
357
				},
358
				new: &v1.CompositeResourceDefinition{
359
					Spec: v1.CompositeResourceDefinitionSpec{
360
						Names: extv1.CustomResourceDefinitionNames{
361
							Kind:     "A",
362
							Plural:   "as",
363
							Singular: "a",
364
							ListKind: "AList",
365
						},
366
						ClaimNames: &extv1.CustomResourceDefinitionNames{
367
							Kind:     "B",
368
							Plural:   "bs",
369
							Singular: "b",
370
							ListKind: "BList",
371
						},
372
					},
373
				},
374
				client: &test.MockClient{
375
					MockGet: test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
376
					MockCreate: test.NewMockCreateFn(nil, func(obj client.Object) error {
377
						p, err := fieldpath.PaveObject(obj)
378
						if err != nil {
379
							return err
380
						}
381
						s, err := p.GetString("spec.names.kind")
382
						if err != nil {
383
							return err
384
						}
385
						if s == "A" {
386
							return errBoom
387
						}
388
						return nil
389
					}),
390
				},
391
			},
392
			err: errBoom,
393
		},
394
		"FailOnCompositeFound": {
395
			args: args{
396
				old: &v1.CompositeResourceDefinition{
397
					Spec: v1.CompositeResourceDefinitionSpec{
398
						Names: extv1.CustomResourceDefinitionNames{
399
							Kind:     "A",
400
							Plural:   "as",
401
							Singular: "a",
402
							ListKind: "AList",
403
						},
404
						ClaimNames: &extv1.CustomResourceDefinitionNames{
405
							Kind:     "B",
406
							Plural:   "bs",
407
							Singular: "b",
408
							ListKind: "BList",
409
						},
410
					},
411
				},
412
				new: &v1.CompositeResourceDefinition{
413
					Spec: v1.CompositeResourceDefinitionSpec{
414
						Names: extv1.CustomResourceDefinitionNames{
415
							Kind:     "A",
416
							Plural:   "as",
417
							Singular: "a",
418
							ListKind: "AList",
419
						},
420
						ClaimNames: &extv1.CustomResourceDefinitionNames{
421
							Kind:     "B",
422
							Plural:   "bs",
423
							Singular: "b",
424
							ListKind: "BList",
425
						},
426
					},
427
				},
428
				client: &test.MockClient{
429
					MockGet: test.NewMockGetFn(nil),
430
					MockUpdate: test.NewMockUpdateFn(nil, func(obj client.Object) error {
431
						p, err := fieldpath.PaveObject(obj)
432
						if err != nil {
433
							return err
434
						}
435
						s, err := p.GetString("spec.names.kind")
436
						if err != nil {
437
							return err
438
						}
439
						if s == "A" {
440
							return errBoom
441
						}
442
						return nil
443
					}),
444
				},
445
			},
446
			err: errBoom,
447
		},
448
	}
449

450
	for name, tc := range cases {
451
		t.Run(name, func(t *testing.T) {
452
			handler := &validator{
453
				client: tc.client,
454
			}
455
			warns, err := handler.ValidateUpdate(context.TODO(), tc.old, tc.new)
456
			if diff := cmp.Diff(tc.warns, warns); diff != "" {
457
				t.Errorf("ValidateUpdate(): -want warnings, +got warnings:\n%s", diff)
458
			}
459
			if diff := cmp.Diff(tc.err, err, test.EquateErrors()); diff != "" {
460
				if d := cmp.Diff(tc.err, err, cmpopts.EquateErrors()); d != "" {
461
					t.Errorf("ValidateUpdate(): -want error, +got error:\n%s", diff)
462
				}
463
			}
464
		})
465
	}
466
}
467

468
func TestValidateCreate(t *testing.T) {
469
	type args struct {
470
		obj    *v1.CompositeResourceDefinition
471
		client client.Client
472
	}
473
	errBoom := errors.New("boom")
474
	cases := map[string]struct {
475
		args
476
		warns admission.Warnings
477
		err   error
478
	}{
479
		"SuccessNoClaim": {
480
			args: args{
481
				obj: &v1.CompositeResourceDefinition{
482
					Spec: v1.CompositeResourceDefinitionSpec{
483
						Names: extv1.CustomResourceDefinitionNames{
484
							Kind: "a",
485
						},
486
					},
487
				},
488
				client: &test.MockClient{
489
					MockGet:    test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
490
					MockCreate: test.NewMockCreateFn(nil),
491
				},
492
			},
493
		},
494
		"SuccessWithClaim": {
495
			args: args{
496
				obj: &v1.CompositeResourceDefinition{
497
					Spec: v1.CompositeResourceDefinitionSpec{
498
						Names: extv1.CustomResourceDefinitionNames{
499
							Kind:     "A",
500
							Plural:   "as",
501
							Singular: "a",
502
							ListKind: "AList",
503
						},
504
						ClaimNames: &extv1.CustomResourceDefinitionNames{
505
							Kind:     "B",
506
							Plural:   "bs",
507
							Singular: "b",
508
							ListKind: "BList",
509
						},
510
					},
511
				},
512
				client: &test.MockClient{
513
					MockGet:    test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
514
					MockCreate: test.NewMockCreateFn(nil),
515
				},
516
			},
517
		},
518
		"FailOnClaim": {
519
			args: args{
520
				obj: &v1.CompositeResourceDefinition{
521
					Spec: v1.CompositeResourceDefinitionSpec{
522
						Names: extv1.CustomResourceDefinitionNames{
523
							Kind:     "A",
524
							Plural:   "as",
525
							Singular: "a",
526
							ListKind: "AList",
527
						},
528
						ClaimNames: &extv1.CustomResourceDefinitionNames{
529
							Kind:     "B",
530
							Plural:   "bs",
531
							Singular: "b",
532
							ListKind: "BList",
533
						},
534
					},
535
				},
536
				client: &test.MockClient{
537
					MockGet: test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
538
					MockCreate: test.NewMockCreateFn(nil, func(obj client.Object) error {
539
						p, err := fieldpath.PaveObject(obj)
540
						if err != nil {
541
							return err
542
						}
543
						s, err := p.GetString("spec.names.kind")
544
						if err != nil {
545
							return err
546
						}
547
						if s == "B" {
548
							return errBoom
549
						}
550
						return nil
551
					}),
552
				},
553
			},
554
			err: errBoom,
555
		},
556
		"FailOnComposite": {
557
			args: args{
558
				obj: &v1.CompositeResourceDefinition{
559
					Spec: v1.CompositeResourceDefinitionSpec{
560
						Names: extv1.CustomResourceDefinitionNames{
561
							Kind:     "A",
562
							Plural:   "as",
563
							Singular: "a",
564
							ListKind: "AList",
565
						},
566
						ClaimNames: &extv1.CustomResourceDefinitionNames{
567
							Kind:     "B",
568
							Plural:   "bs",
569
							Singular: "b",
570
							ListKind: "BList",
571
						},
572
					},
573
				},
574
				client: &test.MockClient{
575
					MockGet: test.NewMockGetFn(kerrors.NewNotFound(schema.GroupResource{}, "")),
576
					MockCreate: test.NewMockCreateFn(nil, func(obj client.Object) error {
577
						p, err := fieldpath.PaveObject(obj)
578
						if err != nil {
579
							return err
580
						}
581
						s, err := p.GetString("spec.names.kind")
582
						if err != nil {
583
							return err
584
						}
585
						if s == "A" {
586
							return errBoom
587
						}
588
						return nil
589
					}),
590
				},
591
			},
592
			err: errBoom,
593
		},
594
	}
595

596
	for name, tc := range cases {
597
		t.Run(name, func(t *testing.T) {
598
			handler := &validator{
599
				client: tc.client,
600
			}
601
			warns, err := handler.ValidateCreate(context.TODO(), tc.obj)
602
			if diff := cmp.Diff(tc.warns, warns); diff != "" {
603
				t.Errorf("ValidateUpdate(): -want warnings, +got warnings:\n%s", diff)
604
			}
605
			if diff := cmp.Diff(tc.err, err, cmpopts.EquateErrors()); diff != "" {
606
				t.Errorf("ValidateUpdate(): -want error, +got error:\n%s", diff)
607
			}
608
		})
609
	}
610
}
611

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.