diff --git a/modules/folder/organization-policies.tf b/modules/folder/organization-policies.tf index 7ad26f04..2486c1bb 100644 --- a/modules/folder/organization-policies.tf +++ b/modules/folder/organization-policies.tf @@ -100,7 +100,7 @@ resource "google_org_policy_policy" "default" { title = rule.value.condition.title } dynamic "values" { - for_each = rule.value.has_values ? [1] : [0] + for_each = rule.value.has_values ? [1] : [] content { allowed_values = try(rule.value.allow.values, null) denied_values = try(rule.value.deny.values, null) diff --git a/modules/organization/organization-policies.tf b/modules/organization/organization-policies.tf index 0d82c6ba..941b491b 100644 --- a/modules/organization/organization-policies.tf +++ b/modules/organization/organization-policies.tf @@ -1,4 +1,4 @@ -s/** +/** * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -59,8 +59,8 @@ locals { resource "google_org_policy_policy" "default" { for_each = local.org_policies - name = "${local.organization_id}/policies/${each.key}" - parent = "${local.organiza}" + name = "${var.organization_id}/policies/${each.key}" + parent = var.organization_id spec { inherit_from_parent = each.value.inherit_from_parent @@ -101,7 +101,7 @@ resource "google_org_policy_policy" "default" { title = rule.value.condition.title } dynamic "values" { - for_each = rule.value.has_values ? [1] : [0] + for_each = rule.value.has_values ? [1] : [] content { allowed_values = try(rule.value.allow.values, null) denied_values = try(rule.value.deny.values, null) diff --git a/modules/organization/outputs.tf b/modules/organization/outputs.tf index 1679a1d7..198b3c8d 100644 --- a/modules/organization/outputs.tf +++ b/modules/organization/outputs.tf @@ -52,8 +52,7 @@ output "organization_id" { google_organization_iam_custom_role.roles, google_organization_iam_member.additive, google_organization_iam_policy.authoritative, - google_organization_policy.boolean, - google_organization_policy.list, + google_org_policy_policy.default, google_tags_tag_key.default, google_tags_tag_key_iam_binding.default, google_tags_tag_value.default, diff --git a/modules/project/organization-policies.tf b/modules/project/organization-policies.tf index bdadbec5..ae4a8501 100644 --- a/modules/project/organization-policies.tf +++ b/modules/project/organization-policies.tf @@ -82,7 +82,7 @@ resource "google_org_policy_policy" "default" { title = rule.value.condition.title } dynamic "values" { - for_each = rule.value.has_values ? [1] : [0] + for_each = rule.value.has_values ? [1] : [] content { allowed_values = try(rule.value.allow.values, null) denied_values = try(rule.value.deny.values, null) diff --git a/tests/modules/folder/fixture/main.tf b/tests/modules/folder/fixture/main.tf index 2fa1b4fd..8290f82e 100644 --- a/tests/modules/folder/fixture/main.tf +++ b/tests/modules/folder/fixture/main.tf @@ -22,10 +22,9 @@ module "test" { iam = var.iam iam_additive = var.iam_additive iam_additive_members = var.iam_additive_members - policy_boolean = var.policy_boolean - policy_list = var.policy_list firewall_policies = var.firewall_policies firewall_policy_association = var.firewall_policy_association logging_sinks = var.logging_sinks logging_exclusions = var.logging_exclusions + org_policies = var.org_policies } diff --git a/tests/modules/folder/fixture/variables.tf b/tests/modules/folder/fixture/variables.tf index da676deb..7c03e056 100644 --- a/tests/modules/folder/fixture/variables.tf +++ b/tests/modules/folder/fixture/variables.tf @@ -34,16 +34,6 @@ variable "iam_additive_members" { default = {} } -variable "policy_boolean" { - type = any - default = {} -} - -variable "policy_list" { - type = any - default = {} -} - variable "firewall_policies" { type = any default = {} @@ -63,3 +53,8 @@ variable "logging_exclusions" { type = any default = {} } + +variable "org_policies" { + type = any + default = {} +} diff --git a/tests/modules/folder/test_plan_org_policies.py b/tests/modules/folder/test_plan_org_policies.py index b7ae96c2..05b8ea26 100644 --- a/tests/modules/folder/test_plan_org_policies.py +++ b/tests/modules/folder/test_plan_org_policies.py @@ -12,56 +12,214 @@ # See the License for the specific language governing permissions and # limitations under the License. -def test_sink(plan_runner): - "Test folder-level sink." - policy_boolean = '{policy-a = true, policy-b = false, policy-c = null}' - _, resources = plan_runner(policy_boolean=policy_boolean) +def test_policy_boolean(plan_runner): + "Test boolean org policy." + policies = '''{ + "iam.disableServiceAccountKeyCreation" = { + enforce = true + } + "iam.disableServiceAccountKeyUpload" = { + enforce = false + rules = [ + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/1234\\", \\"tagValues/1234\\")" + title = "condition" + description = "test condition" + location = "xxx" + } + enforce = true + } + ] + } + }''' + _, resources = plan_runner(org_policies=policies) + assert len(resources) == 3 + + policies = [r for r in resources if r['type'] == 'google_org_policy_policy'] + from icecream import ic + ic(policies) + assert len(policies) == 2 + + p1 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.disableServiceAccountKeyCreation' + ][0] + + assert p1['inherit_from_parent'] is None + assert p1['reset'] is None + assert p1['rules'] == [{ + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': 'TRUE', + 'values': [] + }] + + p2 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.disableServiceAccountKeyUpload' + ][0] + + assert p2['inherit_from_parent'] is None + assert p2['reset'] is None + assert len(p2['rules']) == 2 + assert p2['rules'][0] == { + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': 'FALSE', + 'values': [] + } + assert p2['rules'][1] == { + 'allow_all': None, + 'condition': [{ + 'description': 'test condition', + 'expression': 'resource.matchTagId("tagKeys/1234", "tagValues/1234")', + 'location': 'xxx', + 'title': 'condition' + }], + 'deny_all': None, + 'enforce': 'TRUE', + 'values': [] + } + + +def test_policy_list(plan_runner): + "Test list org policy." + policies = '''{ + "compute.vmExternalIpAccess" = { + deny = { all = true } + } + "iam.allowedPolicyMemberDomains" = { + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + } + "compute.restrictLoadBalancerCreationForTypes" = { + deny = { values = ["in:EXTERNAL"] } + rules = [ + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/1234\\", \\"tagValues/1234\\")" + title = "condition" + description = "test condition" + location = "xxx" + } + allow = { + values = ["EXTERNAL_1"] + } + }, + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/12345\\", \\"tagValues/12345\\")" + title = "condition2" + description = "test condition2" + location = "xxx" + } + allow = { + all = true + } + } + ] + } + }''' + _, resources = plan_runner(org_policies=policies) assert len(resources) == 4 - resources = [r for r in resources if r['type'] - == 'google_folder_organization_policy'] - assert sorted([r['index'] for r in resources]) == [ - 'policy-a', - 'policy-b', - 'policy-c', - ] - policy_values = [] - for resource in resources: - for policy in ('boolean_policy', 'restore_policy'): - value = resource['values'][policy] - if value: - policy_values.append((resource['index'], policy,) + value[0].popitem()) - assert sorted(policy_values) == [ - ('policy-a', 'boolean_policy', 'enforced', True), - ('policy-b', 'boolean_policy', 'enforced', False), - ('policy-c', 'restore_policy', 'default', True), - ] + policies = [r for r in resources if r['type'] == 'google_org_policy_policy'] + assert len(policies) == 3 -def test_exclussions(plan_runner): - "Test folder-level logging exclusions." - policy_list = ( - '{' - 'policy-a = {inherit_from_parent = true, suggested_value = null, status = true, values = []}, ' - 'policy-b = {inherit_from_parent = null, suggested_value = "foo", status = false, values = ["bar"]}, ' - 'policy-c = {inherit_from_parent = null, suggested_value = true, status = null, values = null}' - '}' - ) - _, resources = plan_runner(policy_list=policy_list) - assert len(resources) == 4 - resources = [r for r in resources if r['type'] - == 'google_folder_organization_policy'] - assert sorted([r['index'] for r in resources]) == [ - 'policy-a', - 'policy-b', - 'policy-c', - ] - values = [r['values'] for r in resources] - assert [r['constraint'] for r in values] == [ - 'policy-a', 'policy-b', 'policy-c' - ] - assert values[0]['list_policy'][0]['allow'] == [ - {'all': True, 'values': None}] - assert values[1]['list_policy'][0]['deny'] == [ - {'all': False, 'values': ["bar"]}] - assert values[2]['restore_policy'] == [{'default': True}] + p1 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'compute.vmExternalIpAccess' + ][0] + assert p1['inherit_from_parent'] is None + assert p1['reset'] is None + assert p1['rules'] == [{ + 'allow_all': None, + 'condition': [], + 'deny_all': 'TRUE', + 'enforce': None, + 'values': [] + }] + + p2 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.allowedPolicyMemberDomains' + ][0] + assert p2['inherit_from_parent'] is None + assert p2['reset'] is None + assert p2['rules'] == [{ + 'allow_all': + None, + 'condition': [], + 'deny_all': + None, + 'enforce': + None, + 'values': [{ + 'allowed_values': [ + 'C0xxxxxxx', + 'C0yyyyyyy', + ], + 'denied_values': None + }] + }] + + p3 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'compute.restrictLoadBalancerCreationForTypes' + ][0] + assert p3['inherit_from_parent'] is None + assert p3['reset'] is None + assert len(p3['rules']) == 3 + assert p3['rules'][0] == { + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': None, + 'values': [{ + 'allowed_values': None, + 'denied_values': ['in:EXTERNAL'] + }] + } + + assert p3['rules'][1] == { + 'allow_all': None, + 'condition': [{ + 'description': 'test condition', + 'expression': 'resource.matchTagId("tagKeys/1234", "tagValues/1234")', + 'location': 'xxx', + 'title': 'condition' + }], + 'deny_all': None, + 'enforce': None, + 'values': [{ + 'allowed_values': ['EXTERNAL_1'], + 'denied_values': None + }] + } + + assert p3['rules'][2] == { + 'allow_all': 'TRUE', + 'condition': [{ + 'description': + 'test condition2', + 'expression': + 'resource.matchTagId("tagKeys/12345", "tagValues/12345")', + 'location': + 'xxx', + 'title': + 'condition2' + }], + 'deny_all': None, + 'enforce': None, + 'values': [] + } diff --git a/tests/modules/organization/fixture/main.tf b/tests/modules/organization/fixture/main.tf index 04ae4adf..13f8e335 100644 --- a/tests/modules/organization/fixture/main.tf +++ b/tests/modules/organization/fixture/main.tf @@ -28,8 +28,7 @@ module "test" { iam_audit_config = var.iam_audit_config logging_sinks = var.logging_sinks logging_exclusions = var.logging_exclusions - policy_boolean = var.policy_boolean - policy_list = var.policy_list + org_policies = var.org_policies tag_bindings = var.tag_bindings tags = var.tags } diff --git a/tests/modules/organization/fixture/variables.tf b/tests/modules/organization/fixture/variables.tf index 1d7ca88d..f56e51dc 100644 --- a/tests/modules/organization/fixture/variables.tf +++ b/tests/modules/organization/fixture/variables.tf @@ -44,16 +44,6 @@ variable "iam_audit_config" { default = {} } -variable "policy_boolean" { - type = any - default = {} -} - -variable "policy_list" { - type = any - default = {} -} - variable "firewall_policies" { type = any default = {} @@ -79,6 +69,11 @@ variable "logging_exclusions" { default = {} } +variable "org_policies" { + type = any + default = {} +} + variable "tag_bindings" { type = any default = null diff --git a/tests/modules/organization/test_plan.py b/tests/modules/organization/test_plan.py index a40758a2..37860ab6 100644 --- a/tests/modules/organization/test_plan.py +++ b/tests/modules/organization/test_plan.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. + def test_audit_config(plan_runner): "Test audit config." iam_audit_config = '{allServices={DATA_READ=[], DATA_WRITE=["user:me@example.org"]}}' _, resources = plan_runner(iam_audit_config=iam_audit_config) assert len(resources) == 1 - log_types = set(r['log_type'] - for r in resources[0]['values']['audit_log_config']) + log_types = set( + r['log_type'] for r in resources[0]['values']['audit_log_config']) assert log_types == set(['DATA_READ', 'DATA_WRITE']) @@ -28,21 +29,21 @@ def test_iam(plan_runner): '{' '"owners@example.org" = ["roles/owner", "roles/resourcemanager.folderAdmin"],' '"viewers@example.org" = ["roles/viewer"]' - '}' - ) - iam = ( - '{' - '"roles/owner" = ["user:one@example.org", "user:two@example.org"],' - '"roles/browser" = ["domain:example.org"]' - '}' - ) + '}') + iam = ('{' + '"roles/owner" = ["user:one@example.org", "user:two@example.org"],' + '"roles/browser" = ["domain:example.org"]' + '}') _, resources = plan_runner(group_iam=group_iam, iam=iam) roles = sorted([(r['values']['role'], sorted(r['values']['members'])) - for r in resources if r['type'] == 'google_organization_iam_binding']) + for r in resources + if r['type'] == 'google_organization_iam_binding']) assert roles == [ ('roles/browser', ['domain:example.org']), - ('roles/owner', ['group:owners@example.org', 'user:one@example.org', - 'user:two@example.org']), + ('roles/owner', [ + 'group:owners@example.org', 'user:one@example.org', + 'user:two@example.org' + ]), ('roles/resourcemanager.folderAdmin', ['group:owners@example.org']), ('roles/viewer', ['group:viewers@example.org']), ] @@ -50,55 +51,12 @@ def test_iam(plan_runner): def test_iam_additive_members(plan_runner): "Test IAM additive members." - iam = ( - '{"user:one@example.org" = ["roles/owner"],' - '"user:two@example.org" = ["roles/owner", "roles/editor"]}' - ) + iam = ('{"user:one@example.org" = ["roles/owner"],' + '"user:two@example.org" = ["roles/owner", "roles/editor"]}') _, resources = plan_runner(iam_additive_members=iam) roles = set((r['values']['role'], r['values']['member']) - for r in resources if r['type'] == 'google_organization_iam_member') - assert roles == set([ - ('roles/owner', 'user:one@example.org'), - ('roles/owner', 'user:two@example.org'), - ('roles/editor', 'user:two@example.org') - ]) - - -def test_policy_boolean(plan_runner): - "Test boolean org policy." - policy_boolean = '{policy-a = true, policy-b = false, policy-c = null}' - _, resources = plan_runner(policy_boolean=policy_boolean) - assert len(resources) == 3 - constraints = set(r['values']['constraint'] for r in resources) - assert set(constraints) == set(['policy-a', 'policy-b', 'policy-c']) - policies = [] - for resource in resources: - for policy in ('boolean_policy', 'restore_policy'): - value = resource['values'][policy] - if value: - policies.append((policy,) + value[0].popitem()) - assert set(policies) == set([ - ('boolean_policy', 'enforced', True), - ('boolean_policy', 'enforced', False), - ('restore_policy', 'default', True)]) - - -def test_policy_list(plan_runner): - "Test list org policy." - policy_list = ( - '{' - 'policy-a = {inherit_from_parent = true, suggested_value = null, status = true, values = []}, ' - 'policy-b = {inherit_from_parent = null, suggested_value = "foo", status = false, values = ["bar"]}, ' - 'policy-c = {inherit_from_parent = null, suggested_value = true, status = null, values = null}' - '}' - ) - _, resources = plan_runner(policy_list=policy_list) - assert len(resources) == 3 - values = [r['values'] for r in resources] - assert [r['constraint'] - for r in values] == ['policy-a', 'policy-b', 'policy-c'] - assert values[0]['list_policy'][0]['allow'] == [ - {'all': True, 'values': None}] - assert values[1]['list_policy'][0]['deny'] == [ - {'all': False, 'values': ["bar"]}] - assert values[2]['restore_policy'] == [{'default': True}] + for r in resources + if r['type'] == 'google_organization_iam_member') + assert roles == set([('roles/owner', 'user:one@example.org'), + ('roles/owner', 'user:two@example.org'), + ('roles/editor', 'user:two@example.org')]) diff --git a/tests/modules/organization/test_plan_org_policies.py b/tests/modules/organization/test_plan_org_policies.py new file mode 100644 index 00000000..35aa1122 --- /dev/null +++ b/tests/modules/organization/test_plan_org_policies.py @@ -0,0 +1,228 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def test_policy_boolean(plan_runner): + "Test boolean org policy." + policies = '''{ + "iam.disableServiceAccountKeyCreation" = { + enforce = true + } + "iam.disableServiceAccountKeyUpload" = { + enforce = false + rules = [ + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/1234\\", \\"tagValues/1234\\")" + title = "condition" + description = "test condition" + location = "xxx" + } + enforce = true + } + ] + } + }''' + _, resources = plan_runner(org_policies=policies) + assert len(resources) == 2 + + policies = [r for r in resources if r['type'] == 'google_org_policy_policy'] + assert len(policies) == 2 + from icecream import ic + assert all( + x['values']['parent'] == 'organizations/1234567890' for x in policies) + + p1 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.disableServiceAccountKeyCreation' + ][0] + + assert p1['inherit_from_parent'] is None + assert p1['reset'] is None + assert p1['rules'] == [{ + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': 'TRUE', + 'values': [] + }] + + p2 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.disableServiceAccountKeyUpload' + ][0] + + assert p2['inherit_from_parent'] is None + assert p2['reset'] is None + assert len(p2['rules']) == 2 + assert p2['rules'][0] == { + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': 'FALSE', + 'values': [] + } + assert p2['rules'][1] == { + 'allow_all': None, + 'condition': [{ + 'description': 'test condition', + 'expression': 'resource.matchTagId("tagKeys/1234", "tagValues/1234")', + 'location': 'xxx', + 'title': 'condition' + }], + 'deny_all': None, + 'enforce': 'TRUE', + 'values': [] + } + + +def test_policy_list(plan_runner): + "Test list org policy." + policies = '''{ + "compute.vmExternalIpAccess" = { + deny = { all = true } + } + "iam.allowedPolicyMemberDomains" = { + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + } + "compute.restrictLoadBalancerCreationForTypes" = { + deny = { values = ["in:EXTERNAL"] } + rules = [ + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/1234\\", \\"tagValues/1234\\")" + title = "condition" + description = "test condition" + location = "xxx" + } + allow = { + values = ["EXTERNAL_1"] + } + }, + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/12345\\", \\"tagValues/12345\\")" + title = "condition2" + description = "test condition2" + location = "xxx" + } + allow = { + all = true + } + } + ] + } + }''' + _, resources = plan_runner(org_policies=policies) + assert len(resources) == 3 + + policies = [r for r in resources if r['type'] == 'google_org_policy_policy'] + assert len(policies) == 3 + assert all( + x['values']['parent'] == 'organizations/1234567890' for x in policies) + + p1 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'compute.vmExternalIpAccess' + ][0] + assert p1['inherit_from_parent'] is None + assert p1['reset'] is None + assert p1['rules'] == [{ + 'allow_all': None, + 'condition': [], + 'deny_all': 'TRUE', + 'enforce': None, + 'values': [] + }] + + p2 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.allowedPolicyMemberDomains' + ][0] + assert p2['inherit_from_parent'] is None + assert p2['reset'] is None + assert p2['rules'] == [{ + 'allow_all': + None, + 'condition': [], + 'deny_all': + None, + 'enforce': + None, + 'values': [{ + 'allowed_values': [ + 'C0xxxxxxx', + 'C0yyyyyyy', + ], + 'denied_values': None + }] + }] + + p3 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'compute.restrictLoadBalancerCreationForTypes' + ][0] + assert p3['inherit_from_parent'] is None + assert p3['reset'] is None + assert len(p3['rules']) == 3 + assert p3['rules'][0] == { + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': None, + 'values': [{ + 'allowed_values': None, + 'denied_values': ['in:EXTERNAL'] + }] + } + + assert p3['rules'][1] == { + 'allow_all': None, + 'condition': [{ + 'description': 'test condition', + 'expression': 'resource.matchTagId("tagKeys/1234", "tagValues/1234")', + 'location': 'xxx', + 'title': 'condition' + }], + 'deny_all': None, + 'enforce': None, + 'values': [{ + 'allowed_values': ['EXTERNAL_1'], + 'denied_values': None + }] + } + + assert p3['rules'][2] == { + 'allow_all': 'TRUE', + 'condition': [{ + 'description': + 'test condition2', + 'expression': + 'resource.matchTagId("tagKeys/12345", "tagValues/12345")', + 'location': + 'xxx', + 'title': + 'condition2' + }], + 'deny_all': None, + 'enforce': None, + 'values': [] + } diff --git a/tests/modules/project/fixture/main.tf b/tests/modules/project/fixture/main.tf index a9867e5d..4c7441ac 100644 --- a/tests/modules/project/fixture/main.tf +++ b/tests/modules/project/fixture/main.tf @@ -25,12 +25,11 @@ module "test" { iam_additive_members = var.iam_additive_members labels = var.labels lien_reason = var.lien_reason + org_policies = var.org_policies oslogin = var.oslogin oslogin_admins = var.oslogin_admins oslogin_users = var.oslogin_users parent = var.parent - policy_boolean = var.policy_boolean - policy_list = var.policy_list prefix = var.prefix service_encryption_key_ids = var.service_encryption_key_ids services = var.services @@ -63,4 +62,3 @@ module "test-svpc-service" { } } } - diff --git a/tests/modules/project/fixture/variables.tf b/tests/modules/project/fixture/variables.tf index 2a4d95d1..236cb69f 100644 --- a/tests/modules/project/fixture/variables.tf +++ b/tests/modules/project/fixture/variables.tf @@ -64,6 +64,11 @@ variable "lien_reason" { default = "" } +variable "org_policies" { + type = any + default = {} +} + variable "oslogin" { type = bool default = false @@ -84,21 +89,6 @@ variable "parent" { default = null } -variable "policy_boolean" { - type = map(bool) - default = {} -} - -variable "policy_list" { - type = map(object({ - inherit_from_parent = bool - suggested_value = string - status = bool - values = list(string) - })) - default = {} -} - variable "prefix" { type = string default = null diff --git a/tests/modules/project/test_plan_org_policies.py b/tests/modules/project/test_plan_org_policies.py index 645db0df..a9c4df68 100644 --- a/tests/modules/project/test_plan_org_policies.py +++ b/tests/modules/project/test_plan_org_policies.py @@ -12,47 +12,214 @@ # See the License for the specific language governing permissions and # limitations under the License. + def test_policy_boolean(plan_runner): "Test boolean org policy." - policy_boolean = '{policy-a = true, policy-b = false, policy-c = null}' - _, resources = plan_runner(policy_boolean=policy_boolean) - assert len(resources) == 7 - resources = [r for r in resources if r['type'] - == 'google_project_organization_policy'] - assert sorted([r['index'] for r in resources]) == [ - 'policy-a', 'policy-b', 'policy-c' - ] - policy_values = [] - for resource in resources: - for policy in ('boolean_policy', 'restore_policy'): - value = resource['values'][policy] - if value: - policy_values.append((policy,) + value[0].popitem()) - assert sorted(policy_values) == [ - ('boolean_policy', 'enforced', False), - ('boolean_policy', 'enforced', True), - ('restore_policy', 'default', True) - ] + policies = '''{ + "iam.disableServiceAccountKeyCreation" = { + enforce = true + } + "iam.disableServiceAccountKeyUpload" = { + enforce = false + rules = [ + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/1234\\", \\"tagValues/1234\\")" + title = "condition" + description = "test condition" + location = "xxx" + } + enforce = true + } + ] + } + }''' + _, resources = plan_runner(org_policies=policies) + assert len(resources) == 6 + + policies = [r for r in resources if r['type'] == 'google_org_policy_policy'] + assert len(policies) == 2 + assert all(x['values']['parent'] == 'projects/my-project' for x in policies) + + p1 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.disableServiceAccountKeyCreation' + ][0] + + assert p1['inherit_from_parent'] is None + assert p1['reset'] is None + assert p1['rules'] == [{ + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': 'TRUE', + 'values': [] + }] + + p2 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.disableServiceAccountKeyUpload' + ][0] + + assert p2['inherit_from_parent'] is None + assert p2['reset'] is None + assert len(p2['rules']) == 2 + assert p2['rules'][0] == { + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': 'FALSE', + 'values': [] + } + assert p2['rules'][1] == { + 'allow_all': None, + 'condition': [{ + 'description': 'test condition', + 'expression': 'resource.matchTagId("tagKeys/1234", "tagValues/1234")', + 'location': 'xxx', + 'title': 'condition' + }], + 'deny_all': None, + 'enforce': 'TRUE', + 'values': [] + } def test_policy_list(plan_runner): "Test list org policy." - policy_list = ( - '{' - 'policy-a = {inherit_from_parent = true, suggested_value = null, status = true, values = []}, ' - 'policy-b = {inherit_from_parent = null, suggested_value = "foo", status = false, values = ["bar"]}, ' - 'policy-c = {inherit_from_parent = null, suggested_value = true, status = null, values = null}' - '}' - ) - _, resources = plan_runner(policy_list=policy_list) + policies = '''{ + "compute.vmExternalIpAccess" = { + deny = { all = true } + } + "iam.allowedPolicyMemberDomains" = { + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + } + "compute.restrictLoadBalancerCreationForTypes" = { + deny = { values = ["in:EXTERNAL"] } + rules = [ + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/1234\\", \\"tagValues/1234\\")" + title = "condition" + description = "test condition" + location = "xxx" + } + allow = { + values = ["EXTERNAL_1"] + } + }, + { + condition = { + expression = "resource.matchTagId(\\"tagKeys/12345\\", \\"tagValues/12345\\")" + title = "condition2" + description = "test condition2" + location = "xxx" + } + allow = { + all = true + } + } + ] + } + }''' + _, resources = plan_runner(org_policies=policies) assert len(resources) == 7 - values = [r['values'] for r in resources if r['type'] - == 'google_project_organization_policy'] - assert [r['constraint'] for r in values] == [ - 'policy-a', 'policy-b', 'policy-c' - ] - assert values[0]['list_policy'][0]['allow'] == [ - {'all': True, 'values': None}] - assert values[1]['list_policy'][0]['deny'] == [ - {'all': False, 'values': ["bar"]}] - assert values[2]['restore_policy'] == [{'default': True}] + + policies = [r for r in resources if r['type'] == 'google_org_policy_policy'] + assert len(policies) == 3 + assert all(x['values']['parent'] == 'projects/my-project' for x in policies) + + p1 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'compute.vmExternalIpAccess' + ][0] + assert p1['inherit_from_parent'] is None + assert p1['reset'] is None + assert p1['rules'] == [{ + 'allow_all': None, + 'condition': [], + 'deny_all': 'TRUE', + 'enforce': None, + 'values': [] + }] + + p2 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'iam.allowedPolicyMemberDomains' + ][0] + assert p2['inherit_from_parent'] is None + assert p2['reset'] is None + assert p2['rules'] == [{ + 'allow_all': + None, + 'condition': [], + 'deny_all': + None, + 'enforce': + None, + 'values': [{ + 'allowed_values': [ + 'C0xxxxxxx', + 'C0yyyyyyy', + ], + 'denied_values': None + }] + }] + + p3 = [ + r['values']['spec'][0] + for r in policies + if r['index'] == 'compute.restrictLoadBalancerCreationForTypes' + ][0] + assert p3['inherit_from_parent'] is None + assert p3['reset'] is None + assert len(p3['rules']) == 3 + assert p3['rules'][0] == { + 'allow_all': None, + 'condition': [], + 'deny_all': None, + 'enforce': None, + 'values': [{ + 'allowed_values': None, + 'denied_values': ['in:EXTERNAL'] + }] + } + + assert p3['rules'][1] == { + 'allow_all': None, + 'condition': [{ + 'description': 'test condition', + 'expression': 'resource.matchTagId("tagKeys/1234", "tagValues/1234")', + 'location': 'xxx', + 'title': 'condition' + }], + 'deny_all': None, + 'enforce': None, + 'values': [{ + 'allowed_values': ['EXTERNAL_1'], + 'denied_values': None + }] + } + + assert p3['rules'][2] == { + 'allow_all': 'TRUE', + 'condition': [{ + 'description': + 'test condition2', + 'expression': + 'resource.matchTagId("tagKeys/12345", "tagValues/12345")', + 'location': + 'xxx', + 'title': + 'condition2' + }], + 'deny_all': None, + 'enforce': None, + 'values': [] + }