From 08e23a2a9338ca48a5dc44a8bd7be9c823102b95 Mon Sep 17 00:00:00 2001 From: Jill R <4121322+jillr@users.noreply.github.com> Date: Wed, 7 Aug 2019 05:39:55 -0700 Subject: [PATCH] Don't truncate cidr_ipv6 addresses in ec2_group.py (#59106) * Better cidr_ipv6 validation in ec2_group.py * Improve warning/error handling, add changelog * Update unit test for ipv6 validation * Fix logic that was causing non /128 cidrs with host bits to not be handled (cherry picked from commit 4308b87d72ad2666c15919949cc66b6eca636cf3) --- ...59106-fix-ipv6-truncating-in-ec2_group.yml | 4 ++++ lib/ansible/modules/cloud/amazon/ec2_group.py | 23 +++++++++++++++---- .../modules/cloud/amazon/test_ec2_group.py | 4 ++-- 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 changelogs/fragments/59106-fix-ipv6-truncating-in-ec2_group.yml diff --git a/changelogs/fragments/59106-fix-ipv6-truncating-in-ec2_group.yml b/changelogs/fragments/59106-fix-ipv6-truncating-in-ec2_group.yml new file mode 100644 index 00000000000..4c27b488281 --- /dev/null +++ b/changelogs/fragments/59106-fix-ipv6-truncating-in-ec2_group.yml @@ -0,0 +1,4 @@ +bugfixes: + - ec2_group - Don't truncate the host bits off of IPv6 CIDRs. + CIDRs will be passed thru to EC2 as-is provided they are valid IPv6 + representations. (https://github.com/ansible/ansible/issues/53297) diff --git a/lib/ansible/modules/cloud/amazon/ec2_group.py b/lib/ansible/modules/cloud/amazon/ec2_group.py index 8c502bffec7..e1897407850 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_group.py +++ b/lib/ansible/modules/cloud/amazon/ec2_group.py @@ -305,6 +305,7 @@ from ansible.module_utils.aws.waiters import get_waiter from ansible.module_utils.ec2 import AWSRetry, camel_dict_to_snake_dict, compare_aws_tags from ansible.module_utils.ec2 import ansible_dict_to_boto3_filter_list, boto3_tag_list_to_ansible_dict, ansible_dict_to_boto3_tag_list from ansible.module_utils.common.network import to_ipv6_subnet, to_subnet +from ansible.module_utils.compat.ipaddress import ip_network, IPv6Network from ansible.module_utils._text import to_text from ansible.module_utils.six import string_types @@ -723,14 +724,26 @@ def validate_ip(module, cidr_ip): split_addr = cidr_ip.split('/') if len(split_addr) == 2: # this_ip is a IPv4 or IPv6 CIDR that may or may not have host bits set - # Get the network bits. + # Get the network bits if IPv4, and validate if IPv6. try: ip = to_subnet(split_addr[0], split_addr[1]) + if ip != cidr_ip: + module.warn("One of your CIDR addresses ({0}) has host bits set. To get rid of this warning, " + "check the network mask and make sure that only network bits are set: {1}.".format( + cidr_ip, ip)) except ValueError: - ip = to_ipv6_subnet(split_addr[0]) + "/" + split_addr[1] - if ip != cidr_ip: - module.warn("One of your CIDR addresses ({0}) has host bits set. To get rid of this warning, " - "check the network mask and make sure that only network bits are set: {1}.".format(cidr_ip, ip)) + # to_subnet throws a ValueError on IPv6 networks, so we should be working with v6 if we get here + try: + isinstance(ip_network(to_text(cidr_ip)), IPv6Network) + ip = cidr_ip + except ValueError: + # If a host bit is set on something other than a /128, IPv6Network will throw a ValueError + # The ipv6_cidr in this case probably looks like "2001:DB8:A0B:12F0::1/64" and we just want the network bits + ip6 = to_ipv6_subnet(split_addr[0]) + "/" + split_addr[1] + if ip6 != cidr_ip: + module.warn("One of your IPv6 CIDR addresses ({0}) has host bits set. To get rid of this warning, " + "check the network mask and make sure that only network bits are set: {1}.".format(cidr_ip, ip6)) + return ip6 return ip return cidr_ip diff --git a/test/units/modules/cloud/amazon/test_ec2_group.py b/test/units/modules/cloud/amazon/test_ec2_group.py index 9fee943e9e8..2fc6e81849c 100644 --- a/test/units/modules/cloud/amazon/test_ec2_group.py +++ b/test/units/modules/cloud/amazon/test_ec2_group.py @@ -73,8 +73,8 @@ def test_validate_ip(): ips = [ ('1.1.1.1/24', '1.1.1.0/24'), ('192.168.56.101/16', '192.168.0.0/16'), - # 64 bits make 8 octets, or 4 hextets - ('1203:8fe0:fe80:b897:8990:8a7c:99bf:323d/64', '1203:8fe0:fe80:b897::/64'), + # Don't modify IPv6 CIDRs, AWS supports /128 and device ranges + ('1203:8fe0:fe80:b897:8990:8a7c:99bf:323d/128', '1203:8fe0:fe80:b897:8990:8a7c:99bf:323d/128'), ] for ip, net in ips: