from samtranslator.model.exceptions import InvalidEventException from samtranslator.model.sqs import SQSQueue, SQSQueuePolicies, SQSQueuePolicy class EventBridgeRuleUtils: @staticmethod def create_dead_letter_queue_with_policy(rule_logical_id, rule_arn, queue_logical_id=None, attributes=None): # type: ignore[no-untyped-def] resources = [] queue = SQSQueue(queue_logical_id or rule_logical_id + "Queue", attributes=attributes) dlq_queue_arn = queue.get_runtime_attr("arn") dlq_queue_url = queue.get_runtime_attr("queue_url") # grant necessary permission to Eventbridge Rule resource for sending messages to dead-letter queue policy = SQSQueuePolicy(rule_logical_id + "QueuePolicy", attributes=attributes) policy.PolicyDocument = SQSQueuePolicies.eventbridge_dlq_send_message_resource_based_policy( # type: ignore[no-untyped-call] rule_arn, dlq_queue_arn ) policy.Queues = [dlq_queue_url] resources.append(queue) resources.append(policy) # type: ignore[arg-type] return resources @staticmethod def validate_dlq_config(source_logical_id, dead_letter_config): # type: ignore[no-untyped-def] supported_types = ["SQS"] is_arn_defined = "Arn" in dead_letter_config is_type_defined = "Type" in dead_letter_config if is_arn_defined and is_type_defined: raise InvalidEventException( source_logical_id, "You can either define 'Arn' or 'Type' property of DeadLetterConfig." ) if is_type_defined and dead_letter_config.get("Type") not in supported_types: raise InvalidEventException( source_logical_id, "The only valid value for 'Type' property of DeadLetterConfig is 'SQS'.", ) if not is_arn_defined and not is_type_defined: raise InvalidEventException(source_logical_id, "No 'Arn' or 'Type' property provided for DeadLetterConfig.") @staticmethod def get_dlq_queue_arn_and_resources(cw_event_source, source_arn, attributes): # type: ignore[no-untyped-def] """returns dlq queue arn and dlq_resources, assuming cw_event_source.DeadLetterConfig has been validated""" dlq_queue_arn = cw_event_source.DeadLetterConfig.get("Arn") if dlq_queue_arn is not None: return dlq_queue_arn, [] queue_logical_id = cw_event_source.DeadLetterConfig.get("QueueLogicalId") if queue_logical_id is not None and not isinstance(queue_logical_id, str): raise InvalidEventException( cw_event_source.logical_id, "QueueLogicalId must be a string", ) dlq_resources = EventBridgeRuleUtils.create_dead_letter_queue_with_policy( # type: ignore[no-untyped-call] cw_event_source.logical_id, source_arn, queue_logical_id, attributes ) dlq_queue_arn = dlq_resources[0].get_runtime_attr("arn") return dlq_queue_arn, dlq_resources