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