Merge pull request #2764 from bblommers/feature/ec2-describe-instance-filters

Feature  - EC2 describe_instance_status now uses filters
This commit is contained in:
Steve Pulec 2020-03-07 11:47:05 -06:00 committed by GitHub
commit a92f862e86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 10 deletions

View file

@ -822,6 +822,21 @@ class Instance(TaggedEC2Resource, BotoInstance):
return self.public_ip
raise UnformattedGetAttTemplateException()
def applies(self, filters):
if filters:
applicable = False
for f in filters:
acceptable_values = f["values"]
if f["name"] == "instance-state-name":
if self._state.name in acceptable_values:
applicable = True
if f["name"] == "instance-state-code":
if str(self._state.code) in acceptable_values:
applicable = True
return applicable
# If there are no filters, all instances are valid
return True
class InstanceBackend(object):
def __init__(self):
@ -921,22 +936,23 @@ class InstanceBackend(object):
value = getattr(instance, key)
return instance, value
def all_instances(self):
def all_instances(self, filters=None):
instances = []
for reservation in self.all_reservations():
for instance in reservation.instances:
instances.append(instance)
return instances
def all_running_instances(self):
instances = []
for reservation in self.all_reservations():
for instance in reservation.instances:
if instance.state_code == 16:
if instance.applies(filters):
instances.append(instance)
return instances
def get_multi_instances_by_id(self, instance_ids):
def all_running_instances(self, filters=None):
instances = []
for reservation in self.all_reservations():
for instance in reservation.instances:
if instance.state_code == 16 and instance.applies(filters):
instances.append(instance)
return instances
def get_multi_instances_by_id(self, instance_ids, filters=None):
"""
:param instance_ids: A string list with instance ids
:return: A list with instance objects
@ -946,7 +962,8 @@ class InstanceBackend(object):
for reservation in self.all_reservations():
for instance in reservation.instances:
if instance.id in instance_ids:
result.append(instance)
if instance.applies(filters):
result.append(instance)
# TODO: Trim error message down to specific invalid id.
if instance_ids and len(instance_ids) > len(result):

View file

@ -113,16 +113,34 @@ class InstanceResponse(BaseResponse):
template = self.response_template(EC2_START_INSTANCES)
return template.render(instances=instances)
def _get_list_of_dict_params(self, param_prefix, _dct):
"""
Simplified version of _get_dict_param
Allows you to pass in a custom dict instead of using self.querystring by default
"""
params = []
for key, value in _dct.items():
if key.startswith(param_prefix):
params.append(value)
return params
def describe_instance_status(self):
instance_ids = self._get_multi_param("InstanceId")
include_all_instances = self._get_param("IncludeAllInstances") == "true"
filters = self._get_list_prefix("Filter")
filters = [
{"name": f["name"], "values": self._get_list_of_dict_params("value.", f)}
for f in filters
]
if instance_ids:
instances = self.ec2_backend.get_multi_instances_by_id(instance_ids)
instances = self.ec2_backend.get_multi_instances_by_id(
instance_ids, filters
)
elif include_all_instances:
instances = self.ec2_backend.all_instances()
instances = self.ec2_backend.all_instances(filters)
else:
instances = self.ec2_backend.all_running_instances()
instances = self.ec2_backend.all_running_instances(filters)
template = self.response_template(EC2_INSTANCE_STATUS)
return template.render(instances=instances)