Skip to content

Commit c5fdee3

Browse files
committed
Prepare ec2_placement_group* module for promotion (ansible-collections#2167)
SUMMARY This PR refactors ec2_placement_group*. Depends-On: ansible-collections#2322 Refer: https://issues.redhat.com/browse/ACA-1886 ISSUE TYPE Bugfix Pull Request Docs Pull Request Feature Pull Request New Module Pull Request COMPONENT NAME ADDITIONAL INFORMATION Reviewed-by: Bikouo Aubin Reviewed-by: GomathiselviS <[email protected]> Reviewed-by: Alina Buzachis This commit was initially merged in https://github.com/ansible-collections/community.aws See: ansible-collections/community.aws@290e89a
1 parent bef47de commit c5fdee3

File tree

5 files changed

+185
-190
lines changed

5 files changed

+185
-190
lines changed

plugins/modules/ec2_placement_group.py

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
partition_count:
2626
description:
2727
- The number of partitions.
28-
- Valid only when I(Strategy) is set to C(partition).
29-
- Must be a value between C(1) and C(7).
28+
- Valid only when O(strategy) is set to V(partition).
29+
- Must be a value between V(1) and V(7).
3030
type: int
3131
version_added: 3.1.0
3232
state:
@@ -86,83 +86,88 @@
8686
placement_group:
8787
description: Placement group attributes
8888
returned: when state != absent
89-
type: complex
89+
type: dict
9090
contains:
91+
group_arn:
92+
description: Placement Group ARN.
93+
type: str
94+
returned: always
95+
sample: "arn:aws:ec2:us-east-1:123456789012:placement-group"
96+
group_id:
97+
description: Placement Group Id.
98+
type: str
99+
returned: always
100+
sample: "pg-123456789012"
91101
name:
92-
description: PG name
102+
description: Placement Group name.
103+
type: str
104+
returned: always
105+
sample: "my-cluster"
106+
partition_count:
107+
description: Partition Count.
93108
type: str
94-
sample: my-cluster
109+
returned: If applicable
110+
sample: "my-cluster"
95111
state:
96-
description: PG state
112+
description: Placement Groupt state.
97113
type: str
114+
returned: If applicable
98115
sample: "available"
99116
strategy:
100-
description: PG strategy
117+
description: Placement Group strategy.
101118
type: str
119+
returned: If applicable
102120
sample: "cluster"
103121
tags:
104-
description: Tags associated with the placement group
122+
description: Tags associated with the placement group.
105123
type: dict
124+
returned: If applicable
106125
version_added: 8.1.0
107126
sample:
108127
tags:
109128
some: value1
110129
other: value2
111130
"""
112131

113-
try:
114-
import botocore
115-
except ImportError:
116-
pass # caught by AnsibleAWSModule
132+
from typing import Any
133+
from typing import Dict
117134

118-
from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code
119-
from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry
135+
from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict
136+
137+
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import create_ec2_placement_group
138+
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import delete_ec2_placement_group
139+
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_ec2_placement_groups
120140
from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict
121141
from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications
122142

123143
from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule
124144

125145

126-
@AWSRetry.exponential_backoff()
127-
def search_placement_group(connection, module):
146+
def search_placement_group(connection, name: str) -> Dict[str, Any]:
128147
"""
129148
Check if a placement group exists.
130149
"""
131-
name = module.params.get("name")
132-
try:
133-
response = connection.describe_placement_groups(Filters=[{"Name": "group-name", "Values": [name]}])
134-
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
135-
module.fail_json_aws(e, msg=f"Couldn't find placement group named [{name}]")
150+
response = describe_ec2_placement_groups(connection, Filters=[{"Name": "group-name", "Values": [name]}])
136151

137-
if len(response["PlacementGroups"]) != 1:
152+
if len(response) != 1:
138153
return None
139154
else:
140-
placement_group = response["PlacementGroups"][0]
141-
return {
142-
"name": placement_group["GroupName"],
143-
"state": placement_group["State"],
144-
"strategy": placement_group["Strategy"],
145-
"tags": boto3_tag_list_to_ansible_dict(placement_group.get("Tags")),
146-
}
155+
return format_placement_group_information(response[0])
147156

148157

149-
@AWSRetry.exponential_backoff(catch_extra_error_codes=["InvalidPlacementGroup.Unknown"])
150-
def get_placement_group_information(connection, name):
158+
def format_placement_group_information(response: Dict[str, Any]) -> Dict[str, Any]:
151159
"""
152-
Retrieve information about a placement group.
160+
Format placement group information
153161
"""
154-
response = connection.describe_placement_groups(GroupNames=[name])
155-
placement_group = response["PlacementGroups"][0]
156-
return {
157-
"name": placement_group["GroupName"],
158-
"state": placement_group["State"],
159-
"strategy": placement_group["Strategy"],
160-
"tags": boto3_tag_list_to_ansible_dict(placement_group.get("Tags")),
161-
}
162-
163-
164-
@AWSRetry.exponential_backoff()
165-
def create_placement_group(connection, module):
162+
163+
response = camel_dict_to_snake_dict(response, ignore_list=["Tags"])
164+
if "tags" in response:
165+
response["tags"] = boto3_tag_list_to_ansible_dict(response.get("tags", []))
166+
response["name"] = response["group_name"]
167+
return response
168+
169+
170+
def create_placement_group(connection, module: AnsibleAWSModule) -> None:
166171
name = module.params.get("name")
167172
strategy = module.params.get("strategy")
168173
tags = module.params.get("tags")
@@ -178,38 +183,26 @@ def create_placement_group(connection, module):
178183
params["TagSpecifications"] = boto3_tag_specifications(tags, types=["placement-group"])
179184
if partition_count:
180185
params["PartitionCount"] = partition_count
181-
params["DryRun"] = module.check_mode
182-
183-
try:
184-
connection.create_placement_group(**params)
185-
except is_boto3_error_code("DryRunOperation"):
186+
if module.check_mode:
186187
module.exit_json(
187188
changed=True,
188189
placement_group={
189190
"name": name,
190-
"state": "DryRun",
191191
"strategy": strategy,
192192
"tags": tags,
193193
},
194+
msg="EC2 placement group would be created if not in check mode",
194195
)
195-
except (
196-
botocore.exceptions.ClientError,
197-
botocore.exceptions.BotoCoreError,
198-
) as e: # pylint: disable=duplicate-except
199-
module.fail_json_aws(e, msg=f"Couldn't create placement group [{name}]")
200196

201-
module.exit_json(changed=True, placement_group=get_placement_group_information(connection, name))
197+
response = create_ec2_placement_group(connection, **params)
198+
module.exit_json(changed=True, placement_group=format_placement_group_information(response))
202199

203200

204-
@AWSRetry.exponential_backoff()
205-
def delete_placement_group(connection, module):
201+
def delete_placement_group(connection, module: AnsibleAWSModule) -> None:
202+
if module.check_mode:
203+
module.exit_json(changed=True, msg="VPC would be deleted if not in check mode")
206204
name = module.params.get("name")
207-
208-
try:
209-
connection.delete_placement_group(GroupName=name, DryRun=module.check_mode)
210-
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
211-
module.fail_json_aws(e, msg=f"Couldn't delete placement group [{name}]")
212-
205+
delete_ec2_placement_group(connection, name)
213206
module.exit_json(changed=True)
214207

215208

@@ -227,9 +220,10 @@ def main():
227220
connection = module.client("ec2")
228221

229222
state = module.params.get("state")
223+
name = module.params.get("name")
224+
placement_group = search_placement_group(connection, name)
230225

231226
if state == "present":
232-
placement_group = search_placement_group(connection, module)
233227
if placement_group is None:
234228
create_placement_group(connection, module)
235229
else:
@@ -243,7 +237,6 @@ def main():
243237
)
244238

245239
elif state == "absent":
246-
placement_group = search_placement_group(connection, module)
247240
if placement_group is None:
248241
module.exit_json(changed=False)
249242
else:

plugins/modules/ec2_placement_group_info.py

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
name:
5959
description: PG name
6060
type: str
61-
sample: my-cluster
61+
sample: "my-cluster"
6262
state:
6363
description: PG state
6464
type: str
@@ -77,36 +77,28 @@
7777
other: value2
7878
"""
7979

80-
try:
81-
from botocore.exceptions import BotoCoreError
82-
from botocore.exceptions import ClientError
83-
except ImportError:
84-
pass # caught by AnsibleAWSModule
80+
from typing import Any
81+
from typing import Dict
82+
from typing import List
8583

84+
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_ec2_placement_groups
85+
from ansible_collections.amazon.aws.plugins.module_utils.modules import AnsibleAWSModule
8686
from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict
8787

88-
from ansible_collections.community.aws.plugins.module_utils.modules import AnsibleCommunityAWSModule as AnsibleAWSModule
8988

90-
91-
def get_placement_groups_details(connection, module):
92-
names = module.params.get("names")
93-
try:
94-
if len(names) > 0:
95-
response = connection.describe_placement_groups(
96-
Filters=[
97-
{
98-
"Name": "group-name",
99-
"Values": names,
100-
}
101-
]
102-
)
103-
else:
104-
response = connection.describe_placement_groups()
105-
except (BotoCoreError, ClientError) as e:
106-
module.fail_json_aws(e, msg=f"Couldn't find placement groups named [{names}]")
89+
def get_placement_groups_details(connection, names: List) -> Dict[str, Any]:
90+
params = {}
91+
if len(names) > 0:
92+
params["Filters"] = [
93+
{
94+
"Name": "group-name",
95+
"Values": names,
96+
}
97+
]
98+
response = describe_ec2_placement_groups(connection, **params)
10799

108100
results = []
109-
for placement_group in response["PlacementGroups"]:
101+
for placement_group in response:
110102
results.append(
111103
{
112104
"name": placement_group["GroupName"],
@@ -129,8 +121,9 @@ def main():
129121
)
130122

131123
connection = module.client("ec2")
124+
names = module.params.get("names")
132125

133-
placement_groups = get_placement_groups_details(connection, module)
126+
placement_groups = get_placement_groups_details(connection, names)
134127
module.exit_json(changed=False, placement_groups=placement_groups)
135128

136129

tests/integration/targets/ec2_placement_group/tasks/env_cleanup.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
- name: remove any instances in the test VPC
2-
ec2_instance:
1+
- name: Remove any instances in the test VPC
2+
amazon.aws.ec2_instance:
33
filters:
44
vpc_id: "{{ testing_vpc.vpc.id }}"
55
state: absent
@@ -9,22 +9,22 @@
99
retries: 10
1010

1111
- name: Get ENIs
12-
ec2_eni_info:
12+
amazon.aws.ec2_eni_info:
1313
filters:
1414
vpc-id: "{{ testing_vpc.vpc.id }}"
1515
register: enis
1616

17-
- name: delete all ENIs
18-
ec2_eni:
17+
- name: Delete all ENIs
18+
amazon.aws.ec2_eni:
1919
eni_id: "{{ item.id }}"
2020
state: absent
2121
until: removed is not failed
2222
with_items: "{{ enis.network_interfaces }}"
2323
ignore_errors: yes
2424
retries: 10
2525

26-
- name: remove the security group
27-
ec2_security_group:
26+
- name: Remove the security group
27+
amazon.aws.ec2_security_group:
2828
name: "{{ resource_prefix }}-sg"
2929
description: a security group for ansible tests
3030
vpc_id: "{{ testing_vpc.vpc.id }}"
@@ -34,8 +34,8 @@
3434
ignore_errors: yes
3535
retries: 10
3636

37-
- name: remove routing rules
38-
ec2_vpc_route_table:
37+
- name: Remove routing rules
38+
amazon.aws.ec2_vpc_route_table:
3939
state: absent
4040
vpc_id: "{{ testing_vpc.vpc.id }}"
4141
tags:
@@ -51,17 +51,17 @@
5151
ignore_errors: yes
5252
retries: 10
5353

54-
- name: remove internet gateway
55-
ec2_vpc_igw:
54+
- name: Remove internet gateway
55+
amazon.aws.ec2_vpc_igw:
5656
vpc_id: "{{ testing_vpc.vpc.id }}"
5757
state: absent
5858
register: removed
5959
until: removed is not failed
6060
ignore_errors: yes
6161
retries: 10
6262

63-
- name: remove subnet A
64-
ec2_vpc_subnet:
63+
- name: Remove subnet A
64+
amazon.aws.ec2_vpc_subnet:
6565
state: absent
6666
vpc_id: "{{ testing_vpc.vpc.id }}"
6767
cidr: 10.22.32.0/24
@@ -70,8 +70,8 @@
7070
ignore_errors: yes
7171
retries: 10
7272

73-
- name: remove subnet B
74-
ec2_vpc_subnet:
73+
- name: Remove subnet B
74+
amazon.aws.ec2_vpc_subnet:
7575
state: absent
7676
vpc_id: "{{ testing_vpc.vpc.id }}"
7777
cidr: 10.22.33.0/24
@@ -80,8 +80,8 @@
8080
ignore_errors: yes
8181
retries: 10
8282

83-
- name: remove the VPC
84-
ec2_vpc_net:
83+
- name: Remove the VPC
84+
amazon.aws.ec2_vpc_net:
8585
name: "{{ resource_prefix }}-vpc"
8686
cidr_block: 10.22.32.0/23
8787
state: absent

0 commit comments

Comments
 (0)