Merge pull request #186 from bobbyi/spot_instance_tags
Spot instance tags
This commit is contained in:
commit
2cbdef663f
@ -1260,7 +1260,7 @@ class VPCGatewayAttachmentBackend(object):
|
|||||||
return attachment
|
return attachment
|
||||||
|
|
||||||
|
|
||||||
class SpotInstanceRequest(BotoSpotRequest):
|
class SpotInstanceRequest(BotoSpotRequest, TaggedEC2Instance):
|
||||||
def __init__(self, spot_request_id, price, image_id, type, valid_from,
|
def __init__(self, spot_request_id, price, image_id, type, valid_from,
|
||||||
valid_until, launch_group, availability_zone_group, key_name,
|
valid_until, launch_group, availability_zone_group, key_name,
|
||||||
security_groups, user_data, instance_type, placement, kernel_id,
|
security_groups, user_data, instance_type, placement, kernel_id,
|
||||||
@ -1296,6 +1296,16 @@ class SpotInstanceRequest(BotoSpotRequest):
|
|||||||
default_group = ec2_backend.get_security_group_from_name("default")
|
default_group = ec2_backend.get_security_group_from_name("default")
|
||||||
ls.groups.append(default_group)
|
ls.groups.append(default_group)
|
||||||
|
|
||||||
|
def get_filter_value(self, filter_name):
|
||||||
|
if filter_name == 'state':
|
||||||
|
return self.state
|
||||||
|
elif filter_name.startswith('tag:'):
|
||||||
|
tag_name = filter_name.replace('tag:', '', 1)
|
||||||
|
tags = dict((tag['key'], tag['value']) for tag in self.get_tags())
|
||||||
|
return tags.get(tag_name)
|
||||||
|
else:
|
||||||
|
ec2_backend.raise_not_implemented_error("The filter '{0}' for DescribeSpotInstanceRequests".format(filter_name))
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(Model)
|
@six.add_metaclass(Model)
|
||||||
class SpotRequestBackend(object):
|
class SpotRequestBackend(object):
|
||||||
@ -1322,8 +1332,14 @@ class SpotRequestBackend(object):
|
|||||||
return requests
|
return requests
|
||||||
|
|
||||||
@Model.prop('SpotInstanceRequest')
|
@Model.prop('SpotInstanceRequest')
|
||||||
def describe_spot_instance_requests(self):
|
def describe_spot_instance_requests(self, filters=None):
|
||||||
return self.spot_instance_requests.values()
|
requests = self.spot_instance_requests.values()
|
||||||
|
|
||||||
|
if filters:
|
||||||
|
for (_filter, _filter_value) in filters.items():
|
||||||
|
requests = [ request for request in requests if request.get_filter_value(_filter) in _filter_value ]
|
||||||
|
|
||||||
|
return requests
|
||||||
|
|
||||||
def cancel_spot_instance_requests(self, request_ids):
|
def cancel_spot_instance_requests(self, request_ids):
|
||||||
requests = []
|
requests = []
|
||||||
|
@ -3,6 +3,7 @@ from jinja2 import Template
|
|||||||
|
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from moto.ec2.models import ec2_backend
|
from moto.ec2.models import ec2_backend
|
||||||
|
from moto.ec2.utils import filters_from_querystring
|
||||||
|
|
||||||
|
|
||||||
class SpotInstances(BaseResponse):
|
class SpotInstances(BaseResponse):
|
||||||
@ -30,7 +31,8 @@ class SpotInstances(BaseResponse):
|
|||||||
raise NotImplementedError('SpotInstances.describe_spot_datafeed_subscription is not yet implemented')
|
raise NotImplementedError('SpotInstances.describe_spot_datafeed_subscription is not yet implemented')
|
||||||
|
|
||||||
def describe_spot_instance_requests(self):
|
def describe_spot_instance_requests(self):
|
||||||
requests = ec2_backend.describe_spot_instance_requests()
|
filters = filters_from_querystring(self.querystring)
|
||||||
|
requests = ec2_backend.describe_spot_instance_requests(filters=filters)
|
||||||
template = Template(DESCRIBE_SPOT_INSTANCES_TEMPLATE)
|
template = Template(DESCRIBE_SPOT_INSTANCES_TEMPLATE)
|
||||||
return template.render(requests=requests)
|
return template.render(requests=requests)
|
||||||
|
|
||||||
@ -186,6 +188,16 @@ DESCRIBE_SPOT_INSTANCES_TEMPLATE = """<DescribeSpotInstanceRequestsResponse xmln
|
|||||||
</PlacementRequestType>
|
</PlacementRequestType>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</launchSpecification>
|
</launchSpecification>
|
||||||
|
<tagSet>
|
||||||
|
{% for tag in request.get_tags() %}
|
||||||
|
<item>
|
||||||
|
<resourceId>{{ tag.resource_id }}</resourceId>
|
||||||
|
<resourceType>{{ tag.resource_type }}</resourceType>
|
||||||
|
<key>{{ tag.key }}</key>
|
||||||
|
<value>{{ tag.value }}</value>
|
||||||
|
</item>
|
||||||
|
{% endfor %}
|
||||||
|
</tagSet>
|
||||||
{% if request.launch_group %}
|
{% if request.launch_group %}
|
||||||
<launchGroup>{{ request.launch_group }}</launchGroup>
|
<launchGroup>{{ request.launch_group }}</launchGroup>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -125,3 +125,58 @@ def test_request_spot_instances_fulfilled():
|
|||||||
request = requests[0]
|
request = requests[0]
|
||||||
|
|
||||||
request.state.should.equal("active")
|
request.state.should.equal("active")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_tag_spot_instance_request():
|
||||||
|
"""
|
||||||
|
Test that moto correctly tags a spot instance request
|
||||||
|
"""
|
||||||
|
conn = boto.connect_ec2()
|
||||||
|
|
||||||
|
request = conn.request_spot_instances(
|
||||||
|
price=0.5, image_id='ami-abcd1234',
|
||||||
|
)
|
||||||
|
request[0].add_tag('tag1', 'value1')
|
||||||
|
request[0].add_tag('tag2', 'value2')
|
||||||
|
|
||||||
|
requests = conn.get_all_spot_instance_requests()
|
||||||
|
requests.should.have.length_of(1)
|
||||||
|
request = requests[0]
|
||||||
|
|
||||||
|
tag_dict = dict(request.tags)
|
||||||
|
tag_dict.should.equal({'tag1' : 'value1', 'tag2' : 'value2'})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_ec2
|
||||||
|
def test_get_all_spot_instance_requests_filtering():
|
||||||
|
"""
|
||||||
|
Test that moto correctly filters spot instance requests
|
||||||
|
"""
|
||||||
|
conn = boto.connect_ec2()
|
||||||
|
|
||||||
|
request1 = conn.request_spot_instances(
|
||||||
|
price=0.5, image_id='ami-abcd1234',
|
||||||
|
)
|
||||||
|
request2 = conn.request_spot_instances(
|
||||||
|
price=0.5, image_id='ami-abcd1234',
|
||||||
|
)
|
||||||
|
request3 = conn.request_spot_instances(
|
||||||
|
price=0.5, image_id='ami-abcd1234',
|
||||||
|
)
|
||||||
|
request1[0].add_tag('tag1', 'value1')
|
||||||
|
request1[0].add_tag('tag2', 'value2')
|
||||||
|
request2[0].add_tag('tag1', 'value1')
|
||||||
|
request2[0].add_tag('tag2', 'wrong')
|
||||||
|
|
||||||
|
requests = conn.get_all_spot_instance_requests(filters={'state' : 'active'})
|
||||||
|
requests.should.have.length_of(0)
|
||||||
|
|
||||||
|
requests = conn.get_all_spot_instance_requests(filters={'state' : 'open'})
|
||||||
|
requests.should.have.length_of(3)
|
||||||
|
|
||||||
|
requests = conn.get_all_spot_instance_requests(filters={'tag:tag1' : 'value1'})
|
||||||
|
requests.should.have.length_of(2)
|
||||||
|
|
||||||
|
requests = conn.get_all_spot_instance_requests(filters={'tag:tag1' : 'value1', 'tag:tag2' : 'value2'})
|
||||||
|
requests.should.have.length_of(1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user