Skip to content

Commit a0306d7

Browse files
authored
Allow nested_type terraform attributes (#101)
* Allow terraform resource_schema attributes with nested_type Fixes #93 Signed-off-by: Justin Cinkelj <[email protected]> * Test nested_type attributes by using awscc Signed-off-by: Justin Cinkelj <[email protected]> * Update unit tests Signed-off-by: Justin Cinkelj <[email protected]> * Add changelog fragment Signed-off-by: Justin Cinkelj <[email protected]> * fix linters, mypy Signed-off-by: Justin Cinkelj <[email protected]> * isort fix Signed-off-by: Justin Cinkelj <[email protected]> --------- Signed-off-by: Justin Cinkelj <[email protected]>
1 parent 957b64b commit a0306d7

File tree

6 files changed

+319
-17
lines changed

6 files changed

+319
-17
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
bugfixes:
3+
- >-
4+
Allow `nested_type` attributes in terraform schema.
5+
(https://github.com/ansible-collections/cloud.terraform/issues/93)

plugins/module_utils/models.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,6 @@ def from_json(cls, json: TJsonObject) -> "TerraformShow":
144144

145145
@dataclass
146146
class TerraformAttributeSpec:
147-
type: Union[str, List[str]]
148147
description_kind: str
149148

150149
# potentially undefined
@@ -157,6 +156,39 @@ class TerraformAttributeSpec:
157156

158157
@classmethod
159158
def from_json(cls, json: TJsonObject) -> "TerraformAttributeSpec":
159+
if "nested_type" in json:
160+
return TerraformNestedAttributeSpec.from_json(json)
161+
else:
162+
return TerraformSimpleAttributeSpec.from_json(json)
163+
164+
165+
@dataclass
166+
class TerraformNestedAttributeSpec(TerraformAttributeSpec):
167+
nested_attributes: Dict[str, TerraformAttributeSpec]
168+
169+
@classmethod
170+
def from_json(cls, json: TJsonObject) -> "TerraformNestedAttributeSpec":
171+
return cls(
172+
nested_attributes={
173+
sub_attribute_name: TerraformAttributeSpec.from_json(sub_attribute_item)
174+
for sub_attribute_name, sub_attribute_item in json.get("nested_type", {}).get("attributes", {}).items()
175+
},
176+
description_kind=json["description_kind"],
177+
description=json.get("description"),
178+
optional=json.get("optional", False),
179+
required=json.get("required", False),
180+
deprecated=json.get("deprecated", False),
181+
sensitive=json.get("sensitive", False),
182+
computed=json.get("computed", False),
183+
)
184+
185+
186+
@dataclass
187+
class TerraformSimpleAttributeSpec(TerraformAttributeSpec):
188+
type: Union[str, List[str]]
189+
190+
@classmethod
191+
def from_json(cls, json: TJsonObject) -> "TerraformSimpleAttributeSpec":
160192
return cls(
161193
type=json["type"],
162194
description_kind=json["description_kind"],
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cloud/aws
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
terraform {
2+
required_providers {
3+
awscc = {
4+
source = "hashicorp/awscc"
5+
version = "=0.63.0"
6+
}
7+
}
8+
}
9+
10+
provider "awscc" {
11+
}
12+
13+
variable "cloud_terraform_integration_id" {
14+
type = string
15+
default = "jci93"
16+
}
17+
18+
variable "cidr_block" {
19+
type = string
20+
default = "10.1.2.0/24"
21+
}
22+
23+
resource "awscc_ec2_vpc" "test_vpc" {
24+
cidr_block = var.cidr_block
25+
tags = [
26+
{
27+
key = "Name",
28+
value = var.cloud_terraform_integration_id,
29+
},
30+
{
31+
key = "cloud_terraform_integration",
32+
value = "true",
33+
},
34+
]
35+
}
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
# Copyright (c) Ansible Project
3+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
4+
# SPDX-License-Identifier: GPL-3.0-or-later
5+
- environment:
6+
AWS_ACCESS_KEY_ID: "{{ aws_access_key | default(omit) }}"
7+
AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key | default(omit) }}"
8+
AWS_SESSION_TOKEN: "{{ security_token | default(omit) }}"
9+
AWS_REGION: "{{ aws_region | default(omit) }}"
10+
11+
block:
12+
- set_fact:
13+
test_basedir: "{{ test_basedir | default(output_dir) }}"
14+
resource_id: "{{ resource_prefix }}-awscc-vpc"
15+
vpc_cidr_block: '10.{{ 256 | random(seed=resource_prefix) }}.0.0/24'
16+
17+
- name: Copy terraform files to workspace
18+
ansible.builtin.copy:
19+
src: "{{ item }}"
20+
dest: "{{ test_basedir }}/{{ item }}"
21+
loop:
22+
- cloud.tf
23+
24+
- &verification
25+
block:
26+
- name: Fetch VPC info
27+
amazon.aws.ec2_vpc_net_info:
28+
filters:
29+
"tag:Name": "{{ resource_id }}"
30+
"cidr": "{{ vpc_cidr_block }}"
31+
register: vpc_info
32+
33+
- name: Assert that there are {{ number_of_vpcs }} VPCs with tag:Name={{ resource_id }} and cidr={{ vpc_cidr_block }}'
34+
assert:
35+
that:
36+
- (vpc_info.vpcs | length) == number_of_vpcs
37+
- name: Assert that VPC {{ resource_id }} is present and the info matches
38+
assert:
39+
that:
40+
- vpc_info.vpcs[0].cidr_block == "{{ vpc_cidr_block }}"
41+
- vpc_info.vpcs[0].tags.Name == "{{ resource_id }}"
42+
when: number_of_vpcs == 1
43+
vars:
44+
number_of_vpcs: 0
45+
46+
- name: Terraform in present check mode
47+
cloud.terraform.terraform:
48+
project_path: "{{ test_basedir }}"
49+
state: present
50+
force_init: true
51+
variables:
52+
cloud_terraform_integration_id: "{{ resource_id }}"
53+
cidr_block: "{{ vpc_cidr_block }}"
54+
register: terraform_result
55+
check_mode: true
56+
57+
- assert:
58+
that:
59+
- terraform_result is not failed
60+
- terraform_result is changed
61+
62+
- <<: *verification
63+
vars:
64+
number_of_vpcs: 0
65+
66+
- name: Terraform in present non-check mode
67+
cloud.terraform.terraform:
68+
project_path: "{{ test_basedir }}"
69+
state: present
70+
force_init: true
71+
variables:
72+
cloud_terraform_integration_id: "{{ resource_id }}"
73+
cidr_block: "{{ vpc_cidr_block }}"
74+
register: terraform_result
75+
check_mode: false
76+
77+
- assert:
78+
that:
79+
- terraform_result is not failed
80+
- terraform_result is changed
81+
82+
- <<: *verification
83+
vars:
84+
number_of_vpcs: 1
85+
86+
- name: Terraform in present non-check mode (idempotency)
87+
cloud.terraform.terraform:
88+
project_path: "{{ test_basedir }}"
89+
state: present
90+
force_init: true
91+
variables:
92+
cloud_terraform_integration_id: "{{ resource_id }}"
93+
cidr_block: "{{ vpc_cidr_block }}"
94+
register: terraform_result
95+
check_mode: false
96+
97+
- assert:
98+
that:
99+
- terraform_result is not failed
100+
- terraform_result is not changed
101+
102+
- <<: *verification
103+
vars:
104+
number_of_vpcs: 1
105+
106+
- name: Terraform in absent check mode
107+
cloud.terraform.terraform:
108+
project_path: "{{ test_basedir }}"
109+
state: absent
110+
force_init: true
111+
variables:
112+
cloud_terraform_integration_id: "{{ resource_id }}"
113+
cidr_block: "{{ vpc_cidr_block }}"
114+
register: terraform_result
115+
check_mode: true
116+
117+
- assert:
118+
that:
119+
- terraform_result is not failed
120+
- terraform_result is changed
121+
122+
- <<: *verification
123+
vars:
124+
number_of_vpcs: 1
125+
126+
- name: Terraform in absent non-check mode
127+
cloud.terraform.terraform:
128+
project_path: "{{ test_basedir }}"
129+
state: absent
130+
force_init: true
131+
variables:
132+
cloud_terraform_integration_id: "{{ resource_id }}"
133+
cidr_block: "{{ vpc_cidr_block }}"
134+
register: terraform_result
135+
check_mode: false
136+
137+
- assert:
138+
that:
139+
- terraform_result is not failed
140+
- terraform_result is changed
141+
142+
- <<: *verification
143+
vars:
144+
number_of_vpcs: 0
145+
146+
# Clean up all integration test resources
147+
always:
148+
- name: Fetch VPC info
149+
amazon.aws.ec2_vpc_net_info:
150+
filters:
151+
"tag:Name": "{{ resource_id }}"
152+
"cidr": "{{ vpc_cidr_block }}"
153+
register: vpc_info
154+
ignore_errors: true
155+
156+
- name: Delete VPC
157+
amazon.aws.ec2_vpc_net:
158+
vpc_id: "{{ item.vpc_id }}"
159+
state: absent
160+
loop: "{{ vpc_info.vpcs }}"
161+
ignore_errors: true

0 commit comments

Comments
 (0)