From 40752980a5f45cf0694979bff349540c91dd43bd Mon Sep 17 00:00:00 2001 From: abikouo Date: Thu, 25 Mar 2021 14:10:19 +0100 Subject: [PATCH 1/6] implement new boto3 api to set ip address type --- plugins/module_utils/elbv2.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/plugins/module_utils/elbv2.py b/plugins/module_utils/elbv2.py index 6078fba34fe..c12bfa75a94 100644 --- a/plugins/module_utils/elbv2.py +++ b/plugins/module_utils/elbv2.py @@ -71,8 +71,10 @@ def __init__(self, connection, module): if self.elb is not None: self.elb_attributes = self.get_elb_attributes() self.elb['tags'] = self.get_elb_tags() + self.elb_ip_addr_type = self.get_elb_ip_address_type() else: self.elb_attributes = None + self.elb_ip_addr_type = None def wait_for_status(self, elb_arn): """ @@ -107,6 +109,23 @@ def get_elb_attributes(self): # Replace '.' with '_' in attribute key names to make it more Ansibley return dict((k.replace('.', '_'), v) for k, v in elb_attributes.items()) + def get_elb_ip_address_type(self): + """ + Retrieve load balancer ip address type using describe_load_balancers + + :return: + """ + + try: + self.elb_ip_addr_type = AWSRetry.jittered_backoff()( + self.connection.describe_load_balancers + )(LoadBalancerArns=[ self.elb['LoadBalancerArn'] ])['LoadBalancers'][0]['IpAddressType'] + return self.elb_ip_addr_type + + except (BotoCoreError, ClientError) as e: + self.module.fail_json_aws(e) + + def update_elb_attributes(self): """ Update the elb_attributes parameter @@ -232,6 +251,21 @@ def update(self): self.elb = get_elb(self.connection, self.module, self.module.params.get("name")) self.elb['tags'] = self.get_elb_tags() + def modify_ip_address_type(self,ip_addr_type) : + """ + Modify ELB ip address type + :return: + """ + if self.elb_ip_addr_type != ip_addr_type : + try: + AWSRetry.jittered_backoff()( + self.connection.set_ip_address_type + )(LoadBalancerArn=self.elb['LoadBalancerArn'], IpAddressType=ip_addr_type) + except (BotoCoreError, ClientError) as e: + self.module.fail_json_aws(e) + + self.changed = True + class ApplicationLoadBalancer(ElasticLoadBalancerV2): @@ -360,7 +394,6 @@ def modify_security_groups(self): self.changed = True - class NetworkLoadBalancer(ElasticLoadBalancerV2): def __init__(self, connection, connection_ec2, module): From 81eaf6145ad4531367bd2e5c2262b2606e78f4a3 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 27 Mar 2021 14:14:59 +0100 Subject: [PATCH 2/6] Whitespace linting --- plugins/module_utils/elbv2.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/module_utils/elbv2.py b/plugins/module_utils/elbv2.py index c12bfa75a94..38be515217a 100644 --- a/plugins/module_utils/elbv2.py +++ b/plugins/module_utils/elbv2.py @@ -119,7 +119,7 @@ def get_elb_ip_address_type(self): try: self.elb_ip_addr_type = AWSRetry.jittered_backoff()( self.connection.describe_load_balancers - )(LoadBalancerArns=[ self.elb['LoadBalancerArn'] ])['LoadBalancers'][0]['IpAddressType'] + )(LoadBalancerArns=[self.elb['LoadBalancerArn']])['LoadBalancers'][0]['IpAddressType'] return self.elb_ip_addr_type except (BotoCoreError, ClientError) as e: @@ -251,12 +251,12 @@ def update(self): self.elb = get_elb(self.connection, self.module, self.module.params.get("name")) self.elb['tags'] = self.get_elb_tags() - def modify_ip_address_type(self,ip_addr_type) : + def modify_ip_address_type(self,ip_addr_type): """ Modify ELB ip address type :return: """ - if self.elb_ip_addr_type != ip_addr_type : + if self.elb_ip_addr_type != ip_addr_type: try: AWSRetry.jittered_backoff()( self.connection.set_ip_address_type @@ -394,6 +394,7 @@ def modify_security_groups(self): self.changed = True + class NetworkLoadBalancer(ElasticLoadBalancerV2): def __init__(self, connection, connection_ec2, module): From 6a756c605c471b3840108f92ae69516d49a2c090 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Sat, 27 Mar 2021 14:15:44 +0100 Subject: [PATCH 3/6] remove extra newline --- plugins/module_utils/elbv2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/module_utils/elbv2.py b/plugins/module_utils/elbv2.py index 38be515217a..b4a3c722808 100644 --- a/plugins/module_utils/elbv2.py +++ b/plugins/module_utils/elbv2.py @@ -125,7 +125,6 @@ def get_elb_ip_address_type(self): except (BotoCoreError, ClientError) as e: self.module.fail_json_aws(e) - def update_elb_attributes(self): """ Update the elb_attributes parameter From 7b5457b8f808d03e89efb8af76f7973c9d6530ed Mon Sep 17 00:00:00 2001 From: abikouo <79859644+abikouo@users.noreply.github.com> Date: Mon, 29 Mar 2021 11:41:22 +0200 Subject: [PATCH 4/6] Update plugins/module_utils/elbv2.py Co-authored-by: Mark Chappell --- plugins/module_utils/elbv2.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/module_utils/elbv2.py b/plugins/module_utils/elbv2.py index b4a3c722808..d62d6982529 100644 --- a/plugins/module_utils/elbv2.py +++ b/plugins/module_utils/elbv2.py @@ -116,14 +116,7 @@ def get_elb_ip_address_type(self): :return: """ - try: - self.elb_ip_addr_type = AWSRetry.jittered_backoff()( - self.connection.describe_load_balancers - )(LoadBalancerArns=[self.elb['LoadBalancerArn']])['LoadBalancers'][0]['IpAddressType'] - return self.elb_ip_addr_type - - except (BotoCoreError, ClientError) as e: - self.module.fail_json_aws(e) + return self.elb.get('IpAddressType', None) def update_elb_attributes(self): """ From 6564ea4887f97727267480fc7710f735edf746f7 Mon Sep 17 00:00:00 2001 From: abikouo <79859644+abikouo@users.noreply.github.com> Date: Tue, 30 Mar 2021 11:49:11 +0200 Subject: [PATCH 5/6] Update elbv2.py --- plugins/module_utils/elbv2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/module_utils/elbv2.py b/plugins/module_utils/elbv2.py index d62d6982529..8ad0bbf0510 100644 --- a/plugins/module_utils/elbv2.py +++ b/plugins/module_utils/elbv2.py @@ -243,7 +243,7 @@ def update(self): self.elb = get_elb(self.connection, self.module, self.module.params.get("name")) self.elb['tags'] = self.get_elb_tags() - def modify_ip_address_type(self,ip_addr_type): + def modify_ip_address_type(self, ip_addr_type): """ Modify ELB ip address type :return: From 6b214ede727d62e611662ceb0a2dcec6c96c80cf Mon Sep 17 00:00:00 2001 From: aubin Date: Wed, 14 Apr 2021 10:47:07 +0200 Subject: [PATCH 6/6] adding unit tests for ip_address_type module --- tests/unit/module_utils/test_elbv2.py | 126 +++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/tests/unit/module_utils/test_elbv2.py b/tests/unit/module_utils/test_elbv2.py index dba2c129bb8..ecabe37d31c 100644 --- a/tests/unit/module_utils/test_elbv2.py +++ b/tests/unit/module_utils/test_elbv2.py @@ -8,7 +8,8 @@ __metaclass__ = type import ansible_collections.amazon.aws.plugins.module_utils.elbv2 as elbv2 - +from ansible_collections.amazon.aws.tests.unit.compat import unittest +from ansible_collections.amazon.aws.tests.unit.compat.mock import MagicMock one_action = [ { @@ -41,3 +42,126 @@ def _prune_secret(): def _sort_actions_one_entry(): assert elbv2._sort_actions(one_action) == one_action + + +class ElBV2UtilsTestSuite(unittest.TestCase): + + def setUp(self): + self.connection = MagicMock(name="connection") + self.module = MagicMock(name="module") + + self.module.params = dict() + + self.conn_paginator = MagicMock(name="connection.paginator") + self.paginate = MagicMock(name="paginator.paginate") + + self.connection.get_paginator.return_value = self.conn_paginator + self.conn_paginator.paginate.return_value = self.paginate + + self.loadbalancer = { + "Type": "application", + "Scheme": "internet-facing", + "IpAddressType": "ipv4", + "VpcId": "vpc-3ac0fb5f", + "AvailabilityZones": [ + { + "ZoneName": "us-west-2a", + "SubnetId": "subnet-8360a9e7" + }, + { + "ZoneName": "us-west-2b", + "SubnetId": "subnet-b7d581c0" + } + ], + "CreatedTime": "2016-03-25T21:26:12.920Z", + "CanonicalHostedZoneId": "Z2P70J7EXAMPLE", + "DNSName": "my-load-balancer-424835706.us-west-2.elb.amazonaws.com", + "SecurityGroups": [ + "sg-5943793c" + ], + "LoadBalancerName": "my-load-balancer", + "State": { + "Code": "active" + }, + "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188" + } + self.paginate.build_full_result.return_value = { + 'LoadBalancers': [self.loadbalancer] + } + + self.connection.describe_load_balancer_attributes.return_value = { + "Attributes": [ + { + "Value": "false", + "Key": "access_logs.s3.enabled" + }, + { + "Value": "", + "Key": "access_logs.s3.bucket" + }, + { + "Value": "", + "Key": "access_logs.s3.prefix" + }, + { + "Value": "60", + "Key": "idle_timeout.timeout_seconds" + }, + { + "Value": "false", + "Key": "deletion_protection.enabled" + }, + { + "Value": "true", + "Key": "routing.http2.enabled" + } + ] + } + self.connection.describe_tags.return_value = { + "TagDescriptions": [ + { + "ResourceArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188", + "Tags": [ + { + "Value": "ansible", + "Key": "project" + }, + { + "Value": "RedHat", + "Key": "company" + } + ] + } + ] + } + self.elbv2obj = elbv2.ElasticLoadBalancerV2(self.connection, self.module) + + # Test the simplest case - Read the ip address type + def test_get_elb_ip_address_type(self): + # Run module + return_value = self.elbv2obj.get_elb_ip_address_type() + # check that no method was called and this has been retrieved from elb attributes + self.connection.describe_load_balancer_attributes.assert_called_once() + self.connection.get_paginator.assert_called_once() + self.connection.describe_tags.assert_called_once() + self.conn_paginator.paginate.assert_called_once() + # assert we got the expected value + self.assertEqual(return_value, 'ipv4') + + # Test modify_ip_address_type idempotency + def test_modify_ip_address_type_idempotency(self): + # Run module + return_value = self.elbv2obj.modify_ip_address_type("ipv4") + # check that no method was called and this has been retrieved from elb attributes + self.connection.set_ip_address_type.assert_not_called() + # assert we got the expected value + self.assertEqual(self.elbv2obj.changed, False) + + # Test modify_ip_address_type + def test_modify_ip_address_type_update(self): + # Run module + return_value = self.elbv2obj.modify_ip_address_type("dualstack") + # check that no method was called and this has been retrieved from elb attributes + self.connection.set_ip_address_type.assert_called_once() + # assert we got the expected value + self.assertEqual(self.elbv2obj.changed, True)