mirror of
				https://github.com/fog/fog.git
				synced 2022-11-09 13:51:43 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			9.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
module Fog
 | 
						|
  module Compute
 | 
						|
    class AWS
 | 
						|
      class Real
 | 
						|
 | 
						|
        require 'fog/compute/parsers/aws/run_instances'
 | 
						|
 | 
						|
        # 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
 | 
						|
        #   * 'Placement.GroupName'<~String> - Name of existing placement group to launch instance into
 | 
						|
        #   * 'Placement.Tenancy'<~String> - Tenancy option in ['dedicated', 'default'], defaults to 'default'
 | 
						|
        #   * '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
 | 
						|
        #   * 'ClientToken'<~String> - unique case-sensitive token for ensuring idempotency
 | 
						|
        #   * 'DisableApiTermination'<~Boolean> - specifies whether or not to allow termination of the instance from the api
 | 
						|
        #   * 'SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances (you must omit this parameter if using Virtual Private Clouds)
 | 
						|
        #   * 'InstanceInitiatedShutdownBehaviour'<~String> - specifies whether volumes are stopped or terminated when instance is shutdown, in [stop, terminate]
 | 
						|
        #   * 'InstanceType'<~String> - Type of instance to boot. Valid options
 | 
						|
        #     in ['t1.micro', 'm1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge', 'm2.xlarge', m2.2xlarge', 'm2.4xlarge', 'cc1.4xlarge', 'cg1.4xlarge']
 | 
						|
        #     default is 'm1.small'
 | 
						|
        #   * 'KernelId'<~String> - Id of kernel with which to launch
 | 
						|
        #   * 'KeyName'<~String> - Name of a keypair to add to booting instances
 | 
						|
        #   * 'Monitoring.Enabled'<~Boolean> - Enables monitoring, defaults to
 | 
						|
        #     disabled
 | 
						|
        #   * 'PrivateIpAddress<~String> - VPC option to specify ip address within subnet
 | 
						|
        #   * 'RamdiskId'<~String> - Id of ramdisk with which to launch
 | 
						|
        #   * 'SubnetId'<~String> - VPC option to specify subnet to launch instance into
 | 
						|
        #   * 'UserData'<~String> -  Additional data to provide to booting instances
 | 
						|
        #
 | 
						|
        # ==== Returns
 | 
						|
        # * response<~Excon::Response>:
 | 
						|
        #   * 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
 | 
						|
        #         * '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
 | 
						|
        #         * '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
 | 
						|
        #         * 'ipAddress'<~String> - public ip address assigned to instance
 | 
						|
        #         * '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
 | 
						|
        #         * 'privateIpAddress'<~String> - private ip address assigned to instance
 | 
						|
        #         * '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
 | 
						|
        #         * 'rootDeviceName'<~String> - specifies how the root device is exposed to the instance
 | 
						|
        #         * 'rootDeviceType'<~String> - root device type used by AMI in [ebs, instance-store]
 | 
						|
        #     * 'ownerId'<~String> - Id of owner
 | 
						|
        #     * 'requestId'<~String> - Id of request
 | 
						|
        #     * 'reservationId'<~String> - Id of reservation
 | 
						|
        #
 | 
						|
        # {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RunInstances.html]
 | 
						|
        def run_instances(image_id, min_count, max_count, options = {})
 | 
						|
          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
 | 
						|
          if security_groups = options.delete('SecurityGroup')
 | 
						|
            options.merge!(Fog::AWS.indexed_param('SecurityGroup', [*security_groups]))
 | 
						|
          end
 | 
						|
          if options['UserData']
 | 
						|
            options['UserData'] = Base64.encode64(options['UserData'])
 | 
						|
          end
 | 
						|
 | 
						|
          idempotent = !(options['ClientToken'].nil? || options['ClientToken'].empty?)
 | 
						|
 | 
						|
          request({
 | 
						|
            'Action'    => 'RunInstances',
 | 
						|
            'ImageId'   => image_id,
 | 
						|
            'MinCount'  => min_count,
 | 
						|
            'MaxCount'  => max_count,
 | 
						|
            :idempotent => idempotent,
 | 
						|
            :parser     => Fog::Parsers::Compute::AWS::RunInstances.new
 | 
						|
          }.merge!(options))
 | 
						|
        end
 | 
						|
 | 
						|
      end
 | 
						|
 | 
						|
      class Mock
 | 
						|
 | 
						|
        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
 | 
						|
            instance = {
 | 
						|
              'amiLaunchIndex'      => i,
 | 
						|
              'blockDeviceMapping'  => [],
 | 
						|
              'clientToken'         => options['clientToken'],
 | 
						|
              'dnsName'             => nil,
 | 
						|
              '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' => options['Placement.AvailabilityZone'] || Fog::AWS::Mock.availability_zone(@region), 'groupName' => nil, 'tenancy' => 'default' },
 | 
						|
              'privateDnsName'      => nil,
 | 
						|
              'productCodes'        => [],
 | 
						|
              'reason'              => nil,
 | 
						|
              'rootDeviceType'      => 'instance-store'
 | 
						|
            }
 | 
						|
            instances_set << instance
 | 
						|
            self.data[:instances][instance_id] = instance.merge({
 | 
						|
              'architecture'        => 'i386',
 | 
						|
              'groupSet'            => group_set,
 | 
						|
              'ownerId'             => self.data[:owner_id],
 | 
						|
              'privateIpAddress'    => nil,
 | 
						|
              'reservationId'       => reservation_id,
 | 
						|
              'stateReason'         => {},
 | 
						|
              'tagSet'              => {}
 | 
						|
            })
 | 
						|
          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
 | 
						|
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |