diff --git a/changelogs/fragments/430-add_support_for_ipv6_addresses.yml b/changelogs/fragments/430-add_support_for_ipv6_addresses.yml new file mode 100644 index 00000000000..b05ea9effcf --- /dev/null +++ b/changelogs/fragments/430-add_support_for_ipv6_addresses.yml @@ -0,0 +1,4 @@ +minor_changes: + - aws_service_ip_ranges - add new option ``ipv6_prefixes`` + to get only IPV6 addresses and prefixes for Amazon services + (https://github.com/ansible-collections/amazon.aws/pull/430) diff --git a/plugins/lookup/aws_service_ip_ranges.py b/plugins/lookup/aws_service_ip_ranges.py index b8bfd4ee501..82447236860 100644 --- a/plugins/lookup/aws_service_ip_ranges.py +++ b/plugins/lookup/aws_service_ip_ranges.py @@ -19,6 +19,9 @@ description: 'The service to filter ranges by. Options: EC2, S3, CLOUDFRONT, CODEbUILD, ROUTE53, ROUTE53_HEALTHCHECKS' region: description: 'The AWS region to narrow the ranges to. Examples: us-east-1, eu-west-2, ap-southeast-1' + ipv6_prefixes: + description: 'When I(ipv6_prefixes=True) the lookup will return ipv6 addresses instead of ipv4 addresses' + version_added: 2.1.0 ''' EXAMPLES = """ @@ -40,7 +43,6 @@ description: comma-separated list of CIDR ranges """ - import json from ansible.errors import AnsibleError @@ -55,9 +57,16 @@ class LookupModule(LookupBase): def run(self, terms, variables, **kwargs): + if "ipv6_prefixes" in kwargs and kwargs["ipv6_prefixes"]: + prefixes_label = "ipv6_prefixes" + ip_prefix_label = "ipv6_prefix" + else: + prefixes_label = "prefixes" + ip_prefix_label = "ip_prefix" + try: resp = open_url('https://ip-ranges.amazonaws.com/ip-ranges.json') - amazon_response = json.load(resp)['prefixes'] + amazon_response = json.load(resp)[prefixes_label] except getattr(json.decoder, 'JSONDecodeError', ValueError) as e: # on Python 3+, json.decoder.JSONDecodeError is raised for bad # JSON. On 2.x it's a ValueError @@ -77,5 +86,5 @@ def run(self, terms, variables, **kwargs): if 'service' in kwargs: service = str.upper(kwargs['service']) amazon_response = (item for item in amazon_response if item['service'] == service) - - return [item['ip_prefix'] for item in amazon_response] + iprange = [item[ip_prefix_label] for item in amazon_response] + return iprange diff --git a/tests/integration/targets/lookup_aws_service_ip_ranges/tasks/main.yaml b/tests/integration/targets/lookup_aws_service_ip_ranges/tasks/main.yaml index 70551c36fcc..8d946ddfe74 100644 --- a/tests/integration/targets/lookup_aws_service_ip_ranges/tasks/main.yaml +++ b/tests/integration/targets/lookup_aws_service_ip_ranges/tasks/main.yaml @@ -11,6 +11,7 @@ - name: lookup range with wantlist set_fact: want_list: "{{ lookup('amazon.aws.aws_service_ip_ranges', wantlist=True) }}" + want_ipv6_list: "{{ lookup('amazon.aws.aws_service_ip_ranges', wantlist=True, ipv6_prefixes=True) }}" - name: assert that we're returned a list assert: @@ -20,10 +21,17 @@ - want_list is not string - want_list | length > 1 - want_list[0] | ansible.netcommon.ipv4 + - want_ipv6_list is defined + - want_ipv6_list is iterable + - want_ipv6_list is not string + - want_ipv6_list | length > 1 + - want_ipv6_list[0] | ansible.netcommon.ipv6 + - name: lookup range with service set_fact: s3_ips: "{{ lookup('amazon.aws.aws_service_ip_ranges', service='S3', wantlist=True) }}" + s3_ipv6s: "{{ lookup('amazon.aws.aws_service_ip_ranges', service='S3', wantlist=True, ipv6_prefixes=True) }}" - name: assert that we're returned a list assert: @@ -33,10 +41,16 @@ - s3_ips is not string - s3_ips | length > 1 - s3_ips[0] | ansible.netcommon.ipv4 + - s3_ipv6s is defined + - s3_ipv6s is iterable + - s3_ipv6s is not string + - s3_ipv6s | length > 1 + - s3_ipv6s[0] | ansible.netcommon.ipv6 - name: lookup range with a different service set_fact: route53_ips: "{{ lookup('amazon.aws.aws_service_ip_ranges', service='ROUTE53_HEALTHCHECKS', wantlist=True) }}" + route53_ipv6s: "{{ lookup('amazon.aws.aws_service_ip_ranges', service='ROUTE53_HEALTHCHECKS', wantlist=True, ipv6_prefixes=True) }}" - name: assert that we're returned a list assert: @@ -46,16 +60,27 @@ - route53_ips is not string - route53_ips | length > 1 - route53_ips[0] | ansible.netcommon.ipv4 + - route53_ipv6s is defined + - route53_ipv6s is iterable + - route53_ipv6s is not string + - route53_ipv6s | length > 1 + - route53_ipv6s[0] | ansible.netcommon.ipv6 + -- name: assert that service IPs don't overlap +- name: assert that service IPV4s and IPV6s do not overlap assert: that: - route53_ips | intersect(s3_ips) | length == 0 + - route53_ipv6s | intersect(s3_ipv6s) | length == 0 - name: lookup range with region set_fact: us_east_1_ips: "{{ lookup('amazon.aws.aws_service_ip_ranges', region='us-east-1', wantlist=True) }}" +- name: lookup IPV6 range with region + set_fact: + us_east_1_ipv6s: "{{ lookup('amazon.aws.aws_service_ip_ranges', region='us-east-1', wantlist=True, ipv6_prefixes=True) }}" + - name: assert that we're returned a list assert: that: @@ -64,10 +89,16 @@ - us_east_1_ips is not string - us_east_1_ips | length > 1 - us_east_1_ips[0] | ansible.netcommon.ipv4 + - us_east_1_ipv6s is defined + - us_east_1_ipv6s is iterable + - us_east_1_ipv6s is not string + - us_east_1_ipv6s | length > 1 + - us_east_1_ipv6s[0] | ansible.netcommon.ipv6 - name: lookup range with a different region set_fact: eu_central_1_ips: "{{ lookup('amazon.aws.aws_service_ip_ranges', region='eu-central-1', wantlist=True) }}" + eu_central_1_ipv6s: "{{ lookup('amazon.aws.aws_service_ip_ranges', region='eu-central-1', wantlist=True, ipv6_prefixes=True) }}" - name: assert that we're returned a list assert: @@ -77,15 +108,22 @@ - eu_central_1_ips is not string - eu_central_1_ips | length > 1 - eu_central_1_ips[0] | ansible.netcommon.ipv4 + - eu_central_1_ipv6s is defined + - eu_central_1_ipv6s is iterable + - eu_central_1_ipv6s is not string + - eu_central_1_ipv6s | length > 1 + - eu_central_1_ipv6s[0] | ansible.netcommon.ipv6 - name: assert that regional IPs don't overlap assert: that: - eu_central_1_ips | intersect(us_east_1_ips) | length == 0 + - eu_central_1_ipv6s | intersect(us_east_1_ipv6s) | length == 0 - name: lookup range with service and region set_fact: s3_us_ips: "{{ lookup('amazon.aws.aws_service_ip_ranges', region='us-east-1', service='S3', wantlist=True) }}" + s3_us_ipv6s: "{{ lookup('amazon.aws.aws_service_ip_ranges', region='us-east-1', service='S3', wantlist=True, ipv6_prefixes=True) }}" - name: assert that we're returned a list assert: @@ -95,9 +133,16 @@ - s3_us_ips is not string - s3_us_ips | length > 1 - s3_us_ips[0] | ansible.netcommon.ipv4 + - s3_us_ipv6s is defined + - s3_us_ipv6s is iterable + - s3_us_ipv6s is not string + - s3_us_ipv6s | length > 1 + - s3_us_ipv6s[0] | ansible.netcommon.ipv6 - name: assert that the regional service IPs are a subset of the regional IPs and service IPs. assert: that: - ( s3_us_ips | intersect(us_east_1_ips) | length ) == ( s3_us_ips | length ) - ( s3_us_ips | intersect(s3_ips) | length ) == ( s3_us_ips | length ) + - ( s3_us_ipv6s | intersect(us_east_1_ipv6s) | length ) == ( s3_us_ipv6s | length ) + - ( s3_us_ipv6s | intersect(s3_ipv6s) | length ) == ( s3_us_ipv6s | length )