Merge #913.
This commit is contained in:
parent
408a70992c
commit
0adebeed24
36 changed files with 669 additions and 58 deletions
|
|
@ -12,6 +12,7 @@ from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
|
|||
from boto.ec2.spotinstancerequest import SpotInstanceRequest as BotoSpotRequest
|
||||
from boto.ec2.launchspecification import LaunchSpecification
|
||||
|
||||
from moto.compat import OrderedDict
|
||||
from moto.core import BaseBackend
|
||||
from moto.core.models import Model, BaseModel
|
||||
from moto.core.utils import iso_8601_datetime_with_milliseconds, camelcase_to_underscores
|
||||
|
|
@ -618,7 +619,7 @@ class Instance(TaggedEC2Resource, BotoInstance):
|
|||
class InstanceBackend(object):
|
||||
|
||||
def __init__(self):
|
||||
self.reservations = {}
|
||||
self.reservations = OrderedDict()
|
||||
super(InstanceBackend, self).__init__()
|
||||
|
||||
def get_instance(self, instance_id):
|
||||
|
|
@ -1049,12 +1050,22 @@ class AmiBackend(object):
|
|||
self.amis[ami_id] = ami
|
||||
return ami
|
||||
|
||||
def describe_images(self, ami_ids=(), filters=None):
|
||||
def describe_images(self, ami_ids=(), filters=None, exec_users=None):
|
||||
images = []
|
||||
if exec_users:
|
||||
for ami_id in self.amis:
|
||||
found = False
|
||||
for user_id in exec_users:
|
||||
if user_id in self.amis[ami_id].launch_permission_users:
|
||||
found = True
|
||||
if found:
|
||||
images.append(self.amis[ami_id])
|
||||
if images == []:
|
||||
return images
|
||||
if filters:
|
||||
images = self.amis.values()
|
||||
images = images or self.amis.values()
|
||||
return generic_filter(filters, images)
|
||||
else:
|
||||
images = []
|
||||
for ami_id in ami_ids:
|
||||
if ami_id in self.amis:
|
||||
images.append(self.amis[ami_id])
|
||||
|
|
@ -1766,6 +1777,9 @@ class Snapshot(TaggedEC2Resource):
|
|||
if filter_name == 'encrypted':
|
||||
return str(self.encrypted).lower()
|
||||
|
||||
if filter_name == 'status':
|
||||
return self.status
|
||||
|
||||
filter_value = super(Snapshot, self).get_filter_value(filter_name)
|
||||
|
||||
if filter_value is None:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from __future__ import unicode_literals
|
||||
from moto.core.responses import BaseResponse
|
||||
from moto.ec2.utils import instance_ids_from_querystring, image_ids_from_querystring, \
|
||||
filters_from_querystring, sequence_from_querystring
|
||||
filters_from_querystring, sequence_from_querystring, executable_users_from_querystring
|
||||
|
||||
|
||||
class AmisResponse(BaseResponse):
|
||||
|
|
@ -43,8 +43,9 @@ class AmisResponse(BaseResponse):
|
|||
def describe_images(self):
|
||||
ami_ids = image_ids_from_querystring(self.querystring)
|
||||
filters = filters_from_querystring(self.querystring)
|
||||
exec_users = executable_users_from_querystring(self.querystring)
|
||||
images = self.ec2_backend.describe_images(
|
||||
ami_ids=ami_ids, filters=filters)
|
||||
ami_ids=ami_ids, filters=filters, exec_users=exec_users)
|
||||
template = self.response_template(DESCRIBE_IMAGES_RESPONSE)
|
||||
return template.render(images=images)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class InstanceResponse(BaseResponse):
|
|||
def describe_instances(self):
|
||||
filter_dict = filters_from_querystring(self.querystring)
|
||||
instance_ids = instance_ids_from_querystring(self.querystring)
|
||||
token = self._get_param("NextToken")
|
||||
if instance_ids:
|
||||
reservations = self.ec2_backend.get_reservations_by_instance_ids(
|
||||
instance_ids, filters=filter_dict)
|
||||
|
|
@ -18,8 +19,18 @@ class InstanceResponse(BaseResponse):
|
|||
reservations = self.ec2_backend.all_reservations(
|
||||
make_copy=True, filters=filter_dict)
|
||||
|
||||
reservation_ids = [reservation.id for reservation in reservations]
|
||||
if token:
|
||||
start = reservation_ids.index(token) + 1
|
||||
else:
|
||||
start = 0
|
||||
max_results = int(self._get_param('MaxResults', 100))
|
||||
reservations_resp = reservations[start:start + max_results]
|
||||
next_token = None
|
||||
if max_results and len(reservations) > (start + max_results):
|
||||
next_token = reservations_resp[-1].id
|
||||
template = self.response_template(EC2_DESCRIBE_INSTANCES)
|
||||
return template.render(reservations=reservations)
|
||||
return template.render(reservations=reservations_resp, next_token=next_token)
|
||||
|
||||
def run_instances(self):
|
||||
min_count = int(self.querystring.get('MinCount', ['1'])[0])
|
||||
|
|
@ -492,6 +503,9 @@ EC2_DESCRIBE_INSTANCES = """<DescribeInstancesResponse xmlns="http://ec2.amazona
|
|||
</item>
|
||||
{% endfor %}
|
||||
</reservationSet>
|
||||
{% if next_token %}
|
||||
<nextToken>{{ next_token }}</nextToken>
|
||||
{% endif %}
|
||||
</DescribeInstancesResponse>"""
|
||||
|
||||
EC2_TERMINATE_INSTANCES = """
|
||||
|
|
|
|||
|
|
@ -190,6 +190,14 @@ def image_ids_from_querystring(querystring_dict):
|
|||
return image_ids
|
||||
|
||||
|
||||
def executable_users_from_querystring(querystring_dict):
|
||||
user_ids = []
|
||||
for key, value in querystring_dict.items():
|
||||
if 'ExecutableBy' in key:
|
||||
user_ids.append(value[0])
|
||||
return user_ids
|
||||
|
||||
|
||||
def route_table_ids_from_querystring(querystring_dict):
|
||||
route_table_ids = []
|
||||
for key, value in querystring_dict.items():
|
||||
|
|
@ -383,7 +391,8 @@ filter_dict_attribute_mapping = {
|
|||
'private-ip-address': 'private_ip',
|
||||
'ip-address': 'public_ip',
|
||||
'availability-zone': 'placement',
|
||||
'architecture': 'architecture'
|
||||
'architecture': 'architecture',
|
||||
'image-id': 'image_id'
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -461,6 +470,9 @@ def filter_internet_gateways(igws, filter_dict):
|
|||
def is_filter_matching(obj, filter, filter_value):
|
||||
value = obj.get_filter_value(filter)
|
||||
|
||||
if not filter_value:
|
||||
return False
|
||||
|
||||
if isinstance(value, six.string_types):
|
||||
if not isinstance(filter_value, list):
|
||||
filter_value = [filter_value]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue