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-22 01:04:12 -04:00
2011-08-24 21:37:00 -04:00
require 'fog/aws/parsers/compute/run_instances'
2010-06-12 18:31:17 -04:00
2009-08-22 01:04:12 -04:00
# Launch specified instances
#
# ==== Parameters
# * image_id<~String> - Id of machine image to load on instances
# * min_count<~Integer> - Minimum number of instances to launch. If this
# exceeds the count of available instances, no instances will be
# launched. Must be between 1 and maximum allowed for your account
# (by default the maximum for an account is 20)
# * max_count<~Integer> - Maximum number of instances to launch. If this
# exceeds the number of available instances, the largest possible
# number of instances above min_count will be launched instead. Must
# be between 1 and maximum allowed for you account
# (by default the maximum for an account is 20)
# * options<~Hash>:
# * 'Placement.AvailabilityZone'<~String> - Placement constraint for instances
2011-08-08 17:19:51 -04:00
# * 'Placement.GroupName'<~String> - Name of existing placement group to launch instance into
# * 'Placement.Tenancy'<~String> - Tenancy option in ['dedicated', 'default'], defaults to 'default'
2010-05-18 00:02:03 -04:00
# * 'BlockDeviceMapping'<~Array>: array of hashes
# * 'DeviceName'<~String> - where the volume will be exposed to instance
# * 'VirtualName'<~String> - volume virtual device name
# * 'Ebs.SnapshotId'<~String> - id of snapshot to boot volume from
# * 'Ebs.VolumeSize'<~String> - size of volume in GiBs required unless snapshot is specified
# * 'Ebs.DeleteOnTermination'<~String> - specifies whether or not to delete the volume on instance termination
2010-09-22 19:52:31 -04:00
# * 'ClientToken'<~String> - unique case-sensitive token for ensuring idempotency
2011-08-08 17:19:51 -04:00
# * 'DisableApiTermination'<~Boolean> - specifies whether or not to allow termination of the instance from the api
2012-03-09 03:09:28 -05:00
# * 'SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances (not supported for VPC)
# * 'SecurityGroupId'<~Array> or <~String> - id's of security group(s) for instances, use this or SecurityGroup
2010-11-15 14:49:16 -05:00
# * 'InstanceInitiatedShutdownBehaviour'<~String> - specifies whether volumes are stopped or terminated when instance is shutdown, in [stop, terminate]
2009-08-22 01:04:12 -04:00
# * 'InstanceType'<~String> - Type of instance to boot. Valid options
2012-04-12 17:34:00 -04:00
# in ['t1.micro', 'm1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge', 'm2.xlarge', m2.2xlarge', 'm2.4xlarge', 'cc1.4xlarge', 'cc2.8xlarge', 'cg1.4xlarge']
2009-08-22 01:04:12 -04:00
# default is 'm1.small'
# * 'KernelId'<~String> - Id of kernel with which to launch
# * 'KeyName'<~String> - Name of a keypair to add to booting instances
2010-10-05 13:34:37 -04:00
# * 'Monitoring.Enabled'<~Boolean> - Enables monitoring, defaults to
2009-08-22 01:04:12 -04:00
# disabled
2011-08-08 17:19:51 -04:00
# * 'PrivateIpAddress<~String> - VPC option to specify ip address within subnet
2009-08-22 01:04:12 -04:00
# * 'RamdiskId'<~String> - Id of ramdisk with which to launch
2011-08-08 17:19:51 -04:00
# * 'SubnetId'<~String> - VPC option to specify subnet to launch instance into
2009-08-22 01:04:12 -04:00
# * 'UserData'<~String> - Additional data to provide to booting instances
#
# ==== Returns
2009-11-02 21:48:49 -05:00
# * response<~Excon::Response>:
2009-08-22 01:04:12 -04:00
# * body<~Hash>:
# * 'groupSet'<~Array>: groups the instances are members in
# * 'groupName'<~String> - Name of group
# * 'instancesSet'<~Array>: returned instances
# * instance<~Hash>:
# * 'amiLaunchIndex'<~Integer> - reference to instance in launch group
2010-02-20 16:40:46 -05:00
# * 'architecture'<~String> - architecture of image in [i386, x86_64]
# * '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-22 01:04:12 -04:00
# * 'dnsName'<~String> - public dns name, blank until instance is running
# * '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:40:46 -05:00
# * 'ipAddress'<~String> - public ip address assigned to instance
2009-08-22 01:04:12 -04:00
# * 'kernelId'<~String> - Id of kernel used to launch instance
# * '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
# * 'privateDnsName'<~String> - private dns name, blank until instance is running
2010-02-20 16:40:46 -05:00
# * 'privateIpAddress'<~String> - private ip address assigned to instance
2009-08-22 01:04:12 -04:00
# * 'productCodes'<~Array> - Product codes for the instance
# * 'ramdiskId'<~String> - Id of ramdisk used to launch instance
# * 'reason'<~String> - reason for most recent state transition, or blank
2010-02-20 16:40:46 -05:00
# * '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-22 01:04:12 -04:00
# * 'ownerId'<~String> - Id of owner
# * 'requestId'<~String> - Id of request
# * 'reservationId'<~String> - Id of reservation
2011-05-19 12:31:56 -04:00
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RunInstances.html]
2009-08-22 01:04:12 -04:00
def run_instances ( image_id , min_count , max_count , options = { } )
2010-05-18 00:02:03 -04:00
if block_device_mapping = options . delete ( 'BlockDeviceMapping' )
block_device_mapping . each_with_index do | mapping , index |
for key , value in mapping
options . merge! ( { format ( " BlockDeviceMapping.%d. #{ key } " , index ) = > value } )
end
end
end
2010-10-03 20:26:34 -04:00
if security_groups = options . delete ( 'SecurityGroup' )
2011-06-16 19:28:54 -04:00
options . merge! ( Fog :: AWS . indexed_param ( 'SecurityGroup' , [ * security_groups ] ) )
2010-05-18 00:02:03 -04:00
end
2012-03-09 03:09:28 -05:00
if security_group_ids = options . delete ( 'SecurityGroupId' )
options . merge! ( Fog :: AWS . indexed_param ( 'SecurityGroupId' , [ * security_group_ids ] ) )
end
2009-10-21 17:50:27 -04:00
if options [ 'UserData' ]
options [ 'UserData' ] = Base64 . encode64 ( options [ 'UserData' ] )
end
2010-10-03 21:07:33 -04:00
2010-10-05 13:34:37 -04:00
idempotent = ! ( options [ 'ClientToken' ] . nil? || options [ 'ClientToken' ] . empty? )
2010-10-03 21:07:33 -04:00
2009-08-22 01:04:12 -04:00
request ( {
2010-03-16 01:15:33 -04:00
'Action' = > 'RunInstances' ,
'ImageId' = > image_id ,
'MinCount' = > min_count ,
'MaxCount' = > max_count ,
2010-10-03 21:07:33 -04:00
:idempotent = > idempotent ,
2011-06-16 19:28:54 -04:00
:parser = > Fog :: Parsers :: Compute :: AWS :: RunInstances . new
2010-03-16 01:15:33 -04:00
} . merge! ( options ) )
2009-08-22 01:04:12 -04:00
end
2009-07-13 22:14:59 -04:00
end
2009-08-22 01:04:12 -04:00
2010-03-16 18:46:21 -04:00
class Mock
2009-08-22 01:04:12 -04:00
def run_instances ( image_id , min_count , max_count , options = { } )
2009-11-20 14:08:08 -05:00
response = Excon :: Response . new
2009-08-22 01:04:12 -04:00
response . status = 200
2009-08-23 14:01:37 -04:00
2011-05-19 16:29:08 -04:00
group_set = [ ( options [ 'SecurityGroup' ] || 'default' ) ] . flatten
2009-08-23 14:01:37 -04:00
instances_set = [ ]
reservation_id = Fog :: AWS :: Mock . reservation_id
2011-05-19 15:02:58 -04:00
if options [ 'KeyName' ] && describe_key_pairs ( 'key-name' = > options [ 'KeyName' ] ) . body [ 'keySet' ] . empty?
2011-06-16 19:28:54 -04:00
raise Fog :: Compute :: AWS :: NotFound . new ( " The key pair ' #{ options [ 'KeyName' ] } ' does not exist " )
2011-05-19 15:02:58 -04:00
end
2009-08-22 01:04:12 -04:00
min_count . times do | i |
instance_id = Fog :: AWS :: Mock . instance_id
2010-04-13 17:42:16 -04:00
instance = {
2010-03-16 18:46:21 -04:00
'amiLaunchIndex' = > i ,
'blockDeviceMapping' = > [ ] ,
2010-10-04 19:27:32 -04:00
'clientToken' = > options [ 'clientToken' ] ,
2010-05-05 17:22:22 -04:00
'dnsName' = > nil ,
2010-03-16 18:46:21 -04:00
'imageId' = > image_id ,
'instanceId' = > instance_id ,
'instanceState' = > { 'code' = > 0 , 'name' = > 'pending' } ,
'instanceType' = > options [ 'InstanceType' ] || 'm1.small' ,
2011-07-08 20:10:36 -04:00
'kernelId' = > options [ 'KernelId' ] || Fog :: AWS :: Mock . kernel_id ,
2011-05-19 15:02:58 -04:00
'keyName' = > options [ 'KeyName' ] ,
2010-03-16 18:46:21 -04:00
'launchTime' = > Time . now ,
'monitoring' = > { 'state' = > options [ 'Monitoring.Enabled' ] || false } ,
2011-07-08 18:39:35 -04:00
'placement' = > { 'availabilityZone' = > options [ 'Placement.AvailabilityZone' ] || Fog :: AWS :: Mock . availability_zone ( @region ) , 'groupName' = > nil , 'tenancy' = > 'default' } ,
2010-05-05 17:22:22 -04:00
'privateDnsName' = > nil ,
2010-03-16 18:46:21 -04:00
'productCodes' = > [ ] ,
2010-05-05 17:22:22 -04:00
'reason' = > nil ,
2010-03-16 18:46:21 -04:00
'rootDeviceType' = > 'instance-store'
2009-08-22 01:04:12 -04:00
}
2010-04-13 17:42:16 -04:00
instances_set << instance
2011-05-19 18:35:33 -04:00
self . data [ :instances ] [ instance_id ] = instance . merge ( {
2010-05-27 14:27:08 -04:00
'architecture' = > 'i386' ,
2010-04-13 17:42:16 -04:00
'groupSet' = > group_set ,
2011-05-19 18:35:33 -04:00
'ownerId' = > self . data [ :owner_id ] ,
2010-05-05 17:22:22 -04:00
'privateIpAddress' = > nil ,
2010-04-13 17:42:16 -04:00
'reservationId' = > reservation_id ,
2011-10-06 16:49:28 -04:00
'stateReason' = > { }
2010-04-13 17:42:16 -04:00
} )
2009-08-22 01:04:12 -04:00
end
response . body = {
2009-08-23 14:01:37 -04:00
'groupSet' = > group_set ,
'instancesSet' = > instances_set ,
2011-05-19 18:35:33 -04:00
'ownerId' = > self . data [ :owner_id ] ,
2009-08-23 14:01:37 -04:00
'requestId' = > Fog :: AWS :: Mock . request_id ,
'reservationId' = > reservation_id
}
2009-08-22 01:04:12 -04:00
response
end
end
2009-07-13 22:14:59 -04:00
end
end
end