1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package webhook
16
17 import (
18 "testing"
19
20 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/core/v1alpha1"
21 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/iam/v1beta1"
22 kcciamclient "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/iam/iamclient"
23 dclmetadata "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/metadata"
24 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/schema/dclschemaloader"
25 testservicemappingloader "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/test/servicemappingloader"
26 "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
27
28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29 "k8s.io/apimachinery/pkg/runtime/schema"
30 )
31
32 func TestValidateIAMPolicy(t *testing.T) {
33 tests := []struct {
34 name string
35 policy *v1beta1.IAMPolicy
36 refResourceRCs []*v1alpha1.ResourceConfig
37 isDCLResource bool
38 expectedAllowedValue bool
39 }{
40 {
41 name: "IAMPolicy without conditions, with reference that doesn't support conditions",
42 policy: newTestPolicy(),
43 refResourceRCs: newTestResourceRCs(),
44 expectedAllowedValue: true,
45 },
46 {
47 name: "IAMPolicy without conditions, with reference that supports conditions",
48 policy: newTestPolicy(),
49 refResourceRCs: newTestResourceRCsThatSupportConditions(),
50 expectedAllowedValue: true,
51 },
52 {
53 name: "IAMPolicy with conditions, with reference that doesn't support conditions",
54 policy: newTestPolicyWithIAMConditions(),
55 refResourceRCs: newTestResourceRCs(),
56 expectedAllowedValue: false,
57 },
58 {
59 name: "IAMPolicy with conditions, with reference that supports conditions",
60 policy: newTestPolicyWithIAMConditions(),
61 refResourceRCs: newTestResourceRCsThatSupportConditions(),
62 expectedAllowedValue: true,
63 },
64 {
65 name: "IAMPolicy without audit configs, with reference that doesn't support audit configs",
66 policy: newTestPolicy(),
67 refResourceRCs: newTestResourceRCs(),
68 expectedAllowedValue: true,
69 },
70 {
71 name: "IAMPolicy without audit configs, with reference that supports audit configs",
72 policy: newTestPolicy(),
73 refResourceRCs: newTestResourceRCsThatSupportAuditConfigs(),
74 expectedAllowedValue: true,
75 },
76 {
77 name: "IAMPolicy with audit configs, with reference that doesn't support audit configs",
78 policy: newTestPolicyWithAuditConfigs(),
79 refResourceRCs: newTestResourceRCs(),
80 expectedAllowedValue: false,
81 },
82 {
83 name: "IAMPolicy with audit configs, with reference that supports audit configs",
84 policy: newTestPolicyWithAuditConfigs(),
85 refResourceRCs: newTestResourceRCsThatSupportAuditConfigs(),
86 expectedAllowedValue: true,
87 },
88
89 {
90 name: "Headless Project IAMPolicy without conditions",
91 policy: newTestHeadlessProjectPolicy(),
92 refResourceRCs: newTestResourceRCsThatSupportConditions(),
93 expectedAllowedValue: true,
94 },
95 {
96 name: "Headless Project IAMPolicy with conditions",
97 policy: newTestHeadlessProjectPolicyWithIAMConditions(),
98 refResourceRCs: newTestResourceRCsThatSupportConditions(),
99 expectedAllowedValue: true,
100 },
101 {
102 name: "Headless Project IAMPolicy without audit configs",
103 policy: newTestHeadlessProjectPolicy(),
104 refResourceRCs: newTestResourceRCsThatSupportAuditConfigs(),
105 expectedAllowedValue: true,
106 },
107 {
108 name: "Headless Project IAMPolicy with audit configs",
109 policy: newTestHeadlessProjectPolicyWithAuditConfigs(),
110 refResourceRCs: newTestResourceRCsThatSupportAuditConfigs(),
111 expectedAllowedValue: true,
112 },
113 {
114 name: "IAMPolicy with external-only reference",
115 policy: newTestExternalOnlyRefPolicy(),
116 refResourceRCs: newTestResourceRCs(),
117 expectedAllowedValue: true,
118 },
119 {
120 name: "DCL-based IAMPolicy",
121 policy: &v1beta1.IAMPolicy{
122 TypeMeta: metav1.TypeMeta{
123 Kind: v1beta1.IAMPolicyGVK.Kind,
124 APIVersion: v1beta1.IAMPolicyGVK.GroupVersion().String(),
125 },
126 Spec: v1beta1.IAMPolicySpec{
127 ResourceReference: v1beta1.ResourceReference{
128 Kind: "DataprocCluster",
129 Namespace: "my-namespace",
130 Name: "my-resource-name",
131 APIVersion: "dataproc/v1beta1",
132 },
133 },
134 },
135 isDCLResource: true,
136 expectedAllowedValue: true,
137 },
138 {
139 name: "DCL-based IAMPolicy with audit configs",
140 policy: newTestHeadlessProjectPolicyWithAuditConfigs(),
141 isDCLResource: true,
142 expectedAllowedValue: false,
143 },
144 }
145
146 for _, tc := range tests {
147 tc := tc
148 t.Run(tc.name, func(t *testing.T) {
149 t.Parallel()
150 dclSchemaLoader, err := dclschemaloader.New()
151 if err != nil {
152 t.Fatalf("error creating a new DCL schema loader: %v", err)
153 }
154 a := iamValidatorHandler{
155 smLoader: testservicemappingloader.New(t),
156 serviceMetadataLoader: dclmetadata.New(),
157 schemaLoader: dclSchemaLoader,
158 }
159 var response admission.Response
160 if tc.isDCLResource {
161 response = a.dclValidateIAMPolicy(tc.policy)
162 } else {
163 response = a.tfValidateIAMPolicy(tc.policy, tc.refResourceRCs)
164 }
165 if response.Allowed != tc.expectedAllowedValue {
166 t.Fatalf("unexpected value for Allowed: got '%v', want '%v'", response.Allowed, tc.expectedAllowedValue)
167 }
168 })
169 }
170 }
171
172 func TestValidateIAMPartialPolicy(t *testing.T) {
173 tests := []struct {
174 name string
175 partialPolicy *v1beta1.IAMPartialPolicy
176 refResourceRCs []*v1alpha1.ResourceConfig
177 isDCLResource bool
178 expectedAllowedValue bool
179 }{
180 {
181 name: "IAMPartialPolicy without conditions, with reference that doesn't support conditions",
182 partialPolicy: newTestPartialPolicy(),
183 refResourceRCs: newTestResourceRCs(),
184 expectedAllowedValue: true,
185 },
186 {
187 name: "IAMPartialPolicy without conditions, with reference that supports conditions",
188 partialPolicy: newTestPartialPolicy(),
189 refResourceRCs: newTestResourceRCsThatSupportConditions(),
190 expectedAllowedValue: true,
191 },
192 {
193 name: "IAMPartialPolicy with conditions, with reference that doesn't support conditions",
194 partialPolicy: newTestPartialPolicyWithIAMConditions(),
195 refResourceRCs: newTestResourceRCs(),
196 expectedAllowedValue: false,
197 },
198 {
199 name: "IAMPartialPolicy with conditions, with reference that supports conditions",
200 partialPolicy: newTestPartialPolicyWithIAMConditions(),
201 refResourceRCs: newTestResourceRCsThatSupportConditions(),
202 expectedAllowedValue: true,
203 },
204 {
205 name: "IAMPartialPolicy without audit configs, with reference that supports audit configs",
206 partialPolicy: newTestPartialPolicy(),
207 refResourceRCs: newTestResourceRCsThatSupportAuditConfigs(),
208 expectedAllowedValue: true,
209 },
210
211 {
212 name: "Headless Project IAMPartialPolicy without conditions",
213 partialPolicy: newTestHeadlessProjectPartialPolicy(),
214 refResourceRCs: newTestResourceRCsThatSupportConditions(),
215 expectedAllowedValue: true,
216 },
217 {
218 name: "Headless Project IAMPartialPolicy with conditions",
219 partialPolicy: newTestHeadlessProjectPartialPolicyWithIAMConditions(),
220 refResourceRCs: newTestResourceRCsThatSupportConditions(),
221 expectedAllowedValue: true,
222 },
223 {
224 name: "IAMPartialPolicy with external-only reference",
225 partialPolicy: newTestExternalOnlyRefPartialPolicy(),
226 refResourceRCs: newTestResourceRCs(),
227 expectedAllowedValue: true,
228 },
229 {
230 name: "DCL-based IAMPartialPolicy",
231 partialPolicy: &v1beta1.IAMPartialPolicy{
232 TypeMeta: metav1.TypeMeta{
233 Kind: v1beta1.IAMPolicyGVK.Kind,
234 APIVersion: v1beta1.IAMPolicyGVK.GroupVersion().String(),
235 },
236 Spec: v1beta1.IAMPartialPolicySpec{
237 ResourceReference: v1beta1.ResourceReference{
238 Kind: "DataprocCluster",
239 Namespace: "my-namespace",
240 Name: "my-resource-name",
241 APIVersion: "dataproc/v1beta1",
242 },
243 },
244 },
245 isDCLResource: true,
246 expectedAllowedValue: true,
247 },
248 }
249
250 for _, tc := range tests {
251 tc := tc
252 t.Run(tc.name, func(t *testing.T) {
253 t.Parallel()
254 dclSchemaLoader, err := dclschemaloader.New()
255 if err != nil {
256 t.Fatalf("error creating a new DCL schema loader: %v", err)
257 }
258 a := iamValidatorHandler{
259 smLoader: testservicemappingloader.New(t),
260 serviceMetadataLoader: dclmetadata.New(),
261 schemaLoader: dclSchemaLoader,
262 }
263 var response admission.Response
264 if tc.isDCLResource {
265 response = a.dclValidateIAMPartialPolicy(tc.partialPolicy)
266 } else {
267 response = a.tfValidateIAMPartialPolicy(tc.partialPolicy, tc.refResourceRCs)
268 }
269 if response.Allowed != tc.expectedAllowedValue {
270 t.Fatalf("unexpected value for Allowed: got '%v', want '%v'", response.Allowed, tc.expectedAllowedValue)
271 }
272 })
273 }
274 }
275
276 func TestValidateIAMPolicyMember(t *testing.T) {
277 tests := []struct {
278 name string
279 policyMember *v1beta1.IAMPolicyMember
280 refResourceRCs []*v1alpha1.ResourceConfig
281 isDCLResource bool
282 expectedAllowedValue bool
283 }{
284 {
285 name: "IAMPolicyMember without conditions, with reference that doesn't support conditions",
286 policyMember: newTestPolicyMember(),
287 refResourceRCs: newTestResourceRCs(),
288 expectedAllowedValue: true,
289 },
290 {
291 name: "IAMPolicyMember without conditions, with reference that supports conditions",
292 policyMember: newTestPolicyMember(),
293 refResourceRCs: newTestResourceRCsThatSupportConditions(),
294 expectedAllowedValue: true,
295 },
296 {
297 name: "IAMPolicyMember with conditions, with reference that doesn't support conditions",
298 policyMember: newTestPolicyMemberWithIAMConditions(),
299 refResourceRCs: newTestResourceRCs(),
300 expectedAllowedValue: false,
301 },
302 {
303 name: "IAMPolicyMember with conditions, with reference that supports conditions",
304 policyMember: newTestPolicyMemberWithIAMConditions(),
305 refResourceRCs: newTestResourceRCsThatSupportConditions(),
306 expectedAllowedValue: true,
307 },
308
309 {
310 name: "Headless Project IAMPolicyMember without conditions",
311 policyMember: newTestHeadlessProjectPolicyMember(),
312 refResourceRCs: newTestResourceRCsThatSupportConditions(),
313 expectedAllowedValue: true,
314 },
315 {
316 name: "Headless Project IAMPolicyMember with conditions",
317 policyMember: newTestHeadlessProjectPolicyMemberWithIAMConditions(),
318 refResourceRCs: newTestResourceRCsThatSupportConditions(),
319 expectedAllowedValue: true,
320 },
321 {
322 name: "IAMPolicyMember with external-only reference",
323 policyMember: newTestExternalOnlyRefPolicyMember(),
324 refResourceRCs: newTestResourceRCs(),
325 expectedAllowedValue: true,
326 },
327 {
328 name: "DCL-based IAMPolicyMember",
329 policyMember: &v1beta1.IAMPolicyMember{
330 TypeMeta: metav1.TypeMeta{
331 Kind: v1beta1.IAMPolicyGVK.Kind,
332 APIVersion: v1beta1.IAMPolicyGVK.GroupVersion().String(),
333 },
334 Spec: v1beta1.IAMPolicyMemberSpec{
335 ResourceReference: v1beta1.ResourceReference{
336 Kind: "DataprocCluster",
337 Namespace: "my-namespace",
338 Name: "my-resource-name",
339 APIVersion: "dataproc/v1beta1",
340 },
341 Role: "role",
342 },
343 },
344 isDCLResource: true,
345 expectedAllowedValue: true,
346 },
347 }
348
349 for _, tc := range tests {
350 tc := tc
351 t.Run(tc.name, func(t *testing.T) {
352 t.Parallel()
353 dclSchemaLoader, err := dclschemaloader.New()
354 if err != nil {
355 t.Fatalf("error creating a new DCL schema loader: %v", err)
356 }
357 a := iamValidatorHandler{
358 smLoader: testservicemappingloader.New(t),
359 serviceMetadataLoader: dclmetadata.New(),
360 schemaLoader: dclSchemaLoader,
361 }
362 response := a.tfValidateIAMPolicyMember(tc.policyMember, tc.refResourceRCs)
363 if response.Allowed != tc.expectedAllowedValue {
364 t.Fatalf("unexpected value for Allowed: got '%v', want '%v'", response.Allowed, tc.expectedAllowedValue)
365 }
366 })
367 }
368 }
369
370 func TestValidateIAMAuditConfig(t *testing.T) {
371 tests := []struct {
372 name string
373 auditConfig *v1beta1.IAMAuditConfig
374 refResourceRCs []*v1alpha1.ResourceConfig
375 expectedAllowedValue bool
376 }{
377 {
378 name: "IAMAuditConfig with reference that doesn't support audit configs",
379 auditConfig: newTestAuditConfig(),
380 refResourceRCs: newTestResourceRCs(),
381 expectedAllowedValue: false,
382 },
383 {
384 name: "IAMAuditConfig with reference that supports audit configs",
385 auditConfig: newTestAuditConfig(),
386 refResourceRCs: newTestResourceRCsThatSupportAuditConfigs(),
387 expectedAllowedValue: true,
388 },
389 }
390
391 for _, tc := range tests {
392 tc := tc
393 t.Run(tc.name, func(t *testing.T) {
394 t.Parallel()
395 response := validateIAMAuditConfig(tc.auditConfig, tc.refResourceRCs)
396 if response.Allowed != tc.expectedAllowedValue {
397 t.Fatalf("unexpected value for Allowed: got '%v', want '%v'", response.Allowed, tc.expectedAllowedValue)
398 }
399 })
400 }
401 }
402
403 func newTestPolicy() *v1beta1.IAMPolicy {
404 return &v1beta1.IAMPolicy{
405 TypeMeta: metav1.TypeMeta{
406 Kind: v1beta1.IAMPolicyGVK.Kind,
407 APIVersion: v1beta1.IAMPolicyGVK.GroupVersion().String(),
408 },
409 Spec: v1beta1.IAMPolicySpec{
410 ResourceReference: v1beta1.ResourceReference{
411 Kind: "my-resource-kind",
412 Namespace: "my-namespace",
413 Name: "my-resource-name",
414 APIVersion: "my-api-version",
415 },
416 Bindings: []v1beta1.IAMPolicyBinding{
417 {
418 Members: []v1beta1.Member{"member"},
419 Role: "role",
420 },
421 },
422 },
423 }
424 }
425
426 func newTestPartialPolicy() *v1beta1.IAMPartialPolicy {
427 return &v1beta1.IAMPartialPolicy{
428 TypeMeta: metav1.TypeMeta{
429 Kind: v1beta1.IAMPolicyGVK.Kind,
430 APIVersion: v1beta1.IAMPolicyGVK.GroupVersion().String(),
431 },
432 Spec: v1beta1.IAMPartialPolicySpec{
433 ResourceReference: v1beta1.ResourceReference{
434 Kind: "my-resource-kind",
435 Namespace: "my-namespace",
436 Name: "my-resource-name",
437 APIVersion: "my-api-version",
438 },
439 Bindings: []v1beta1.IAMPartialPolicyBinding{
440 {
441 Members: []v1beta1.IAMPartialPolicyMember{
442 {
443 Member: "member",
444 },
445 },
446 Role: "role",
447 },
448 },
449 },
450 }
451 }
452
453 func newTestPolicyMember() *v1beta1.IAMPolicyMember {
454 return &v1beta1.IAMPolicyMember{
455 TypeMeta: metav1.TypeMeta{
456 Kind: v1beta1.IAMPolicyMemberGVK.Kind,
457 APIVersion: v1beta1.IAMPolicyMemberGVK.GroupVersion().String(),
458 },
459 Spec: v1beta1.IAMPolicyMemberSpec{
460 ResourceReference: v1beta1.ResourceReference{
461 Kind: "my-resource-kind",
462 Namespace: "my-namespace",
463 Name: "my-resource-name",
464 APIVersion: "my-api-version",
465 },
466 Member: "member",
467 Role: "role",
468 },
469 }
470 }
471
472 func newTestAuditConfig() *v1beta1.IAMAuditConfig {
473 return &v1beta1.IAMAuditConfig{
474 TypeMeta: metav1.TypeMeta{
475 Kind: v1beta1.IAMAuditConfigGVK.Kind,
476 APIVersion: v1beta1.IAMAuditConfigGVK.GroupVersion().String(),
477 },
478 Spec: v1beta1.IAMAuditConfigSpec{
479 ResourceReference: v1beta1.ResourceReference{
480 Kind: "my-resource-kind",
481 Namespace: "my-namespace",
482 Name: "my-resource-name",
483 APIVersion: "my-api-version",
484 },
485 Service: "service",
486 AuditLogConfigs: []v1beta1.AuditLogConfig{
487 {
488 LogType: "log-type",
489 ExemptedMembers: []v1beta1.Member{"member"},
490 },
491 },
492 },
493 }
494 }
495
496 func newTestHeadlessProjectPolicy() *v1beta1.IAMPolicy {
497 p := newTestPolicy()
498 p.Spec.ResourceReference = v1beta1.ResourceReference{
499 Kind: kcciamclient.ProjectKind,
500 }
501 return p
502 }
503
504 func newTestHeadlessProjectPolicyWithIAMConditions() *v1beta1.IAMPolicy {
505 p := newTestPolicyWithIAMConditions()
506 p.Spec.ResourceReference = v1beta1.ResourceReference{
507 Kind: kcciamclient.ProjectKind,
508 }
509 return p
510 }
511
512 func newTestHeadlessProjectPartialPolicy() *v1beta1.IAMPartialPolicy {
513 p := newTestPartialPolicy()
514 p.Spec.ResourceReference = v1beta1.ResourceReference{
515 Kind: kcciamclient.ProjectKind,
516 }
517 return p
518 }
519
520 func newTestHeadlessProjectPartialPolicyWithIAMConditions() *v1beta1.IAMPartialPolicy {
521 p := newTestPartialPolicyWithIAMConditions()
522 p.Spec.ResourceReference = v1beta1.ResourceReference{
523 Kind: kcciamclient.ProjectKind,
524 }
525 return p
526 }
527
528 func newTestHeadlessProjectPolicyMember() *v1beta1.IAMPolicyMember {
529 p := newTestPolicyMember()
530 p.Spec.ResourceReference = v1beta1.ResourceReference{
531 Kind: kcciamclient.ProjectKind,
532 }
533 return p
534 }
535
536 func newTestHeadlessProjectPolicyMemberWithIAMConditions() *v1beta1.IAMPolicyMember {
537 p := newTestPolicyMemberWithIAMConditions()
538 p.Spec.ResourceReference = v1beta1.ResourceReference{
539 Kind: kcciamclient.ProjectKind,
540 }
541 return p
542 }
543
544 func newTestPolicyWithIAMConditions() *v1beta1.IAMPolicy {
545 policy := newTestPolicy()
546 bindings := make([]v1beta1.IAMPolicyBinding, 0)
547 for _, binding := range policy.Spec.Bindings {
548 binding.Condition = newTestIAMCondition()
549 bindings = append(bindings, binding)
550 }
551 policy.Spec.Bindings = bindings
552 return policy
553 }
554
555 func newTestPartialPolicyWithIAMConditions() *v1beta1.IAMPartialPolicy {
556 pPolicy := newTestPartialPolicy()
557 bindings := make([]v1beta1.IAMPartialPolicyBinding, 0)
558 for _, binding := range pPolicy.Spec.Bindings {
559 binding.Condition = newTestIAMCondition()
560 bindings = append(bindings, binding)
561 }
562 pPolicy.Spec.Bindings = bindings
563 return pPolicy
564 }
565
566 func newTestPolicyMemberWithIAMConditions() *v1beta1.IAMPolicyMember {
567 policyMember := newTestPolicyMember()
568 policyMember.Spec.Condition = newTestIAMCondition()
569 return policyMember
570 }
571
572 func newTestIAMCondition() *v1beta1.IAMCondition {
573 return &v1beta1.IAMCondition{
574 Title: "test-iam-condition",
575 Description: "Test IAM Condition",
576 Expression: "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
577 }
578 }
579
580 func newTestPolicyWithAuditConfigs() *v1beta1.IAMPolicy {
581 policy := newTestPolicy()
582 policy.Spec.AuditConfigs = []v1beta1.IAMPolicyAuditConfig{
583 {
584 Service: "service",
585 AuditLogConfigs: []v1beta1.AuditLogConfig{
586 {
587 LogType: "log-type",
588 ExemptedMembers: []v1beta1.Member{"member"},
589 },
590 },
591 },
592 }
593 return policy
594 }
595
596 func newTestHeadlessProjectPolicyWithAuditConfigs() *v1beta1.IAMPolicy {
597 p := newTestPolicyWithAuditConfigs()
598 p.Spec.ResourceReference = v1beta1.ResourceReference{
599 Kind: kcciamclient.ProjectKind,
600 }
601 return p
602 }
603
604 func newTestExternalOnlyRefPolicy() *v1beta1.IAMPolicy {
605 p := newTestPolicy()
606 resourceRef := v1beta1.ResourceReference{}
607 resourceRef.SetGroupVersionKind(schema.GroupVersionKind{
608 Group: "resourcemanager.cnrm.cloud.google.com",
609 Version: "v1beta1",
610 Kind: "Organization",
611 })
612 p.Spec.ResourceReference = resourceRef
613 return p
614 }
615
616 func newTestExternalOnlyRefPartialPolicy() *v1beta1.IAMPartialPolicy {
617 p := newTestPartialPolicy()
618 resourceRef := v1beta1.ResourceReference{}
619 resourceRef.SetGroupVersionKind(schema.GroupVersionKind{
620 Group: "resourcemanager.cnrm.cloud.google.com",
621 Version: "v1beta1",
622 Kind: "Organization",
623 })
624 p.Spec.ResourceReference = resourceRef
625 return p
626 }
627
628 func newTestExternalOnlyRefPolicyMember() *v1beta1.IAMPolicyMember {
629 policyMember := newTestPolicyMember()
630 resourceRef := v1beta1.ResourceReference{}
631 resourceRef.SetGroupVersionKind(schema.GroupVersionKind{
632 Group: "resourcemanager.cnrm.cloud.google.com",
633 Version: "v1beta1",
634 Kind: "Organization",
635 })
636 policyMember.Spec.ResourceReference = resourceRef
637 return policyMember
638 }
639
640 func newTestResourceRCs() []*v1alpha1.ResourceConfig {
641 return []*v1alpha1.ResourceConfig{
642 &v1alpha1.ResourceConfig{
643 Name: "google_resource_type",
644 Kind: "ResourceType",
645 IAMConfig: v1alpha1.IAMConfig{
646 PolicyName: "google_resource_type_iam_policy",
647 PolicyMemberName: "google_resource_type_iam_policy_member",
648 ReferenceField: v1alpha1.IAMReferenceField{
649 Name: "name",
650 Type: v1alpha1.IAMReferenceTypeName,
651 },
652 },
653 },
654 }
655 }
656
657 func newTestResourceRCsThatSupportConditions() []*v1alpha1.ResourceConfig {
658 rcs := newTestResourceRCs()
659 for _, rc := range rcs {
660 rc.IAMConfig.SupportsConditions = true
661 }
662 return rcs
663 }
664
665 func newTestResourceRCsThatSupportAuditConfigs() []*v1alpha1.ResourceConfig {
666 rcs := newTestResourceRCs()
667 for _, rc := range rcs {
668 rc.IAMConfig.AuditConfigName = "google_resource_type_iam_audit_config"
669 }
670 return rcs
671 }
672
View as plain text