@@ -26,6 +26,7 @@ import (
2626 policyclustermodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/policy/cluster"
2727 policyclustergroupmodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/policy/clustergroup"
2828 policyorganizationmodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/policy/organization"
29+ custompolicytemplateres "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/custompolicytemplate"
2930 "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy"
3031 policykindCustom "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy/kind/custom"
3132 policyoperations "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy/operations"
@@ -61,6 +62,7 @@ func testGetDefaultAcceptanceConfig(t *testing.T) *testAcceptanceConfig {
6162
6263func TestAcceptanceForCustomPolicyResource (t * testing.T ) {
6364 testConfig := testGetDefaultAcceptanceConfig (t )
65+ customPolicyTemplateResource := fmt .Sprintf ("%s.%s" , custompolicytemplateres .ResourceName , "test_custom_policy_template" )
6466
6567 t .Log ("start custom policy resource acceptance tests!" )
6668
@@ -267,9 +269,64 @@ func TestAcceptanceForCustomPolicyResource(t *testing.T) {
267269 )
268270
269271 t .Log ("Custom policy resource acceptance test complete for tmc-require-labels recipe!" )
272+
273+ // Test case for custom policy template assignment resource
274+ resource .Test (t , resource.TestCase {
275+ PreCheck : testhelper .TestPreCheck (t ),
276+ ProviderFactories : testhelper .GetTestProviderFactories (testConfig .Provider ),
277+ CheckDestroy : nil ,
278+ Steps : []resource.TestStep {
279+ {
280+ Config : testConfig .getTestCustomPolicyTemplateConfigValue (),
281+ Check : resource .ComposeTestCheckFunc (
282+ resource .TestCheckResourceAttr (customPolicyTemplateResource , "name" , "tf-custom-template-test" ),
283+ ),
284+ },
285+ {
286+ PreConfig : func () {
287+ if testConfig .ScopeHelperResources .Cluster .KubeConfigPath == "" {
288+ t .Skip ("KUBECONFIG env var is not set for cluster scoped custom policy acceptance test" )
289+ }
290+ },
291+ ResourceName : customPolicyTemplateResource ,
292+ ImportState : true ,
293+ ImportStateVerify : true ,
294+ Config : testConfig .getTestCustomPolicyConfigValue (scope .ClusterScope , policykindCustom .TMCCustomRecipe ),
295+ Check : testConfig .checkCustomPolicyResourceAttributes (scope .ClusterScope ),
296+ },
297+ {
298+ Config : testConfig .getTestCustomPolicyConfigValue (scope .ClusterGroupScope , policykindCustom .TMCCustomRecipe ),
299+ ResourceName : customPolicyTemplateResource ,
300+ ImportState : true ,
301+ ImportStateVerify : true ,
302+ Check : resource .ComposeTestCheckFunc (
303+ testConfig .checkCustomPolicyResourceAttributes (scope .ClusterGroupScope ),
304+ ),
305+ },
306+ {
307+ PreConfig : func () {
308+ if testConfig .ScopeHelperResources .OrgID == "" {
309+ t .Skip ("ORG_ID env var is not set for organization scoped custom policy acceptance test" )
310+ }
311+ },
312+ ResourceName : customPolicyTemplateResource ,
313+ ImportState : true ,
314+ ImportStateVerify : true ,
315+ Config : testConfig .getTestCustomPolicyConfigValue (scope .OrganizationScope , policykindCustom .TMCCustomRecipe ),
316+ Check : testConfig .checkCustomPolicyResourceAttributes (scope .OrganizationScope ),
317+ },
318+ },
319+ },
320+ )
321+
322+ t .Log ("Custom policy resource acceptance test complete for custom recipe!" )
270323 t .Log ("all custom policy resource acceptance tests complete!" )
271324}
272325
326+ func (testConfig * testAcceptanceConfig ) getTestCustomPolicyConfigValue (scope scope.Scope , recipe policykindCustom.Recipe ) string {
327+ return fmt .Sprintf ("%s\n %s" , testConfig .getTestCustomPolicyTemplateConfigValue (), testConfig .getTestCustomPolicyResourceBasicConfigValue (scope , recipe ))
328+ }
329+
273330func (testConfig * testAcceptanceConfig ) getTestCustomPolicyResourceBasicConfigValue (scope scope.Scope , recipe policykindCustom.Recipe ) string {
274331 helperBlock , scopeBlock := testConfig .ScopeHelperResources .GetTestPolicyResourceHelperAndScope (scope , policyoperations .ScopeMap [testConfig .CustomPolicyResource ], false )
275332 inputBlock := testConfig .getTestCustomPolicyResourceInput (recipe )
@@ -305,6 +362,85 @@ func (testConfig *testAcceptanceConfig) getTestCustomPolicyResourceBasicConfigVa
305362 ` , helperBlock , testConfig .CustomPolicyResource , testConfig .CustomPolicyResourceVar , testConfig .CustomPolicyName , scopeBlock , inputBlock )
306363}
307364
365+ func (testConfig * testAcceptanceConfig ) getTestCustomPolicyTemplateConfigValue () string {
366+ customTemplate := `
367+ resource "tanzu-mission-control_custom_policy_template" "test_custom_policy_template" {
368+ name = "tf-custom-template-test"
369+
370+ spec {
371+ object_type = "ConstraintTemplate"
372+ template_type = "OPAGatekeeper"
373+
374+ data_inventory {
375+ kind = "ConfigMap"
376+ group = "admissionregistration.k8s.io"
377+ version = "v1"
378+ }
379+
380+ data_inventory {
381+ kind = "Deployment"
382+ group = "extensions"
383+ version = "v1"
384+ }
385+
386+ template_manifest = <<YAML
387+ apiVersion: templates.gatekeeper.sh/v1beta1
388+ kind: ConstraintTemplate
389+ metadata:
390+ name: tf-custom-template-test
391+ annotations:
392+ description: Requires Pods to have readiness and/or liveness probes.
393+ spec:
394+ crd:
395+ spec:
396+ names:
397+ kind: tf-custom-template-test
398+ validation:
399+ openAPIV3Schema:
400+ properties:
401+ probes:
402+ type: array
403+ items:
404+ type: string
405+ probeTypes:
406+ type: array
407+ items:
408+ type: string
409+ targets:
410+ - target: admission.k8s.gatekeeper.sh
411+ rego: |
412+ package k8srequiredprobes
413+ probe_type_set = probe_types {
414+ probe_types := {type | type := input.parameters.probeTypes[_]}
415+ }
416+ violation[{"msg": msg}] {
417+ container := input.review.object.spec.containers[_]
418+ probe := input.parameters.probes[_]
419+ probe_is_missing(container, probe)
420+ msg := get_violation_message(container, input.review, probe)
421+ }
422+ probe_is_missing(ctr, probe) = true {
423+ not ctr[probe]
424+ }
425+ probe_is_missing(ctr, probe) = true {
426+ probe_field_empty(ctr, probe)
427+ }
428+ probe_field_empty(ctr, probe) = true {
429+ probe_fields := {field | ctr[probe][field]}
430+ diff_fields := probe_type_set - probe_fields
431+ count(diff_fields) == count(probe_type_set)
432+ }
433+ get_violation_message(container, review, probe) = msg {
434+ msg := sprintf("Container <%v> in your <%v> <%v> has no <%v>", [container.name, review.kind.kind, review.object.metadata.name, probe])
435+ }
436+ YAML
437+ }
438+ }
439+ `
440+
441+ return customTemplate
442+ }
443+
308444// getTestCustomPolicyResourceInput builds the input block for custom policy resource based a recipe.
309445func (testConfig * testAcceptanceConfig ) getTestCustomPolicyResourceInput (recipe policykindCustom.Recipe ) string {
310446 var inputBlock string
@@ -430,6 +566,33 @@ func (testConfig *testAcceptanceConfig) getTestCustomPolicyResourceInput(recipe
430566 }
431567 }
432568 }
569+ `
570+ case policykindCustom .TMCCustomRecipe :
571+ inputBlock = `
572+ input {
573+ custom {
574+ template_name = "tf-custom-template-test"
575+ audit = false
576+
577+ target_kubernetes_resources {
578+ api_groups = [
579+ "apps",
580+ ]
581+ kinds = [
582+ "Deployment"
583+ ]
584+ }
585+
586+ target_kubernetes_resources {
587+ api_groups = [
588+ "apps",
589+ ]
590+ kinds = [
591+ "StatefulSet",
592+ ]
593+ }
594+ }
595+ }
433596`
434597 case policykindCustom .UnknownRecipe :
435598 log .Printf ("[ERROR]: No valid input recipe block found: minimum one valid input recipe block is required among: %v. Please check the schema." , strings .Join (policykindCustom .RecipesAllowed [:], `, ` ))
0 commit comments