Add Tags
field for describe_spot_fleet_requests
response (#6332)
* add tag specifications for request parameters * add unit test for invalid tag resource type
This commit is contained in:
parent
334a259856
commit
b1b269208c
@ -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__(
|
||||
|
@ -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
|
||||
|
@ -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 = """<DescribeSpotFleetRequestsResponse xmlns="http
|
||||
<item>
|
||||
<spotFleetRequestId>{{ request.id }}</spotFleetRequestId>
|
||||
<spotFleetRequestState>{{ request.state }}</spotFleetRequestState>
|
||||
<tagSet>
|
||||
{% for key, value in request.tags.get('spot-fleet-request', {}).items() %}
|
||||
<item>
|
||||
<key>{{ key }}</key>
|
||||
<value>{{ value }}</value>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</tagSet>
|
||||
<spotFleetRequestConfig>
|
||||
{% if request.spot_price %}
|
||||
<spotPrice>{{ request.spot_price }}</spotPrice>
|
||||
|
@ -4,6 +4,7 @@ import pytest
|
||||
|
||||
from moto import mock_ec2
|
||||
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
|
||||
from botocore.exceptions import ClientError
|
||||
from tests import EXAMPLE_AMI_ID
|
||||
from uuid import uuid4
|
||||
|
||||
@ -64,13 +65,49 @@ def spot_config(subnet_id, allocation_strategy="lowestPrice"):
|
||||
"EbsOptimized": False,
|
||||
"WeightedCapacity": 4.0,
|
||||
"SpotPrice": "10.00",
|
||||
"TagSpecifications": [
|
||||
{
|
||||
"ResourceType": "instance",
|
||||
"Tags": [{"Key": "test", "Value": "value"}],
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
"AllocationStrategy": allocation_strategy,
|
||||
"FulfilledCapacity": 6,
|
||||
"TagSpecifications": [
|
||||
{
|
||||
"ResourceType": "spot-fleet-request",
|
||||
"Tags": [{"Key": "test2", "Value": "value2"}],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_spot_fleet_with_invalid_tag_specifications():
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
subnet_id = get_subnet_id(conn)
|
||||
|
||||
config = spot_config(subnet_id)
|
||||
invalid_resource_type = "invalid-resource-type"
|
||||
config["TagSpecifications"] = [
|
||||
{
|
||||
"ResourceType": invalid_resource_type,
|
||||
"Tags": [{"Key": "test2", "Value": "value2"}],
|
||||
}
|
||||
]
|
||||
|
||||
with pytest.raises(ClientError) as ex:
|
||||
_ = conn.request_spot_fleet(SpotFleetRequestConfig=config)
|
||||
|
||||
ex.value.response["Error"]["Code"].should.equal("InvalidParameterValue")
|
||||
ex.value.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.value.response["Error"]["Message"].should.equal(
|
||||
f"The value for `ResourceType` must be `spot-fleet-request`, but got `{invalid_resource_type}` instead."
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_spot_fleet_with_lowest_price():
|
||||
conn = boto3.client("ec2", region_name="us-west-2")
|
||||
@ -87,6 +124,7 @@ def test_create_spot_fleet_with_lowest_price():
|
||||
len(spot_fleet_requests).should.equal(1)
|
||||
spot_fleet_request = spot_fleet_requests[0]
|
||||
spot_fleet_request["SpotFleetRequestState"].should.equal("active")
|
||||
spot_fleet_request["Tags"].should.equal([{"Key": "test2", "Value": "value2"}])
|
||||
spot_fleet_config = spot_fleet_request["SpotFleetRequestConfig"]
|
||||
|
||||
spot_fleet_config["SpotPrice"].should.equal("0.12")
|
||||
|
Loading…
Reference in New Issue
Block a user