From 7be3288cc7434a90a2736a9cac3cf63603052933 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 16 Nov 2022 23:03:29 +0100 Subject: [PATCH 1/6] Add tests for factory examples --- .../iam-delegated-role-grants/README.md | 5 ++-- .../data-platform-foundations/README.md | 4 +-- .../factories/bigquery-factory/README.md | 2 +- .../networking/hub-and-spoke-vpn/README.md | 2 +- .../net-dns-policy-address/README.md | 2 +- modules/endpoints/README.md | 4 +-- modules/folder/README.md | 6 ++--- modules/kms/README.md | 2 +- modules/net-vpc-firewall/README.md | 12 ++++----- modules/net-vpc/README.md | 2 +- modules/organization/README.md | 18 ++++++------- .../org-policy-custom-constraints.tf | 4 +-- modules/project/README.md | 8 +++--- modules/projects-data-source/README.md | 4 +-- .../configs/custom-constraints/dataproc.yaml | 10 +++++++ .../configs/custom-constraints/gke.yaml | 18 +++++++++++++ tests/examples/configs/endpoints/openapi.yaml | 1 + .../configs/firewall-policies/cidrs.yaml | 4 +++ .../configs/firewall-policies/rules.yaml | 23 ++++++++++++++++ .../configs/firewall/cidr_template.yaml | 5 ++++ .../firewall/rules/laod_balancers.yaml | 10 +++++++ .../configs/org-policies/boolean.yaml | 12 +++++++++ tests/examples/configs/org-policies/list.yaml | 26 +++++++++++++++++++ .../examples/configs/subnets/subnet-name.yaml | 14 ++++++++++ tests/examples/test_plan.py | 7 +++-- 25 files changed, 163 insertions(+), 42 deletions(-) create mode 100644 tests/examples/configs/custom-constraints/dataproc.yaml create mode 100644 tests/examples/configs/custom-constraints/gke.yaml create mode 100644 tests/examples/configs/endpoints/openapi.yaml create mode 100644 tests/examples/configs/firewall-policies/cidrs.yaml create mode 100644 tests/examples/configs/firewall-policies/rules.yaml create mode 100644 tests/examples/configs/firewall/cidr_template.yaml create mode 100644 tests/examples/configs/firewall/rules/laod_balancers.yaml create mode 100644 tests/examples/configs/org-policies/boolean.yaml create mode 100644 tests/examples/configs/org-policies/list.yaml create mode 100644 tests/examples/configs/subnets/subnet-name.yaml diff --git a/blueprints/cloud-operations/iam-delegated-role-grants/README.md b/blueprints/cloud-operations/iam-delegated-role-grants/README.md index dae32ef9..4c4d227d 100644 --- a/blueprints/cloud-operations/iam-delegated-role-grants/README.md +++ b/blueprints/cloud-operations/iam-delegated-role-grants/README.md @@ -27,13 +27,12 @@ By changing the `restricted_role_grant`, the blueprint can be used to grant admi You can easily configure the blueprint for this use case: -```hcl +```tfvars # terraform.tfvars delegated_role_grants = ["roles/compute.networkUser"] -direct_role_grants = [] +direct_role_grants = [] restricted_role_grant = "roles/compute.networkAdmin" -# tftest skip ``` This diagram shows the resources and expected behaviour: diff --git a/blueprints/data-solutions/data-platform-foundations/README.md b/blueprints/data-solutions/data-platform-foundations/README.md index 51545d58..b7fcc806 100644 --- a/blueprints/data-solutions/data-platform-foundations/README.md +++ b/blueprints/data-solutions/data-platform-foundations/README.md @@ -135,7 +135,6 @@ service_encryption_keys = { storage = "KEY_URL_MULTIREGIONAL" pubsub = "KEY_URL_MULTIREGIONAL" } -# tftest skip ``` This step is optional and depends on customer policies and security best practices. @@ -198,8 +197,7 @@ billing_account_id = "111111-222222-333333" older_id = "folders/123456789012" organization_domain = "domain.com" prefix = "myco" -# tftest skip` -`` +``` For more fine details check variables on [`variables.tf`](./variables.tf) and update according to the desired configuration. Remember to create team groups described [below](#groups). diff --git a/blueprints/factories/bigquery-factory/README.md b/blueprints/factories/bigquery-factory/README.md index 01c098be..11767ab1 100644 --- a/blueprints/factories/bigquery-factory/README.md +++ b/blueprints/factories/bigquery-factory/README.md @@ -24,7 +24,7 @@ module "bq" { views = try(each.value.views, null) tables = try(each.value.tables, null) } -# tftest skip +# tftest modules=1 resources= ``` ### Configuration Structure diff --git a/blueprints/networking/hub-and-spoke-vpn/README.md b/blueprints/networking/hub-and-spoke-vpn/README.md index 20fb2c51..2ba3a86a 100644 --- a/blueprints/networking/hub-and-spoke-vpn/README.md +++ b/blueprints/networking/hub-and-spoke-vpn/README.md @@ -35,7 +35,7 @@ You can easily create such a project by commenting turning on project creation i ```hcl module "project" { - source = "../../..//modules/project" + source = "../../../modules/project" name = var.project_id # comment or remove this line to enable project creation # project_create = false diff --git a/modules/__experimental/net-dns-policy-address/README.md b/modules/__experimental/net-dns-policy-address/README.md index 3dbabdac..7044ef2e 100644 --- a/modules/__experimental/net-dns-policy-address/README.md +++ b/modules/__experimental/net-dns-policy-address/README.md @@ -12,7 +12,7 @@ module "dns-policy-addresses" { project_id = "myproject" regions = ["europe-west1", "europe-west3"] } -# tftest skip +# tftest skip (uses data sources) ``` The output is a map with lists of addresses of type `DNS_RESOLVER` for each region specified in variables. diff --git a/modules/endpoints/README.md b/modules/endpoints/README.md index 0d85961d..a000e2b0 100644 --- a/modules/endpoints/README.md +++ b/modules/endpoints/README.md @@ -11,14 +11,14 @@ module "endpoint" { source = "./fabric/modules/endpoints" project_id = "my-project" service_name = "YOUR-API.endpoints.YOUR-PROJECT-ID.cloud.goog" - openapi_config = { "yaml_path" = "openapi.yaml" } + openapi_config = { "yaml_path" = "configs/endpoints/openapi.yaml" } iam = { "servicemanagement.serviceController" = [ "serviceAccount:123456890-compute@developer.gserviceaccount.com" ] } } -# tftest skip +# tftest modules=1 resources=2 ``` [Here](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/endpoints/getting-started/openapi.yaml) you can find an example of an openapi.yaml file. Once created the endpoint, remember to activate the service at project level. diff --git a/modules/folder/README.md b/modules/folder/README.md index 1943882d..7169776e 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -89,15 +89,15 @@ module "folder" { parent = "organizations/1234567890" name = "Folder name" firewall_policy_factory = { - cidr_file = "data/cidrs.yaml" + cidr_file = "configs/firewall-policies/cidrs.yaml" policy_name = null - rules_file = "data/rules.yaml" + rules_file = "configs/firewall-policies/rules.yaml" } firewall_policy_association = { factory-policy = module.folder.firewall_policy_id["factory"] } } -# tftest skip +# tftest modules=1 resources=5 ``` ```yaml diff --git a/modules/kms/README.md b/modules/kms/README.md index cfaa822a..4fe74857 100644 --- a/modules/kms/README.md +++ b/modules/kms/README.md @@ -23,7 +23,7 @@ module "kms" { keyring_create = false keys = { key-a = null, key-b = null, key-c = null } } -# tftest skip +# tftest skip (uses data sources) ``` ### Keyring creation and crypto key rotation and IAM roles diff --git a/modules/net-vpc-firewall/README.md b/modules/net-vpc-firewall/README.md index 6b36edd9..877b15e7 100644 --- a/modules/net-vpc-firewall/README.md +++ b/modules/net-vpc-firewall/README.md @@ -138,16 +138,16 @@ module "firewall" { project_id = "my-project" network = "my-network" factories_config = { - rules_folder = "config/firewall" - cidr_tpl_file = "config/cidr_template.yaml" + rules_folder = "configs/firewal/rules" + cidr_tpl_file = "configs/firewal/cidr_template.yaml" } } -# tftest skip +# tftest modules=1 resources=3 ``` ```yaml -# ./config/firewall/load_balancers.yaml +# ./configs/firewall/rules/load_balancers.yaml allow-healthchecks: description: Allow ingress from healthchecks. ranges: @@ -161,13 +161,13 @@ allow-healthchecks: ``` ```yaml -# ./config/cidr_template.yaml +# ./configs/firewall/cidr_template.yaml healthchecks: - 35.191.0.0/16 + - 130.211.0.0/22 - 209.85.152.0/22 - 209.85.204.0/22 - ``` diff --git a/modules/net-vpc/README.md b/modules/net-vpc/README.md index 0d6a231e..6b08c3b0 100644 --- a/modules/net-vpc/README.md +++ b/modules/net-vpc/README.md @@ -233,7 +233,7 @@ module "vpc" { name = "my-network" data_folder = "config/subnets" } -# tftest skip +# tftest modules=1 resources=1 ``` ```yaml diff --git a/modules/organization/README.md b/modules/organization/README.md index d2e8ef31..ce495863 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -137,14 +137,13 @@ module "org" { source = "./fabric/modules/organization" organization_id = var.organization_id - org_policy_custom_constraints_data_path = "/my/path" - + org_policy_custom_constraints_data_path = "configs/custom-constraints" } -# tftest skip +# tftest modules=1 resources=3 ``` ```yaml -# /my/path/gke.yaml +# configs/custom-constraints/gke.yaml custom.gkeEnableLogging: resource_types: - container.googleapis.com/Cluster @@ -166,9 +165,8 @@ custom.gkeEnableAutoUpgrade: ``` ```yaml -# /my/path/dataproc.yaml - -custom.dataprocNoMoreThan10Workers +# configs/custom-constraints/dataproc.yaml +custom.dataprocNoMoreThan10Workers: resource_types: - dataproc.googleapis.com/Cluster method_types: @@ -228,15 +226,15 @@ module "org" { source = "./fabric/modules/organization" organization_id = var.organization_id firewall_policy_factory = { - cidr_file = "data/cidrs.yaml" + cidr_file = "configs/firewall-policies/cidrs.yaml" policy_name = null - rules_file = "data/rules.yaml" + rules_file = "configs/firewall-policies/rules.yaml" } firewall_policy_association = { factory-policy = module.org.firewall_policy_id["factory"] } } -# tftest skip +# tftest modules=1 resources=4 ``` ```yaml diff --git a/modules/organization/org-policy-custom-constraints.tf b/modules/organization/org-policy-custom-constraints.tf index bfc2de1b..b6414641 100644 --- a/modules/organization/org-policy-custom-constraints.tf +++ b/modules/organization/org-policy-custom-constraints.tf @@ -18,10 +18,10 @@ locals { _custom_constraints_factory_data_raw = ( var.org_policy_custom_constraints_data_path == null ? tomap({}) - : tomap(merge([ + : merge([ for f in fileset(var.org_policy_custom_constraints_data_path, "*.yaml") : yamldecode(file("${var.org_policy_custom_constraints_data_path}/${f}")) - ]...)) + ]...) ) _custom_constraints_factory_data = { diff --git a/modules/project/README.md b/modules/project/README.md index 03ea00a1..f5277cd0 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -224,13 +224,13 @@ module "folder" { source = "./fabric/modules/folder" parent = "organizations/1234567890" name = "Folder name" - org_policies_data_path = "/my/path" + org_policies_data_path = "configs/org-policies/" } -# tftest skip +# tftest modules=1 resources=6 ``` ```yaml -# /my/path/boolean.yaml +# configs/org-policies/boolean.yaml iam.disableServiceAccountKeyCreation: enforce: true @@ -246,7 +246,7 @@ iam.disableServiceAccountKeyUpload: ``` ```yaml -# /my/path/list.yaml +# configs/org-policies/list.yaml compute.vmExternalIpAccess: deny: all: true diff --git a/modules/projects-data-source/README.md b/modules/projects-data-source/README.md index 35c5df56..617a01db 100644 --- a/modules/projects-data-source/README.md +++ b/modules/projects-data-source/README.md @@ -22,7 +22,7 @@ output "folders" { value = module.my-org.folders } -# tftest skip +# tftest skip (uses data sources) ``` ### My dev projects based on parent and label @@ -42,7 +42,7 @@ output "dev-folders" { value = module.my-dev.folders } -# tftest skip +# tftest skip (uses data sources) ``` diff --git a/tests/examples/configs/custom-constraints/dataproc.yaml b/tests/examples/configs/custom-constraints/dataproc.yaml new file mode 100644 index 00000000..05a8d2b8 --- /dev/null +++ b/tests/examples/configs/custom-constraints/dataproc.yaml @@ -0,0 +1,10 @@ +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/examples/configs/custom-constraints/gke.yaml b/tests/examples/configs/custom-constraints/gke.yaml new file mode 100644 index 00000000..d80a2005 --- /dev/null +++ b/tests/examples/configs/custom-constraints/gke.yaml @@ -0,0 +1,18 @@ +custom.gkeEnableLogging: + resource_types: + - container.googleapis.com/Cluster + method_types: + - CREATE + - UPDATE + condition: resource.loggingService == "none" + action_type: DENY + display_name: Do not disable Cloud Logging +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. diff --git a/tests/examples/configs/endpoints/openapi.yaml b/tests/examples/configs/endpoints/openapi.yaml new file mode 100644 index 00000000..1bb8bf6d --- /dev/null +++ b/tests/examples/configs/endpoints/openapi.yaml @@ -0,0 +1 @@ +# empty diff --git a/tests/examples/configs/firewall-policies/cidrs.yaml b/tests/examples/configs/firewall-policies/cidrs.yaml new file mode 100644 index 00000000..6df2b79e --- /dev/null +++ b/tests/examples/configs/firewall-policies/cidrs.yaml @@ -0,0 +1,4 @@ +rfc1918: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 diff --git a/tests/examples/configs/firewall-policies/rules.yaml b/tests/examples/configs/firewall-policies/rules.yaml new file mode 100644 index 00000000..d823983c --- /dev/null +++ b/tests/examples/configs/firewall-policies/rules.yaml @@ -0,0 +1,23 @@ +allow-admins: + description: Access from the admin subnet to all subnets + direction: INGRESS + action: allow + priority: 1000 + ranges: + - $rfc1918 + ports: + all: [] + target_resources: null + enable_logging: false + +allow-ssh-from-iap: + description: Enable SSH from IAP + direction: INGRESS + action: allow + priority: 1002 + ranges: + - 35.235.240.0/20 + ports: + tcp: ["22"] + target_resources: null + enable_logging: false diff --git a/tests/examples/configs/firewall/cidr_template.yaml b/tests/examples/configs/firewall/cidr_template.yaml new file mode 100644 index 00000000..99026641 --- /dev/null +++ b/tests/examples/configs/firewall/cidr_template.yaml @@ -0,0 +1,5 @@ +healthchecks: + - 35.191.0.0/16 + - 130.211.0.0/22 + - 209.85.152.0/22 + - 209.85.204.0/22 diff --git a/tests/examples/configs/firewall/rules/laod_balancers.yaml b/tests/examples/configs/firewall/rules/laod_balancers.yaml new file mode 100644 index 00000000..29b2dfc8 --- /dev/null +++ b/tests/examples/configs/firewall/rules/laod_balancers.yaml @@ -0,0 +1,10 @@ +allow-healthchecks: + description: Allow ingress from healthchecks. + ranges: + - healthchecks + targets: ["lb-backends"] + rules: + - protocol: tcp + ports: + - 80 + - 443 diff --git a/tests/examples/configs/org-policies/boolean.yaml b/tests/examples/configs/org-policies/boolean.yaml new file mode 100644 index 00000000..83aea420 --- /dev/null +++ b/tests/examples/configs/org-policies/boolean.yaml @@ -0,0 +1,12 @@ +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 diff --git a/tests/examples/configs/org-policies/list.yaml b/tests/examples/configs/org-policies/list.yaml new file mode 100644 index 00000000..d66a3da2 --- /dev/null +++ b/tests/examples/configs/org-policies/list.yaml @@ -0,0 +1,26 @@ +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 + allow: + values: ["in:EXTERNAL"] + - condition: + expression: resource.matchTagId("tagKeys/12345", "tagValues/12345") + title: condition2 + description: test condition2 + allow: + all: true diff --git a/tests/examples/configs/subnets/subnet-name.yaml b/tests/examples/configs/subnets/subnet-name.yaml new file mode 100644 index 00000000..5ac92e6f --- /dev/null +++ b/tests/examples/configs/subnets/subnet-name.yaml @@ -0,0 +1,14 @@ +region: europe-west1 +description: Sample description +ip_cidr_range: 10.0.0.0/24 +# optional attributes +enable_private_access: false # defaults to true +iam_users: ["foobar@example.com"] # grant compute/networkUser to users +iam_groups: ["lorem@example.com"] # grant compute/networkUser to groups +iam_service_accounts: ["fbz@prj.iam.gserviceaccount.com"] +secondary_ip_ranges: # map of secondary ip ranges + secondary-range-a: 192.168.0.0/24 +flow_logs: # enable, set to empty map to use defaults + - aggregation_interval: "INTERVAL_5_SEC" + - flow_sampling: 0.5 + - metadata: "INCLUDE_ALL_METADATA" diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py index be068642..fda7284a 100644 --- a/tests/examples/test_plan.py +++ b/tests/examples/test_plan.py @@ -23,13 +23,16 @@ def test_example(recursive_e2e_plan_runner, tmp_path, example): (tmp_path / 'fabric').symlink_to(Path(BASE_PATH, '../../').resolve()) (tmp_path / 'variables.tf').symlink_to( Path(BASE_PATH, 'variables.tf').resolve()) + (tmp_path / 'configs').symlink_to(Path(BASE_PATH, 'configs').resolve()) (tmp_path / 'main.tf').write_text(example) match = EXPECTED_RESOURCES_RE.search(example) expected_modules = int(match.group(1)) if match is not None else 1 expected_resources = int(match.group(2)) if match is not None else 1 + assert match is not None, "can't find tftest directive" + num_modules, num_resources = recursive_e2e_plan_runner( str(tmp_path), tmpdir=False) - assert expected_modules == num_modules - assert expected_resources == num_resources + assert expected_modules == num_modules, 'wrong number of modules' + assert expected_resources == num_resources, 'wrong number of resources' From 5cfa1062ccbdc9f2178523eed160a55fdbca80d3 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Thu, 17 Nov 2022 00:14:09 +0100 Subject: [PATCH 2/6] Ensure inline README file match fixture files --- modules/folder/README.md | 6 ++-- modules/net-vpc-firewall/README.md | 5 ++- modules/organization/README.md | 16 +++++----- modules/project/README.md | 4 +-- .../configs/custom-constraints/dataproc.yaml | 1 + .../configs/custom-constraints/gke.yaml | 1 + .../configs/firewall-policies/cidrs.yaml | 1 + .../configs/firewall-policies/rules.yaml | 1 + .../configs/firewall/cidr_template.yaml | 1 + ...aod_balancers.yaml => load_balancers.yaml} | 1 + .../configs/org-policies/boolean.yaml | 1 + tests/examples/configs/org-policies/list.yaml | 1 + tests/examples/conftest.py | 15 ++++----- tests/examples/test_plan.py | 31 +++++++++++++------ 14 files changed, 51 insertions(+), 34 deletions(-) rename tests/examples/configs/firewall/rules/{laod_balancers.yaml => load_balancers.yaml} (88%) diff --git a/modules/folder/README.md b/modules/folder/README.md index 7169776e..71cf3e08 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -101,8 +101,7 @@ module "folder" { ``` ```yaml -# cidrs.yaml - +# tftest file configs/firewall-policies/cidrs.yaml rfc1918: - 10.0.0.0/8 - 172.16.0.0/12 @@ -110,8 +109,7 @@ rfc1918: ``` ```yaml -# rules.yaml - +# tftest file configs/firewall-policies/rules.yaml allow-admins: description: Access from the admin subnet to all subnets direction: INGRESS diff --git a/modules/net-vpc-firewall/README.md b/modules/net-vpc-firewall/README.md index 877b15e7..d0cd32ff 100644 --- a/modules/net-vpc-firewall/README.md +++ b/modules/net-vpc-firewall/README.md @@ -147,7 +147,7 @@ module "firewall" { ``` ```yaml -# ./configs/firewall/rules/load_balancers.yaml +# tftest file configs/firewall/rules/load_balancers.yaml allow-healthchecks: description: Allow ingress from healthchecks. ranges: @@ -161,10 +161,9 @@ allow-healthchecks: ``` ```yaml -# ./configs/firewall/cidr_template.yaml +# tftest file configs/firewall/cidr_template.yaml healthchecks: - 35.191.0.0/16 - - 130.211.0.0/22 - 209.85.152.0/22 - 209.85.204.0/22 diff --git a/modules/organization/README.md b/modules/organization/README.md index ce495863..f60413f2 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -143,9 +143,9 @@ module "org" { ``` ```yaml -# configs/custom-constraints/gke.yaml +# tftest file configs/custom-constraints/gke.yaml custom.gkeEnableLogging: - resource_types: + resource_types: - container.googleapis.com/Cluster method_types: - CREATE @@ -154,7 +154,7 @@ custom.gkeEnableLogging: action_type: DENY display_name: Do not disable Cloud Logging custom.gkeEnableAutoUpgrade: - resource_types: + resource_types: - container.googleapis.com/NodePool method_types: - CREATE @@ -165,9 +165,9 @@ custom.gkeEnableAutoUpgrade: ``` ```yaml -# configs/custom-constraints/dataproc.yaml +# tftest file configs/custom-constraints/dataproc.yaml custom.dataprocNoMoreThan10Workers: - resource_types: + resource_types: - dataproc.googleapis.com/Cluster method_types: - CREATE @@ -238,8 +238,7 @@ module "org" { ``` ```yaml -# cidrs.yaml - +# tftest file configs/firewall-policies/cidrs.yaml rfc1918: - 10.0.0.0/8 - 172.16.0.0/12 @@ -247,8 +246,7 @@ rfc1918: ``` ```yaml -# rules.yaml - +# tftest file configs/firewall-policies/rules.yaml allow-admins: description: Access from the admin subnet to all subnets direction: INGRESS diff --git a/modules/project/README.md b/modules/project/README.md index f5277cd0..53ab731d 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -230,7 +230,7 @@ module "folder" { ``` ```yaml -# configs/org-policies/boolean.yaml +# tftest file configs/org-policies/boolean.yaml iam.disableServiceAccountKeyCreation: enforce: true @@ -246,7 +246,7 @@ iam.disableServiceAccountKeyUpload: ``` ```yaml -# configs/org-policies/list.yaml +# tftest file configs/org-policies/list.yaml compute.vmExternalIpAccess: deny: all: true diff --git a/tests/examples/configs/custom-constraints/dataproc.yaml b/tests/examples/configs/custom-constraints/dataproc.yaml index 05a8d2b8..0aa55484 100644 --- a/tests/examples/configs/custom-constraints/dataproc.yaml +++ b/tests/examples/configs/custom-constraints/dataproc.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check custom.dataprocNoMoreThan10Workers: resource_types: - dataproc.googleapis.com/Cluster diff --git a/tests/examples/configs/custom-constraints/gke.yaml b/tests/examples/configs/custom-constraints/gke.yaml index d80a2005..c47c41e3 100644 --- a/tests/examples/configs/custom-constraints/gke.yaml +++ b/tests/examples/configs/custom-constraints/gke.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check custom.gkeEnableLogging: resource_types: - container.googleapis.com/Cluster diff --git a/tests/examples/configs/firewall-policies/cidrs.yaml b/tests/examples/configs/firewall-policies/cidrs.yaml index 6df2b79e..de1b86fb 100644 --- a/tests/examples/configs/firewall-policies/cidrs.yaml +++ b/tests/examples/configs/firewall-policies/cidrs.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check rfc1918: - 10.0.0.0/8 - 172.16.0.0/12 diff --git a/tests/examples/configs/firewall-policies/rules.yaml b/tests/examples/configs/firewall-policies/rules.yaml index d823983c..d7725a4d 100644 --- a/tests/examples/configs/firewall-policies/rules.yaml +++ b/tests/examples/configs/firewall-policies/rules.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check allow-admins: description: Access from the admin subnet to all subnets direction: INGRESS diff --git a/tests/examples/configs/firewall/cidr_template.yaml b/tests/examples/configs/firewall/cidr_template.yaml index 99026641..3350e0e0 100644 --- a/tests/examples/configs/firewall/cidr_template.yaml +++ b/tests/examples/configs/firewall/cidr_template.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check healthchecks: - 35.191.0.0/16 - 130.211.0.0/22 diff --git a/tests/examples/configs/firewall/rules/laod_balancers.yaml b/tests/examples/configs/firewall/rules/load_balancers.yaml similarity index 88% rename from tests/examples/configs/firewall/rules/laod_balancers.yaml rename to tests/examples/configs/firewall/rules/load_balancers.yaml index 29b2dfc8..bfaf474e 100644 --- a/tests/examples/configs/firewall/rules/laod_balancers.yaml +++ b/tests/examples/configs/firewall/rules/load_balancers.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check allow-healthchecks: description: Allow ingress from healthchecks. ranges: diff --git a/tests/examples/configs/org-policies/boolean.yaml b/tests/examples/configs/org-policies/boolean.yaml index 83aea420..b9cbe388 100644 --- a/tests/examples/configs/org-policies/boolean.yaml +++ b/tests/examples/configs/org-policies/boolean.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check iam.disableServiceAccountKeyCreation: enforce: true diff --git a/tests/examples/configs/org-policies/list.yaml b/tests/examples/configs/org-policies/list.yaml index d66a3da2..00a44a88 100644 --- a/tests/examples/configs/org-policies/list.yaml +++ b/tests/examples/configs/org-policies/list.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check compute.vmExternalIpAccess: deny: all: true diff --git a/tests/examples/conftest.py b/tests/examples/conftest.py index 2cea9e36..6d6246a3 100644 --- a/tests/examples/conftest.py +++ b/tests/examples/conftest.py @@ -39,17 +39,18 @@ def pytest_generate_tests(metafunc): last_header = None mark = pytest.mark.xdist_group(name=module.name) for child in doc.children: - if isinstance(child, marko.block.FencedCode) and child.lang == 'hcl': + if isinstance(child, marko.block.FencedCode): index += 1 code = child.children[0].children if 'tftest skip' in code: continue - examples.append(pytest.param(code, marks=mark)) - path = module.relative_to(FABRIC_ROOT) - name = f'{path}:{last_header}' - if index > 1: - name += f' {index}' - ids.append(name) + if child.lang == 'hcl' or 'tftest file' in code: + examples.append(pytest.param(code, marks=mark)) + path = module.relative_to(FABRIC_ROOT) + name = f'{path}:{last_header}' + if index > 1: + name += f' {index}' + ids.append(name) elif isinstance(child, marko.block.Heading): last_header = child.children[0].children index = 0 diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py index fda7284a..c22f9998 100644 --- a/tests/examples/test_plan.py +++ b/tests/examples/test_plan.py @@ -16,7 +16,8 @@ import re from pathlib import Path BASE_PATH = Path(__file__).parent -EXPECTED_RESOURCES_RE = re.compile(r'# tftest modules=(\d+) resources=(\d+)') +COUNT_TEST_RE = re.compile(r'# tftest modules=(\d+) resources=(\d+)') +FILE_TEST_RE = re.compile(r'# tftest file (.+)') def test_example(recursive_e2e_plan_runner, tmp_path, example): @@ -26,13 +27,25 @@ def test_example(recursive_e2e_plan_runner, tmp_path, example): (tmp_path / 'configs').symlink_to(Path(BASE_PATH, 'configs').resolve()) (tmp_path / 'main.tf').write_text(example) - match = EXPECTED_RESOURCES_RE.search(example) - expected_modules = int(match.group(1)) if match is not None else 1 - expected_resources = int(match.group(2)) if match is not None else 1 + if match := COUNT_TEST_RE.search(example): + expected_modules = int(match.group(1)) if match is not None else 1 + expected_resources = int(match.group(2)) if match is not None else 1 - assert match is not None, "can't find tftest directive" + num_modules, num_resources = recursive_e2e_plan_runner( + str(tmp_path), tmpdir=False) + assert expected_modules == num_modules, 'wrong number of modules' + assert expected_resources == num_resources, 'wrong number of resources' - num_modules, num_resources = recursive_e2e_plan_runner( - str(tmp_path), tmpdir=False) - assert expected_modules == num_modules, 'wrong number of modules' - assert expected_resources == num_resources, 'wrong number of resources' + elif match := FILE_TEST_RE.search(example): + filename = tmp_path / match.group(1) + assert filename.exists(), f'cant read {filename}' + + file_content = filename.read_text() + + # skip first line + file_content = file_content.split('\n', 1)[1] + example = example.split('\n', 1)[1] + assert file_content == example, "README inline file and fixture file don't match" + + else: + assert False, "can't find tftest directive" From 17fde88a57dfbcc2565e6df765095befe1702e7b Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Thu, 17 Nov 2022 10:26:14 +0100 Subject: [PATCH 3/6] Skip bq factory tests --- blueprints/factories/bigquery-factory/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blueprints/factories/bigquery-factory/README.md b/blueprints/factories/bigquery-factory/README.md index 11767ab1..01c098be 100644 --- a/blueprints/factories/bigquery-factory/README.md +++ b/blueprints/factories/bigquery-factory/README.md @@ -24,7 +24,7 @@ module "bq" { views = try(each.value.views, null) tables = try(each.value.tables, null) } -# tftest modules=1 resources= +# tftest skip ``` ### Configuration Structure From a3767cdfe207fb8554f6505d5b789226925a99ff Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Thu, 17 Nov 2022 10:29:27 +0100 Subject: [PATCH 4/6] Fix boilerplate check --- tests/examples/configs/endpoints/openapi.yaml | 2 +- tests/examples/configs/subnets/subnet-name.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/examples/configs/endpoints/openapi.yaml b/tests/examples/configs/endpoints/openapi.yaml index 1bb8bf6d..6f848aa9 100644 --- a/tests/examples/configs/endpoints/openapi.yaml +++ b/tests/examples/configs/endpoints/openapi.yaml @@ -1 +1 @@ -# empty +# skip boilerplate check diff --git a/tests/examples/configs/subnets/subnet-name.yaml b/tests/examples/configs/subnets/subnet-name.yaml index 5ac92e6f..4416cf11 100644 --- a/tests/examples/configs/subnets/subnet-name.yaml +++ b/tests/examples/configs/subnets/subnet-name.yaml @@ -1,3 +1,4 @@ +# skip boilerplate check region: europe-west1 description: Sample description ip_cidr_range: 10.0.0.0/24 From b2510ea4cf0904dfc7560e67785628f4f17bf554 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Thu, 17 Nov 2022 17:51:15 +0100 Subject: [PATCH 5/6] Fix org policies factories --- modules/folder/organization-policies.tf | 12 ++++-------- .../organization/org-policy-custom-constraints.tf | 13 +++++-------- modules/organization/organization-policies.tf | 12 ++++-------- modules/project/organization-policies.tf | 12 ++++-------- .../organization/test_plan_org_policies_modules.py | 10 +++++----- 5 files changed, 22 insertions(+), 37 deletions(-) diff --git a/modules/folder/organization-policies.tf b/modules/folder/organization-policies.tf index 3766005a..999d1c58 100644 --- a/modules/folder/organization-policies.tf +++ b/modules/folder/organization-policies.tf @@ -17,14 +17,10 @@ # tfdoc:file:description Folder-level organization policies. locals { - _factory_data_raw = ( - var.org_policies_data_path == null - ? tomap({}) - : merge([ - for f in fileset(var.org_policies_data_path, "*.yaml") : - yamldecode(file("${var.org_policies_data_path}/${f}")) - ]...) - ) + _factory_data_raw = merge([ + for f in try(fileset(var.org_policies_data_path, "*.yaml"), []) : + yamldecode(file("${var.org_policies_data_path}/${f}")) + ]...) # simulate applying defaults to data coming from yaml files _factory_data = { diff --git a/modules/organization/org-policy-custom-constraints.tf b/modules/organization/org-policy-custom-constraints.tf index b6414641..6a8cf5e6 100644 --- a/modules/organization/org-policy-custom-constraints.tf +++ b/modules/organization/org-policy-custom-constraints.tf @@ -15,14 +15,11 @@ */ locals { - _custom_constraints_factory_data_raw = ( - var.org_policy_custom_constraints_data_path == null - ? tomap({}) - : merge([ - for f in fileset(var.org_policy_custom_constraints_data_path, "*.yaml") : - yamldecode(file("${var.org_policy_custom_constraints_data_path}/${f}")) - ]...) - ) + _custom_constraints_factory_data_raw = merge([ + for f in try(fileset(var.org_policy_custom_constraints_data_path, "*.yaml"), []) : + yamldecode(file("${var.org_policy_custom_constraints_data_path}/${f}")) + ]...) + _custom_constraints_factory_data = { for k, v in local._custom_constraints_factory_data_raw : diff --git a/modules/organization/organization-policies.tf b/modules/organization/organization-policies.tf index 425e8f52..62d46455 100644 --- a/modules/organization/organization-policies.tf +++ b/modules/organization/organization-policies.tf @@ -17,14 +17,10 @@ # tfdoc:file:description Organization-level organization policies. locals { - _factory_data_raw = ( - var.org_policies_data_path == null - ? tomap({}) - : merge([ - for f in fileset(var.org_policies_data_path, "*.yaml") : - yamldecode(file("${var.org_policies_data_path}/${f}")) - ]...) - ) + _factory_data_raw = merge([ + for f in try(fileset(var.org_policies_data_path, "*.yaml"), []) : + yamldecode(file("${var.org_policies_data_path}/${f}")) + ]...) # simulate applying defaults to data coming from yaml files _factory_data = { diff --git a/modules/project/organization-policies.tf b/modules/project/organization-policies.tf index d64dd956..7763aff4 100644 --- a/modules/project/organization-policies.tf +++ b/modules/project/organization-policies.tf @@ -17,14 +17,10 @@ # tfdoc:file:description Project-level organization policies. locals { - _factory_data_raw = ( - var.org_policies_data_path == null - ? tomap({}) - : merge([ - for f in fileset(var.org_policies_data_path, "*.yaml") : - yamldecode(file("${var.org_policies_data_path}/${f}")) - ]...) - ) + _factory_data_raw = merge([ + for f in try(fileset(var.org_policies_data_path, "*.yaml"), []) : + yamldecode(file("${var.org_policies_data_path}/${f}")) + ]...) # simulate applying defaults to data coming from yaml files _factory_data = { diff --git a/tests/modules/organization/test_plan_org_policies_modules.py b/tests/modules/organization/test_plan_org_policies_modules.py index 8bc3a390..1d19ee1e 100644 --- a/tests/modules/organization/test_plan_org_policies_modules.py +++ b/tests/modules/organization/test_plan_org_policies_modules.py @@ -38,8 +38,8 @@ def test_policy_implementation(): '+# tfdoc:file:description Folder-level organization policies.\n', ' \n', ' locals {\n', - ' _factory_data_raw = (\n', - '@@ -69,8 +69,8 @@\n', + ' _factory_data_raw = merge([\n', + '@@ -65,8 +65,8 @@\n', ' org_policies = {\n', ' for k, v in local._org_policies :\n', ' k => merge(v, {\n', @@ -64,8 +64,8 @@ def test_policy_implementation(): '+# tfdoc:file:description Organization-level organization policies.\n', ' \n', ' locals {\n', - ' _factory_data_raw = (\n', - '@@ -69,8 +69,8 @@\n', + ' _factory_data_raw = merge([\n', + '@@ -65,8 +65,8 @@\n', ' org_policies = {\n', ' for k, v in local._org_policies :\n', ' k => merge(v, {\n', @@ -76,7 +76,7 @@ def test_policy_implementation(): ' \n', ' is_boolean_policy = v.allow == null && v.deny == null\n', ' has_values = (\n', - '@@ -143,4 +143,13 @@\n', + '@@ -139,4 +139,13 @@\n', ' }\n', ' }\n', ' }\n', From 2cd74823b1f06371aa5448ff9e85acb3b0558b3c Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Thu, 17 Nov 2022 19:15:42 +0100 Subject: [PATCH 6/6] Generate files based on readme contents --- modules/endpoints/README.md | 12 ++++++- modules/folder/README.md | 6 ++-- modules/net-vpc/README.md | 4 +-- modules/organization/README.md | 12 +++---- modules/project/README.md | 6 ++-- .../configs/custom-constraints/dataproc.yaml | 11 ------- .../configs/custom-constraints/gke.yaml | 19 ----------- tests/examples/configs/endpoints/openapi.yaml | 1 - .../configs/firewall-policies/cidrs.yaml | 5 --- .../configs/firewall-policies/rules.yaml | 24 -------------- .../configs/firewall/cidr_template.yaml | 6 ---- .../firewall/rules/load_balancers.yaml | 11 ------- .../configs/org-policies/boolean.yaml | 13 -------- tests/examples/configs/org-policies/list.yaml | 27 ---------------- .../examples/configs/subnets/subnet-name.yaml | 15 --------- tests/examples/conftest.py | 23 +++++++++++-- tests/examples/test_plan.py | 32 ++++++++----------- 17 files changed, 58 insertions(+), 169 deletions(-) delete mode 100644 tests/examples/configs/custom-constraints/dataproc.yaml delete mode 100644 tests/examples/configs/custom-constraints/gke.yaml delete mode 100644 tests/examples/configs/endpoints/openapi.yaml delete mode 100644 tests/examples/configs/firewall-policies/cidrs.yaml delete mode 100644 tests/examples/configs/firewall-policies/rules.yaml delete mode 100644 tests/examples/configs/firewall/cidr_template.yaml delete mode 100644 tests/examples/configs/firewall/rules/load_balancers.yaml delete mode 100644 tests/examples/configs/org-policies/boolean.yaml delete mode 100644 tests/examples/configs/org-policies/list.yaml delete mode 100644 tests/examples/configs/subnets/subnet-name.yaml diff --git a/modules/endpoints/README.md b/modules/endpoints/README.md index a000e2b0..4e6fd2eb 100644 --- a/modules/endpoints/README.md +++ b/modules/endpoints/README.md @@ -18,7 +18,17 @@ module "endpoint" { ] } } -# tftest modules=1 resources=2 +# tftest modules=1 resources=2 files=openapi +``` + +```yaml +# tftest file openapi configs/endpoints/openapi.yaml +swagger: "2.0" +info: + description: "A simple Google Cloud Endpoints API example." + title: "Endpoints Example" + version: "1.0.0" +host: "echo-api.endpoints.YOUR-PROJECT-ID.cloud.goog" ``` [Here](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/endpoints/getting-started/openapi.yaml) you can find an example of an openapi.yaml file. Once created the endpoint, remember to activate the service at project level. diff --git a/modules/folder/README.md b/modules/folder/README.md index 71cf3e08..5120d246 100644 --- a/modules/folder/README.md +++ b/modules/folder/README.md @@ -97,11 +97,11 @@ module "folder" { factory-policy = module.folder.firewall_policy_id["factory"] } } -# tftest modules=1 resources=5 +# tftest modules=1 resources=5 files=cidrs,rules ``` ```yaml -# tftest file configs/firewall-policies/cidrs.yaml +# tftest file cidrs configs/firewall-policies/cidrs.yaml rfc1918: - 10.0.0.0/8 - 172.16.0.0/12 @@ -109,7 +109,7 @@ rfc1918: ``` ```yaml -# tftest file configs/firewall-policies/rules.yaml +# tftest file rules configs/firewall-policies/rules.yaml allow-admins: description: Access from the admin subnet to all subnets direction: INGRESS diff --git a/modules/net-vpc/README.md b/modules/net-vpc/README.md index 6b08c3b0..b5969406 100644 --- a/modules/net-vpc/README.md +++ b/modules/net-vpc/README.md @@ -233,11 +233,11 @@ module "vpc" { name = "my-network" data_folder = "config/subnets" } -# tftest modules=1 resources=1 +# tftest modules=1 resources=1 file=subnets ``` ```yaml -# ./config/subnets/subnet-name.yaml +# tftest file subnets ./config/subnets/subnet-name.yaml region: europe-west1 description: Sample description ip_cidr_range: 10.0.0.0/24 diff --git a/modules/organization/README.md b/modules/organization/README.md index f60413f2..a716e665 100644 --- a/modules/organization/README.md +++ b/modules/organization/README.md @@ -139,11 +139,11 @@ module "org" { org_policy_custom_constraints_data_path = "configs/custom-constraints" } -# tftest modules=1 resources=3 +# tftest modules=1 resources=3 files=gke,dataproc ``` ```yaml -# tftest file configs/custom-constraints/gke.yaml +# tftest file gke configs/custom-constraints/gke.yaml custom.gkeEnableLogging: resource_types: - container.googleapis.com/Cluster @@ -165,7 +165,7 @@ custom.gkeEnableAutoUpgrade: ``` ```yaml -# tftest file configs/custom-constraints/dataproc.yaml +# tftest file dataproc configs/custom-constraints/dataproc.yaml custom.dataprocNoMoreThan10Workers: resource_types: - dataproc.googleapis.com/Cluster @@ -234,11 +234,11 @@ module "org" { factory-policy = module.org.firewall_policy_id["factory"] } } -# tftest modules=1 resources=4 +# tftest modules=1 resources=4 files=cidrs,rules ``` ```yaml -# tftest file configs/firewall-policies/cidrs.yaml +# tftest file cidrs configs/firewall-policies/cidrs.yaml rfc1918: - 10.0.0.0/8 - 172.16.0.0/12 @@ -246,7 +246,7 @@ rfc1918: ``` ```yaml -# tftest file configs/firewall-policies/rules.yaml +# tftest file rules configs/firewall-policies/rules.yaml allow-admins: description: Access from the admin subnet to all subnets direction: INGRESS diff --git a/modules/project/README.md b/modules/project/README.md index 53ab731d..b6fb3881 100644 --- a/modules/project/README.md +++ b/modules/project/README.md @@ -226,11 +226,11 @@ module "folder" { name = "Folder name" org_policies_data_path = "configs/org-policies/" } -# tftest modules=1 resources=6 +# tftest modules=1 resources=6 files=boolean,list ``` ```yaml -# tftest file configs/org-policies/boolean.yaml +# tftest file boolean configs/org-policies/boolean.yaml iam.disableServiceAccountKeyCreation: enforce: true @@ -246,7 +246,7 @@ iam.disableServiceAccountKeyUpload: ``` ```yaml -# tftest file configs/org-policies/list.yaml +# tftest file list configs/org-policies/list.yaml compute.vmExternalIpAccess: deny: all: true diff --git a/tests/examples/configs/custom-constraints/dataproc.yaml b/tests/examples/configs/custom-constraints/dataproc.yaml deleted file mode 100644 index 0aa55484..00000000 --- a/tests/examples/configs/custom-constraints/dataproc.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# skip boilerplate check -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/examples/configs/custom-constraints/gke.yaml b/tests/examples/configs/custom-constraints/gke.yaml deleted file mode 100644 index c47c41e3..00000000 --- a/tests/examples/configs/custom-constraints/gke.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# skip boilerplate check -custom.gkeEnableLogging: - resource_types: - - container.googleapis.com/Cluster - method_types: - - CREATE - - UPDATE - condition: resource.loggingService == "none" - action_type: DENY - display_name: Do not disable Cloud Logging -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. diff --git a/tests/examples/configs/endpoints/openapi.yaml b/tests/examples/configs/endpoints/openapi.yaml deleted file mode 100644 index 6f848aa9..00000000 --- a/tests/examples/configs/endpoints/openapi.yaml +++ /dev/null @@ -1 +0,0 @@ -# skip boilerplate check diff --git a/tests/examples/configs/firewall-policies/cidrs.yaml b/tests/examples/configs/firewall-policies/cidrs.yaml deleted file mode 100644 index de1b86fb..00000000 --- a/tests/examples/configs/firewall-policies/cidrs.yaml +++ /dev/null @@ -1,5 +0,0 @@ -# skip boilerplate check -rfc1918: - - 10.0.0.0/8 - - 172.16.0.0/12 - - 192.168.0.0/16 diff --git a/tests/examples/configs/firewall-policies/rules.yaml b/tests/examples/configs/firewall-policies/rules.yaml deleted file mode 100644 index d7725a4d..00000000 --- a/tests/examples/configs/firewall-policies/rules.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# skip boilerplate check -allow-admins: - description: Access from the admin subnet to all subnets - direction: INGRESS - action: allow - priority: 1000 - ranges: - - $rfc1918 - ports: - all: [] - target_resources: null - enable_logging: false - -allow-ssh-from-iap: - description: Enable SSH from IAP - direction: INGRESS - action: allow - priority: 1002 - ranges: - - 35.235.240.0/20 - ports: - tcp: ["22"] - target_resources: null - enable_logging: false diff --git a/tests/examples/configs/firewall/cidr_template.yaml b/tests/examples/configs/firewall/cidr_template.yaml deleted file mode 100644 index 3350e0e0..00000000 --- a/tests/examples/configs/firewall/cidr_template.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# skip boilerplate check -healthchecks: - - 35.191.0.0/16 - - 130.211.0.0/22 - - 209.85.152.0/22 - - 209.85.204.0/22 diff --git a/tests/examples/configs/firewall/rules/load_balancers.yaml b/tests/examples/configs/firewall/rules/load_balancers.yaml deleted file mode 100644 index bfaf474e..00000000 --- a/tests/examples/configs/firewall/rules/load_balancers.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# skip boilerplate check -allow-healthchecks: - description: Allow ingress from healthchecks. - ranges: - - healthchecks - targets: ["lb-backends"] - rules: - - protocol: tcp - ports: - - 80 - - 443 diff --git a/tests/examples/configs/org-policies/boolean.yaml b/tests/examples/configs/org-policies/boolean.yaml deleted file mode 100644 index b9cbe388..00000000 --- a/tests/examples/configs/org-policies/boolean.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# skip boilerplate check -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 diff --git a/tests/examples/configs/org-policies/list.yaml b/tests/examples/configs/org-policies/list.yaml deleted file mode 100644 index 00a44a88..00000000 --- a/tests/examples/configs/org-policies/list.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# skip boilerplate check -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 - allow: - values: ["in:EXTERNAL"] - - condition: - expression: resource.matchTagId("tagKeys/12345", "tagValues/12345") - title: condition2 - description: test condition2 - allow: - all: true diff --git a/tests/examples/configs/subnets/subnet-name.yaml b/tests/examples/configs/subnets/subnet-name.yaml deleted file mode 100644 index 4416cf11..00000000 --- a/tests/examples/configs/subnets/subnet-name.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# skip boilerplate check -region: europe-west1 -description: Sample description -ip_cidr_range: 10.0.0.0/24 -# optional attributes -enable_private_access: false # defaults to true -iam_users: ["foobar@example.com"] # grant compute/networkUser to users -iam_groups: ["lorem@example.com"] # grant compute/networkUser to groups -iam_service_accounts: ["fbz@prj.iam.gserviceaccount.com"] -secondary_ip_ranges: # map of secondary ip ranges - secondary-range-a: 192.168.0.0/24 -flow_logs: # enable, set to empty map to use defaults - - aggregation_interval: "INTERVAL_5_SEC" - - flow_sampling: 0.5 - - metadata: "INCLUDE_ALL_METADATA" diff --git a/tests/examples/conftest.py b/tests/examples/conftest.py index 6d6246a3..b2b915ea 100644 --- a/tests/examples/conftest.py +++ b/tests/examples/conftest.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import collections +import re from pathlib import Path import marko @@ -21,6 +23,11 @@ FABRIC_ROOT = Path(__file__).parents[2] MODULES_PATH = FABRIC_ROOT / 'modules/' BLUEPRINTS_PATH = FABRIC_ROOT / 'blueprints/' +FILE_TEST_RE = re.compile(r'# tftest file (\w+) ([\S]+)') + +Example = collections.namedtuple('Example', 'code files') +File = collections.namedtuple('File', 'path content') + def pytest_generate_tests(metafunc): if 'example' in metafunc.fixturenames: @@ -37,15 +44,25 @@ def pytest_generate_tests(metafunc): doc = marko.parse(readme.read_text()) index = 0 last_header = None - mark = pytest.mark.xdist_group(name=module.name) + files = {} + + #first pass: collect all tftest tagged files + for child in doc.children: + if isinstance(child, marko.block.FencedCode): + code = child.children[0].children + match = FILE_TEST_RE.search(code) + if match: + name, path = match.groups() + files[name] = File(path, code) + for child in doc.children: if isinstance(child, marko.block.FencedCode): index += 1 code = child.children[0].children if 'tftest skip' in code: continue - if child.lang == 'hcl' or 'tftest file' in code: - examples.append(pytest.param(code, marks=mark)) + if child.lang == 'hcl': + examples.append(Example(code, files)) path = module.relative_to(FABRIC_ROOT) name = f'{path}:{last_header}' if index > 1: diff --git a/tests/examples/test_plan.py b/tests/examples/test_plan.py index c22f9998..2bb45af1 100644 --- a/tests/examples/test_plan.py +++ b/tests/examples/test_plan.py @@ -16,18 +16,23 @@ import re from pathlib import Path BASE_PATH = Path(__file__).parent -COUNT_TEST_RE = re.compile(r'# tftest modules=(\d+) resources=(\d+)') -FILE_TEST_RE = re.compile(r'# tftest file (.+)') +COUNT_TEST_RE = re.compile( + r'# tftest modules=(\d+) resources=(\d+)(?: files=([\w,]+))?') def test_example(recursive_e2e_plan_runner, tmp_path, example): - (tmp_path / 'fabric').symlink_to(Path(BASE_PATH, '../../').resolve()) - (tmp_path / 'variables.tf').symlink_to( - Path(BASE_PATH, 'variables.tf').resolve()) - (tmp_path / 'configs').symlink_to(Path(BASE_PATH, 'configs').resolve()) - (tmp_path / 'main.tf').write_text(example) + if match := COUNT_TEST_RE.search(example.code): + (tmp_path / 'fabric').symlink_to(Path(BASE_PATH, '../../')) + (tmp_path / 'variables.tf').symlink_to(Path(BASE_PATH, 'variables.tf')) + (tmp_path / 'main.tf').write_text(example.code) + + if match.group(3) is not None: + requested_files = match.group(3).split(',') + for f in requested_files: + destination = tmp_path / example.files[f].path + destination.parent.mkdir(parents=True, exist_ok=True) + destination.write_text(example.files[f].content) - if match := COUNT_TEST_RE.search(example): expected_modules = int(match.group(1)) if match is not None else 1 expected_resources = int(match.group(2)) if match is not None else 1 @@ -36,16 +41,5 @@ def test_example(recursive_e2e_plan_runner, tmp_path, example): assert expected_modules == num_modules, 'wrong number of modules' assert expected_resources == num_resources, 'wrong number of resources' - elif match := FILE_TEST_RE.search(example): - filename = tmp_path / match.group(1) - assert filename.exists(), f'cant read {filename}' - - file_content = filename.read_text() - - # skip first line - file_content = file_content.split('\n', 1)[1] - example = example.split('\n', 1)[1] - assert file_content == example, "README inline file and fixture file don't match" - else: assert False, "can't find tftest directive"