Add tests for data_defaults / data_overrides

This commit is contained in:
Wiktor Niesiobędzki
2025-04-02 19:54:59 +00:00
committed by Wiktor Niesiobędzki
parent 46f731fee0
commit c90005553a
8 changed files with 385 additions and 5 deletions

View File

@@ -207,11 +207,16 @@ def plan_validator(module_path, inventory_paths, basedir, tf_var_files=None,
try:
expected_counts = inventory['counts']
for type_, expected_count in expected_counts.items():
assert type_ in summary.counts, \
f'{relative_path}: module does not create any resources of type `{type_}`'
plan_count = summary.counts[type_]
assert plan_count == expected_count, \
f'{relative_path}: count of {type_} resources failed. Got {plan_count}, expected {expected_count}'
# modules and resources always exists in summary
if expected_count == 0 and type_ not in ('modules', 'resources'):
assert type_ not in summary.counts, \
f'{relative_path}: module creates resources of type `{type_}` when expected not to create any'
else:
assert type_ in summary.counts, \
f'{relative_path}: module does not create any resources of type `{type_}`'
plan_count = summary.counts[type_]
assert plan_count == expected_count, \
f'{relative_path}: count of {type_} resources failed. Got {plan_count}, expected {expected_count}'
except AssertionError:
print(f'\n{path}')
print(yaml.dump({'counts': summary.counts}))

View File

@@ -0,0 +1,25 @@
# Copyright 2025 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.
billing_account: 012345-67890A-BCDEF0
contacts: # this should be overridden by value
admin-default@example.org:
- "ALL"
tag_bindings: # this should be overridden with empty value
name1: project_id1
services:
- run.googleapis.com

View File

@@ -0,0 +1,17 @@
# Copyright 2025 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.
billing_account: 012345-67890A-BCDEF0
# take defaults + overrides only

View File

@@ -0,0 +1,51 @@
data_defaults = {
billing_account = "1245-5678-9012"
parent = "folders/1234"
storage_location = "EU"
contacts = {
"admin-default@example.org" = ["ALL"] # should not surface, as overrides provide value
}
tag_bindings = { # should not surface, as overrides provide empty value
name1 = "default-id1"
name2 = "default-id2"
}
services = [
"default-service.googleapis.com"
]
}
# make sure the environment label and stackdriver service are always added
data_merges = {
labels = {
environment = "test"
}
services = [
"stackdriver.googleapis.com"
]
}
# always use this contacts and prefix, regardless of what is in the yaml file
data_overrides = {
contacts = {
"admin@example.org" = ["ALL"]
}
tag_bindings = {} # prevent setting any encryption keys
prefix = "test-pf"
}
# location where the yaml files are read from
factories_config = {
projects_data_path = "projects"
context = {
folder_ids = {
default = "folders/5678901234"
teams = "folders/5678901234"
}
iam_principals = {
gcp-devops = "group:gcp-devops@example.org"
}
tag_values = {
"org-policies/drs-allow-all" = "tagValues/123456"
}
vpc_host_projects = {
dev-spoke-0 = "test-pf-dev-net-spoke-0"
}
}
}

View File

@@ -0,0 +1,64 @@
# Copyright 2025 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:
module.projects["service1"].google_essential_contacts_contact.contact["admin@example.org"]:
email: admin@example.org
parent: projects/test-pf-service1
module.projects["service1"].google_project.project[0]:
billing_account: 012345-67890A-BCDEF0
folder_id: '1234'
labels:
environment: test
name: test-pf-service1
project_id: test-pf-service1
module.projects["service1"].google_project_service.project_services["run.googleapis.com"]:
project: test-pf-service1
service: run.googleapis.com
module.projects["service1"].google_project_service.project_services["stackdriver.googleapis.com"]:
project: test-pf-service1
service: stackdriver.googleapis.com
module.projects["service2"].google_essential_contacts_contact.contact["admin@example.org"]:
email: admin@example.org
parent: projects/test-pf-service2
module.projects["service2"].google_project.project[0]:
billing_account: 012345-67890A-BCDEF0
folder_id: '1234'
labels:
environment: test
name: test-pf-service2
project_id: test-pf-service2
module.projects["service2"].google_project_service.project_services["default-service.googleapis.com"]:
project: test-pf-service2
service: default-service.googleapis.com
module.projects["service2"].google_project_service.project_services["stackdriver.googleapis.com"]:
project: test-pf-service2
service: stackdriver.googleapis.com
counts:
google_essential_contacts_contact: 2
google_project: 2
google_project_iam_member: 1
google_project_service: 4
google_project_service_identity: 1
google_tags_tag_binding: 0 # keep this, to ensure that tag_bindings are not created
modules: 2
resources: 10
outputs:
buckets: {}
folders: {}
foo: {}
projects: __missing__
service_accounts: {}

View File

@@ -0,0 +1,42 @@
# Copyright 2025 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.
data_defaults = {
billing_account = "1245-5678-9012"
storage_location = "EU"
prefix = "my-prefix"
parent = "folders/1234"
shared_vpc_service_config = null
}
data_merges = {
services = [
"stackdriver.googleapis.com"
]
}
data_overrides = {
prefix = "myprefix"
}
# location where the yaml files are read from
factories_config = {
projects_data_path = "projects"
context = {
folder_ids = {
default = "folders/5678901234"
teams = "folders/4321056789"
}
vpc_host_projects = {
dev-spoke-0 = "test-pf-dev-net-spoke-0"
}
}
}

View File

@@ -0,0 +1,173 @@
# Copyright 2025 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:
module.automation-service-accounts["service1/ro"].google_service_account.service_account[0]:
account_id: myprefix-service1-ro
create_ignore_already_exists: null
description: Service read-only automation sa.
disabled: false
display_name: Service account ro for service1.
email: myprefix-service1-ro@service-iac.iam.gserviceaccount.com
member: serviceAccount:myprefix-service1-ro@service-iac.iam.gserviceaccount.com
project: service-iac
timeouts: null
module.automation-service-accounts["service1/rw"].google_service_account.service_account[0]:
account_id: myprefix-service1-rw
create_ignore_already_exists: null
description: Service read/write automation sa.
disabled: false
display_name: Service account rw for service1.
email: myprefix-service1-rw@service-iac.iam.gserviceaccount.com
member: serviceAccount:myprefix-service1-rw@service-iac.iam.gserviceaccount.com
project: service-iac
timeouts: null
module.projects-iam["service1"].google_compute_shared_vpc_service_project.shared_vpc_service[0]:
deletion_policy: null
host_project: test-pf-dev-net-spoke-0
service_project: myprefix-service1
timeouts: null
? module.projects-iam["service1"].google_project_iam_member.shared_vpc_host_iam["serviceAccount:myprefix-service1-ro@service-iac.iam.gserviceaccount.com"]
: condition: []
member: serviceAccount:myprefix-service1-ro@service-iac.iam.gserviceaccount.com
project: test-pf-dev-net-spoke-0
role: roles/compute.networkUser
? module.projects-iam["service1"].google_project_iam_member.shared_vpc_host_iam["serviceAccount:myprefix-service1-rw@service-iac.iam.gserviceaccount.com"]
: condition: []
member: serviceAccount:myprefix-service1-rw@service-iac.iam.gserviceaccount.com
project: test-pf-dev-net-spoke-0
role: roles/compute.networkUser
? module.projects-iam["service1"].google_project_iam_member.shared_vpc_host_iam["serviceAccount:terraform-rw@myprefix-service1.iam.gserviceaccount.com"]
: condition: []
member: serviceAccount:terraform-rw@myprefix-service1.iam.gserviceaccount.com
project: test-pf-dev-net-spoke-0
role: roles/compute.networkUser
module.projects["service1"].google_project.project[0]:
auto_create_network: false
billing_account: 012345-67890A-BCDEF0
deletion_policy: DELETE
effective_labels:
goog-terraform-provisioned: 'true'
folder_id: '1234'
labels: null
name: myprefix-service1
org_id: null
project_id: myprefix-service1
tags: null
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
module.projects["service1"].google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: myprefix-service1
service: stackdriver.googleapis.com
timeouts: null
module.projects["service2"].data.google_storage_project_service_account.gcs_sa[0]:
project: myprefix-service2
user_project: null
module.projects["service2"].google_project.project[0]:
auto_create_network: false
billing_account: 012345-67890A-BCDEF0
deletion_policy: DELETE
effective_labels:
goog-terraform-provisioned: 'true'
folder_id: '1234'
labels: null
name: myprefix-service2
org_id: null
project_id: myprefix-service2
tags: null
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
module.projects["service2"].google_project_iam_member.service_agents["compute-system"]:
condition: []
project: myprefix-service2
role: roles/compute.serviceAgent
module.projects["service2"].google_project_service.project_services["compute.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: myprefix-service2
service: compute.googleapis.com
timeouts: null
module.projects["service2"].google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: myprefix-service2
service: stackdriver.googleapis.com
timeouts: null
module.projects["service2"].google_project_service.project_services["storage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: myprefix-service2
service: storage.googleapis.com
timeouts: null
module.service-accounts["service1/app-be-0"].google_service_account.service_account[0]:
account_id: app-be-0
create_ignore_already_exists: null
description: null
disabled: false
display_name: Terraform-managed.
email: app-be-0@myprefix-service1.iam.gserviceaccount.com
member: serviceAccount:app-be-0@myprefix-service1.iam.gserviceaccount.com
project: myprefix-service1
timeouts: null
module.service-accounts["service1/terraform-rw"].google_service_account.service_account[0]:
account_id: terraform-rw
create_ignore_already_exists: null
description: null
disabled: false
display_name: Terraform-managed.
email: terraform-rw@myprefix-service1.iam.gserviceaccount.com
member: serviceAccount:terraform-rw@myprefix-service1.iam.gserviceaccount.com
project: myprefix-service1
timeouts: null
module.service-accounts["service2/app-be-0"].google_service_account.service_account[0]:
account_id: app-be-0
create_ignore_already_exists: null
description: null
disabled: false
display_name: Terraform-managed.
email: app-be-0@myprefix-service2.iam.gserviceaccount.com
member: serviceAccount:app-be-0@myprefix-service2.iam.gserviceaccount.com
project: myprefix-service2
timeouts: null
module.service-accounts["service2/terraform-rw"].google_service_account.service_account[0]:
account_id: terraform-rw
create_ignore_already_exists: null
description: null
disabled: false
display_name: Terraform-managed.
email: terraform-rw@myprefix-service2.iam.gserviceaccount.com
member: serviceAccount:terraform-rw@myprefix-service2.iam.gserviceaccount.com
project: myprefix-service2
timeouts: null
counts:
google_compute_shared_vpc_service_project: 1
google_project: 2
google_project_iam_member: 4
google_project_service: 4
google_service_account: 6
google_storage_project_service_account: 1
modules: 9
resources: 18
outputs:
buckets: {}
folders: {}
foo: {}
projects: __missing__
service_accounts: __missing__

View File

@@ -21,3 +21,6 @@ tests:
shared_vpc_network_user:
extra_dirs:
- ../../tests/modules/project_factory/data/shared_vpc_network_user/projects
data_overrides_defaults:
extra_dirs:
- ../../tests/modules/project_factory/data/data_overrides_defaults/projects