Skip to content

Commit

Permalink
Tags feature: support tags specification for NAT gateway (solves ansi…
Browse files Browse the repository at this point in the history
…ble-collections#345)

- implements tags feature for NAT gateway
- adds integration test tasks for tags feature
- refactor integration tests (overall) removing hard-coded parameters
- add missing integration test tasks without CHECK_MODE
  • Loading branch information
alinabuzachis committed Jan 28, 2021
2 parents 380f686 + dae62f4 commit 5622828
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 49 deletions.
32 changes: 10 additions & 22 deletions plugins/modules/ec2_vpc_nat_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@
type: bool
tags:
description:
- A dict of tags to apply to the internet gateway.
- A dict of tags to apply to the NAT gateway.
- To remove all tags set I(tags={}) and I(purge_tags=true).
aliases: [ 'resource_tags' ]
type: dict
version_added: 1.4.0
purge_tags:
description:
- Remove tags not listed in I(tags).
Expand Down Expand Up @@ -173,8 +174,8 @@
allocation_id: eipalloc-12345678
region: ap-southeast-2
tags:
- Tag1: tag1
- Tag2: tag2
Name: nonprod NAT gateway
status: testing
register: new_nat_gateway
'''

Expand Down Expand Up @@ -736,7 +737,7 @@ def create(client, module, subnet_id, allocation_id, tags, purge_tags, client_to
result['tags'], tags_update_exists = ensure_tags(
client, module, nat_gw_id=result['nat_gateway_id'], tags=tags,
purge_tags=purge_tags, check_mode=check_mode
)
)
except is_boto3_error_code('IdempotentParameterMismatch'):
err_msg = (
'NAT Gateway does not support update and token has already been provided: ' + err_msg
Expand Down Expand Up @@ -810,8 +811,6 @@ def pre_create(client, module, subnet_id, tags, purge_tags, allocation_id=None,
err_msg = ""
results = list()

check_input_tags(module, tags)

if not allocation_id and not eip_address:
existing_gateways, allocation_id_exists = (gateway_in_subnet_exists(client, subnet_id, check_mode=check_mode))
if len(existing_gateways) > 0 and if_exist_do_not_create:
Expand Down Expand Up @@ -981,20 +980,9 @@ def remove(client, nat_gateway_id, wait=False, wait_timeout=0,
return success, changed, err_msg, results


def check_input_tags(module, tags):
if tags is None:
return
nonstring_tags = [k for k, v in tags.items() if not isinstance(v, string_types)]
if nonstring_tags:
module.fail_json(
msg='One or more tags contain non-string values: {0}'
.format(nonstring_tags)
)


def ensure_tags(client, module, nat_gw_id, tags, purge_tags, check_mode):
final_tags = []
results = False
changed = False

filters = ansible_dict_to_boto3_filter_list({'resource-id': nat_gw_id, 'resource-type': 'natgateway'})
cur_tags = None
Expand All @@ -1003,7 +991,7 @@ def ensure_tags(client, module, nat_gw_id, tags, purge_tags, check_mode):
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, 'Couldnt describe tags')
if tags is None:
return boto3_tag_list_to_ansible_dict(cur_tags['Tags']), results
return boto3_tag_list_to_ansible_dict(cur_tags['Tags']), changed

to_update, to_delete = compare_aws_tags(boto3_tag_list_to_ansible_dict(cur_tags.get('Tags')), tags, purge_tags)
final_tags = boto3_tag_list_to_ansible_dict(cur_tags.get('Tags'))
Expand All @@ -1020,7 +1008,7 @@ def ensure_tags(client, module, nat_gw_id, tags, purge_tags, check_mode):
Tags=ansible_dict_to_boto3_tag_list(to_update)
)

results = True
changed = True
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, "Couldn't create tags")

Expand All @@ -1037,7 +1025,7 @@ def ensure_tags(client, module, nat_gw_id, tags, purge_tags, check_mode):

client.delete_tags(aws_retry=True, Resources=[nat_gw_id], Tags=tags_list)

results = True
changed = True
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, "Couldn't delete tags")

Expand All @@ -1047,7 +1035,7 @@ def ensure_tags(client, module, nat_gw_id, tags, purge_tags, check_mode):
final_tags = boto3_tag_list_to_ansible_dict(response.get('Tags'))
except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e:
module.fail_json_aws(e, "Couldn't describe tags")
return final_tags, results
return final_tags, changed


def main():
Expand Down
62 changes: 35 additions & 27 deletions tests/integration/targets/ec2_vpc_nat_gateway/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@
# when CHECK_MODE is used, don't correspond to those used for the DRY_RUN_GATEWAY and all test
# (except when the NAT gateway is created for the first time) fail.
#
# `Create new NAT gateway with eip address` - when the task is run for the first time, do we expect changed=true?
# `Create new NAT gateway with eip address` (line 173) - when the task is run for the first time, do we expect changed=true?
# As we use the same EIP, I think changed should be false (if this is correct, lines 194-218 are redundant and
# lines 177 and 190 should report `not create_ngw.changed`).
#
#`Delete NAT gateway` in always block throws `(DependencyViolation) when calling the DeleteVpc operation`
# lines 177 and 190 should report `not create_ngw.changed`).
# ============================================================

- name: ec2_vpc_nat_gateway tests
Expand Down Expand Up @@ -97,8 +95,7 @@
that:
- existing_ngws is successful
- (existing_ngws.result|length) == 0




# ============================================================
- name: Create IGW
Expand All @@ -124,25 +121,26 @@
assert:
that:
- create_ngw.changed

- name: "set facts: NAT gateway ID"
set_fact:
nat_gateway_id: "{{ create_ngw.nat_gateway_id }}"
network_interface_id: "{{ create_ngw.nat_gateway_addresses.0.network_interface_id }}"

- name: Create new NAT gateway with eip allocation-id - CHECK_MODE
ec2_vpc_nat_gateway:
subnet_id: "{{ subnet_id }}"
allocation_id: "{{ allocation_id }}"
wait: yes
register: create_ngw
register: create_ngw_check
check_mode: yes

- name: Assert creation happened (expected changed=true) - CHECK_MODE
assert:
that:
- create_ngw.changed

- name: "set facts: NAT gateway ID"
set_fact:
nat_gateway_id: "{{ create_ngw.nat_gateway_id }}"
network_interface_id: "{{ create_ngw.nat_gateway_addresses.0.network_interface_id }}"


# ============================================================
- name: Trying this again for idempotency - create new NAT gateway with eip allocation-id
ec2_vpc_nat_gateway:
Expand Down Expand Up @@ -266,7 +264,7 @@

# - name: Delete NAT gateway - CHECK_MODE
# ec2_vpc_nat_gateway:
# nat_gateway_id: "{{ nat_gateway_id }}"
# nat_gateway_id: "{{ nat_gateway_id_check }}"
# state: absent
# wait: yes
# register: delete_nat_gateway
Expand All @@ -293,7 +291,7 @@
that:
- create_ngw.changed

# - name: Create new NAT gateway with eip allocation-id and tags - CHECK_MODE
# - name: Create new NAT gateway with eip allocation-id and tags - CHECK_MODE
# ec2_vpc_nat_gateway:
# subnet_id: "{{ subnet_id }}"
# allocation_id: "{{ allocation_id }}"
Expand All @@ -309,7 +307,8 @@
# that:
# - create_ngw.changed




# ============================================================
- name: Update the tags (no change)
ec2_vpc_nat_gateway:
Expand Down Expand Up @@ -491,33 +490,42 @@


always:

- name: Get NAT gateways
ec2_vpc_nat_gateway_info:
filters:
vpc-id: "{{ vpc_id }}"
register: existing_nat_gateways

- name: Tidy up NAT gateway
ec2_vpc_nat_gateway:
subnet_id: "{{ subnet_id }}"
nat_gateway_id: "{{ nat_gateway_id }}"
subnet_id: "{{ item.subnet_id }}"
nat_gateway_id: "{{ item.nat_gateway_id }}"
#release_eip: yes
state: absent
wait: yes
with_items: "{{ existing_nat_gateways.result }}"
ignore_errors: true

- name: Delete IGW
ec2_vpc_igw:
vpc_id: "{{ vpc_id }}"
state: absent
ignore_errors: true


- name: Remove subnet
ec2_vpc_subnet:
state: absent
cidr: "{{ subnet_cidr }}"
vpc_id: "{{ subnet_id }}"
ignore_errors: true
vpc_id: "{{ vpc_id }}"
ignore_errors: true

- name: Delete IGW
ec2_vpc_igw:
vpc_id: "{{ vpc_id }}"
state: absent
ignore_errors: true

- name: Ensure EIP is actually released
ec2_eip:
state: absent
device_id: "{{ network_interface_id }}"
device_id: "{{ item.nat_gateway_addresses[0].network_interface_id }}"
in_vpc: yes
loop: "{{ existing_nat_gateways.result }}"
ignore_errors: yes

- name: Delete VPC
Expand Down

0 comments on commit 5622828

Please sign in to comment.