2010-03-16 18:46:21 -04:00
module Fog
2011-06-16 19:28:54 -04:00
module Compute
class AWS
2010-03-16 18:46:21 -04:00
class Real
2009-08-23 14:01:37 -04:00
2011-08-24 21:37:00 -04:00
require 'fog/aws/parsers/compute/describe_instances'
2010-06-12 18:31:17 -04:00
2009-08-23 14:01:37 -04:00
# Describe all or specified instances
#
# ==== Parameters
2010-10-04 18:46:12 -04:00
# * filters<~Hash> - List of filters to limit results with
2009-08-23 14:01:37 -04:00
#
# ==== Returns
2009-11-02 21:48:49 -05:00
# * response<~Excon::Response>:
2009-08-23 14:01:37 -04:00
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'reservationSet'<~Array>:
# * 'groupSet'<~Array> - Group names for reservation
# * 'ownerId'<~String> - AWS Access Key ID of reservation owner
# * 'reservationId'<~String> - Id of the reservation
# * 'instancesSet'<~Array>:
# * instance<~Hash>:
2010-02-20 16:12:04 -05:00
# * 'architecture'<~String> - architecture of image in [i386, x86_64]
2009-08-23 14:01:37 -04:00
# * 'amiLaunchIndex'<~Integer> - reference to instance in launch group
2010-02-20 16:12:04 -05:00
# * 'blockDeviceMapping'<~Array>
# * 'attachTime'<~Time> - time of volume attachment
# * 'deleteOnTermination'<~Boolean> - whether or not to delete volume on termination
# * 'deviceName'<~String> - specifies how volume is exposed to instance
# * 'status'<~String> - status of attached volume
# * 'volumeId'<~String> - Id of attached volume
2009-08-23 14:01:37 -04:00
# * 'dnsName'<~String> - public dns name, blank until instance is running
2012-08-01 12:03:07 -04:00
# * 'ebsOptimized'<~Boolean> - Whether the instance is optimized for EBS I/O
2009-08-23 14:01:37 -04:00
# * 'imageId'<~String> - image id of ami used to launch instance
# * 'instanceId'<~String> - id of the instance
# * 'instanceState'<~Hash>:
# * 'code'<~Integer> - current status code
# * 'name'<~String> - current status name
# * 'instanceType'<~String> - type of instance
2010-02-20 16:12:04 -05:00
# * 'ipAddress'<~String> - public ip address assigned to instance
# * 'kernelId'<~String> - id of kernel used to launch instance
2009-08-23 14:01:37 -04:00
# * 'keyName'<~String> - name of key used launch instances or blank
# * 'launchTime'<~Time> - time instance was launched
# * 'monitoring'<~Hash>:
# * 'state'<~Boolean - state of monitoring
# * 'placement'<~Hash>:
# * 'availabilityZone'<~String> - Availability zone of the instance
2011-09-06 12:31:20 -04:00
# * 'platform'<~String> - Platform of the instance (e.g., Windows).
2009-08-23 14:01:37 -04:00
# * 'productCodes'<~Array> - Product codes for the instance
# * 'privateDnsName'<~String> - private dns name, blank until instance is running
2010-02-20 16:12:04 -05:00
# * 'privateIpAddress'<~String> - private ip address assigned to instance
# * 'rootDeviceName'<~String> - specifies how the root device is exposed to the instance
# * 'rootDeviceType'<~String> - root device type used by AMI in [ebs, instance-store]
2009-08-23 14:01:37 -04:00
# * 'ramdiskId'<~String> - Id of ramdisk used to launch instance
# * 'reason'<~String> - reason for most recent state transition, or blank
2011-05-19 12:31:56 -04:00
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html]
2010-10-04 18:46:12 -04:00
def describe_instances ( filters = { } )
unless filters . is_a? ( Hash )
2011-10-19 15:49:34 -04:00
Fog :: Logger . deprecation ( " describe_instances with #{ filters . class } param is deprecated, use describe_instances('instance-id' => []) instead [light_black]( #{ caller . first } )[/] " )
2010-10-04 18:46:12 -04:00
filters = { 'instance-id' = > [ * filters ] }
end
2011-05-11 19:09:13 -04:00
params = { }
2011-08-30 15:39:21 -04:00
if filters [ 'instance-id' ]
instance_ids = filters . delete ( 'instance-id' )
instance_ids = [ instance_ids ] unless instance_ids . is_a? ( Array )
instance_ids . each_with_index do | id , index |
params . merge! ( " InstanceId. #{ index } " = > id )
end
2011-05-11 19:09:13 -04:00
end
2011-06-20 16:49:37 -04:00
params . merge! ( Fog :: AWS . indexed_filters ( filters ) )
2010-10-04 18:46:12 -04:00
2009-08-23 14:01:37 -04:00
request ( {
2010-05-17 14:30:11 -04:00
'Action' = > 'DescribeInstances' ,
2010-05-17 23:45:59 -04:00
:idempotent = > true ,
2011-06-16 19:28:54 -04:00
:parser = > Fog :: Parsers :: Compute :: AWS :: DescribeInstances . new
2010-03-16 01:15:33 -04:00
} . merge! ( params ) )
2009-08-23 14:01:37 -04:00
end
2009-07-13 22:14:59 -04:00
end
2009-08-23 14:01:37 -04:00
2010-03-16 18:46:21 -04:00
class Mock
2009-07-13 22:14:59 -04:00
2010-10-04 18:46:12 -04:00
def describe_instances ( filters = { } )
unless filters . is_a? ( Hash )
2011-10-19 15:49:34 -04:00
Fog :: Logger . deprecation ( " describe_instances with #{ filters . class } param is deprecated, use describe_instances('instance-id' => []) instead [light_black]( #{ caller . first } )[/] " )
2010-10-04 18:46:12 -04:00
filters = { 'instance-id' = > [ * filters ] }
end
2009-11-20 14:08:08 -05:00
response = Excon :: Response . new
2010-10-04 18:46:12 -04:00
2011-05-19 18:35:33 -04:00
instance_set = self . data [ :instances ] . values
2011-10-06 16:49:28 -04:00
instance_set = apply_tag_filters ( instance_set , filters , 'instanceId' )
2011-08-16 19:13:56 -04:00
2010-10-04 18:46:12 -04:00
aliases = {
'architecture' = > 'architecture' ,
'availability-zone' = > 'availabilityZone' ,
'client-token' = > 'clientToken' ,
2011-03-28 17:40:14 -04:00
'dns-name' = > 'dnsName' ,
2010-10-04 18:46:12 -04:00
'group-id' = > 'groupId' ,
'image-id' = > 'imageId' ,
'instance-id' = > 'instanceId' ,
'instance-lifecycle' = > 'instanceLifecycle' ,
'instance-type' = > 'instanceType' ,
'ip-address' = > 'ipAddress' ,
'kernel-id' = > 'kernelId' ,
'key-name' = > 'key-name' ,
'launch-index' = > 'launchIndex' ,
'launch-time' = > 'launchTime' ,
'monitoring-state' = > 'monitoringState' ,
'owner-id' = > 'ownerId' ,
'placement-group-name' = > 'placementGroupName' ,
'platform' = > 'platform' ,
'private-dns-name' = > 'privateDnsName' ,
'private-ip-address' = > 'privateIpAddress' ,
'product-code' = > 'productCode' ,
'ramdisk-id' = > 'ramdiskId' ,
'reason' = > 'reason' ,
'requester-id' = > 'requesterId' ,
'reservation-id' = > 'reservationId' ,
'root-device-name' = > 'rootDeviceName' ,
'root-device-type' = > 'rootDeviceType' ,
'spot-instance-request-id' = > 'spotInstanceRequestId' ,
'subnet-id' = > 'subnetId' ,
'virtualization-type' = > 'virtualizationType' ,
'vpc-id' = > 'vpcId'
}
block_device_mapping_aliases = {
'attach-time' = > 'attachTime' ,
'delete-on-termination' = > 'deleteOnTermination' ,
'device-name' = > 'deviceName' ,
'status' = > 'status' ,
'volume-id' = > 'volumeId' ,
}
instance_state_aliases = {
'code' = > 'code' ,
'name' = > 'name'
}
state_reason_aliases = {
'code' = > 'code' ,
'message' = > 'message'
}
for filter_key , filter_value in filters
if block_device_mapping_key = filter_key . split ( 'block-device-mapping.' ) [ 1 ]
aliased_key = block_device_mapping_aliases [ block_device_mapping_key ]
instance_set = instance_set . reject { | instance | ! instance [ 'blockDeviceMapping' ] . detect { | block_device_mapping | [ * filter_value ] . include? ( block_device_mapping [ aliased_key ] ) } }
elsif instance_state_key = filter_key . split ( 'instance-state-' ) [ 1 ]
aliased_key = instance_state_aliases [ instance_state_key ]
instance_set = instance_set . reject { | instance | ! [ * filter_value ] . include? ( instance [ 'instanceState' ] [ aliased_key ] ) }
elsif state_reason_key = filter_key . split ( 'state-reason-' ) [ 1 ]
aliased_key = state_reason_aliases [ state_reason_key ]
instance_set = instance_set . reject { | instance | ! [ * filter_value ] . include? ( instance [ 'stateReason' ] [ aliased_key ] ) }
2012-07-03 10:54:45 -04:00
elsif filter_key == " group-name "
instance_set = instance_set . reject { | instance | ! instance [ 'groupSet' ] . include? ( filter_value ) }
2010-10-04 18:46:12 -04:00
else
aliased_key = aliases [ filter_key ]
instance_set = instance_set . reject { | instance | ! [ * filter_value ] . include? ( instance [ aliased_key ] ) }
end
2009-08-23 14:01:37 -04:00
end
2011-10-13 09:25:11 -04:00
brand_new_instances = instance_set . find_all do | instance |
instance [ 'instanceState' ] [ 'name' ] == 'pending' &&
Time . now - instance [ 'launchTime' ] < Fog :: Mock . delay * 2
end
# Error if filtering for a brand new instance directly
if ( filters [ 'instance-id' ] || filters [ 'instanceId' ] ) && ! brand_new_instances . empty?
raise Fog :: Compute :: AWS :: NotFound . new ( " The instance ID ' #{ brand_new_instances . first [ 'instanceId' ] } ' does not exist " )
end
# Otherwise don't include it in the list
instance_set = instance_set . reject { | instance | brand_new_instances . include? ( instance ) }
2010-10-04 18:46:12 -04:00
response . status = 200
reservation_set = { }
2010-04-13 17:42:16 -04:00
2010-10-04 18:46:12 -04:00
instance_set . each do | instance |
case instance [ 'instanceState' ] [ 'name' ]
when 'pending'
2011-09-19 16:17:44 -04:00
if Time . now - instance [ 'launchTime' ] > = Fog :: Mock . delay * 2
2010-10-04 18:46:12 -04:00
instance [ 'ipAddress' ] = Fog :: AWS :: Mock . ip_address
2011-08-16 19:13:56 -04:00
instance [ 'originalIpAddress' ] = instance [ 'ipAddress' ]
2010-10-04 18:46:12 -04:00
instance [ 'dnsName' ] = Fog :: AWS :: Mock . dns_name_for ( instance [ 'ipAddress' ] )
2012-07-13 11:46:37 -04:00
instance [ 'privateIpAddress' ] = Fog :: AWS :: Mock . private_ip_address
2010-10-04 18:46:12 -04:00
instance [ 'privateDnsName' ] = Fog :: AWS :: Mock . private_dns_name_for ( instance [ 'privateIpAddress' ] )
instance [ 'instanceState' ] = { 'code' = > 16 , 'name' = > 'running' }
2010-04-13 17:42:16 -04:00
end
2010-10-04 18:46:12 -04:00
when 'rebooting'
instance [ 'instanceState' ] = { 'code' = > 16 , 'name' = > 'running' }
2012-05-30 20:52:59 -04:00
when 'stopping'
instance [ 'instanceState' ] = { 'code' = > 0 , 'name' = > 'stopping' }
instance [ 'stateReason' ] = { 'code' = > 0 }
2010-10-04 18:46:12 -04:00
when 'shutting-down'
2011-05-19 18:35:33 -04:00
if Time . now - self . data [ :deleted_at ] [ instance [ 'instanceId' ] ] > = Fog :: Mock . delay * 2
self . data [ :deleted_at ] . delete ( instance [ 'instanceId' ] )
self . data [ :instances ] . delete ( instance [ 'instanceId' ] )
elsif Time . now - self . data [ :deleted_at ] [ instance [ 'instanceId' ] ] > = Fog :: Mock . delay
2010-10-04 18:46:12 -04:00
instance [ 'instanceState' ] = { 'code' = > 48 , 'name' = > 'terminating' }
end
when 'terminating'
2011-05-19 18:35:33 -04:00
if Time . now - self . data [ :deleted_at ] [ instance [ 'instanceId' ] ] > = Fog :: Mock . delay
self . data [ :deleted_at ] . delete ( instance [ 'instanceId' ] )
self . data [ :instances ] . delete ( instance [ 'instanceId' ] )
2010-04-13 17:42:16 -04:00
end
2009-08-23 14:01:37 -04:00
end
2011-05-19 18:35:33 -04:00
if self . data [ :instances ] [ instance [ 'instanceId' ] ]
2010-10-04 18:46:12 -04:00
reservation_set [ instance [ 'reservationId' ] ] || = {
'groupSet' = > instance [ 'groupSet' ] ,
2012-08-01 12:20:39 -04:00
'groupIds' = > instance [ 'groupIds' ] ,
2010-10-04 18:46:12 -04:00
'instancesSet' = > [ ] ,
'ownerId' = > instance [ 'ownerId' ] ,
'reservationId' = > instance [ 'reservationId' ]
}
2013-05-13 10:17:55 -04:00
reservation_set [ instance [ 'reservationId' ] ] [ 'instancesSet' ] << instance . reject { | key , value | ! [ 'amiLaunchIndex' , 'architecture' , 'blockDeviceMapping' , 'clientToken' , 'dnsName' , 'ebsOptimized' , 'hypervisor' , 'iamInstanceProfile' , 'imageId' , 'instanceId' , 'instanceState' , 'instanceType' , 'ipAddress' , 'kernelId' , 'keyName' , 'launchTime' , 'monitoring' , 'networkInterfaces' , 'ownerId' , 'placement' , 'platform' , 'privateDnsName' , 'privateIpAddress' , 'productCodes' , 'ramdiskId' , 'reason' , 'rootDeviceType' , 'stateReason' , 'virtualizationType' ] . include? ( key ) } . merge ( 'tagSet' = > self . data [ :tag_sets ] [ instance [ 'instanceId' ] ] )
2010-10-04 18:46:12 -04:00
end
2009-08-23 14:01:37 -04:00
end
2010-10-04 18:46:12 -04:00
response . body = {
'requestId' = > Fog :: AWS :: Mock . request_id ,
'reservationSet' = > reservation_set . values
}
response
2009-08-23 14:01:37 -04:00
end
end
2009-07-13 22:14:59 -04:00
end
end
end