From 5f8f84ca0b882bb0ba0374a0d1bc91b5d20eda29 Mon Sep 17 00:00:00 2001 From: GomathiselviS Date: Mon, 29 Aug 2022 17:13:13 -0400 Subject: [PATCH 1/7] Handle absence of classic link support for shared VPCs Signed-off-by: GomathiselviS --- plugins/modules/ec2_vpc_net_info.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/plugins/modules/ec2_vpc_net_info.py b/plugins/modules/ec2_vpc_net_info.py index 5ffd74fa4ee..408a4ad079c 100644 --- a/plugins/modules/ec2_vpc_net_info.py +++ b/plugins/modules/ec2_vpc_net_info.py @@ -167,7 +167,6 @@ from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict - def describe_vpcs(connection, module): """ Describe VPCs. @@ -194,12 +193,16 @@ def describe_vpcs(connection, module): vpc_list.append(vpc['VpcId']) # We can get these results in bulk but still needs two separate calls to the API - try: - cl_enabled = connection.describe_vpc_classic_link(VpcIds=vpc_list, aws_retry=True) - except is_boto3_error_code('UnsupportedOperation'): - cl_enabled = {'Vpcs': [{'VpcId': vpc_id, 'ClassicLinkEnabled': False} for vpc_id in vpc_list]} - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e, msg='Unable to describe if ClassicLink is enabled') + cl_enabled = {} + # Looping through the vpc list because one or more vpcs might be a shared vpc + # and classic link is not supported on them + for vpc in vpc_list: + try: + cl_enabled.update(connection.describe_vpc_classic_link(VpcIds=[vpc], aws_retry=True)) + except is_boto3_error_code('UnsupportedOperation'): + cl_enabled.update({'Vpcs': [{'VpcId': vpc, 'ClassicLinkEnabled': False}]}) + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except + module.warn('Unable to describe if ClassicLink is enabled. One of the VPCs might be a shared VPC. {0}'.format(e)) try: cl_dns_support = connection.describe_vpc_classic_link_dns_support(VpcIds=vpc_list, aws_retry=True) @@ -223,10 +226,11 @@ def describe_vpcs(connection, module): except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg=error_message.format('enableDnsHostnames')) - # loop through the ClassicLink Enabled results and add the value for the correct VPC - for item in cl_enabled['Vpcs']: - if vpc['VpcId'] == item['VpcId']: - vpc['ClassicLinkEnabled'] = item['ClassicLinkEnabled'] + if cl_enabled: + # loop through the ClassicLink Enabled results and add the value for the correct VPC + for item in cl_enabled['Vpcs']: + if vpc['VpcId'] == item['VpcId']: + vpc['ClassicLinkEnabled'] = item['ClassicLinkEnabled'] # loop through the ClassicLink DNS support results and add the value for the correct VPC for item in cl_dns_support['Vpcs']: From 5efae79d6a9f4b9a988f34568bbc4de239e04484 Mon Sep 17 00:00:00 2001 From: GomathiselviS Date: Mon, 29 Aug 2022 17:23:02 -0400 Subject: [PATCH 2/7] Added changelog --- changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml diff --git a/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml b/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml new file mode 100644 index 00000000000..32b0ab76433 --- /dev/null +++ b/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml @@ -0,0 +1,3 @@ +--- +minor_changes: +- "ec2_vpc_net_info - handle classic link check for shared vpcs by throwing a warning instead of an error.https://github.com/ansible-collections/amazon.aws/pull/984" From 57a25101c3beefb8738982a89e947c81ad0c2afd Mon Sep 17 00:00:00 2001 From: GomathiselviS Date: Tue, 30 Aug 2022 13:52:21 -0400 Subject: [PATCH 3/7] refactor --- plugins/modules/ec2_vpc_net_info.py | 77 ++++++++++++++--------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/plugins/modules/ec2_vpc_net_info.py b/plugins/modules/ec2_vpc_net_info.py index 408a4ad079c..89056878c07 100644 --- a/plugins/modules/ec2_vpc_net_info.py +++ b/plugins/modules/ec2_vpc_net_info.py @@ -180,7 +180,6 @@ def describe_vpcs(connection, module): # init empty list for return vars vpc_info = list() - vpc_list = list() # Get the basic VPC info try: @@ -188,54 +187,26 @@ def describe_vpcs(connection, module): except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: module.fail_json_aws(e, msg="Unable to describe VPCs {0}".format(vpc_ids)) - # Loop through results and create a list of VPC IDs - for vpc in response['Vpcs']: - vpc_list.append(vpc['VpcId']) - # We can get these results in bulk but still needs two separate calls to the API cl_enabled = {} - # Looping through the vpc list because one or more vpcs might be a shared vpc - # and classic link is not supported on them - for vpc in vpc_list: - try: - cl_enabled.update(connection.describe_vpc_classic_link(VpcIds=[vpc], aws_retry=True)) - except is_boto3_error_code('UnsupportedOperation'): - cl_enabled.update({'Vpcs': [{'VpcId': vpc, 'ClassicLinkEnabled': False}]}) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except - module.warn('Unable to describe if ClassicLink is enabled. One of the VPCs might be a shared VPC. {0}'.format(e)) - - try: - cl_dns_support = connection.describe_vpc_classic_link_dns_support(VpcIds=vpc_list, aws_retry=True) - except is_boto3_error_code('UnsupportedOperation'): - cl_dns_support = {'Vpcs': [{'VpcId': vpc_id, 'ClassicLinkDnsSupported': False} for vpc_id in vpc_list]} - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except - module.fail_json_aws(e, msg='Unable to describe if ClassicLinkDns is supported') - + cl_dns_support = {} # Loop through the results and add the other VPC attributes we gathered for vpc in response['Vpcs']: - error_message = "Unable to describe VPC attribute {0}" - # We have to make two separate calls per VPC to get these attributes. - try: - dns_support = connection.describe_vpc_attribute(VpcId=vpc['VpcId'], - Attribute='enableDnsSupport', aws_retry=True) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg=error_message.format('enableDnsSupport')) - try: - dns_hostnames = connection.describe_vpc_attribute(VpcId=vpc['VpcId'], - Attribute='enableDnsHostnames', aws_retry=True) - except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: - module.fail_json_aws(e, msg=error_message.format('enableDnsHostnames')) - + error_message = "Unable to describe VPC attribute {0} on VPC {1}" + cl_enabled = describe_classic_links(module, connection, vpc['VpcId'], 'ClassicLinkEnabled', error_message) + cl_dns_support = describe_classic_links(module, connection, vpc['VpcId'], 'ClassicLinkDnsSupported', error_message) + dns_support = describe_vpc_attribute(module, connection, vpc['VpcId'], 'enableDnsSupport', error_message) + dns_hostnames = describe_vpc_attribute(module, connection, vpc['VpcId'], 'enableDnsHostnames', error_message) if cl_enabled: # loop through the ClassicLink Enabled results and add the value for the correct VPC for item in cl_enabled['Vpcs']: if vpc['VpcId'] == item['VpcId']: vpc['ClassicLinkEnabled'] = item['ClassicLinkEnabled'] - - # loop through the ClassicLink DNS support results and add the value for the correct VPC - for item in cl_dns_support['Vpcs']: - if vpc['VpcId'] == item['VpcId']: - vpc['ClassicLinkDnsSupported'] = item['ClassicLinkDnsSupported'] + if cl_dns_support: + # loop through the ClassicLink DNS support results and add the value for the correct VPC + for item in cl_dns_support['Vpcs']: + if vpc['VpcId'] == item['VpcId']: + vpc['ClassicLinkDnsSupported'] = item['ClassicLinkDnsSupported'] # add the two DNS attributes vpc['EnableDnsSupport'] = dns_support['EnableDnsSupport'].get('Value') @@ -248,6 +219,32 @@ def describe_vpcs(connection, module): module.exit_json(vpcs=vpc_info) +def describe_classic_links (module, connection, vpc, attribute, error_message): + result = None + try: + if attribute == "ClassicLinkEnabled": + result = connection.describe_vpc_classic_link(VpcIds=[vpc], aws_retry=True) + else: + result = connection.describe_vpc_classic_link_dns_support(VpcIds=[vpc], aws_retry=True) + except is_boto3_error_code('UnsupportedOperation'): + result = {'Vpcs': [{'VpcId': vpc, 'ClassicLinkEnabled': False}]} + except is_boto3_error_code('InvalidVpcID.NotFound'): + module.warn(error_message.format(attribute, vpc)) + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: # pylint: disable=duplicate-except + module.fail_json_aws(e, msg='Unable to describe if {0} is enabled'.format(attribute)) + return result + +def describe_vpc_attribute(module, connection, vpc, attribute, error_message): + result = None + try: + return connection.describe_vpc_attribute(VpcId=vpc, Attribute=attribute, aws_retry=True) + except is_boto3_error_code('InvalidVpcID.NotFound'): + module.warn(error_message.format(attribute, vpc)) + except (botocore.exceptions.ClientError, botocore.exceptions.BotoCoreError) as e: + module.fail_json_aws(e, msg=error_message.format(attribute, vpc)) + return result + + def main(): argument_spec = dict( From 92d9e5f7062cfd18abc2ebf58d6378aef9202ceb Mon Sep 17 00:00:00 2001 From: GomathiselviS Date: Tue, 30 Aug 2022 14:51:30 -0400 Subject: [PATCH 4/7] Fix pep8 failures --- plugins/modules/ec2_vpc_net_info.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/modules/ec2_vpc_net_info.py b/plugins/modules/ec2_vpc_net_info.py index 89056878c07..27c02089880 100644 --- a/plugins/modules/ec2_vpc_net_info.py +++ b/plugins/modules/ec2_vpc_net_info.py @@ -167,6 +167,7 @@ from ansible_collections.amazon.aws.plugins.module_utils.ec2 import ansible_dict_to_boto3_filter_list from ansible_collections.amazon.aws.plugins.module_utils.ec2 import boto3_tag_list_to_ansible_dict + def describe_vpcs(connection, module): """ Describe VPCs. @@ -219,7 +220,8 @@ def describe_vpcs(connection, module): module.exit_json(vpcs=vpc_info) -def describe_classic_links (module, connection, vpc, attribute, error_message): + +def describe_classic_links(module, connection, vpc, attribute, error_message): result = None try: if attribute == "ClassicLinkEnabled": @@ -234,6 +236,7 @@ def describe_classic_links (module, connection, vpc, attribute, error_message): module.fail_json_aws(e, msg='Unable to describe if {0} is enabled'.format(attribute)) return result + def describe_vpc_attribute(module, connection, vpc, attribute, error_message): result = None try: @@ -245,7 +248,6 @@ def describe_vpc_attribute(module, connection, vpc, attribute, error_message): return result - def main(): argument_spec = dict( vpc_ids=dict(type='list', elements='str', default=[]), From a94d487a2b9451935c21be9261bb9ac9bf632776 Mon Sep 17 00:00:00 2001 From: GomathiselviS Date: Fri, 2 Sep 2022 16:06:57 -0400 Subject: [PATCH 5/7] Handle variables with empty value --- plugins/modules/ec2_vpc_net_info.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/modules/ec2_vpc_net_info.py b/plugins/modules/ec2_vpc_net_info.py index 27c02089880..f2d896fab0a 100644 --- a/plugins/modules/ec2_vpc_net_info.py +++ b/plugins/modules/ec2_vpc_net_info.py @@ -191,6 +191,8 @@ def describe_vpcs(connection, module): # We can get these results in bulk but still needs two separate calls to the API cl_enabled = {} cl_dns_support = {} + dns_support = {} + dns_hostnames = {} # Loop through the results and add the other VPC attributes we gathered for vpc in response['Vpcs']: error_message = "Unable to describe VPC attribute {0} on VPC {1}" @@ -210,8 +212,10 @@ def describe_vpcs(connection, module): vpc['ClassicLinkDnsSupported'] = item['ClassicLinkDnsSupported'] # add the two DNS attributes - vpc['EnableDnsSupport'] = dns_support['EnableDnsSupport'].get('Value') - vpc['EnableDnsHostnames'] = dns_hostnames['EnableDnsHostnames'].get('Value') + if dns_support: + vpc['EnableDnsSupport'] = dns_support['EnableDnsSupport'].get('Value') + if dns_hostnames: + vpc['EnableDnsHostnames'] = dns_hostnames['EnableDnsHostnames'].get('Value') # for backwards compatibility vpc['id'] = vpc['VpcId'] vpc_info.append(camel_dict_to_snake_dict(vpc)) From adfb007435e96e20b94d28af91e912547d784fbd Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 7 Sep 2022 14:26:48 +0200 Subject: [PATCH 6/7] Update changelog --- changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml b/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml index 32b0ab76433..2c02dd2d356 100644 --- a/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml +++ b/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml @@ -1,3 +1,3 @@ --- minor_changes: -- "ec2_vpc_net_info - handle classic link check for shared vpcs by throwing a warning instead of an error.https://github.com/ansible-collections/amazon.aws/pull/984" +- ec2_vpc_net_info - handle classic link check for shared VPCs by throwing a warning instead of an error (https://github.com/ansible-collections/amazon.aws/pull/984)." From e15c6886d8b9c95f47a5ccb22d6ae15890995d6f Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Wed, 7 Sep 2022 14:27:20 +0200 Subject: [PATCH 7/7] changelog --- changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml b/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml index 2c02dd2d356..3ea4f827d82 100644 --- a/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml +++ b/changelogs/fragments/984-ec2_vpc_net_info_shared_vpc.yml @@ -1,3 +1,3 @@ --- minor_changes: -- ec2_vpc_net_info - handle classic link check for shared VPCs by throwing a warning instead of an error (https://github.com/ansible-collections/amazon.aws/pull/984)." +- ec2_vpc_net_info - handle classic link check for shared VPCs by throwing a warning instead of an error (https://github.com/ansible-collections/amazon.aws/pull/984).