From 175c49a73c4fc969a845a59f098b5ef508ee6ce4 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Sun, 26 Dec 2021 05:55:34 -0800 Subject: [PATCH 01/10] Add support for OutpostArn --- plugins/modules/ec2_vol.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/modules/ec2_vol.py b/plugins/modules/ec2_vol.py index cea01de96ff..ffc5b41a386 100644 --- a/plugins/modules/ec2_vol.py +++ b/plugins/modules/ec2_vol.py @@ -455,6 +455,7 @@ def create_volume(module, ec2_conn, zone): snapshot = module.params.get('snapshot') throughput = module.params.get('throughput') multi_attach = module.params.get('multi_attach') + outpost_arn = module.params.get('outpost_arn') volume = get_volume(module, ec2_conn) @@ -488,6 +489,9 @@ def create_volume(module, ec2_conn, zone): if multi_attach: additional_params['MultiAttachEnabled'] = True + if outpost_arn: + additional_params['OutpostArn'] = outpost_arn + create_vol_response = ec2_conn.create_volume( aws_retry=True, AvailabilityZone=zone, @@ -700,6 +704,7 @@ def main(): tags=dict(default={}, type='dict'), modify_volume=dict(default=False, type='bool'), throughput=dict(type='int'), + outpost_arn=dict(type='str'), purge_tags=dict(type='bool', default=False), multi_attach=dict(type='bool'), ) From 2fd54064a1dbe37c7f98ea18bb3ba4c37fa865e4 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Sun, 26 Dec 2021 06:19:05 -0800 Subject: [PATCH 02/10] Added documentation for parameter --- plugins/modules/ec2_vol.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/modules/ec2_vol.py b/plugins/modules/ec2_vol.py index ffc5b41a386..fe326b20b20 100644 --- a/plugins/modules/ec2_vol.py +++ b/plugins/modules/ec2_vol.py @@ -111,6 +111,11 @@ - This parameter is supported with io1 and io2 volumes only. type: bool version_added: 2.0.0 + outpost_arn: + description: + - The Amazon Resource Name (ARN) of the Outpost. + - If set to C(yes), allows to create volume in an Outpost. + type: str author: "Lester Wade (@lwade)" extends_documentation_fragment: - amazon.aws.aws From 7d6e09dfc58cf0e1a46bdd80788edecb88898ebf Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Tue, 4 Jan 2022 07:42:06 -0800 Subject: [PATCH 03/10] Add changelogs fragment --- changelogs/fragments/597-ec2_vol-add-outpostarn-support.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/597-ec2_vol-add-outpostarn-support.yml diff --git a/changelogs/fragments/597-ec2_vol-add-outpostarn-support.yml b/changelogs/fragments/597-ec2_vol-add-outpostarn-support.yml new file mode 100644 index 00000000000..26daff8b700 --- /dev/null +++ b/changelogs/fragments/597-ec2_vol-add-outpostarn-support.yml @@ -0,0 +1,2 @@ +minor_changes: + - ec2_vol - add support for OutpostArn param (https://github.com/ansible-collections/amazon.aws/pull/597). From 6c2d28cfbbcceec824a6d12ec752adfd2cfe0313 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Mon, 10 Jan 2022 12:11:34 -0800 Subject: [PATCH 04/10] Modified based on feedback --- plugins/module_utils/ec2.py | 8 ++++++++ plugins/modules/ec2_vol.py | 9 +++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/plugins/module_utils/ec2.py b/plugins/module_utils/ec2.py index 61ce99b440f..0fd8ec9f40d 100644 --- a/plugins/module_utils/ec2.py +++ b/plugins/module_utils/ec2.py @@ -742,3 +742,11 @@ def normalize_ec2_vpc_dhcp_config(option_config): config_data[option] = [val['Value'] for val in config_item['Values']] return config_data + + +def is_outposts_arn(input_regex): + #API Doc: https://docs.aws.amazon.com/outposts/latest/APIReference/API_Outpost.html + regex_pattern = r'^arn:aws([a-z-]+)?:outposts:[a-z\d-]+:\d{12}:outpost/op-[a-f0-9]{17}$' + if not re.match(regex_pattern, input_regex): + return False + return True diff --git a/plugins/modules/ec2_vol.py b/plugins/modules/ec2_vol.py index fe326b20b20..ed710f23960 100644 --- a/plugins/modules/ec2_vol.py +++ b/plugins/modules/ec2_vol.py @@ -114,8 +114,9 @@ outpost_arn: description: - The Amazon Resource Name (ARN) of the Outpost. - - If set to C(yes), allows to create volume in an Outpost. + - If set, allows to create volume in an Outpost. type: str + version_added: 3.1.0 author: "Lester Wade (@lwade)" extends_documentation_fragment: - amazon.aws.aws @@ -267,6 +268,7 @@ from ..module_utils.ec2 import ansible_dict_to_boto3_filter_list from ..module_utils.ec2 import describe_ec2_tags from ..module_utils.ec2 import ensure_ec2_tags +from ..module_utils.ec2 import is_outposts_arn from ..module_utils.ec2 import AWSRetry from ..module_utils.core import is_boto3_error_code @@ -495,7 +497,10 @@ def create_volume(module, ec2_conn, zone): additional_params['MultiAttachEnabled'] = True if outpost_arn: - additional_params['OutpostArn'] = outpost_arn + if is_outposts_arn(outpost_arn): + additional_params['OutpostArn'] = outpost_arn + else: + module.fail_json('OutpostArn does not match the pattern specified in API specifications.') create_vol_response = ec2_conn.create_volume( aws_retry=True, From b09acded676c8f2f2f7dae919c0eca94141a6f7f Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Tue, 11 Jan 2022 03:19:46 -0800 Subject: [PATCH 05/10] Add unit test --- plugins/module_utils/ec2.py | 7 ++++++- tests/unit/module_utils/test_ec2.py | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/plugins/module_utils/ec2.py b/plugins/module_utils/ec2.py index 0fd8ec9f40d..4947e36b47f 100644 --- a/plugins/module_utils/ec2.py +++ b/plugins/module_utils/ec2.py @@ -745,7 +745,12 @@ def normalize_ec2_vpc_dhcp_config(option_config): def is_outposts_arn(input_regex): - #API Doc: https://docs.aws.amazon.com/outposts/latest/APIReference/API_Outpost.html + """ + Validates the provided regex pattern of outpost arn as per API specification document. + + API Specification Document: + https://docs.aws.amazon.com/outposts/latest/APIReference/API_Outpost.html + """ regex_pattern = r'^arn:aws([a-z-]+)?:outposts:[a-z\d-]+:\d{12}:outpost/op-[a-f0-9]{17}$' if not re.match(regex_pattern, input_regex): return False diff --git a/tests/unit/module_utils/test_ec2.py b/tests/unit/module_utils/test_ec2.py index 759747a5eb7..68b0512ae69 100644 --- a/tests/unit/module_utils/test_ec2.py +++ b/tests/unit/module_utils/test_ec2.py @@ -4,14 +4,16 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import (absolute_import, division, print_function) + +from plugins.module_utils.ec2 import is_outposts_arn __metaclass__ = type import unittest +import pytest 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 map_complex_type - class Ec2Utils(unittest.TestCase): # ======================================================== @@ -76,3 +78,19 @@ def test_ansible_dict_with_integer_to_boto3_filter_list(self): converted_filters_int = ansible_dict_to_boto3_filter_list(filters) self.assertEqual(converted_filters_int, filter_list_integer) + + +# ======================================================== +# ec2.is_outposts_arn +# ======================================================== +@pytest.mark.parametrize( + 'outpost_arn, result', + [ + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), + ("arn:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False) + ] +) +def test_is_outposts_arn(outpost_arn, result): + assert is_outposts_arn(outpost_arn) == result + From db5504ee3d77a28465a4dae06ab3f292a6cf788e Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Tue, 11 Jan 2022 04:03:10 -0800 Subject: [PATCH 06/10] Use parametrize for unit test --- tests/unit/module_utils/test_ec2.py | 31 +++++++++++++++-------------- tests/unit/requirements.txt | 3 +++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/tests/unit/module_utils/test_ec2.py b/tests/unit/module_utils/test_ec2.py index 68b0512ae69..c30adfe6e6d 100644 --- a/tests/unit/module_utils/test_ec2.py +++ b/tests/unit/module_utils/test_ec2.py @@ -9,7 +9,7 @@ __metaclass__ = type import unittest -import pytest +from parametrize import parametrize 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 map_complex_type @@ -80,17 +80,18 @@ def test_ansible_dict_with_integer_to_boto3_filter_list(self): self.assertEqual(converted_filters_int, filter_list_integer) -# ======================================================== -# ec2.is_outposts_arn -# ======================================================== -@pytest.mark.parametrize( - 'outpost_arn, result', - [ - ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), - ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), - ("arn:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False) - ] -) -def test_is_outposts_arn(outpost_arn, result): - assert is_outposts_arn(outpost_arn) == result - + # ======================================================== + # ec2.is_outposts_arn + # ======================================================== + @parametrize( + "outpost_arn, result", + [ + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), + ("arn:aws:outpost:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ("ars:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ("arn:was:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ] + ) + def test_is_outposts_arn(self, outpost_arn, result): + self.assertEqual(is_outposts_arn(outpost_arn), result) diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt index 704c73a25b2..a3bb042c900 100644 --- a/tests/unit/requirements.txt +++ b/tests/unit/requirements.txt @@ -4,3 +4,6 @@ boto3 boto placebo + +# Used for unit testing using parametrize +parametrize From 370d08d14198ea7932a3ce303f832f123da65585 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Tue, 11 Jan 2022 09:43:13 -0800 Subject: [PATCH 07/10] Minor sanity fix --- tests/unit/module_utils/test_ec2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/module_utils/test_ec2.py b/tests/unit/module_utils/test_ec2.py index c30adfe6e6d..dcc709d51e3 100644 --- a/tests/unit/module_utils/test_ec2.py +++ b/tests/unit/module_utils/test_ec2.py @@ -14,6 +14,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 map_complex_type + class Ec2Utils(unittest.TestCase): # ======================================================== @@ -79,10 +80,10 @@ def test_ansible_dict_with_integer_to_boto3_filter_list(self): converted_filters_int = ansible_dict_to_boto3_filter_list(filters) self.assertEqual(converted_filters_int, filter_list_integer) - # ======================================================== # ec2.is_outposts_arn # ======================================================== + @parametrize( "outpost_arn, result", [ From 9191b8bca5de38bb921af83f9718f2c8c8d926c5 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Tue, 11 Jan 2022 11:02:35 -0800 Subject: [PATCH 08/10] sanity fix --- test-requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test-requirements.txt b/test-requirements.txt index 77c76b86509..635335baea4 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -14,3 +14,5 @@ netaddr awscli # Used for comparing SSH Public keys to the Amazon fingerprints pycrypto +# Used for unit testing using parametrize +parametrize From 049a42e90f8c24b28ca4961714492cee15137513 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Thu, 13 Jan 2022 05:24:51 -0800 Subject: [PATCH 09/10] Fix unit test --- test-requirements.txt | 2 -- tests/unit/module_utils/test_ec2.py | 30 ++++++++++++++--------------- tests/unit/requirements.txt | 3 --- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index 635335baea4..77c76b86509 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -14,5 +14,3 @@ netaddr awscli # Used for comparing SSH Public keys to the Amazon fingerprints pycrypto -# Used for unit testing using parametrize -parametrize diff --git a/tests/unit/module_utils/test_ec2.py b/tests/unit/module_utils/test_ec2.py index dcc709d51e3..66cfa2b14da 100644 --- a/tests/unit/module_utils/test_ec2.py +++ b/tests/unit/module_utils/test_ec2.py @@ -9,7 +9,7 @@ __metaclass__ = type import unittest -from parametrize import parametrize +import pytest 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 map_complex_type @@ -80,19 +80,17 @@ def test_ansible_dict_with_integer_to_boto3_filter_list(self): converted_filters_int = ansible_dict_to_boto3_filter_list(filters) self.assertEqual(converted_filters_int, filter_list_integer) - # ======================================================== - # ec2.is_outposts_arn - # ======================================================== - - @parametrize( - "outpost_arn, result", - [ - ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), - ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), - ("arn:aws:outpost:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), - ("ars:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), - ("arn:was:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), +# ======================================================== +# ec2.is_outposts_arn +# ======================================================== +outpost_arn_test_inputs = [ + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), + ("arn:aws:outpost:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ("ars:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ("arn:was:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), ] - ) - def test_is_outposts_arn(self, outpost_arn, result): - self.assertEqual(is_outposts_arn(outpost_arn), result) + +@pytest.mark.parametrize("outpost_arn, result", outpost_arn_test_inputs) +def test_is_outposts_arn(outpost_arn, result): + assert is_outposts_arn(outpost_arn) == result diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt index a3bb042c900..704c73a25b2 100644 --- a/tests/unit/requirements.txt +++ b/tests/unit/requirements.txt @@ -4,6 +4,3 @@ boto3 boto placebo - -# Used for unit testing using parametrize -parametrize From 4fd7f4424c1669fda22ca529ef5517143307f6e7 Mon Sep 17 00:00:00 2001 From: Mandar Kulkarni Date: Thu, 13 Jan 2022 06:15:07 -0800 Subject: [PATCH 10/10] Sanity fixes --- plugins/modules/ec2_vol.py | 1 - tests/unit/module_utils/test_ec2.py | 15 +++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/plugins/modules/ec2_vol.py b/plugins/modules/ec2_vol.py index 5869f488209..bfb6092d88a 100644 --- a/plugins/modules/ec2_vol.py +++ b/plugins/modules/ec2_vol.py @@ -515,7 +515,6 @@ def create_volume(module, ec2_conn, zone): if tags: additional_params['TagSpecifications'] = boto3_tag_specifications(tags, types=['volume']) - create_vol_response = ec2_conn.create_volume( aws_retry=True, AvailabilityZone=zone, diff --git a/tests/unit/module_utils/test_ec2.py b/tests/unit/module_utils/test_ec2.py index 66cfa2b14da..fe66556bcb8 100644 --- a/tests/unit/module_utils/test_ec2.py +++ b/tests/unit/module_utils/test_ec2.py @@ -83,13 +83,16 @@ def test_ansible_dict_with_integer_to_boto3_filter_list(self): # ======================================================== # ec2.is_outposts_arn # ======================================================== + + outpost_arn_test_inputs = [ - ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), - ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), - ("arn:aws:outpost:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), - ("ars:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), - ("arn:was:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), - ] + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0", True), + ("arn:aws:outposts:us-east-1:123456789012:outpost/op-1234567890abcdef0123", False), + ("arn:aws:outpost:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ("ars:aws:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), + ("arn:was:outposts:us-east-1: 123456789012:outpost/ op-1234567890abcdef0", False), +] + @pytest.mark.parametrize("outpost_arn, result", outpost_arn_test_inputs) def test_is_outposts_arn(outpost_arn, result):