From b1b269208c3690cc20bf07ea375e1de9296effc2 Mon Sep 17 00:00:00 2001 From: Akira Noda <61897166+tsugumi-sys@users.noreply.github.com> Date: Tue, 23 May 2023 05:53:57 +0900 Subject: [PATCH] Add `Tags` field for `describe_spot_fleet_requests` response (#6332) * add tag specifications for request parameters * add unit test for invalid tag resource type --- moto/ec2/exceptions.py | 8 +++++++ moto/ec2/models/spot_requests.py | 12 ++++++++++ moto/ec2/responses/spot_fleets.py | 10 ++++++++ tests/test_ec2/test_spot_fleet.py | 38 +++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/moto/ec2/exceptions.py b/moto/ec2/exceptions.py index 4b3373fb7..6eb8d515e 100644 --- a/moto/ec2/exceptions.py +++ b/moto/ec2/exceptions.py @@ -436,6 +436,14 @@ class InvalidParameterValueError(EC2ClientError): ) +class InvalidParameterValueErrorTagSpotFleetRequest(EC2ClientError): + def __init__(self, resource_type: str): + super().__init__( + "InvalidParameterValue", + f"The value for `ResourceType` must be `spot-fleet-request`, but got `{resource_type}` instead.", + ) + + class EmptyTagSpecError(EC2ClientError): def __init__(self) -> None: super().__init__( diff --git a/moto/ec2/models/spot_requests.py b/moto/ec2/models/spot_requests.py index d9242931c..7887d1c35 100644 --- a/moto/ec2/models/spot_requests.py +++ b/moto/ec2/models/spot_requests.py @@ -2,6 +2,7 @@ from collections import defaultdict from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING from moto.core.common_models import BaseModel, CloudFormationModel +from moto.ec2.exceptions import InvalidParameterValueErrorTagSpotFleetRequest if TYPE_CHECKING: from moto.ec2.models.instances import Instance @@ -185,6 +186,7 @@ class SpotFleetRequest(TaggedEC2Resource, CloudFormationModel): launch_specs: List[Dict[str, Any]], launch_template_config: Optional[List[Dict[str, Any]]], instance_interruption_behaviour: Optional[str], + tag_specifications: Optional[List[Dict[str, Any]]], ): self.ec2_backend = ec2_backend @@ -202,6 +204,14 @@ class SpotFleetRequest(TaggedEC2Resource, CloudFormationModel): self.launch_specs = [] + self.tags = {} + if tag_specifications is not None: + tags = convert_tag_spec(tag_specifications) + for resource_type in tags: + if resource_type != "spot-fleet-request": + raise InvalidParameterValueErrorTagSpotFleetRequest(resource_type) + self.tags.update(tags) + launch_specs_from_config = [] for config in launch_template_config or []: spec = config["LaunchTemplateSpecification"] @@ -456,6 +466,7 @@ class SpotRequestBackend: launch_specs: List[Dict[str, Any]], launch_template_config: Optional[List[Dict[str, Any]]] = None, instance_interruption_behaviour: Optional[str] = None, + tag_specifications: Optional[List[Dict[str, Any]]] = None, ) -> SpotFleetRequest: spot_fleet_request_id = random_spot_fleet_request_id() @@ -470,6 +481,7 @@ class SpotRequestBackend: launch_specs=launch_specs, launch_template_config=launch_template_config, instance_interruption_behaviour=instance_interruption_behaviour, + tag_specifications=tag_specifications, ) self.spot_fleet_requests[spot_fleet_request_id] = request return request diff --git a/moto/ec2/responses/spot_fleets.py b/moto/ec2/responses/spot_fleets.py index 254525fbc..a0ddc5f66 100644 --- a/moto/ec2/responses/spot_fleets.py +++ b/moto/ec2/responses/spot_fleets.py @@ -57,6 +57,7 @@ class SpotFleets(EC2BaseResponse): .get("LaunchTemplateConfigs", {}) .values() ) + tag_specifications = spot_config.get("TagSpecification") request = self.ec2_backend.request_spot_fleet( spot_price=spot_price, @@ -66,6 +67,7 @@ class SpotFleets(EC2BaseResponse): launch_specs=launch_specs, launch_template_config=launch_template_config, instance_interruption_behaviour=instance_interruption_behaviour, + tag_specifications=tag_specifications, ) template = self.response_template(REQUEST_SPOT_FLEET_TEMPLATE) @@ -89,6 +91,14 @@ DESCRIBE_SPOT_FLEET_TEMPLATE = """