def run_instances(image_id, min_count, max_count, options = {})
response = Excon::Response.new
response.status = 200
group_set = [ (options['SecurityGroup'] || 'default') ].flatten
instances_set = []
reservation_id = Fog::AWS::Mock.reservation_id
if options['KeyName'] && describe_key_pairs('key-name' => options['KeyName']).body['keySet'].empty?
raise Fog::Compute::AWS::NotFound.new("The key pair '#{options['KeyName']}' does not exist")
end
min_count.times do |i|
instance_id = Fog::AWS::Mock.instance_id
availability_zone = options['Placement.AvailabilityZone'] || Fog::AWS::Mock.availability_zone(@region)
block_device_mapping = (options['BlockDeviceMapping'] || []).reduce([]) do |mapping, device|
device_name = device.fetch("DeviceName", "/dev/sda1")
volume_size = device.fetch("Ebs.VolumeSize", 15)
delete_on_termination = device.fetch("Ebs.DeleteOnTermination", true)
volume_id = create_volume(availability_zone, volume_size).data[:body]["volumeId"]
self.data[:volumes][volume_id].merge!("DeleteOnTermination" => delete_on_termination)
mapping << {
"deviceName" => device_name,
"volumeId" => volume_id,
"status" => "attached",
"attachTime" => Time.now,
"deleteOnTermination" => delete_on_termination,
}
end
if options['SubnetId']
if options['PrivateIpAddress']
ni_options = {'PrivateIpAddress' => options['PrivateIpAddress']}
else
ni_options = {}
end
network_interface_id = create_network_interface(options['SubnetId'], ni_options).body['networkInterface']['networkInterfaceId']
end
network_interfaces = (options['NetworkInterfaces'] || []).reduce([]) do |mapping, device|
device_index = device.fetch("DeviceIndex", 0)
subnet_id = device.fetch("SubnetId", options[:subnet_id] || Fog::AWS::Mock.subnet_id)
private_ip_address = device.fetch("PrivateIpAddress", options[:private_ip_address] || Fog::AWS::Mock.private_ip_address)
delete_on_termination = device.fetch("DeleteOnTermination", true)
description = device.fetch("Description", "mock_network_interface")
security_group_id = device.fetch("SecurityGroupId", self.data[:security_groups]['default']['groupId'])
interface_options = {
"PrivateIpAddress" => private_ip_address,
"GroupSet" => device.fetch("GroupSet", [security_group_id]),
"Description" => description
}
interface_id = device.fetch("NetworkInterfaceId", create_network_interface(subnet_id, interface_options))
mapping << {
"networkInterfaceId" => interface_id,
"subnetId" => subnet_id,
"status" => "attached",
"attachTime" => Time.now,
"deleteOnTermination" => delete_on_termination,
}
end
instance = {
'amiLaunchIndex' => i,
'associatePublicIP' => options['associatePublicIP'] || false,
'architecture' => 'i386',
'blockDeviceMapping' => block_device_mapping,
'networkInterfaces' => network_interfaces,
'clientToken' => options['clientToken'],
'dnsName' => nil,
'ebsOptimized' => options['EbsOptimized'] || false,
'hypervisor' => 'xen',
'imageId' => image_id,
'instanceId' => instance_id,
'instanceState' => { 'code' => 0, 'name' => 'pending' },
'instanceType' => options['InstanceType'] || 'm1.small',
'kernelId' => options['KernelId'] || Fog::AWS::Mock.kernel_id,
'keyName' => options['KeyName'],
'launchTime' => Time.now,
'monitoring' => { 'state' => options['Monitoring.Enabled'] || false },
'placement' => { 'availabilityZone' => availability_zone, 'groupName' => nil, 'tenancy' => options['Placement.Tenancy'] || 'default' },
'privateDnsName' => nil,
'productCodes' => [],
'reason' => nil,
'rootDeviceName' => block_device_mapping.first && block_device_mapping.first["deviceName"],
'rootDeviceType' => 'instance-store',
'spotInstanceRequestId' => options['SpotInstanceRequestId'],
'subnetId' => options['SubnetId'],
'virtualizationType' => 'paravirtual'
}
instances_set << instance
self.data[:instances][instance_id] = instance.merge({
'groupIds' => [],
'groupSet' => group_set,
'iamInstanceProfile' => {},
'ownerId' => self.data[:owner_id],
'reservationId' => reservation_id,
'stateReason' => {}
})
if options['SubnetId']
self.data[:instances][instance_id]['vpcId'] = self.data[:subnets].find{|subnet| subnet['subnetId'] == options['SubnetId'] }['vpcId']
attachment_id = attach_network_interface(network_interface_id, instance_id, '0').data[:body]['attachmentId']
modify_network_interface_attribute(network_interface_id, 'attachment', {'attachmentId' => attachment_id, 'deleteOnTermination' => 'true'})
end
end
response.body = {
'groupSet' => group_set,
'instancesSet' => instances_set,
'ownerId' => self.data[:owner_id],
'requestId' => Fog::AWS::Mock.request_id,
'reservationId' => reservation_id
}
response
end