diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bb5daa091..a0f1364ae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,6 @@ repos: language: python additional_dependencies: - click - - deepdiff - ghapi - iso8601 - marko @@ -49,7 +48,6 @@ repos: entry: tools/check_boilerplate.py additional_dependencies: - click - - deepdiff - ghapi - iso8601 - marko @@ -66,7 +64,6 @@ repos: language: python additional_dependencies: - click - - deepdiff - ghapi - iso8601 - marko @@ -89,7 +86,6 @@ repos: language: python additional_dependencies: - click - - deepdiff - ghapi - iso8601 - marko @@ -105,7 +101,6 @@ repos: language: python additional_dependencies: - click - - deepdiff - ghapi - iso8601 - marko @@ -121,7 +116,6 @@ repos: language: python additional_dependencies: - click - - deepdiff - ghapi - iso8601 - marko diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a66b5c27b..5447235c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1331,7 +1331,7 @@ def test_name(plan_summary, tfvars_to_yaml, tmp_path): assert s.values[address]['project'] == 'my-project' ``` -For more examples on how to write python tests, check the tests for the [`organization`](./tests/modules/organization/test_plan_org_policies.py) module. +For more examples on how to write python tests, check the tests for the [`organization`](./tests/modules/organization/) module. ### Running tests from a temporary directory diff --git a/tests/modules/conftest.py b/tests/modules/conftest.py deleted file mode 100644 index ce707bbda..000000000 --- a/tests/modules/conftest.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 2023 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. - -import inspect -import pathlib - -import hcl2 -import pytest -import yaml - - -@pytest.fixture() -def tfvars_to_yaml(request): - - def converter(source, dest, from_var, to_var=None): - p_fixture = pathlib.Path(request.path).parent - p_source = p_fixture / source - if not p_source.exists(): - raise ValueError(f"tfvars '{source}' not found") - try: - with p_source.open() as f: - data = hcl2.load(f) - except Exception as e: - raise ValueError(f'error decoding tfvars: {e.args[0]}') - if from_var not in data: - raise ValueError(f"variable '{from_var}' not in tfvars") - if to_var is None: - data_yaml = data[from_var] - else: - data_yaml = {to_var: data[from_var]} - p_dest = pathlib.Path(dest) if not isinstance(dest, pathlib.Path) else dest - try: - with p_dest.open('w') as f: - data_yaml = yaml.dump(data_yaml, f) - except yaml.YAMLError as e: - raise ValueError(f'error encoding data to yaml: {e.args[0]}') - except (IOError, OSError) as e: - raise ValueError(f"error writing '{dest}': {e.args[0]}") - - return converter diff --git a/tests/modules/folder/common.tfvars b/tests/modules/folder/common.tfvars deleted file mode 100644 index aebc74a01..000000000 --- a/tests/modules/folder/common.tfvars +++ /dev/null @@ -1,2 +0,0 @@ -parent = "organizations/12345678" -name = "folder-a" diff --git a/tests/modules/folder/factory/policies/policies_boolean.yaml b/tests/modules/folder/factory/policies/policies_boolean.yaml new file mode 100644 index 000000000..05b5dd9f6 --- /dev/null +++ b/tests/modules/folder/factory/policies/policies_boolean.yaml @@ -0,0 +1,28 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +iam.disableServiceAccountKeyCreation: + rules: + - enforce: true +iam.disableServiceAccountKeyUpload: + rules: + - condition: + expression: resource.matchTagId(aa, bb) + title: condition + description: test condition + location: xxx + enforce: true + - enforce: false diff --git a/tests/modules/folder/factory/policies/policies_list.yaml b/tests/modules/folder/factory/policies/policies_list.yaml new file mode 100644 index 000000000..0426f3dab --- /dev/null +++ b/tests/modules/folder/factory/policies/policies_list.yaml @@ -0,0 +1,47 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +compute.vmExternalIpAccess: + rules: + - deny: + all: true +iam.allowedPolicyMemberDomains: + inherit_from_parent: true + rules: + - allow: + values: + - C0xxxxxxx + - C0yyyyyyy +compute.restrictLoadBalancerCreationForTypes: + rules: + - condition: + expression: resource.matchTagId(aa, bb) + title: condition + description: test condition + location: xxx + allow: + values: + - EXTERNAL_1 + - condition: + expression: resource.matchTagId(cc, dd) + title: condition2 + description: test condition2 + location: xxx + allow: + all: true + - deny: + values: + - in:EXTERNAL diff --git a/tests/modules/folder/org_policies_list.tfvars b/tests/modules/folder/org_policies.tfvars similarity index 63% rename from tests/modules/folder/org_policies_list.tfvars rename to tests/modules/folder/org_policies.tfvars index 2c83de47e..f35599283 100644 --- a/tests/modules/folder/org_policies_list.tfvars +++ b/tests/modules/folder/org_policies.tfvars @@ -1,8 +1,30 @@ +parent = "organizations/12345678" +name = "folder-a" org_policies = { + "iam.disableServiceAccountKeyCreation" = { + rules = [{ enforce = true }] + } + "iam.disableServiceAccountKeyUpload" = { + rules = [ + { + condition = { + expression = "resource.matchTagId(aa, bb)" + title = "condition" + description = "test condition" + location = "xxx" + } + enforce = true + }, + { + enforce = false + } + ] + } "compute.vmExternalIpAccess" = { rules = [{ deny = { all = true } }] } "iam.allowedPolicyMemberDomains" = { + inherit_from_parent = true rules = [{ allow = { values = ["C0xxxxxxx", "C0yyyyyyy"] diff --git a/tests/modules/folder/org_policies.yaml b/tests/modules/folder/org_policies.yaml new file mode 100644 index 000000000..dc913ee23 --- /dev/null +++ b/tests/modules/folder/org_policies.yaml @@ -0,0 +1,132 @@ +# Copyright 2026 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. + +values: + google_folder.folder[0]: + deletion_protection: false + display_name: folder-a + parent: organizations/12345678 + tags: null + timeouts: null + google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]: + dry_run_spec: [] + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: test condition + expression: resource.matchTagId(aa, bb) + location: xxx + title: condition + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - EXTERNAL_1 + denied_values: null + - allow_all: 'TRUE' + condition: + - description: test condition2 + expression: resource.matchTagId(cc, dd) + location: xxx + title: condition2 + deny_all: null + enforce: null + parameters: null + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: null + denied_values: + - in:EXTERNAL + timeouts: null + google_org_policy_policy.default["compute.vmExternalIpAccess"]: + dry_run_spec: [] + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + parameters: null + values: [] + timeouts: null + google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: + dry_run_spec: [] + spec: + - inherit_from_parent: true + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + parameters: null + values: + - allowed_values: + - C0xxxxxxx + - C0yyyyyyy + denied_values: null + timeouts: null + google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: + dry_run_spec: [] + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + timeouts: null + google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: + dry_run_spec: [] + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: test condition + expression: resource.matchTagId(aa, bb) + location: xxx + title: condition + deny_all: null + enforce: 'TRUE' + parameters: null + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: 'FALSE' + parameters: null + values: [] + timeouts: null + +counts: + google_folder: 1 + google_org_policy_policy: 5 + modules: 0 + resources: 6 diff --git a/tests/modules/folder/org_policies_boolean.tfvars b/tests/modules/folder/org_policies_boolean.tfvars deleted file mode 100644 index cf5047a20..000000000 --- a/tests/modules/folder/org_policies_boolean.tfvars +++ /dev/null @@ -1,21 +0,0 @@ -org_policies = { - "iam.disableServiceAccountKeyCreation" = { - rules = [{ enforce = true }] - } - "iam.disableServiceAccountKeyUpload" = { - rules = [ - { - condition = { - expression = "resource.matchTagId(aa, bb)" - title = "condition" - description = "test condition" - location = "xxx" - } - enforce = true - }, - { - enforce = false - } - ] - } -} diff --git a/tests/modules/folder/org_policies_factory.tfvars b/tests/modules/folder/org_policies_factory.tfvars new file mode 100644 index 000000000..83c7385e1 --- /dev/null +++ b/tests/modules/folder/org_policies_factory.tfvars @@ -0,0 +1,5 @@ +parent = "organizations/12345678" +name = "folder-a" +factories_config = { + org_policies = "factory/policies" +} diff --git a/tests/modules/folder/test_plan_org_policies.py b/tests/modules/folder/test_plan_org_policies.py deleted file mode 100644 index 48d4257ad..000000000 --- a/tests/modules/folder/test_plan_org_policies.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2023 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. - -import pytest - -_params = ['boolean', 'list'] - - -@pytest.mark.parametrize('policy_type', _params) -def test_policy_factory(plan_summary, tfvars_to_yaml, tmp_path, policy_type): - dest = tmp_path / 'policies.yaml' - tfvars_to_yaml(f'org_policies_{policy_type}.tfvars', dest, 'org_policies') - tfvars_plan = plan_summary( - 'modules/folder', - tf_var_files=['common.tfvars', f'org_policies_{policy_type}.tfvars']) - yaml_plan = plan_summary('modules/folder', tf_var_files=['common.tfvars'], - factories_config=f'{{org_policies="{tmp_path}"}}') - assert tfvars_plan.values == yaml_plan.values diff --git a/tests/modules/folder/tftest.yaml b/tests/modules/folder/tftest.yaml index eaad585be..0382dd35b 100644 --- a/tests/modules/folder/tftest.yaml +++ b/tests/modules/folder/tftest.yaml @@ -18,3 +18,9 @@ tests: context: iam_by_principals_additive: iam_by_principals_conditional: + org_policies: + org_policies_factory: + inventory: + - org_policies.yaml + extra_dirs: + - ../../tests/modules/folder/factory diff --git a/tests/modules/organization/factory/custom_constraints/custom_constraints.yaml b/tests/modules/organization/factory/custom_constraints/custom_constraints.yaml new file mode 100644 index 000000000..0c5b8b7dd --- /dev/null +++ b/tests/modules/organization/factory/custom_constraints/custom_constraints.yaml @@ -0,0 +1,35 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +custom.gkeEnableAutoUpgrade: + resource_types: + - container.googleapis.com/NodePool + method_types: + - CREATE + condition: resource.management.autoUpgrade == true + action_type: ALLOW + display_name: Enable node auto-upgrade + description: All node pools must have node auto-upgrade enabled. +custom.dataprocNoMoreThan10Workers: + resource_types: + - dataproc.googleapis.com/Cluster + method_types: + - CREATE + - UPDATE + condition: resource.config.workerConfig.numInstances + resource.config.secondaryWorkerConfig.numInstances > 10 + action_type: DENY + display_name: Total number of worker instances cannot be larger than 10 + description: Cluster cannot have more than 10 workers, including primary and secondary workers. diff --git a/tests/modules/organization/factory/policies/policies_boolean.yaml b/tests/modules/organization/factory/policies/policies_boolean.yaml new file mode 100644 index 000000000..05b5dd9f6 --- /dev/null +++ b/tests/modules/organization/factory/policies/policies_boolean.yaml @@ -0,0 +1,28 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +iam.disableServiceAccountKeyCreation: + rules: + - enforce: true +iam.disableServiceAccountKeyUpload: + rules: + - condition: + expression: resource.matchTagId(aa, bb) + title: condition + description: test condition + location: xxx + enforce: true + - enforce: false diff --git a/tests/modules/organization/factory/policies/policies_list.yaml b/tests/modules/organization/factory/policies/policies_list.yaml new file mode 100644 index 000000000..0426f3dab --- /dev/null +++ b/tests/modules/organization/factory/policies/policies_list.yaml @@ -0,0 +1,47 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +compute.vmExternalIpAccess: + rules: + - deny: + all: true +iam.allowedPolicyMemberDomains: + inherit_from_parent: true + rules: + - allow: + values: + - C0xxxxxxx + - C0yyyyyyy +compute.restrictLoadBalancerCreationForTypes: + rules: + - condition: + expression: resource.matchTagId(aa, bb) + title: condition + description: test condition + location: xxx + allow: + values: + - EXTERNAL_1 + - condition: + expression: resource.matchTagId(cc, dd) + title: condition2 + description: test condition2 + location: xxx + allow: + all: true + - deny: + values: + - in:EXTERNAL diff --git a/tests/modules/organization/org_policies.tfvars b/tests/modules/organization/org_policies.tfvars new file mode 100644 index 000000000..07fed1524 --- /dev/null +++ b/tests/modules/organization/org_policies.tfvars @@ -0,0 +1,80 @@ +org_policies = { + "iam.disableServiceAccountKeyCreation" = { + rules = [{ enforce = true }] + } + "iam.disableServiceAccountKeyUpload" = { + rules = [ + { + condition = { + expression = "resource.matchTagId(aa, bb)" + title = "condition" + description = "test condition" + location = "xxx" + } + enforce = true + }, + { + enforce = false + } + ] + } + "compute.vmExternalIpAccess" = { + rules = [{ deny = { all = true } }] + } + "iam.allowedPolicyMemberDomains" = { + inherit_from_parent = true + rules = [{ + allow = { + values = ["C0xxxxxxx", "C0yyyyyyy"] + } + }] + } + "compute.restrictLoadBalancerCreationForTypes" = { + rules = [ + { + condition = { + expression = "resource.matchTagId(aa, bb)" + title = "condition" + description = "test condition" + location = "xxx" + } + allow = { + values = ["EXTERNAL_1"] + } + }, + { + condition = { + expression = "resource.matchTagId(cc, dd)" + title = "condition2" + description = "test condition2" + location = "xxx" + } + allow = { + all = true + } + }, + { + deny = { values = ["in:EXTERNAL"] } + } + ] + } +} + +org_policy_custom_constraints = { + "custom.gkeEnableAutoUpgrade" = { + resource_types = ["container.googleapis.com/NodePool"] + method_types = ["CREATE"] + condition = "resource.management.autoUpgrade == true" + action_type = "ALLOW" + display_name = "Enable node auto-upgrade" + description = "All node pools must have node auto-upgrade enabled." + }, + "custom.dataprocNoMoreThan10Workers" = { + resource_types = ["dataproc.googleapis.com/Cluster"] + method_types = ["CREATE", "UPDATE"] + condition = "resource.config.workerConfig.numInstances + resource.config.secondaryWorkerConfig.numInstances > 10" + action_type = "DENY" + display_name = "Total number of worker instances cannot be larger than 10" + description = "Cluster cannot have more than 10 workers, including primary and secondary workers." + } +} diff --git a/tests/modules/organization/org_policies.yaml b/tests/modules/organization/org_policies.yaml new file mode 100644 index 000000000..26201c48f --- /dev/null +++ b/tests/modules/organization/org_policies.yaml @@ -0,0 +1,140 @@ +# Copyright 2023 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. + +values: + google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: + name: organizations/1234567890/policies/iam.disableServiceAccountKeyCreation + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: + name: organizations/1234567890/policies/iam.disableServiceAccountKeyUpload + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: test condition + expression: resource.matchTagId(aa, bb) + location: xxx + title: condition + deny_all: null + enforce: 'TRUE' + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: 'FALSE' + values: [] + timeouts: null + google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]: + name: organizations/1234567890/policies/compute.restrictLoadBalancerCreationForTypes + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: test condition + expression: resource.matchTagId(aa, bb) + location: xxx + title: condition + deny_all: null + enforce: null + values: + - allowed_values: + - EXTERNAL_1 + denied_values: null + - allow_all: 'TRUE' + condition: + - description: test condition2 + expression: resource.matchTagId(cc, dd) + location: xxx + title: condition2 + deny_all: null + enforce: null + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: null + denied_values: + - in:EXTERNAL + timeouts: null + google_org_policy_policy.default["compute.vmExternalIpAccess"]: + name: organizations/1234567890/policies/compute.vmExternalIpAccess + parent: organizations/1234567890 + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: 'TRUE' + enforce: null + values: [] + timeouts: null + google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: + name: organizations/1234567890/policies/iam.allowedPolicyMemberDomains + parent: organizations/1234567890 + spec: + - inherit_from_parent: true + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: null + values: + - allowed_values: + - C0xxxxxxx + - C0yyyyyyy + denied_values: null + timeouts: null + google_org_policy_custom_constraint.constraint["custom.dataprocNoMoreThan10Workers"]: + action_type: DENY + condition: resource.config.workerConfig.numInstances + resource.config.secondaryWorkerConfig.numInstances + > 10 + method_types: + - CREATE + - UPDATE + name: custom.dataprocNoMoreThan10Workers + parent: organizations/1234567890 + resource_types: + - dataproc.googleapis.com/Cluster + google_org_policy_custom_constraint.constraint["custom.gkeEnableAutoUpgrade"]: + action_type: ALLOW + condition: resource.management.autoUpgrade == true + method_types: + - CREATE + name: custom.gkeEnableAutoUpgrade + parent: organizations/1234567890 + resource_types: + - container.googleapis.com/NodePool +counts: + google_org_policy_policy: 5 + google_org_policy_custom_constraint: 2 diff --git a/tests/modules/organization/org_policies_boolean.tfvars b/tests/modules/organization/org_policies_boolean.tfvars deleted file mode 100644 index cf5047a20..000000000 --- a/tests/modules/organization/org_policies_boolean.tfvars +++ /dev/null @@ -1,21 +0,0 @@ -org_policies = { - "iam.disableServiceAccountKeyCreation" = { - rules = [{ enforce = true }] - } - "iam.disableServiceAccountKeyUpload" = { - rules = [ - { - condition = { - expression = "resource.matchTagId(aa, bb)" - title = "condition" - description = "test condition" - location = "xxx" - } - enforce = true - }, - { - enforce = false - } - ] - } -} diff --git a/tests/modules/organization/org_policies_boolean.yaml b/tests/modules/organization/org_policies_boolean.yaml deleted file mode 100644 index 30352b429..000000000 --- a/tests/modules/organization/org_policies_boolean.yaml +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright 2023 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. - -values: - google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: - name: organizations/1234567890/policies/iam.disableServiceAccountKeyCreation - parent: organizations/1234567890 - spec: - - inherit_from_parent: null - reset: null - rules: - - allow_all: null - condition: [] - deny_all: null - enforce: 'TRUE' - values: [] - timeouts: null - google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: - name: organizations/1234567890/policies/iam.disableServiceAccountKeyUpload - parent: organizations/1234567890 - spec: - - inherit_from_parent: null - reset: null - rules: - - allow_all: null - condition: - - description: test condition - expression: resource.matchTagId(aa, bb) - location: xxx - title: condition - deny_all: null - enforce: 'TRUE' - values: [] - - allow_all: null - condition: [] - deny_all: null - enforce: 'FALSE' - values: [] - timeouts: null - -counts: - google_org_policy_policy: 2 diff --git a/tests/modules/organization/org_policies_custom_constraints.tfvars b/tests/modules/organization/org_policies_custom_constraints.tfvars deleted file mode 100644 index a02f97c48..000000000 --- a/tests/modules/organization/org_policies_custom_constraints.tfvars +++ /dev/null @@ -1,18 +0,0 @@ -org_policy_custom_constraints = { - "custom.gkeEnableAutoUpgrade" = { - resource_types = ["container.googleapis.com/NodePool"] - method_types = ["CREATE"] - condition = "resource.management.autoUpgrade == true" - action_type = "ALLOW" - display_name = "Enable node auto-upgrade" - description = "All node pools must have node auto-upgrade enabled." - }, - "custom.dataprocNoMoreThan10Workers" = { - resource_types = ["dataproc.googleapis.com/Cluster"] - method_types = ["CREATE", "UPDATE"] - condition = "resource.config.workerConfig.numInstances + resource.config.secondaryWorkerConfig.numInstances > 10" - action_type = "DENY" - display_name = "Total number of worker instances cannot be larger than 10" - description = "Cluster cannot have more than 10 workers, including primary and secondary workers." - } -} diff --git a/tests/modules/organization/org_policies_custom_constraints.yaml b/tests/modules/organization/org_policies_custom_constraints.yaml deleted file mode 100644 index 40043575e..000000000 --- a/tests/modules/organization/org_policies_custom_constraints.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2023 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. - -values: - google_org_policy_custom_constraint.constraint["custom.dataprocNoMoreThan10Workers"]: - action_type: DENY - condition: resource.config.workerConfig.numInstances + resource.config.secondaryWorkerConfig.numInstances > 10 - method_types: - - CREATE - - UPDATE - name: custom.dataprocNoMoreThan10Workers - parent: organizations/1234567890 - resource_types: - - dataproc.googleapis.com/Cluster - google_org_policy_custom_constraint.constraint["custom.gkeEnableAutoUpgrade"]: - action_type: ALLOW - condition: resource.management.autoUpgrade == true - method_types: - - CREATE - name: custom.gkeEnableAutoUpgrade - parent: organizations/1234567890 - resource_types: - - container.googleapis.com/NodePool - -counts: - google_org_policy_custom_constraint: 2 diff --git a/tests/modules/organization/org_policies_factory.tfvars b/tests/modules/organization/org_policies_factory.tfvars new file mode 100644 index 000000000..2c6743e9e --- /dev/null +++ b/tests/modules/organization/org_policies_factory.tfvars @@ -0,0 +1,4 @@ +factories_config = { + org_policies = "factory/policies" + org_policy_custom_constraints = "factory/custom_constraints" +} \ No newline at end of file diff --git a/tests/modules/organization/test_plan_org_policies.py b/tests/modules/organization/test_plan_org_policies.py deleted file mode 100644 index 1e4474402..000000000 --- a/tests/modules/organization/test_plan_org_policies.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright 2023 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. - -import pytest - -_params = ['boolean', 'list'] - - -@pytest.mark.parametrize('policy_type', _params) -def test_policy_factory(plan_summary, tfvars_to_yaml, tmp_path, policy_type): - dest = tmp_path / 'policies.yaml' - tfvars_to_yaml(f'org_policies_{policy_type}.tfvars', dest, 'org_policies') - tfvars_plan = plan_summary( - 'modules/organization', - tf_var_files=['common.tfvars', f'org_policies_{policy_type}.tfvars']) - yaml_plan = plan_summary('modules/organization', - tf_var_files=['common.tfvars'], - factories_config=f'{{org_policies="{tmp_path}"}}') - assert tfvars_plan.values == yaml_plan.values - - -def test_custom_constraint_factory(plan_summary, tfvars_to_yaml, tmp_path): - dest = tmp_path / 'constraints.yaml' - tfvars_to_yaml(f'org_policies_custom_constraints.tfvars', dest, - 'org_policy_custom_constraints') - tfvars_plan = plan_summary( - 'modules/organization', - tf_var_files=['common.tfvars', f'org_policies_custom_constraints.tfvars']) - yaml_plan = plan_summary( - 'modules/organization', tf_var_files=['common.tfvars'], - factories_config=f'{{org_policy_custom_constraints="{tmp_path}"}}') - assert tfvars_plan.values == yaml_plan.values diff --git a/tests/modules/organization/tftest.yaml b/tests/modules/organization/tftest.yaml index 2a9c63d7f..2c6f547a7 100644 --- a/tests/modules/organization/tftest.yaml +++ b/tests/modules/organization/tftest.yaml @@ -21,9 +21,12 @@ tests: context: iam_by_principals_additive: iam_by_principals_conditional: - org_policies_list: - org_policies_boolean: - org_policies_custom_constraints: + org_policies: + org_policies_factory: + inventory: + - org_policies.yaml + extra_dirs: + - ../../tests/modules/organization/factory tags: tags_force_context: tags_skip_iam: diff --git a/tests/modules/project/factory/policies/policies_boolean.yaml b/tests/modules/project/factory/policies/policies_boolean.yaml new file mode 100644 index 000000000..05b5dd9f6 --- /dev/null +++ b/tests/modules/project/factory/policies/policies_boolean.yaml @@ -0,0 +1,28 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +iam.disableServiceAccountKeyCreation: + rules: + - enforce: true +iam.disableServiceAccountKeyUpload: + rules: + - condition: + expression: resource.matchTagId(aa, bb) + title: condition + description: test condition + location: xxx + enforce: true + - enforce: false diff --git a/tests/modules/project/factory/policies/policies_list.yaml b/tests/modules/project/factory/policies/policies_list.yaml new file mode 100644 index 000000000..0426f3dab --- /dev/null +++ b/tests/modules/project/factory/policies/policies_list.yaml @@ -0,0 +1,47 @@ +# Copyright 2026 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. + +# yamllint disable rule:line-length + +compute.vmExternalIpAccess: + rules: + - deny: + all: true +iam.allowedPolicyMemberDomains: + inherit_from_parent: true + rules: + - allow: + values: + - C0xxxxxxx + - C0yyyyyyy +compute.restrictLoadBalancerCreationForTypes: + rules: + - condition: + expression: resource.matchTagId(aa, bb) + title: condition + description: test condition + location: xxx + allow: + values: + - EXTERNAL_1 + - condition: + expression: resource.matchTagId(cc, dd) + title: condition2 + description: test condition2 + location: xxx + allow: + all: true + - deny: + values: + - in:EXTERNAL diff --git a/tests/modules/organization/org_policies_list.tfvars b/tests/modules/project/org_policies.tfvars similarity index 68% rename from tests/modules/organization/org_policies_list.tfvars rename to tests/modules/project/org_policies.tfvars index d03f8530f..3b0a2a6e4 100644 --- a/tests/modules/organization/org_policies_list.tfvars +++ b/tests/modules/project/org_policies.tfvars @@ -1,4 +1,23 @@ org_policies = { + "iam.disableServiceAccountKeyCreation" = { + rules = [{ enforce = true }] + } + "iam.disableServiceAccountKeyUpload" = { + rules = [ + { + condition = { + expression = "resource.matchTagId(aa, bb)" + title = "condition" + description = "test condition" + location = "xxx" + } + enforce = true + }, + { + enforce = false + } + ] + } "compute.vmExternalIpAccess" = { rules = [{ deny = { all = true } }] } @@ -9,7 +28,6 @@ org_policies = { values = ["C0xxxxxxx", "C0yyyyyyy"] } }] - } "compute.restrictLoadBalancerCreationForTypes" = { rules = [ diff --git a/tests/modules/organization/org_policies_list.yaml b/tests/modules/project/org_policies.yaml similarity index 61% rename from tests/modules/organization/org_policies_list.yaml rename to tests/modules/project/org_policies.yaml index 1f1c1bf9d..b5c3adafb 100644 --- a/tests/modules/organization/org_policies_list.yaml +++ b/tests/modules/project/org_policies.yaml @@ -13,9 +13,44 @@ # limitations under the License. values: + google_org_policy_policy.default["iam.disableServiceAccountKeyCreation"]: + name: projects/my-project/policies/iam.disableServiceAccountKeyCreation + parent: projects/my-project + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: [] + deny_all: null + enforce: 'TRUE' + values: [] + timeouts: null + google_org_policy_policy.default["iam.disableServiceAccountKeyUpload"]: + name: projects/my-project/policies/iam.disableServiceAccountKeyUpload + parent: projects/my-project + spec: + - inherit_from_parent: null + reset: null + rules: + - allow_all: null + condition: + - description: test condition + expression: resource.matchTagId(aa, bb) + location: xxx + title: condition + deny_all: null + enforce: 'TRUE' + values: [] + - allow_all: null + condition: [] + deny_all: null + enforce: 'FALSE' + values: [] + timeouts: null google_org_policy_policy.default["compute.restrictLoadBalancerCreationForTypes"]: - name: organizations/1234567890/policies/compute.restrictLoadBalancerCreationForTypes - parent: organizations/1234567890 + name: projects/my-project/policies/compute.restrictLoadBalancerCreationForTypes + parent: projects/my-project spec: - inherit_from_parent: null reset: null @@ -51,8 +86,8 @@ values: - in:EXTERNAL timeouts: null google_org_policy_policy.default["compute.vmExternalIpAccess"]: - name: organizations/1234567890/policies/compute.vmExternalIpAccess - parent: organizations/1234567890 + name: projects/my-project/policies/compute.vmExternalIpAccess + parent: projects/my-project spec: - inherit_from_parent: null reset: null @@ -64,8 +99,8 @@ values: values: [] timeouts: null google_org_policy_policy.default["iam.allowedPolicyMemberDomains"]: - name: organizations/1234567890/policies/iam.allowedPolicyMemberDomains - parent: organizations/1234567890 + name: projects/my-project/policies/iam.allowedPolicyMemberDomains + parent: projects/my-project spec: - inherit_from_parent: true reset: null @@ -80,6 +115,5 @@ values: - C0yyyyyyy denied_values: null timeouts: null - counts: - google_org_policy_policy: 3 + google_org_policy_policy: 5 diff --git a/tests/modules/project/org_policies_factory.tfvars b/tests/modules/project/org_policies_factory.tfvars new file mode 100644 index 000000000..ec37c9026 --- /dev/null +++ b/tests/modules/project/org_policies_factory.tfvars @@ -0,0 +1,3 @@ +factories_config = { + org_policies = "factory/policies" +} \ No newline at end of file diff --git a/tests/modules/project/test_plan_org_policies.py b/tests/modules/project/test_plan_org_policies.py deleted file mode 100644 index a85bf9c5f..000000000 --- a/tests/modules/project/test_plan_org_policies.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2023 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. - -import pytest - -_params = ['boolean', 'list'] - - -@pytest.mark.parametrize('policy_type', _params) -def test_policy_factory(plan_summary, tfvars_to_yaml, tmp_path, policy_type): - dest = tmp_path / 'policies.yaml' - tfvars_to_yaml(f'org_policies_{policy_type}.tfvars', dest, 'org_policies') - tfvars_plan = plan_summary( - 'modules/project', - tf_var_files=['common.tfvars', f'org_policies_{policy_type}.tfvars']) - yaml_plan = plan_summary('modules/project', tf_var_files=['common.tfvars'], - factories_config=f'{{org_policies="{tmp_path}"}}') - assert tfvars_plan.values == yaml_plan.values diff --git a/tests/modules/project/tftest.yaml b/tests/modules/project/tftest.yaml index 465f71bb1..08a1712ac 100644 --- a/tests/modules/project/tftest.yaml +++ b/tests/modules/project/tftest.yaml @@ -23,8 +23,12 @@ tests: iam_by_principals_conditional: no_parent: no_prefix: - org_policies_boolean: - org_policies_list: + org_policies: + org_policies_factory: + inventory: + - org_policies.yaml + extra_dirs: + - ../../tests/modules/project/factory parent_folder: parent_org: prefix: diff --git a/tests/requirements.txt b/tests/requirements.txt index 7f6a0ea38..a1035175c 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -3,8 +3,7 @@ pytest>=7.2.1 PyYAML>=6.0 tftest>=1.8.7 marko>=1.2.2 -deepdiff>=6.2.3 -python-hcl2>=4.3.0 pytest-xdist>=3.1.0 jsonschema>=4.22.0 yamllint>=1.37.1 + diff --git a/tools/duplicate-diff.py b/tools/duplicate-diff.py index c619718e3..71b13250d 100755 --- a/tools/duplicate-diff.py +++ b/tools/duplicate-diff.py @@ -21,6 +21,12 @@ import os # List of folders and files that are expected to have same content duplicates = [ + # factory policies + [ + "tests/modules/folder/factory/policies", + "tests/modules/organization/factory/policies", + "tests/modules/project/factory/policies", + ], # schemas [ "fast/stages/1-vpcsc/schemas/access-level.schema.json", diff --git a/tools/requirements.txt b/tools/requirements.txt index e46e1129c..59bb2c699 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -1,6 +1,5 @@ click cloudpickle -deepdiff ghapi iso8601 marko