diff --git a/changelogs/fragments/add-utils-support-ec2_transit_gateway-modules.yml b/changelogs/fragments/add-utils-support-ec2_transit_gateway-modules.yml new file mode 100644 index 00000000000..d37c5f8f256 --- /dev/null +++ b/changelogs/fragments/add-utils-support-ec2_transit_gateway-modules.yml @@ -0,0 +1,2 @@ +minor_changes: + - module_utils/ec2 - add utils for the ec2_transit_gateway_* modules (https://github.com/ansible-collections/amazon.aws/pull/2325). diff --git a/plugins/module_utils/ec2.py b/plugins/module_utils/ec2.py index 9ec6a4f99ee..0dd15e41ff7 100644 --- a/plugins/module_utils/ec2.py +++ b/plugins/module_utils/ec2.py @@ -1783,3 +1783,36 @@ def determine_iam_arn_from_name(iam_client, name_or_arn: str) -> str: if not iam_instance_profiles: raise AnsibleEC2Error(message=f"Could not find IAM instance profile {name_or_arn}") return iam_instance_profiles[0]["Arn"] + + +# EC2 Transit Gateway +class EC2TransitGatewayErrorHandler(AWSErrorHandler): + _CUSTOM_EXCEPTION = AnsibleEC2Error + + @classmethod + def _is_missing(cls): + return is_boto3_error_code("InvalidTransitGatewayID.NotFound") + + +@EC2TransitGatewayErrorHandler.list_error_handler("describe transit gateway", []) +@AWSRetry.jittered_backoff() +def describe_ec2_transit_gateways( + client, **params: Dict[str, Union[List[str], List[Dict[str, Union[str, List[str]]]]]] +) -> List[Dict[str, Any]]: + paginator = client.get_paginator("describe_transit_gateways") + return paginator.paginate(**params).build_full_result()["TransitGateways"] + + +@EC2TransitGatewayErrorHandler.common_error_handler("create transit gateway") +@AWSRetry.jittered_backoff() +def create_ec2_transit_gateway( + client, **params: Dict[str, Union[List[str], List[Dict[str, Union[str, List[str]]]]]] +) -> Dict[str, Any]: + return client.create_transit_gateway(**params)["TransitGateway"] + + +@EC2TransitGatewayErrorHandler.deletion_error_handler("delete transit gateway") +@AWSRetry.jittered_backoff() +def delete_ec2_transit_gateway(client, transit_gateway_id: str) -> bool: + client.delete_transit_gateway(TransitGatewayId=transit_gateway_id) + return True diff --git a/plugins/module_utils/waiters.py b/plugins/module_utils/waiters.py index 0251be96c31..e3f26bda362 100644 --- a/plugins/module_utils/waiters.py +++ b/plugins/module_utils/waiters.py @@ -51,6 +51,56 @@ {"matcher": "error", "expected": "InvalidInternetGatewayID.NotFound", "state": "retry"}, ], }, + "TransitGatewayAvailable": { + "operation": "DescribeTransitGateways", + "delay": 5, + "maxAttempts": 120, + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "TransitGateways[].State", + "expected": "available", + }, + { + "state": "retry", + "matcher": "pathAll", + "argument": "TransitGateways[].State", + "expected": "pending", + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "TransitGateways[].State", + "expected": "failed", + }, + ], + }, + "TransitGatewayDeleted": { + "operation": "DescribeTransitGateways", + "delay": 5, + "maxAttempts": 120, + "acceptors": [ + { + "state": "success", + "matcher": "pathAll", + "argument": "TransitGateways[].State", + "expected": "deleted", + }, + { + "state": "retry", + "matcher": "pathAll", + "argument": "TransitGateways[].State", + "expected": "deleting", + }, + { + "state": "failure", + "matcher": "pathAny", + "argument": "TransitGateways[].State", + "expected": "failed", + }, + ], + }, "TGWVpcAttachmentAvailable": { "operation": "DescribeTransitGatewayVpcAttachments", "delay": 5, @@ -833,6 +883,16 @@ def route53_model(name): ec2_model("InternetGatewayAttached"), core_waiter.NormalizedOperationMethod(ec2.describe_internet_gateways), ), + ("EC2", "transit_gateway_available"): lambda ec2: core_waiter.Waiter( + "transit_gateway_available", + ec2_model("TransitGatewayAvailable"), + core_waiter.NormalizedOperationMethod(ec2.describe_transit_gateways), + ), + ("EC2", "transit_gateway_deleted"): lambda ec2: core_waiter.Waiter( + "transit_gateway_deleted", + ec2_model("TransitGatewayDeleted"), + core_waiter.NormalizedOperationMethod(ec2.describe_transit_gateways), + ), ("EC2", "transit_gateway_vpc_attachment_available"): lambda ec2: core_waiter.Waiter( "transit_gateway_vpc_attachment_available", ec2_model("TGWVpcAttachmentAvailable"),