diff --git a/lib/fog/compute/aws.rb b/lib/fog/compute/aws.rb index 304b6d347..a1dd9559b 100644 --- a/lib/fog/compute/aws.rb +++ b/lib/fog/compute/aws.rb @@ -24,6 +24,8 @@ module Fog collection :tags model :volume collection :volumes + model :spot_request + collection :spot_requests request_path 'fog/compute/requests/aws' request :allocate_address diff --git a/lib/fog/compute/models/aws/spot_request.rb b/lib/fog/compute/models/aws/spot_request.rb new file mode 100644 index 000000000..b622175fb --- /dev/null +++ b/lib/fog/compute/models/aws/spot_request.rb @@ -0,0 +1,93 @@ +require 'fog/core/model' + +module Fog + module Compute + class AWS + + class SpotRequest < Fog::Model + + identity :id, :aliases => 'spotInstanceRequestId' + + attribute :price, :aliases => 'spotPrice' + attribute :request_type, :aliases => 'type' + attribute :created_at, :aliases => 'createTime' + attribute :instance_count, :aliases => 'instanceCount' + attribute :instance_id, :aliases => 'instanceId' + attribute :state + + attribute :valid_from, :aliases => 'validFrom' + attribute :valid_until, :aliases => 'validUntil' + attribute :launch_group, :aliases => 'launchGroup' + attribute :availability_zone_group, :aliases => 'availabilityZoneGroup' + attribute :product_description, :aliases => 'productDescription' + + attribute :groups, :aliases => 'LaunchSpecification.SecurityGroup' + attribute :key_name, :aliases => 'LaunchSpecification.KeyName' + attribute :availability_zone, :aliases => 'LaunchSpecification.Placement.AvailabilityZone' + attribute :flavor_id, :aliases => 'LaunchSpecification.InstanceType' + attribute :image_id, :aliases => 'LaunchSpecification.ImageId' + attribute :monitoring, :aliases => 'LaunchSpecification.Monitoring' + attribute :block_device_mapping, :aliases => 'LaunchSpecification.BlockDeviceMapping' + attribute :tags, :aliases => 'tagSet' + attribute :fault, :squash => 'message' + attribute :user_data + + attr_writer :username + + def initialize(attributes={}) + self.groups ||= ["default"] + self.flavor_id ||= 't1.micro' + self.image_id ||= begin + self.username = 'ubuntu' + case attributes[:connection].instance_variable_get(:@region) # Ubuntu 10.04 LTS 64bit (EBS) + when 'ap-northeast-1' + 'ami-5e0fa45f' + when 'ap-southeast-1' + 'ami-f092eca2' + when 'eu-west-1' + 'ami-3d1f2b49' + when 'us-east-1' + 'ami-3202f25b' + when 'us-west-1' + 'ami-f5bfefb0' + end + end + super + end + + def save + requires :image_id, :flavor_id, :price + + options = { + 'AvailabilityZoneGroup' => availability_zone_group, + 'InstanceCount' => instance_count, + 'LaunchGroup' => launch_group, + 'LaunchSpecification.BlockDeviceMapping' => block_device_mapping, + 'LaunchSpecification.KeyName' => key_name, + 'LaunchSpecification.Monitoring.Enabled' => monitoring, + 'LaunchSpecification.Placement.AvailabilityZone' => availability_zone, + 'LaunchSpecification.SecurityGroup' => groups, + 'LaunchSpecification.UserData' => user_data, + 'Type' => request_type, + 'ValidFrom' => valid_from, + 'ValidUntil' => valid_until } + options.delete_if {|key, value| value.nil?} + + data = connection.request_spot_instances(image_id, flavor_id, price, options).body + spot_instance_request = data['spotInstanceRequestSet'].first + spot_instance_request['launchSpecification'].each do |name,value| + spot_instance_request['LaunchSpecification.' + name[0,1].upcase + name[1..-1]] = value + end + spot_instance_request.merge(:groups => spot_instance_request['LaunchSpecification.GroupSet']) + spot_instance_request.merge(options) + merge_attributes( spot_instance_request ) + end + + def ready? + state == 'active' + end + + end + end + end +end diff --git a/lib/fog/compute/models/aws/spot_requests.rb b/lib/fog/compute/models/aws/spot_requests.rb new file mode 100644 index 000000000..9db6f4727 --- /dev/null +++ b/lib/fog/compute/models/aws/spot_requests.rb @@ -0,0 +1,48 @@ +require 'fog/core/collection' +require 'fog/compute/models/aws/spot_request' + +module Fog + module Compute + class AWS + class SpotRequests < Fog::Collection + + attribute :filters + + model Fog::Compute::AWS::SpotRequest + + def initialize(attributes) + self.filters ||= {} + super + end + + def all(filters = self.filters) + unless filters.is_a?(Hash) + Formatador.display_line("[yellow][WARN] all with #{filters.class} param is deprecated, use all('spot-instance-request-id' => []) instead[/] [light_black](#{caller.first})[/]") + filters = {'spot-instance-request-id' => [*filters]} + end + self.filters = filters + data = connection.describe_spot_instance_requests(filters).body + load( + data['spotInstanceRequestSet'].map do |spot_instance_request| + spot_instance_request['LaunchSpecification.Placement.AvailabilityZone'] = spot_instance_request['launchedAvailabilityZone'] + spot_instance_request['launchSpecification'].each do |name,value| + spot_instance_request['LaunchSpecification.' + name[0,1].upcase + name[1..-1]] = value + end + spot_instance_request.merge(:groups => spot_instance_request['LaunchSpecification.GroupSet']) + spot_instance_request + end.flatten + ) + end + + def get(spot_request_id) + if spot_request_id + self.class.new(:connection => connection).all('spot-instance-request-id' => spot_request_id).first + end + rescue Fog::Errors::NotFound + nil + end + + end + end + end +end