Add tftests for project factory

This commit is contained in:
Wiktor Niesiobędzki
2025-02-18 08:35:12 +00:00
committed by Wiktor Niesiobędzki
parent 0a1b6c6e0f
commit fd07db5000
12 changed files with 767 additions and 2 deletions

View File

@@ -108,8 +108,9 @@ def plan_summary(module_path, basedir, tf_var_files=None, extra_files=None,
extra_dirs = [
(module_path / dirname).resolve() for dirname in extra_dirs or []
]
tf.setup(extra_files=extra_files + extra_dirs, upgrade=True)
# raise SystemExit(extra_dirs)
tf.setup(extra_files=extra_files, upgrade=True)
for extra_dir in extra_dirs:
os.symlink(extra_dir, tf.tfdir / extra_dir.name)
tf_var_files = [(basedir / x).resolve() for x in tf_var_files or []]
plan = tf.plan(output=True, tf_var_file=tf_var_files, tf_vars=tf_vars)

View File

@@ -0,0 +1,54 @@
# 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"
}
# 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"]
}
prefix = "test-pf"
}
# location where the yaml files are read from
factories_config = {
folders_data_path = "bucket_iam/hierarchy"
projects_data_path = "bucket_iam/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,275 @@
# 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.buckets["project1/state"].google_storage_bucket.bucket[0]:
autoclass: []
cors: []
custom_placement_config: []
default_event_based_hold: null
effective_labels:
goog-terraform-provisioned: 'true'
enable_object_retention: null
encryption: []
force_destroy: false
hierarchical_namespace: []
labels: null
lifecycle_rule: []
location: EUROPE-WEST8
logging: []
name: test-pf-project1-state
project: test-pf-project1
requester_pays: null
retention_policy: []
storage_class: STANDARD
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
uniform_bucket_level_access: true
versioning:
- enabled: false
module.buckets["project1/state"].google_storage_bucket_iam_binding.authoritative["roles/storage.admin"]:
bucket: test-pf-project1-state
condition: []
members:
- serviceAccount:terraform-rw@test-pf-project1.iam.gserviceaccount.com
role: roles/storage.admin
module.buckets["project2/state"].google_storage_bucket.bucket[0]:
autoclass: []
cors: []
custom_placement_config: []
default_event_based_hold: null
effective_labels:
goog-terraform-provisioned: 'true'
enable_object_retention: null
encryption: []
force_destroy: false
hierarchical_namespace: []
labels: null
lifecycle_rule: []
location: EUROPE-WEST8
logging: []
name: test-pf-project2-state
project: test-pf-project2
requester_pays: null
retention_policy: []
storage_class: STANDARD
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
uniform_bucket_level_access: true
versioning:
- enabled: false
module.hierarchy-folder-lvl-1["team-a"].google_folder.folder[0]:
deletion_protection: false
display_name: Team A
parent: folders/5678901234
tags: null
timeouts: null
module.hierarchy-folder-lvl-1["team-a"].google_folder_iam_binding.authoritative["roles/viewer"]:
condition: []
members:
- group:gcp-devops@example.org
- group:team-a-admins@example.org
role: roles/viewer
module.projects["project1"].data.google_storage_project_service_account.gcs_sa[0]:
project: test-pf-project1
user_project: null
module.projects["project1"].google_essential_contacts_contact.contact["admin@example.org"]:
email: admin@example.org
language_tag: en
notification_category_subscriptions:
- ALL
parent: projects/test-pf-project1
timeouts: null
module.projects["project1"].google_project.project[0]:
auto_create_network: false
billing_account: 012345-67890A-BCDEF0
deletion_policy: DELETE
effective_labels:
environment: test
goog-terraform-provisioned: 'true'
labels:
environment: test
name: test-pf-project1
project_id: test-pf-project1
tags: null
terraform_labels:
environment: test
goog-terraform-provisioned: 'true'
timeouts: null
module.projects["project1"].google_project_iam_member.service_agents["container-engine-robot"]:
condition: []
project: test-pf-project1
role: roles/container.serviceAgent
module.projects["project1"].google_project_iam_member.service_agents["gkenode"]:
condition: []
project: test-pf-project1
role: roles/container.defaultNodeServiceAgent
module.projects["project1"].google_project_service.project_services["container.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: test-pf-project1
service: container.googleapis.com
timeouts: null
module.projects["project1"].google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: test-pf-project1
service: stackdriver.googleapis.com
timeouts: null
module.projects["project1"].google_project_service.project_services["storage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: test-pf-project1
service: storage.googleapis.com
timeouts: null
module.projects["project1"].google_project_service_identity.default["container.googleapis.com"]:
project: test-pf-project1
service: container.googleapis.com
timeouts: null
module.projects["project2"].google_essential_contacts_contact.contact["admin@example.org"]:
email: admin@example.org
language_tag: en
notification_category_subscriptions:
- ALL
parent: projects/test-pf-project2
timeouts: null
module.projects["project2"].google_project.project[0]:
auto_create_network: false
billing_account: 012345-67890A-BCDEF0
deletion_policy: DELETE
effective_labels:
app: app-0
environment: test
goog-terraform-provisioned: 'true'
team: team-a
labels:
app: app-0
environment: test
team: team-a
name: test-pf-project2
project_id: test-pf-project2
tags: null
terraform_labels:
app: app-0
environment: test
goog-terraform-provisioned: 'true'
team: team-a
timeouts: null
module.projects["project2"].google_project_service.project_services["stackdriver.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: test-pf-project2
service: stackdriver.googleapis.com
timeouts: null
module.service-accounts["project1/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@test-pf-project1.iam.gserviceaccount.com
member: serviceAccount:app-be-0@test-pf-project1.iam.gserviceaccount.com
project: test-pf-project1
timeouts: null
? module.service-accounts["project1/app-fe-1"].google_project_iam_member.project-roles["my-host-project-roles/compute.networkUser"]
: condition: []
project: my-host-project
role: roles/compute.networkUser
? module.service-accounts["project1/app-fe-1"].google_project_iam_member.project-roles["test-pf-project1-roles/storage.objectViewer"]
: condition: []
project: test-pf-project1
role: roles/storage.objectViewer
module.service-accounts["project1/app-fe-1"].google_service_account.service_account[0]:
account_id: app-fe-1
create_ignore_already_exists: null
description: null
disabled: false
display_name: GCE frontend service account.
email: app-fe-1@test-pf-project1.iam.gserviceaccount.com
member: serviceAccount:app-fe-1@test-pf-project1.iam.gserviceaccount.com
project: test-pf-project1
timeouts: null
module.service-accounts["project1/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@test-pf-project1.iam.gserviceaccount.com
member: serviceAccount:terraform-rw@test-pf-project1.iam.gserviceaccount.com
project: test-pf-project1
timeouts: null
module.service-accounts["project2/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@test-pf-project2.iam.gserviceaccount.com
member: serviceAccount:app-be-0@test-pf-project2.iam.gserviceaccount.com
project: test-pf-project2
timeouts: null
? module.service-accounts["project2/app-fe-1"].google_project_iam_member.project-roles["my-host-project-roles/compute.networkUser"]
: condition: []
project: my-host-project
role: roles/compute.networkUser
? module.service-accounts["project2/app-fe-1"].google_project_iam_member.project-roles["test-pf-project2-roles/storage.objectViewer"]
: condition: []
project: test-pf-project2
role: roles/storage.objectViewer
module.service-accounts["project2/app-fe-1"].google_service_account.service_account[0]:
account_id: app-fe-1
create_ignore_already_exists: null
description: null
disabled: false
display_name: GCE frontend service account.
email: app-fe-1@test-pf-project2.iam.gserviceaccount.com
member: serviceAccount:app-fe-1@test-pf-project2.iam.gserviceaccount.com
project: test-pf-project2
timeouts: null
module.service-accounts["project2/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@test-pf-project2.iam.gserviceaccount.com
member: serviceAccount:terraform-rw@test-pf-project2.iam.gserviceaccount.com
project: test-pf-project2
timeouts: null
counts:
google_essential_contacts_contact: 2
google_folder: 1
google_folder_iam_binding: 1
google_project: 2
google_project_iam_member: 6
google_project_service: 4
google_project_service_identity: 1
google_service_account: 6
google_storage_bucket: 2
google_storage_bucket_iam_binding: 1
google_storage_project_service_account: 1
modules: 11
resources: 27
outputs:
buckets:
project1/state: test-pf-project1-state
project2/state: test-pf-project2-state
folders: __missing__
projects: __missing__
service_accounts: __missing__

View File

@@ -0,0 +1,20 @@
# 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.
name: Team A
# implicit parent definition via 'default' key
iam:
roles/viewer:
- group:team-a-admins@example.org
- gcp-devops

View File

@@ -0,0 +1,35 @@
# 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
services:
- container.googleapis.com
- storage.googleapis.com
service_accounts:
app-be-0: {}
app-fe-1:
display_name: GCE frontend service account.
iam_self_roles:
- roles/storage.objectViewer
iam_project_roles:
my-host-project:
- roles/compute.networkUser
terraform-rw: {}
buckets:
state:
location: europe-west8
iam:
roles/storage.admin:
- terraform-rw

View File

@@ -0,0 +1,36 @@
# 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
labels:
app: app-0
team: team-a
parent: team-a
buckets:
state:
location: europe-west8
# iam:
# roles/storage.admin:
# - terraform-rw
service_accounts:
app-be-0: {}
app-fe-1:
display_name: GCE frontend service account.
iam_self_roles:
- roles/storage.objectViewer
iam_project_roles:
my-host-project:
- roles/compute.networkUser
terraform-rw: {}

View File

@@ -0,0 +1,35 @@
# 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
service_accounts:
app-be-0: {}
terraform-rw: {}
automation:
project: service-iac
service_accounts:
rw:
description: Service read/write automation sa.
ro:
description: Service read-only automation sa.
shared_vpc_service_config:
host_project: dev-spoke-0
network_users:
- terraform-rw
- ro
- rw

View File

@@ -0,0 +1,22 @@
# 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
services:
- compute.googleapis.com
- storage.googleapis.com
service_accounts:
app-be-0: {}
terraform-rw: {}

View File

@@ -0,0 +1,39 @@
# 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"
}
# 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,161 @@
# 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: my-prefix-service1-ro
create_ignore_already_exists: null
description: Service read-only automation sa.
disabled: false
display_name: Service account ro for service1.
email: my-prefix-service1-ro@service-iac.iam.gserviceaccount.com
member: serviceAccount:my-prefix-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: my-prefix-service1-rw
create_ignore_already_exists: null
description: Service read/write automation sa.
disabled: false
display_name: Service account rw for service1.
email: my-prefix-service1-rw@service-iac.iam.gserviceaccount.com
member: serviceAccount:my-prefix-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: my-prefix-service1
timeouts: null
? module.projects-iam["service1"].google_project_iam_member.shared_vpc_host_iam["serviceAccount:my-prefix-service1-ro@service-iac.iam.gserviceaccount.com"]
: condition: []
member: serviceAccount:my-prefix-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:my-prefix-service1-rw@service-iac.iam.gserviceaccount.com"]
: condition: []
member: serviceAccount:my-prefix-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@my-prefix-service1.iam.gserviceaccount.com"]
: condition: []
member: serviceAccount:terraform-rw@my-prefix-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: my-prefix-service1
org_id: null
project_id: my-prefix-service1
tags: null
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
module.projects["service2"].data.google_storage_project_service_account.gcs_sa[0]:
project: my-prefix-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: my-prefix-service2
org_id: null
project_id: my-prefix-service2
tags: null
terraform_labels:
goog-terraform-provisioned: 'true'
timeouts: null
module.projects["service2"].google_project_iam_member.service_agents["compute-system"]:
condition: []
project: my-prefix-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: my-prefix-service2
service: compute.googleapis.com
timeouts: null
module.projects["service2"].google_project_service.project_services["storage.googleapis.com"]:
disable_dependent_services: false
disable_on_destroy: false
project: my-prefix-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@my-prefix-service1.iam.gserviceaccount.com
member: serviceAccount:app-be-0@my-prefix-service1.iam.gserviceaccount.com
project: my-prefix-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@my-prefix-service1.iam.gserviceaccount.com
member: serviceAccount:terraform-rw@my-prefix-service1.iam.gserviceaccount.com
project: my-prefix-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@my-prefix-service2.iam.gserviceaccount.com
member: serviceAccount:app-be-0@my-prefix-service2.iam.gserviceaccount.com
project: my-prefix-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@my-prefix-service2.iam.gserviceaccount.com
member: serviceAccount:terraform-rw@my-prefix-service2.iam.gserviceaccount.com
project: my-prefix-service2
timeouts: null
counts:
google_compute_shared_vpc_service_project: 1
google_project: 2
google_project_iam_member: 4
google_project_service: 2
google_service_account: 6
google_storage_project_service_account: 1
modules: 9
resources: 16
outputs:
buckets: {}
folders: {}
projects: __missing__
service_accounts: __missing__

View File

@@ -0,0 +1,23 @@
# 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.
module: modules/project-factory
tests:
bucket_iam:
extra_dirs:
- ../../tests/modules/project_factory/data/bucket_iam
shared_vpc_network_user:
extra_dirs:
- ../../tests/modules/project_factory/data/shared_vpc_network_user/projects

64
tools/tftest_plan_summary.py Executable file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env python3
# 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
#
# https://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 click
import sys
import yaml
from pathlib import Path
try:
import fixtures
except ImportError:
BASEDIR = Path(__file__).parents[1]
sys.path.append(str(BASEDIR / 'tests'))
import fixtures
@click.command()
@click.argument('test_file', type=click.Path(), nargs=1)
@click.argument('test_name', nargs=1)
def main(test_file, test_name):
test_base_dir = Path(test_file).parent
try:
with open(test_file) as f:
raw = yaml.safe_load(f)
module = raw.pop('module')
except (IOError, OSError, yaml.YAMLError) as e:
raise Exception(f'cannot read test spec {test_file}: {e}')
except KeyError as e:
raise Exception(f'`module` key not found in {test_file}: {e}')
common = raw.pop('common_tfvars', [])
spec = raw.get('tests', {})[test_name] or {}
extra_dirs = spec.get('extra_dirs', [])
extra_files = spec.get('extra_files', [])
tf_var_files = common + [f'{test_name}.tfvars'] + spec.get('tfvars', [])
module_path = BASEDIR / module
summary = fixtures.plan_summary(module_path, test_base_dir, tf_var_files,
extra_files=extra_files,
extra_dirs=extra_dirs)
print(yaml.dump({'values': summary.values}))
print(yaml.dump({'counts': summary.counts}))
outputs = {
k: v.get('value', '__missing__') for k, v in summary.outputs.items()
}
print(yaml.dump({'outputs': outputs}))
if __name__ == '__main__':
main()