This commit is contained in:
Steve Pulec 2017-05-10 21:58:42 -04:00
commit 0adebeed24
36 changed files with 669 additions and 58 deletions

View file

@ -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:

View file

@ -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)

View file

@ -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 = """

View file

@ -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]