Add ec2 instance state reason
- Add instance.reason and instance.state_reason (http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-Item Type-StateReasonType.html) - Add ec2 filtering by state-reason-code and state-reason-message
This commit is contained in:
		
							parent
							
								
									68d2db55d4
								
							
						
					
					
						commit
						6963866c7e
					
				@ -2,6 +2,7 @@ from __future__ import unicode_literals
 | 
			
		||||
import copy
 | 
			
		||||
import itertools
 | 
			
		||||
from collections import defaultdict
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
 | 
			
		||||
import six
 | 
			
		||||
import boto
 | 
			
		||||
@ -95,6 +96,11 @@ class InstanceState(object):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.code = code
 | 
			
		||||
 | 
			
		||||
class StateReason(object):
 | 
			
		||||
    def __init__(self, message="", code=""):
 | 
			
		||||
        self.message = message
 | 
			
		||||
        self.code = code
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TaggedEC2Resource(object):
 | 
			
		||||
    def get_tags(self, *args, **kwargs):
 | 
			
		||||
@ -258,6 +264,8 @@ class Instance(BotoInstance, TaggedEC2Resource):
 | 
			
		||||
        self.id = random_instance_id()
 | 
			
		||||
        self.image_id = image_id
 | 
			
		||||
        self._state = InstanceState("running", 16)
 | 
			
		||||
        self._reason = ""
 | 
			
		||||
        self._state_reason = StateReason()
 | 
			
		||||
        self.user_data = user_data
 | 
			
		||||
        self.security_groups = security_groups
 | 
			
		||||
        self.instance_type = kwargs.get("instance_type", "m1.small")
 | 
			
		||||
@ -317,6 +325,9 @@ class Instance(BotoInstance, TaggedEC2Resource):
 | 
			
		||||
        self._state.name = "running"
 | 
			
		||||
        self._state.code = 16
 | 
			
		||||
 | 
			
		||||
        self._reason = ""
 | 
			
		||||
        self._state_reason = StateReason()
 | 
			
		||||
 | 
			
		||||
    def stop(self, *args, **kwargs):
 | 
			
		||||
        for nic in self.nics.values():
 | 
			
		||||
            nic.stop()
 | 
			
		||||
@ -324,6 +335,10 @@ class Instance(BotoInstance, TaggedEC2Resource):
 | 
			
		||||
        self._state.name = "stopped"
 | 
			
		||||
        self._state.code = 80
 | 
			
		||||
 | 
			
		||||
        self._reason = "User initiated ({0})".format(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC'))
 | 
			
		||||
        self._state_reason = StateReason("Client.UserInitiatedShutdown: User initiated shutdown",
 | 
			
		||||
                                         "Client.UserInitiatedShutdown")
 | 
			
		||||
 | 
			
		||||
    def terminate(self, *args, **kwargs):
 | 
			
		||||
        for nic in self.nics.values():
 | 
			
		||||
            nic.stop()
 | 
			
		||||
@ -331,10 +346,17 @@ class Instance(BotoInstance, TaggedEC2Resource):
 | 
			
		||||
        self._state.name = "terminated"
 | 
			
		||||
        self._state.code = 48
 | 
			
		||||
 | 
			
		||||
        self._reason = "User initiated ({0})".format(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC'))
 | 
			
		||||
        self._state_reason = StateReason("Client.UserInitiatedShutdown: User initiated shutdown",
 | 
			
		||||
                                         "Client.UserInitiatedShutdown")
 | 
			
		||||
 | 
			
		||||
    def reboot(self, *args, **kwargs):
 | 
			
		||||
        self._state.name = "running"
 | 
			
		||||
        self._state.code = 16
 | 
			
		||||
 | 
			
		||||
        self._reason = ""
 | 
			
		||||
        self._state_reason = StateReason()
 | 
			
		||||
 | 
			
		||||
    def get_tags(self):
 | 
			
		||||
        tags = ec2_backend.describe_tags(filters={'resource-id': [self.id]})
 | 
			
		||||
        return tags
 | 
			
		||||
 | 
			
		||||
@ -303,7 +303,7 @@ EC2_DESCRIBE_INSTANCES = """<DescribeInstancesResponse xmlns='http://ec2.amazona
 | 
			
		||||
                    </instanceState>
 | 
			
		||||
                    <privateDnsName>ip-10.0.0.12.ec2.internal</privateDnsName>
 | 
			
		||||
                    <dnsName>ec2-46.51.219.63.compute-1.amazonaws.com</dnsName>
 | 
			
		||||
                    <reason/>
 | 
			
		||||
                    <reason>{{ instance._reason }}</reason>
 | 
			
		||||
                    <keyName>{{ instance.key_name }}</keyName>
 | 
			
		||||
                    <amiLaunchIndex>0</amiLaunchIndex>
 | 
			
		||||
                    <productCodes/>
 | 
			
		||||
@ -337,6 +337,10 @@ EC2_DESCRIBE_INSTANCES = """<DescribeInstancesResponse xmlns='http://ec2.amazona
 | 
			
		||||
                      </item>
 | 
			
		||||
                      {% endfor %}
 | 
			
		||||
                    </groupSet>
 | 
			
		||||
                    <stateReason>
 | 
			
		||||
                      <code>{{ instance._state_reason.code }}</code>
 | 
			
		||||
                      <message>{{ instance._state_reason.message }}</message>
 | 
			
		||||
                    </stateReason>
 | 
			
		||||
                    <architecture>{{ instance.architecture }}</architecture>
 | 
			
		||||
                    <kernelId>{{ instance.kernel }}</kernelId>
 | 
			
		||||
                    <rootDeviceType>ebs</rootDeviceType>
 | 
			
		||||
 | 
			
		||||
@ -266,15 +266,28 @@ def keypair_names_from_querystring(querystring_dict):
 | 
			
		||||
 | 
			
		||||
filter_dict_attribute_mapping = {
 | 
			
		||||
    'instance-state-name': 'state',
 | 
			
		||||
    'instance-id': 'id'
 | 
			
		||||
    'instance-id': 'id',
 | 
			
		||||
    'state-reason-code': '_state_reason.code',
 | 
			
		||||
    'state-reason-message': '_state_reason.message'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def get_instance_value(instance, instance_attr):
 | 
			
		||||
    keys = instance_attr.split('.')
 | 
			
		||||
    val = instance
 | 
			
		||||
    for key in keys:
 | 
			
		||||
        if hasattr(val, key):
 | 
			
		||||
            val = getattr(val, key)
 | 
			
		||||
        elif isinstance(val, dict):
 | 
			
		||||
            val = val[key]
 | 
			
		||||
        else:
 | 
			
		||||
            return None
 | 
			
		||||
    return val
 | 
			
		||||
 | 
			
		||||
def passes_filter_dict(instance, filter_dict):
 | 
			
		||||
    for filter_name, filter_values in filter_dict.items():
 | 
			
		||||
        if filter_name in filter_dict_attribute_mapping:
 | 
			
		||||
            instance_attr = filter_dict_attribute_mapping[filter_name]
 | 
			
		||||
            instance_value = getattr(instance, instance_attr)
 | 
			
		||||
            instance_value = get_instance_value(instance, instance_attr)
 | 
			
		||||
            if instance_value not in filter_values:
 | 
			
		||||
                return False
 | 
			
		||||
        elif filter_name.startswith('tag:'):
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user