Skip to content

Commit

Permalink
ec2_vpc_nacl - Add support for purge_tags
Browse files Browse the repository at this point in the history
  • Loading branch information
tremble committed Jun 1, 2022
1 parent b11ffae commit e8e19c9
Show file tree
Hide file tree
Showing 10 changed files with 740 additions and 518 deletions.
4 changes: 4 additions & 0 deletions changelogs/fragments/1189-ec2_vpc_nacl-tagging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
minor_changes:
- ec2_vpc_nacl - add support for ``purge_tags`` parameter (https://github.com/ansible-collections/community.aws/pull/1189).
- ec2_vpc_nacl - ``resource_tags`` has been added as an alias for the ``tags`` parameter (https://github.com/ansible-collections/community.aws/pull/1189).
- ec2_vpc_nacl - the default value for ``tags`` has been updated, to remove all tags the ``tags`` parameter must be explicitly set to the empty dict ``{}`` and ``purge_tags`` to ``True`` (https://github.com/ansible-collections/community.aws/pull/1189).
109 changes: 38 additions & 71 deletions plugins/modules/ec2_vpc_nacl.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

DOCUMENTATION = r'''
module: ec2_vpc_nacl
short_description: create and delete Network ACLs.
short_description: create and delete Network ACLs
version_added: 1.0.0
description:
- Read the AWS documentation for Network ACLS
Expand Down Expand Up @@ -64,11 +64,6 @@
required: false
type: list
elements: list
tags:
description:
- Dictionary of tags to look for and apply when creating a network ACL.
required: false
type: dict
state:
description:
- Creates or modifies an existing NACL
Expand All @@ -79,8 +74,11 @@
default: present
author: Mike Mochan (@mmochan)
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
- amazon.aws.aws
- amazon.aws.ec2
- amazon.aws.tags
notes:
- Support for I(purge_tags) was added in release 4.0.0.
'''

EXAMPLES = r'''
Expand Down Expand Up @@ -161,6 +159,8 @@

from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AWSRetry
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ensure_ec2_tags
from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_specifications

# VPC-supported IANA protocol numbers
# http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml
Expand All @@ -173,17 +173,6 @@ def icmp_present(entry):
return True


def load_tags(module):
tags = []
if module.params.get('tags'):
for name, value in module.params.get('tags').items():
tags.append({'Key': name, 'Value': str(value)})
tags.append({'Key': "Name", 'Value': module.params.get('name')})
else:
tags.append({'Key': "Name", 'Value': module.params.get('name')})
return tags


def subnets_removed(nacl_id, subnets, client, module):
results = find_acl_by_id(nacl_id, client, module)
associations = results['NetworkAcls'][0]['Associations']
Expand Down Expand Up @@ -243,27 +232,25 @@ def nacls_changed(nacl, client, module):


def tags_changed(nacl_id, client, module):
tags = module.params.get('tags')
name = module.params.get('name')
purge_tags = module.params.get('purge_tags')
changed = False
tags = dict()
if module.params.get('tags'):
tags = module.params.get('tags')
if module.params.get('name') and not tags.get('Name'):
tags['Name'] = module.params['name']
nacl = find_acl_by_id(nacl_id, client, module)
if nacl['NetworkAcls']:
nacl_values = [t.values() for t in nacl['NetworkAcls'][0]['Tags']]
nacl_tags = [item for sublist in nacl_values for item in sublist]
tag_values = [[key, str(value)] for key, value in tags.items()]
tags = [item for sublist in tag_values for item in sublist]
if sorted(nacl_tags) == sorted(tags):
changed = False
return changed
else:
delete_tags(nacl_id, client, module)
create_tags(nacl_id, client, module)
changed = True
return changed
return changed

if name is None and tags is None:
return False

if module.params.get('tags') is None:
# Only purge tags if tags is explicitly set to {} and purge_tags is True
purge_tags = False

new_tags = dict()
if module.params.get('name') is not None:
new_tags['Name'] = module.params.get('name')
new_tags.update(module.params.get('tags') or {})

return ensure_ec2_tags(client, module, nacl_id, tags=new_tags,
purge_tags=purge_tags, retry_codes=['InvalidNetworkAclID.NotFound'])


def rules_changed(aws_rules, param_rules, Egress, nacl_id, client, module):
Expand Down Expand Up @@ -340,9 +327,12 @@ def setup_network_acl(client, module):
changed = False
nacl = describe_network_acl(client, module)
if not nacl['NetworkAcls']:
nacl = create_network_acl(module.params.get('vpc_id'), client, module)
tags = {}
if module.params.get('name'):
tags['Name'] = module.params.get('name')
tags.update(module.params.get('tags') or {})
nacl = create_network_acl(module.params.get('vpc_id'), client, module, tags)
nacl_id = nacl['NetworkAcl']['NetworkAclId']
create_tags(nacl_id, client, module)
subnets = subnets_to_associate(nacl, client, module)
replace_network_acl_association(nacl_id, subnets, client, module)
construct_acl_entries(nacl, client, module)
Expand Down Expand Up @@ -389,12 +379,15 @@ def _create_network_acl(client, *args, **kwargs):
return client.create_network_acl(*args, **kwargs)


def create_network_acl(vpc_id, client, module):
def create_network_acl(vpc_id, client, module, tags):
params = dict(VpcId=vpc_id)
if tags:
params['TagSpecifications'] = boto3_tag_specifications(tags, ['network-acl'])
try:
if module.check_mode:
nacl = dict(NetworkAcl=dict(NetworkAclId="nacl-00000000"))
else:
nacl = _create_network_acl(client, VpcId=vpc_id)
nacl = _create_network_acl(client, **params)
except botocore.exceptions.ClientError as e:
module.fail_json_aws(e)
return nacl
Expand All @@ -413,20 +406,6 @@ def create_network_acl_entry(params, client, module):
module.fail_json_aws(e)


@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound'])
def _create_tags(client, *args, **kwargs):
return client.create_tags(*args, **kwargs)


def create_tags(nacl_id, client, module):
try:
delete_tags(nacl_id, client, module)
if not module.check_mode:
_create_tags(client, Resources=[nacl_id], Tags=load_tags(module))
except botocore.exceptions.ClientError as e:
module.fail_json_aws(e)


@AWSRetry.jittered_backoff()
def _delete_network_acl(client, *args, **kwargs):
return client.delete_network_acl(*args, **kwargs)
Expand All @@ -453,19 +432,6 @@ def delete_network_acl_entry(params, client, module):
module.fail_json_aws(e)


@AWSRetry.jittered_backoff(catch_extra_error_codes=['InvalidNetworkAclID.NotFound'])
def _delete_tags(client, *args, **kwargs):
return client.delete_tags(*args, **kwargs)


def delete_tags(nacl_id, client, module):
try:
if not module.check_mode:
_delete_tags(client, Resources=[nacl_id])
except botocore.exceptions.ClientError as e:
module.fail_json_aws(e)


@AWSRetry.jittered_backoff()
def _describe_network_acls(client, **kwargs):
return client.describe_network_acls(**kwargs)
Expand Down Expand Up @@ -614,7 +580,8 @@ def main():
name=dict(),
nacl_id=dict(),
subnets=dict(required=False, type='list', default=list(), elements='str'),
tags=dict(required=False, type='dict'),
tags=dict(required=False, type='dict', aliases=['resource_tags']),
purge_tags=dict(required=False, type='bool', default=True),
ingress=dict(required=False, type='list', default=list(), elements='list'),
egress=dict(required=False, type='list', default=list(), elements='list'),
state=dict(default='present', choices=['present', 'absent']),
Expand Down
3 changes: 0 additions & 3 deletions tests/integration/targets/ec2_vpc_nacl/aliases
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# https://github.com/ansible-collections/community.aws/issues/153
unstable

cloud/aws

ec2_vpc_nacl_info
12 changes: 12 additions & 0 deletions tests/integration/targets/ec2_vpc_nacl/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
vpc_name: '{{ resource_prefix }}-ec2-vpc-nacl'
nacl_name: '{{ resource_prefix }}-ec2-vpc-nacl'
subnet_name: '{{ resource_prefix }}-ec2-vpc-nacl'
vpc_cidr: '10.{{ 256 | random(seed=resource_prefix) }}.0.0/16'
subnet_1: '10.{{ 256 | random(seed=resource_prefix) }}.1.0/24'
subnet_2: '10.{{ 256 | random(seed=resource_prefix) }}.2.0/24'
subnet_3: '10.{{ 256 | random(seed=resource_prefix) }}.3.0/24'
subnet_4: '10.{{ 256 | random(seed=resource_prefix) }}.4.0/24'

vpc_ipv6_cidr: '10.{{ 256 | random(seed=resource_prefix) }}.5.0/25'
vpc_ipv6_name: '{{ vpc_name }}-ipv6'
Loading

0 comments on commit e8e19c9

Please sign in to comment.