Remove hcl2 python dependency (#3836)
* Migrate organization policy tests to standard tftest.yaml. Remove python-hcl2 dependency and the custom python test file. Consolidate the boolean, list, and custom constraint tests into a single `org_policies` test with a factory equivalent. Restructure factory files into a unified `factory/` directory. * Migrate project and folder org policy tests to standard tftest.yaml. Replicate the organization module changes for project and folder modules: - Remove python-hcl2 dependency usages and conftest.py. - Remove custom python test files for org policies. - Consolidate org policy tests into a single `org_policies` test with a factory equivalent. - Unify factory files into a `factory/` directory. - Remove redundant common.tfvars in folder module. * Add factory policies directory to duplicate-diff checks. Ensure the YAML factory files for org policies remain perfectly identical across the organization, folder, and project modules. * Remove unused deepdiff dependency from requirements and pre-commit config. * Add boilerplate * fix broken link
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
parent = "organizations/12345678"
|
||||
name = "folder-a"
|
||||
28
tests/modules/folder/factory/policies/policies_boolean.yaml
Normal file
28
tests/modules/folder/factory/policies/policies_boolean.yaml
Normal file
@@ -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
|
||||
47
tests/modules/folder/factory/policies/policies_list.yaml
Normal file
47
tests/modules/folder/factory/policies/policies_list.yaml
Normal file
@@ -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
|
||||
@@ -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"]
|
||||
132
tests/modules/folder/org_policies.yaml
Normal file
132
tests/modules/folder/org_policies.yaml
Normal file
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
5
tests/modules/folder/org_policies_factory.tfvars
Normal file
5
tests/modules/folder/org_policies_factory.tfvars
Normal file
@@ -0,0 +1,5 @@
|
||||
parent = "organizations/12345678"
|
||||
name = "folder-a"
|
||||
factories_config = {
|
||||
org_policies = "factory/policies"
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
80
tests/modules/organization/org_policies.tfvars
Normal file
80
tests/modules/organization/org_policies.tfvars
Normal file
@@ -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."
|
||||
}
|
||||
}
|
||||
140
tests/modules/organization/org_policies.yaml
Normal file
140
tests/modules/organization/org_policies.yaml
Normal file
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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."
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
4
tests/modules/organization/org_policies_factory.tfvars
Normal file
4
tests/modules/organization/org_policies_factory.tfvars
Normal file
@@ -0,0 +1,4 @@
|
||||
factories_config = {
|
||||
org_policies = "factory/policies"
|
||||
org_policy_custom_constraints = "factory/custom_constraints"
|
||||
}
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
28
tests/modules/project/factory/policies/policies_boolean.yaml
Normal file
28
tests/modules/project/factory/policies/policies_boolean.yaml
Normal file
@@ -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
|
||||
47
tests/modules/project/factory/policies/policies_list.yaml
Normal file
47
tests/modules/project/factory/policies/policies_list.yaml
Normal file
@@ -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
|
||||
@@ -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 = [
|
||||
@@ -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
|
||||
3
tests/modules/project/org_policies_factory.tfvars
Normal file
3
tests/modules/project/org_policies_factory.tfvars
Normal file
@@ -0,0 +1,3 @@
|
||||
factories_config = {
|
||||
org_policies = "factory/policies"
|
||||
}
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
click
|
||||
cloudpickle
|
||||
deepdiff
|
||||
ghapi
|
||||
iso8601
|
||||
marko
|
||||
|
||||
Reference in New Issue
Block a user