Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare modules ec2_vpc_nacl and ec2_vpc_nacl_info for promotion #2159

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
minor_changes:
- ec2_vpc_nacl_info - Refactor module to use shared code from `amazon.aws.plugins.module_utils.ec2` (https://github.com/ansible-collections/community.aws/pull/2159).
- ec2_vpc_nacl - Refactor module to use shared code from `amazon.aws.plugins.module_utils.ec2` (https://github.com/ansible-collections/community.aws/pull/2159).
606 changes: 268 additions & 338 deletions plugins/modules/ec2_vpc_nacl.py

Large diffs are not rendered by default.

100 changes: 53 additions & 47 deletions plugins/modules/ec2_vpc_nacl_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,16 @@
sample: [[100, 'all', 'allow', '0.0.0.0/0', null, null, null, null]]
"""

try:
import botocore
except ImportError:
pass # caught by AnsibleAWSModule
from typing import Any
from typing import Dict
from typing import List
from typing import Union

from ansible.module_utils.common.dict_transformations import camel_dict_to_snake_dict

from ansible_collections.amazon.aws.plugins.module_utils.botocore import is_boto3_error_code
from ansible_collections.amazon.aws.plugins.module_utils.retries import AWSRetry
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import AnsibleAWSError
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import describe_network_acls
from ansible_collections.amazon.aws.plugins.module_utils.exceptions import is_ansible_aws_error_code
from ansible_collections.amazon.aws.plugins.module_utils.tagging import boto3_tag_list_to_ansible_dict
from ansible_collections.amazon.aws.plugins.module_utils.transformation import ansible_dict_to_boto3_filter_list

Expand All @@ -121,55 +122,60 @@
PROTOCOL_NAMES = {"-1": "all", "1": "icmp", "6": "tcp", "17": "udp"}


def list_ec2_vpc_nacls(connection, module):
def format_nacl(nacl: Dict[str, Any]) -> Dict[str, Any]:
# Turn the boto3 result into ansible friendly snake cases
nacl = camel_dict_to_snake_dict(nacl)

# convert boto3 tags list into ansible dict
if "tags" in nacl:
nacl["tags"] = boto3_tag_list_to_ansible_dict(nacl["tags"], "key", "value")

# Convert NACL entries
if "entries" in nacl:
nacl["egress"] = [
nacl_entry_to_list(entry) for entry in nacl["entries"] if entry["rule_number"] < 32767 and entry["egress"]
]
nacl["ingress"] = [
nacl_entry_to_list(entry)
for entry in nacl["entries"]
if entry["rule_number"] < 32767 and not entry["egress"]
]
del nacl["entries"]

# Read subnets from NACL Associations
if "associations" in nacl:
nacl["subnets"] = [a["subnet_id"] for a in nacl["associations"]]
del nacl["associations"]

# Read Network ACL id
if "network_acl_id" in nacl:
nacl["nacl_id"] = nacl["network_acl_id"]
del nacl["network_acl_id"]

return nacl


def list_ec2_vpc_nacls(connection, module: AnsibleAWSModule) -> None:
nacl_ids = module.params.get("nacl_ids")
filters = ansible_dict_to_boto3_filter_list(module.params.get("filters"))
filters = module.params.get("filters")

if nacl_ids is None:
nacl_ids = []
params = {}
if filters:
params["Filters"] = ansible_dict_to_boto3_filter_list(filters)
if nacl_ids:
params["NetworkAclIds"] = nacl_ids

try:
nacls = connection.describe_network_acls(aws_retry=True, NetworkAclIds=nacl_ids, Filters=filters)
except is_boto3_error_code("InvalidNetworkAclID.NotFound"):
module.fail_json(msg="Unable to describe ACL. NetworkAcl does not exist")
except (
botocore.exceptions.ClientError,
botocore.exceptions.BotoCoreError,
) as e: # pylint: disable=duplicate-except
snaked_nacls = [format_nacl(nacl) for nacl in describe_network_acls(connection, **params)]
except is_ansible_aws_error_code("InvalidNetworkAclID.NotFound"):
abikouo marked this conversation as resolved.
Show resolved Hide resolved
module.fail_json(msg="Unable to describe ACL. NetworkAcl does not exist")
except AnsibleAWSError as e: # pylint: disable=duplicate-except
module.fail_json_aws(e, msg=f"Unable to describe network ACLs {nacl_ids}")

# Turn the boto3 result in to ansible_friendly_snaked_names
snaked_nacls = []
for nacl in nacls["NetworkAcls"]:
snaked_nacls.append(camel_dict_to_snake_dict(nacl))

# Turn the boto3 result in to ansible friendly tag dictionary
for nacl in snaked_nacls:
if "tags" in nacl:
nacl["tags"] = boto3_tag_list_to_ansible_dict(nacl["tags"], "key", "value")
if "entries" in nacl:
nacl["egress"] = [
nacl_entry_to_list(entry)
for entry in nacl["entries"]
if entry["rule_number"] < 32767 and entry["egress"]
]
nacl["ingress"] = [
nacl_entry_to_list(entry)
for entry in nacl["entries"]
if entry["rule_number"] < 32767 and not entry["egress"]
]
del nacl["entries"]
if "associations" in nacl:
nacl["subnets"] = [a["subnet_id"] for a in nacl["associations"]]
del nacl["associations"]
if "network_acl_id" in nacl:
nacl["nacl_id"] = nacl["network_acl_id"]
del nacl["network_acl_id"]

module.exit_json(nacls=snaked_nacls)


def nacl_entry_to_list(entry):
def nacl_entry_to_list(entry: Dict[str, Any]) -> List[Union[str, int, None]]:
# entry list format
# [ rule_num, protocol name or number, allow or deny, ipv4/6 cidr, icmp type, icmp code, port from, port to]
elist = []
Expand Down Expand Up @@ -217,7 +223,7 @@ def main():
supports_check_mode=True,
)

connection = module.client("ec2", retry_decorator=AWSRetry.jittered_backoff())
connection = module.client("ec2")

list_ec2_vpc_nacls(connection, module)

Expand Down
36 changes: 18 additions & 18 deletions tests/integration/targets/ec2_vpc_nacl/tasks/ingress_and_egress.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ============================================================
- block:
- name: create ingress and egress rules using subnet IDs
- name: Create ingress and egress rules using subnet IDs
abikouo marked this conversation as resolved.
Show resolved Hide resolved
ec2_vpc_nacl:
vpc_id: "{{ vpc_id }}"
name: "{{ nacl_name }}"
Expand All @@ -16,19 +16,19 @@
state: 'present'
register: nacl

- name: assert the network acl was created
- name: Assert the network acl was created
assert:
that:
- nacl.changed
- nacl.nacl_id.startswith('acl-')

- name: get network ACL facts
- name: Get network ACL facts
ec2_vpc_nacl_info:
nacl_ids:
- "{{ nacl.nacl_id }}"
register: nacl_facts

- name: assert the nacl has the correct attributes
- name: Assert the nacl has the correct attributes
assert:
that:
- nacl_facts.nacls | length == 1
Expand All @@ -37,7 +37,7 @@

# ============================================================

- name: remove an ingress rule
- name: Remove an ingress rule
ec2_vpc_nacl:
vpc_id: "{{ vpc_id }}"
name: "{{ nacl_name }}"
Expand All @@ -52,19 +52,19 @@
state: 'present'
register: nacl

- name: assert the network acl changed
- name: Assert the network acl changed
assert:
that:
- nacl.changed
- nacl.nacl_id.startswith('acl-')

- name: get network ACL facts
- name: Get network ACL facts
ec2_vpc_nacl_info:
nacl_ids:
- "{{ nacl.nacl_id }}"
register: nacl_facts

- name: assert the nacl has the correct attributes
- name: Assert the nacl has the correct attributes
assert:
that:
- nacl_facts.nacls | length == 1
Expand All @@ -73,7 +73,7 @@

# ============================================================

- name: remove the egress rule
- name: Remove the egress rule
ec2_vpc_nacl:
vpc_id: "{{ vpc_id }}"
name: "{{ nacl_name }}"
Expand All @@ -87,19 +87,19 @@
state: 'present'
register: nacl

- name: assert the network acl changed
- name: Assert the network acl changed
assert:
that:
- nacl.changed
- nacl.nacl_id.startswith('acl-')

- name: get network ACL facts
- name: Get network ACL facts
ec2_vpc_nacl_info:
nacl_ids:
- "{{ nacl.nacl_id }}"
register: nacl_facts

- name: assert the nacl has the correct attributes
- name: Assert the nacl has the correct attributes
assert:
that:
- nacl_facts.nacls | length == 1
Expand All @@ -108,7 +108,7 @@

# ============================================================

- name: add egress rules
- name: Add egress rules
ec2_vpc_nacl:
vpc_id: "{{ vpc_id }}"
name: "{{ nacl_name }}"
Expand All @@ -124,19 +124,19 @@
state: 'present'
register: nacl

- name: assert the network acl changed
- name: Assert the network acl changed
assert:
that:
- nacl.changed
- nacl.nacl_id.startswith('acl-')

- name: get network ACL facts
- name: Get network ACL facts
ec2_vpc_nacl_info:
nacl_ids:
- "{{ nacl.nacl_id }}"
register: nacl_facts

- name: assert the nacl has the correct attributes
- name: Assert the nacl has the correct attributes
assert:
that:
- nacl_facts.nacls | length == 1
Expand All @@ -145,14 +145,14 @@

# ============================================================

- name: remove the network ACL
- name: Remove the network ACL
ec2_vpc_nacl:
vpc_id: "{{ vpc_id }}"
name: "{{ nacl_name }}"
state: absent
register: nacl

- name: assert nacl was removed
- name: Assert nacl was removed
assert:
that:
- nacl.changed
33 changes: 19 additions & 14 deletions tests/integration/targets/ec2_vpc_nacl/tasks/ipv6.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# ============================================================

- name: create ingress and egress rules using subnet names
- name: Create ingress and egress rules using subnet names
ec2_vpc_nacl:
vpc_id: "{{ vpc_ipv6_id }}"
name: "{{ nacl_name }}"
Expand All @@ -18,14 +18,16 @@
- [100, 'all', 'allow', '0.0.0.0/0', null, null, null, null]
state: 'present'
register: nacl
- assert:

- name: Assert that module returned the Network ACL id
assert:
that:
- nacl.nacl_id

- set_fact:
nacl_id: "{{ nacl.nacl_id }}"

- name: add ipv6 entries
- name: Add ipv6 entries
ec2_vpc_nacl:
vpc_id: "{{ vpc_ipv6_id }}"
name: "{{ nacl_name }}"
Expand All @@ -45,25 +47,26 @@
state: 'present'
register: nacl

- assert:
- name: Assert that module reported change while the Network ACL remained unchanged
assert:
that:
- nacl.changed
- nacl.nacl_id == nacl_id

- name: get network ACL facts (test that it works with ipv6 entries)
- name: Get network ACL facts (test that it works with ipv6 entries)
ec2_vpc_nacl_info:
nacl_ids:
- "{{ nacl_id }}"
register: nacl_facts

- name: assert the nacl has the correct attributes
- name: Assert the nacl has the correct attributes
assert:
that:
- nacl_facts.nacls | length == 1
- nacl_facts.nacls[0].ingress | length == 5
- nacl_facts.nacls[0].egress | length == 2

- name: purge ingress entries
- name: Purge ingress entries
ec2_vpc_nacl:
vpc_id: "{{ vpc_ipv6_id }}"
name: "{{ nacl_name }}"
Expand All @@ -78,12 +81,13 @@
state: 'present'
register: nacl

- assert:
- name: Assert that module reported change while the Network ACL remained unchanged
assert:
that:
- nacl.changed
- nacl.nacl_id == nacl_id

- name: purge egress entries
- name: Purge egress entries
ec2_vpc_nacl:
vpc_id: "{{ vpc_ipv6_id }}"
name: "{{ nacl_name }}"
Expand All @@ -96,17 +100,18 @@
state: 'present'
register: nacl

- assert:
- name: Assert that module reported change
assert:
that:
- nacl.changed

- name: get network ACL facts (test that removed entries are gone)
- name: Get network ACL facts (test that removed entries are gone)
ec2_vpc_nacl_info:
nacl_ids:
- "{{ nacl_id }}"
register: nacl_facts

- name: assert the nacl has the correct attributes
- name: Assert the nacl has the correct attributes
assert:
that:
- nacl_facts.nacls | length == 1
Expand All @@ -115,10 +120,10 @@

always:

- name: remove network ACL
- name: Remove network ACL
ec2_vpc_nacl:
vpc_id: "{{ vpc_ipv6_id }}"
name: "{{ nacl_name }}"
state: absent
register: removed_acl
ignore_errors: yes
ignore_errors: true
Loading
Loading