From 74ce8bcf6b6692cf1c9e71f201b80d79eb984f35 Mon Sep 17 00:00:00 2001 From: nehalk-google <146125981+nehalk-tf@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:26:22 +0530 Subject: [PATCH] Add `parameters` to `google_org_policy_policy` (#12008) --- mmv1/products/orgpolicy/Policy.yaml | 17 +++ ...g_policy_policy_parameters_enforce.tf.tmpl | 18 +++ .../resource_org_policy_policy_test.go | 103 ++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 mmv1/templates/terraform/examples/org_policy_policy_parameters_enforce.tf.tmpl diff --git a/mmv1/products/orgpolicy/Policy.yaml b/mmv1/products/orgpolicy/Policy.yaml index 6a5260d3efa6..05abe2dff0b2 100644 --- a/mmv1/products/orgpolicy/Policy.yaml +++ b/mmv1/products/orgpolicy/Policy.yaml @@ -54,6 +54,9 @@ examples: - name: 'org_policy_policy_dry_run_spec' primary_resource_id: 'primary' exclude_test: true + - name: 'org_policy_policy_parameters_enforce' + primary_resource_id: 'primary' + exclude_test: true parameters: - name: 'parent' type: String @@ -121,6 +124,13 @@ properties: send_empty_value: true custom_flatten: 'templates/terraform/custom_flatten/enum_bool.go.tmpl' custom_expand: 'templates/terraform/custom_expand/enum_bool.go.tmpl' + - name: 'parameters' + description: 'Optional. Required for Managed Constraints if parameters defined in constraints. Pass parameter values when policy enforcement is enabled. Ensure that parameter value types match those defined in the constraint definition. For example: { \"allowedLocations\" : [\"us-east1\", \"us-west1\"], \"allowAll\" : true }' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.tmpl' + custom_expand: 'templates/terraform/custom_expand/json_schema.tmpl' + state_func: 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s }' + validation: + function: 'validation.StringIsJSON' - name: 'condition' type: NestedObject description: 'A condition which determines whether this rule is used in the evaluation of the policy. When set, the `expression` field in the `Expr'' must include from 1 to 10 subexpressions, joined by the "||" or "&&" operators. Each subexpression must be of the form "resource.matchTag(''/tag_key_short_name, ''tag_value_short_name'')". or "resource.matchTagId(''tagKeys/key_id'', ''tagValues/value_id'')". where key_name and value_name are the resource names for Label Keys and Values. These names are available from the Tag Manager Service. An example expression is: "resource.matchTag(''123456789/environment, ''prod'')". or "resource.matchTagId(''tagKeys/123'', ''tagValues/456'')".' @@ -197,6 +207,13 @@ properties: send_empty_value: true custom_flatten: 'templates/terraform/custom_flatten/enum_bool.go.tmpl' custom_expand: 'templates/terraform/custom_expand/enum_bool.go.tmpl' + - name: 'parameters' + description: 'Optional. Required for Managed Constraints if parameters defined in constraints. Pass parameter values when policy enforcement is enabled. Ensure that parameter value types match those defined in the constraint definition. For example: { \"allowedLocations\" : [\"us-east1\", \"us-west1\"], \"allowAll\" : true }' + custom_flatten: 'templates/terraform/custom_flatten/json_schema.tmpl' + custom_expand: 'templates/terraform/custom_expand/json_schema.tmpl' + state_func: 'func(v interface{}) string { s, _ := structure.NormalizeJsonString(v); return s }' + validation: + function: 'validation.StringIsJSON' - name: 'condition' type: NestedObject description: 'A condition which determines whether this rule is used in the evaluation of the policy. When set, the `expression` field in the `Expr'' must include from 1 to 10 subexpressions, joined by the "||" or "&&" operators. Each subexpression must be of the form "resource.matchTag(''/tag_key_short_name, ''tag_value_short_name'')". or "resource.matchTagId(''tagKeys/key_id'', ''tagValues/value_id'')". where key_name and value_name are the resource names for Label Keys and Values. These names are available from the Tag Manager Service. An example expression is: "resource.matchTag(''123456789/environment, ''prod'')". or "resource.matchTagId(''tagKeys/123'', ''tagValues/456'')".' diff --git a/mmv1/templates/terraform/examples/org_policy_policy_parameters_enforce.tf.tmpl b/mmv1/templates/terraform/examples/org_policy_policy_parameters_enforce.tf.tmpl new file mode 100644 index 000000000000..73ef6088e186 --- /dev/null +++ b/mmv1/templates/terraform/examples/org_policy_policy_parameters_enforce.tf.tmpl @@ -0,0 +1,18 @@ +resource "google_org_policy_policy" "primary" { + name = "projects/${google_project.basic.name}/policies/compute.managed.restrictDiskCreation" + parent = "projects/${google_project.basic.name}" + + spec { + rules { + enforce = "TRUE" + parameters = jsonencode({"isSizeLimitCheck" : true, "allowedDiskTypes" : ["pd-ssd", "pd-standard"]}) + } + } +} + +resource "google_project" "basic" { + project_id = "id" + name = "id" + org_id = "123456789" + deletion_policy = "DELETE" +} diff --git a/mmv1/third_party/terraform/services/orgpolicy/resource_org_policy_policy_test.go b/mmv1/third_party/terraform/services/orgpolicy/resource_org_policy_policy_test.go index f4cb03f24fde..3d44bbb3fc7c 100644 --- a/mmv1/third_party/terraform/services/orgpolicy/resource_org_policy_policy_test.go +++ b/mmv1/third_party/terraform/services/orgpolicy/resource_org_policy_policy_test.go @@ -458,3 +458,106 @@ func testAccCheckOrgPolicyPolicyDestroyProducer(t *testing.T) func(s *terraform. return nil } } +func TestAccOrgPolicyPolicy_EnforceParameterizedMCPolicy(t *testing.T) { + // Skip this test as no constraints yet launched in production, verified functionality with manual testing. + t.Skip() + t.Parallel() + + context := map[string]interface{}{ + "org_id": envvar.GetTestOrgFromEnv(t), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckOrgPolicyPolicyDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccOrgPolicyPolicy_EnforceParameterizedMCPolicy(context), + }, + { + ResourceName: "google_org_policy_policy.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "spec.0.rules.0.condition.0.expression"}, + }, + }, + }) +} +func testAccOrgPolicyPolicy_EnforceParameterizedMCPolicy(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_org_policy_policy" "primary" { + name = "projects/${google_project.basic.name}/policies/essentialcontacts.managed.allowedContactDomains" + parent = "projects/${google_project.basic.name}" + + spec { + rules { + enforce = "TRUE" + parameters = "{\"allowedDomains\": [\"@google.com\"]}" + } + } +} + +resource "google_project" "basic" { + project_id = "tf-test-id%{random_suffix}" + name = "tf-test-id%{random_suffix}" + org_id = "%{org_id}" + deletion_policy = "DELETE" +} + + +`, context) +} + +func TestAccOrgPolicyPolicy_EnforceParameterizedMCDryRunPolicy(t *testing.T) { + // Skip this test as no constraints yet launched in production, verified functionality with manual testing. + t.Skip() + t.Parallel() + + context := map[string]interface{}{ + "org_id": envvar.GetTestOrgFromEnv(t), + "random_suffix": acctest.RandString(t, 10), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckOrgPolicyPolicyDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccOrgPolicyPolicy_EnforceParameterizedMCDryRunPolicy(context), + }, + { + ResourceName: "google_org_policy_policy.primary", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"name", "spec.0.rules.0.condition.0.expression"}, + }, + }, + }) +} +func testAccOrgPolicyPolicy_EnforceParameterizedMCDryRunPolicy(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_org_policy_policy" "primary" { + name = "projects/${google_project.basic.name}/policies/essentialcontacts.managed.allowedContactDomains" + parent = "projects/${google_project.basic.name}" + + dry_run_spec { + rules { + enforce = "TRUE" + parameters = "{\"allowedDomains\": [\"@google.com\"]}" + } + } +} + +resource "google_project" "basic" { + project_id = "tf-test-id%{random_suffix}" + name = "tf-test-id%{random_suffix}" + org_id = "%{org_id}" + deletion_policy = "DELETE" +} + + +`, context) +}