1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

Merge branch 'master' of git://github.com/geemus/fog into auto_scaling_20100801

This commit is contained in:
Nick Osborn 2011-07-07 23:30:34 +01:00
commit 083df379b1
68 changed files with 1499 additions and 154 deletions

View file

@ -138,6 +138,7 @@ task :release => :build do
sh "git tag v#{version}"
sh "git push origin master"
sh "git push origin v#{version}"
Rake::Task[:build].invoke # rebuild with updated changelog
sh "gem push pkg/#{name}-#{version}.gem"
Rake::Task[:docs].invoke
end

View file

@ -37,13 +37,13 @@ Gem::Specification.new do |s|
## List your runtime dependencies here. Runtime dependencies are those
## that are needed for an end user to actually USE your code.
s.add_dependency('builder')
s.add_dependency('excon', '~>0.6.1')
s.add_dependency('formatador', '>=0.1.3')
s.add_dependency('excon', '~>0.6.4')
s.add_dependency('formatador', '~>0.1.5')
s.add_dependency('json')
s.add_dependency('mime-types')
s.add_dependency('net-scp', '>=1.0.4')
s.add_dependency('net-ssh', '>=2.1.4')
s.add_dependency('nokogiri', '>=1.4.4')
s.add_dependency('net-scp', '~>1.0.4')
s.add_dependency('net-ssh', '~>2.1.4')
s.add_dependency('nokogiri', '~>1.4.4')
s.add_dependency('ruby-hmac')
## List your development dependencies here. Development dependencies are
@ -51,9 +51,9 @@ Gem::Specification.new do |s|
s.add_development_dependency('jekyll')
s.add_development_dependency('rake')
s.add_development_dependency('rdoc')
s.add_development_dependency('rspec', '1.3.1')
s.add_development_dependency('shindo', '0.3.4')
s.add_development_dependency('virtualbox', '0.8.3')
s.add_development_dependency('rspec', '~>1.3.1')
s.add_development_dependency('shindo', '~>0.3.4')
s.add_development_dependency('virtualbox', '~>0.8.3')
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {spec,tests}/*`.split("\n")

View file

@ -36,10 +36,43 @@ module Fog
class Mock
def initialize(options={})
Fog::Mock.not_implemented
def self.data
@data ||= Hash.new do |hash, region|
owner_id = Fog::AWS::Mock.owner_id
hash[region] = Hash.new do |region_hash, key|
region_hash[key] = {
:owner_id => owner_id,
:load_balancers => {}
}
end
end
end
def self.dns_name(name, region)
"#{name}-#{Fog::Mock.random_hex(8)}.#{region}.elb.amazonaws.com"
end
def self.reset
@data = nil
end
def initialize(options={})
@aws_access_key_id = options[:aws_access_key_id]
@region = options[:region] || 'us-east-1'
unless ['ap-northeast-1', 'ap-southeast-1', 'eu-west-1', 'us-east-1', 'us-west-1'].include?(@region)
raise ArgumentError, "Unknown region: #{@region.inspect}"
end
end
def data
self.class.data[@region][@aws_access_key_id]
end
def reset_data
self.class.data[@region].delete(@aws_access_key_id)
end
end
class Real

View file

@ -43,11 +43,36 @@ module Fog
request :upload_signing_certificate
class Mock
def initialize(options={})
Fog::Mock.not_implemented
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {
:owner_id => Fog::AWS::Mock.owner_id,
:server_certificates => {}
}
end
end
def self.reset
@data = nil
end
def self.server_certificate_id
Fog::Mock.random_hex(16)
end
def initialize(options={})
require 'fog/aws/parsers/iam/basic'
@aws_access_key_id = options[:aws_access_key_id]
end
def data
self.class.data[@aws_access_key_id]
end
def reset_data
self.class.data.delete(@aws_access_key_id)
end
end
class Real

View file

@ -36,6 +36,30 @@ module Fog
end
end
class Mock
def configure_health_check(lb_name, health_check)
if load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['HealthCheck'] = health_check
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'ConfigureHealthCheckResult' => {
'HealthCheck' => load_balancer['HealthCheck']
}
}
response
else
raise Fog::AWS::ELB::NotFound
end
end
end
end
end
end

View file

@ -28,6 +28,27 @@ module Fog
end
end
class Mock
def create_app_cookie_stickiness_policy(lb_name, policy_name, cookie_name)
if load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['Policies']['AppCookieStickinessPolicies'] << { 'CookieName' => cookie_name, 'PolicyName' => policy_name }
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
}
}
response
else
raise Fog::AWS::ELB::NotFound
end
end
end
end
end
end

View file

@ -30,6 +30,27 @@ module Fog
end
end
class Mock
def create_lb_cookie_stickiness_policy(lb_name, policy_name, cookie_expiration_period=nil)
if load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['Policies']['LBCookieStickinessPolicies'] << { 'PolicyName' => policy_name, 'CookieExpirationPeriod' => cookie_expiration_period }
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
}
}
response
else
raise Fog::AWS::ELB::NotFound
end
end
end
end
end
end

View file

@ -49,6 +49,62 @@ module Fog
end
end
class Mock
def create_load_balancer(availability_zones, lb_name, listeners)
response = Excon::Response.new
response.status = 200
raise Fog::AWS::ELB::IdentifierTaken if self.data[:load_balancers].has_key? lb_name
dns_name = Fog::AWS::ELB::Mock.dns_name(lb_name, @region)
self.data[:load_balancers][lb_name] = {
'AvailabilityZones' => availability_zones,
'CanonicalHostedZoneName' => '',
'CanonicalHostedZoneNameID' => '',
'CreatedTime' => Time.now,
'DNSName' => dns_name,
'HealthCheck' => {
'HealthyThreshold' => 10,
'Timeout' => 5,
'UnhealthyThreshold' => 2,
'Interval' => 30,
'Target' => 'TCP:80'
},
'Instances' => [],
'ListenerDescriptions' => [
{
'Listener' => {
'InstancePort' => 80,
'Protocol' => 'HTTP',
'LoadBalancerPort' => 80
},
'PolicyNames' => []
}
],
'LoadBalancerName' => lb_name,
'Policies' => {
'LBCookieStickinessPolicies' => [],
'AppCookieStickinessPolicies' => []
},
'SourceSecurityGroup' => {
'GroupName' => '',
'OwnerAlias' => ''
}
}
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'CreateLoadBalancerResult' => {
'DNSName' => dns_name
}
}
response
end
end
end
end
end

View file

@ -46,6 +46,29 @@ module Fog
end
end
class Mock
def create_load_balancer_listeners(lb_name, listeners)
if load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
listeners.each do |listener|
load_balancer['ListenerDescriptions'] << {'Listener' => listener, 'PolicyNames' => []}
end
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
}
}
response
else
raise Fog::AWS::ELB::NotFound
end
end
end
end
end
end

View file

@ -28,6 +28,24 @@ module Fog
end
end
class Mock
def delete_load_balancer(lb_name)
response = Excon::Response.new
response.status = 200
self.data[:load_balancers].delete(lb_name)
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DeleteLoadBalancerResult' => nil
}
response
end
end
end
end
end

View file

@ -26,6 +26,25 @@ module Fog
end
end
class Mock
def delete_load_balancer_listeners(lb_name, load_balancer_ports)
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['ListenerDescriptions'].delete_if { |listener| load_balancer_ports.include? listener['Listener']['LoadBalancerPort'] }
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
}
}
response
end
end
end
end
end

View file

@ -26,6 +26,29 @@ module Fog
end
end
class Mock
def delete_load_balancer_policy(lb_name, policy_name)
if load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['Policies'].each do |name, policies|
policies.delete_if { |p| p['PolicyName'] == policy_name }
end
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
}
}
response
else
raise Fog::AWS::ELB::NotFound
end
end
end
end
end
end

View file

@ -33,15 +33,31 @@ module Fog
end
class Mock
def deregister_instances_from_load_balancer(instance_ids, lb_name)
Fog::Mock.not_implemented
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
instance_ids = [*instance_ids]
instance_ids.each do |instance|
raise Fog::AWS::ELB::InvalidInstance unless Compute[:aws].servers.get(instance)
end
response = Excon::Response.new
response.status = 200
load_balancer['Instances'].delete_if { |i| instance_ids.include? i['InstanceId'] }
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DeregisterInstancesFromLoadBalancerResult' => {
'Instances' => load_balancer['Instances'].dup
}
}
response
end
alias :deregister_instances :deregister_instances_from_load_balancer
end
end
end
end

View file

@ -32,6 +32,41 @@ module Fog
end
end
class Mock
def describe_instance_health(lb_name, instance_ids = [])
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
instance_ids = [*instance_ids]
instance_ids = load_balancer['Instances'].collect { |i| i['InstanceId'] } unless instance_ids.any?
data = instance_ids.map do |id|
unless instance = Compute[:aws].servers.get(id)
raise Fog::AWS::ELB::InvalidInstance
end
{
'Description' => "",
'InstanceId' => instance.id,
'ReasonCode' => "",
'State' => 'OutOfService'
}
end
response = Excon::Response.new
response.status = 200
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DescribeInstanceHealthResult' => {
'InstanceStates' => data
}
}
response
end
end
end
end
end

View file

@ -51,6 +51,35 @@ module Fog
end
end
class Mock
def describe_load_balancers(lb_names = [])
lb_names = [*lb_names]
load_balancers = if lb_names.any?
lb_names.map do |lb_name|
lb = self.data[:load_balancers].find { |name, data| name == lb_name }
raise Fog::AWS::ELB::NotFound unless lb
lb[1]
end.compact
else
self.data[:load_balancers].values
end
response = Excon::Response.new
response.status = 200
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DescribeLoadBalancersResult' => {
'LoadBalancerDescriptions' => load_balancers
}
}
response
end
end
end
end
end

View file

@ -17,7 +17,7 @@ module Fog
# * 'ResponseMetadata'<~Hash>:
# * 'RequestId'<~String> - Id of request
# * 'DisableAvailabilityZonesForLoadBalancerResult'<~Hash>:
# * 'AvailabilityZones'<~Array> - array of strings describing instances currently enabled
# * 'AvailabilityZones'<~Array> - A list of updated Availability Zones for the LoadBalancer.
def disable_availability_zones_for_load_balancer(availability_zones, lb_name)
params = Fog::AWS.indexed_param('AvailabilityZones.member', [*availability_zones])
request({
@ -32,15 +32,28 @@ module Fog
end
class Mock
def disable_availability_zones_for_load_balancer(availability_zones, lb_name)
Fog::Mock.not_implemented
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['AvailabilityZones'].delete_if { |az| availability_zones.include? az }
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'DisableAvailabilityZonesForLoadBalancerResult' => {
'AvailabilityZones' => load_balancer['AvailabilityZones']
}
}
response
end
alias :disable_zones :disable_availability_zones_for_load_balancer
end
end
end
end

View file

@ -34,13 +34,28 @@ module Fog
class Mock
def enable_availability_zones_for_load_balancer(availability_zones, lb_name)
Fog::Mock.not_implemented
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
response = Excon::Response.new
response.status = 200
load_balancer['AvailabilityZones'] << availability_zones
load_balancer['AvailabilityZones'].flatten!.uniq!
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'EnableAvailabilityZonesForLoadBalancerResult' => {
'AvailabilityZones' => load_balancer['AvailabilityZones']
}
}
response
end
alias :enable_zones :enable_availability_zones_for_load_balancer
end
end
end
end

View file

@ -33,15 +33,32 @@ module Fog
end
class Mock
def register_instances_with_load_balancer(instance_ids, lb_name)
Fog::Mock.not_implemented
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
instance_ids = [*instance_ids]
instances = instance_ids.map do |instance|
raise Fog::AWS::ELB::InvalidInstance unless Compute[:aws].servers.get(instance)
{'InstanceId' => instance}
end
response = Excon::Response.new
response.status = 200
load_balancer['Instances'] = instances.dup
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
},
'RegisterInstancesWithLoadBalancerResult' => {
'Instances' => instances
}
}
response
end
alias :register_instances :register_instances_with_load_balancer
end
end
end
end

View file

@ -38,6 +38,43 @@ module Fog
end
end
class Mock
def set_load_balancer_policies_of_listener(lb_name, load_balancer_port, policy_names)
raise Fog::AWS::ELB::NotFound unless load_balancer = self.data[:load_balancers][lb_name]
policy_names = [*policy_names]
response = Excon::Response.new
if policy_names.size > 1
response.status = 409
response.body = "<?xml version=\"1.0\"?><Response><Errors><Error><Code>InvalidConfigurationRequest</Code><Message>Requested configuration change is invalid.</Message></Error></Errors><RequestID>#{Fog::AWS::Mock.request_id}</RequestId></Response>"
raise Excon::Errors.status_error({:expects => 200}, response)
end
unless listener = load_balancer['ListenerDescriptions'].find { |listener| listener['Listener']['LoadBalancerPort'] == load_balancer_port }
response.status = 400
response.body = "<?xml version=\"1.0\"?><Response><Errors><Error><Code>ListenerNotFound</Code><Message>LoadBalancer does not have a listnener configured at the given port.</Message></Error></Errors><RequestID>#{Fog::AWS::Mock.request_id}</RequestId></Response>"
raise Excon::Errors.status_error({:expects => 200}, response)
end
unless load_balancer['Policies'].find { |name, policies| policies.find { |policy| policy['PolicyName'] == policy_names.first } }
response.status = 400
response.body = "<?xml version=\"1.0\"?><Response><Errors><Error><Code>PolicyNotFound</Code><Message>One or more specified policies were not found.</Message></Error></Errors><RequestID>#{Fog::AWS::Mock.request_id}</RequestId></Response>"
raise Excon::Errors.status_error({:expects => 200}, response)
end if policy_names.any?
listener['PolicyNames'] = policy_names
response.status = 200
response.body = {
'ResponseMetadata' => {
'RequestId' => Fog::AWS::Mock.request_id
}
}
response
end
end
end
end
end

View file

@ -27,6 +27,20 @@ module Fog
end
end
class Mock
def delete_server_certificate(server_certificate_name)
response = Excon::Response.new
response.status = 200
response.body = {
'RequestId' => Fog::AWS::Mock.request_id
}
self.data[:server_certificates].delete(server_certificate_name)
response
end
end
end
end
end

View file

@ -37,6 +37,18 @@ module Fog
end
end
class Mock
def list_server_certificates(options = {})
response = Excon::Response.new
response.status = 200
response.body = {
'Certificates' => self.data[:server_certificates].values
}
response
end
end
end
end
end

View file

@ -19,11 +19,12 @@ module Fog
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'UploadServerCertificateResult'<~Hash>:
# * 'CertificateId'<~String> -
# * 'UserName'<~String> -
# * 'CertificateBody'<~String> -
# * 'Status'<~String> -
# * 'Certificate'<~Hash>:
# * 'Arn'<~String> -
# * 'Path'<~String> -
# * 'ServerCertificateId'<~String> -
# * 'ServerCertificateName'<~String> -
# * 'UploadDate'<~Time>
# * 'RequestId'<~String> - Id of the request
#
# ==== See Also
@ -40,6 +41,32 @@ module Fog
end
end
class Mock
def upload_server_certificate(certificate, private_key, name, options = {})
response = Excon::Response.new
if self.data[:server_certificates][name]
else
response.status = 200
path = "server-certificates/#{name}"
data = {
'Arn' => Fog::AWS::Mock.arn('iam', self.data[:owner_id], path),
'Path' => path,
'ServerCertificateId' => Fog::AWS::IAM::Mock.server_certificate_id,
'ServerCertificateName' => name,
'UploadDate' => Time.now
}
self.data[:server_certificates][name] = data
response.body = {
'Certificate' => data,
'RequestId' => Fog::AWS::Mock.request_id
}
end
response
end
end
end
end
end

View file

@ -14,7 +14,7 @@ class Brightbox < Fog::Bin
@@connections ||= Hash.new do |hash, key|
hash[key] = case key
when :compute
Formatador.display_line("[yellow][WARN] Brightbox[:compute] is deprecated, use Brightbox[:aws] instead[/]")
Formatador.display_line("[yellow][WARN] Brightbox[:compute] is deprecated, use Compute[:brightbox] instead[/]")
Fog::Compute.new(:provider => 'Brightbox')
else
raise ArgumentError, "Unrecognized service: #{key.inspect}"

View file

@ -45,13 +45,21 @@ module Fog
require 'json'
credentials = Fog::Rackspace.authenticate(options)
@auth_token = credentials['X-Auth-Token']
@enabled = false
uri = URI.parse(credentials['X-CDN-Management-Url'])
@host = uri.host
@path = uri.path
@port = uri.port
@scheme = uri.scheme
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", options[:persistent])
if credentials['X-CDN-Management-Url']
uri = URI.parse(credentials['X-CDN-Management-Url'])
@host = uri.host
@path = uri.path
@port = uri.port
@scheme = uri.scheme
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", options[:persistent])
@enabled = true
end
end
def enabled?
@enabled
end
def reload

View file

@ -30,17 +30,20 @@ module Fog
request :associate_address
request :attach_volume
request :authorize_security_group_ingress
request :cancel_spot_instance_requests
request :create_image
request :create_key_pair
request :create_placement_group
request :create_security_group
request :create_snapshot
request :create_spot_datafeed_subscription
request :create_tags
request :create_volume
request :delete_key_pair
request :delete_security_group
request :delete_placement_group
request :delete_snapshot
request :delete_spot_datafeed_subscription
request :delete_tags
request :delete_volume
request :deregister_image
@ -55,6 +58,9 @@ module Fog
request :describe_reserved_instances_offerings
request :describe_security_groups
request :describe_snapshots
request :describe_spot_datafeed_subscription
request :describe_spot_instance_requests
request :describe_spot_price_history
request :describe_tags
request :describe_volumes
request :detach_volume
@ -67,6 +73,7 @@ module Fog
request :reboot_instances
request :release_address
request :register_image
request :request_spot_instances
request :revoke_security_group_ingress
request :run_instances
request :terminate_instances
@ -252,7 +259,7 @@ module Fog
:host => @host,
:path => @path,
:port => @port,
:version => '2010-08-31'
:version => '2011-05-15'
}
)

View file

@ -38,7 +38,8 @@ module Fog
def save
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if identity
requires :availability_zone, :size
requires :availability_zone
requires_one :size, :snapshot_id
data = connection.create_volume(availability_zone, size, snapshot_id).body
new_attributes = data.reject {|key,value| key == 'requestId'}
@ -49,6 +50,11 @@ module Fog
true
end
def server
requires :server_id
connection.servers('instance-id' => server_id)
end
def server=(new_server)
if new_server
attach(new_server)
@ -62,6 +68,10 @@ module Fog
connection.snapshots(:volume => self)
end
def force_detach
detach(true)
end
private
def attachmentSet=(new_attachment_set)
@ -81,25 +91,15 @@ module Fog
end
end
def detach
def detach(force = false)
@server = nil
self.server_id = nil
unless new_record?
connection.detach_volume(id)
connection.detach_volume(id, 'Force' => force)
reload
end
end
def force_detach
@server = nil
self.server_id = nil
unless new_record?
connection.detach_volume(id, 'Force' => true)
reload
end
end
end
end

View file

@ -17,8 +17,9 @@ module Fog
end
def cores
# 2 quad-cores >= 2Ghz = 8 cores
8 * case ram
# Each server is assigned 4 virtual cores and
# given a percentage of CPU cycles based on size
4 * case ram
when 256
1/64.0
when 512

View file

@ -0,0 +1,30 @@
module Fog
module Parsers
module Compute
module AWS
class CancelSpotInstanceRequests < Fog::Parsers::Base
def reset
@spot_instance_request = {}
@response = { 'spotInstanceRequestSet' => [] }
end
def end_element(name)
case name
when 'item'
@response['spotInstanceRequestSet'] << @spot_instance_request
@spot_instance_request = {}
when 'requestId'
@response[name] = value
when 'spotInstanceRequestId', 'state'
@spot_instance_request[name] = value
end
end
end
end
end
end
end

View file

@ -0,0 +1,34 @@
module Fog
module Parsers
module Compute
module AWS
class DescribeSpotPriceHistory < Fog::Parsers::Base
def reset
@spot_price = {}
@response = { 'spotPriceHistorySet' => [] }
end
def end_element(name)
case name
when 'availabilityZone', 'instanceType', 'productDescription'
@spot_price[name] = value
when 'item'
@response['spotPriceHistorySet'] << @spot_price
@spot_price = {}
when 'requestId'
@response[name] = value
when 'spotPrice'
@spot_price[name] = value.to_f
when 'timestamp'
@spot_price[name] = Time.parse(value)
end
end
end
end
end
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Parsers
module Compute
module AWS
class SpotDatafeedSubscription < Fog::Parsers::Base
def reset
@response = { 'spotDatafeedSubscription' => {} }
end
def end_element(name)
case name
when 'bucket', 'ownerId', 'prefix', 'state'
@response['spotDatafeedSubscription'][name] = value
when 'code', 'message'
@response['spotDatafeedSubscription']['fault'] ||= {}
@response['spotDatafeedSubscription'][name] = value
when 'requestId'
@response[name] = value
end
end
end
end
end
end
end

View file

@ -0,0 +1,67 @@
module Fog
module Parsers
module Compute
module AWS
class SpotInstanceRequests < Fog::Parsers::Base
def reset
@block_device_mapping = []
@context = []
@contexts = ['blockDeviceMapping', 'groupSet']
@spot_instance_request = { 'launchSpecification' => { 'blockDeviceMapping' => [], 'groupSet' => [] } }
@response = { 'spotInstanceRequestSet' => [] }
end
def start_element(name, attrs = [])
super
if @contexts.include?(name)
@context.push(name)
end
end
def end_element(name)
case name
when 'attachTime'
@block_device_mapping[name] = Time.parse(value)
when *@contexts
@context.pop
when 'code', 'message'
@spot_instance_request['fault'] ||= {}
@spot_instance_request['fault'][name] = value
when 'createTime'
@spot_instance_request[name] = Time.parse(value)
when 'deleteOnTermination'
@block_device_mapping[name] = (value == 'true')
when 'deviceName', 'status', 'volumeId'
@block_device_mapping[name] = value
when 'groupId'
@spot_instance_request['launchSpecification']['groupSet'] << value
when 'instanceId', 'launchedAvailabilityZone', 'productDescription', 'spotInstanceRequestId', 'state', 'type'
@spot_instance_request[name] = value
when 'item'
case @context.last
when 'blockDeviceMapping'
@instance['blockDeviceMapping'] << @block_device_mapping
@block_device_mapping = {}
when nil
@response['spotInstanceRequestSet'] << @spot_instance_request
@spot_instance_request = { 'launchSpecification' => { 'blockDeviceMapping' => [], 'groupSet' => [] } }
end
when 'imageId', 'instanceType', 'keyname'
@spot_instance_request['launchSpecification'][name] = value
when 'enabled'
@spot_instance_request['launchSpecification']['monitoring'] = (value == 'true')
when 'requestId'
@response[name] = value
when 'spotPrice'
@spot_instance_request[name] = value.to_f
end
end
end
end
end
end
end

View file

@ -0,0 +1,34 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/cancel_spot_instance_requests'
# Terminate specified spot instance requests
#
# ==== Parameters
# * spot_instance_request_id<~Array> - Ids of instances to terminates
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> id of request
# * 'spotInstanceRequestSet'<~Array>:
# * 'spotInstanceRequestId'<~String> - id of cancelled spot instance
# * 'state'<~String> - state of cancelled spot instance
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CancelSpotInstanceRequests.html]
def cancel_spot_instance_requests(spot_instance_request_id)
params = Fog::AWS.indexed_param('SpotInstanceRequestId', spot_instance_request_id)
request({
'Action' => 'CancelSpotInstanceRequests',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::CancelSpotInstanceRequests.new
}.merge!(params))
end
end
end
end
end

View file

@ -0,0 +1,41 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/spot_datafeed_subscription'
# Create a spot datafeed subscription
#
# ==== Parameters
# * bucket<~String> - bucket name to store datafeed in
# * prefix<~String> - prefix to store data with
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'spotDatafeedSubscription'<~Hash>:
# * 'bucket'<~String> - S3 bucket where data is stored
# * 'fault'<~Hash>:
# * 'code'<~String> - fault code
# * 'reason'<~String> - fault reason
# * 'ownerId'<~String> - AWS id of account owner
# * 'prefix'<~String> - prefix for datafeed items
# * 'state'<~String> - state of datafeed subscription
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSpotDatafeedSubscription.html]
def create_spot_datafeed_subscription(bucket, prefix)
request(
'Action' => 'CreateSpotDatafeedSubscription',
'Bucket' => bucket,
'Prefix' => prefix,
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::SpotDatafeedSubscription.new
)
end
end
end
end
end

View file

@ -0,0 +1,28 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/basic'
# Delete a spot datafeed subscription
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> id of request
# * 'return'<~Boolean> - success?
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSpotDatafeedSubscription.html]
def delete_spot_datafeed_subscription
request(
'Action' => 'DeleteSpotDatafeedSubscription',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::Basic.new
)
end
end
end
end
end

View file

@ -0,0 +1,35 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/spot_datafeed_subscription'
# Describe spot datafeed subscription
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'spotDatafeedSubscription'<~Hash>:
# * 'bucket'<~String> - S3 bucket where data is stored
# * 'fault'<~Hash>:
# * 'code'<~String> - fault code
# * 'reason'<~String> - fault reason
# * 'ownerId'<~String> - AWS id of account owner
# * 'prefix'<~String> - prefix for datafeed items
# * 'state'<~String> - state of datafeed subscription
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotDatafeedSubscription.html]
def describe_spot_datafeed_subscription
request({
'Action' => 'DescribeSpotDatafeedSubscription',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::SpotDatafeedSubscription.new
})
end
end
end
end
end

View file

@ -0,0 +1,47 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/spot_instance_requests'
# Describe all or specified spot instance requests
#
# ==== Parameters
# * filters<~Hash> - List of filters to limit results with
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'spotInstanceRequestSet'<~Array>:
# * 'createTime'<~Time> - time of instance request creation
# * 'instanceId'<~String> - instance id if one has been launched to fulfill request
# * 'launchedAvailabilityZone'<~String> - availability zone of instance if one has been launched to fulfill request
# * 'launchSpecification'<~Hash>:
# * 'blockDeviceMapping'<~Hash> - list of block device mappings for instance
# * 'groupSet'<~String> - security group(s) for instance
# * 'keyName'<~String> - keypair name for instance
# * 'imageId'<~String> - AMI for instance
# * 'instanceType'<~String> - type for instance
# * 'monitoring'<~Boolean> - monitoring status for instance
# * 'productDescription'<~String> - general description of AMI
# * 'spotInstanceRequestId'<~String> - id of spot instance request
# * 'spotPrice'<~Float> - maximum price for instances to be launched
# * 'state'<~String> - spot instance request state
# * 'type'<~String> - spot instance request type
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotInstanceRequests.html]
def describe_spot_instance_requests(filters = {})
params = Fog::AWS.indexed_filters(filters)
request({
'Action' => 'DescribeSpotInstanceRequests',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::SpotInstanceRequests.new
}.merge!(params))
end
end
end
end
end

View file

@ -0,0 +1,37 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/describe_spot_price_history'
# Describe all or specified spot price history
#
# ==== Parameters
# * filters<~Hash> - List of filters to limit results with
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'spotPriceHistorySet'<~Array>:
# * 'availabilityZone'<~String> - availability zone for instance
# * 'instanceType'<~String> - the type of instance
# * 'productDescription'<~String> - general description of AMI
# * 'spotPrice'<~Float> - maximum price to launch one or more instances
# * 'timestamp'<~Time> - date and time of request creation
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSpotPriceHistory.html]
def describe_spot_price_history(filters = {})
params = Fog::AWS.indexed_filters(filters)
request({
'Action' => 'DescribeSpotPriceHistory',
:idempotent => true,
:parser => Fog::Parsers::Compute::AWS::DescribeSpotPriceHistory.new
}.merge!(params))
end
end
end
end
end

View file

@ -74,7 +74,7 @@ module Fog
}
for filter_key, filter_value in filters
if attachment_key = filter_key.split('attachment.')[1]
aliased_key = permission_aliases[filter_key]
aliased_key = attachment_aliases[filter_key]
volume_set = volume_set.reject{|volume| !volume['attachmentSet'].detect {|attachment| [*filter_value].include?(attachment[aliased_key])}}
else
aliased_key = aliases[filter_key]

View file

@ -0,0 +1,83 @@
module Fog
module Compute
class AWS
class Real
require 'fog/compute/parsers/aws/spot_instance_requests'
# Launch specified instances
#
# ==== Parameters
# * 'image_id'<~String> - Id of machine image to load on instances
# * 'instance_type'<~String> - Type of instance
# * 'spot_price'<~Float> - maximum hourly price for instances launched
# * options<~Hash>:
# * 'AvailabilityZoneGroup'<~String> - specify whether or not to launch all instances in the same availability group
# * 'InstanceCount'<~Integer> - maximum number of instances to launch
# * 'LaunchGroup'<~String> - whether or not to launch/shutdown instances as a group
# * 'LaunchSpecification.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.NoDevice'<~String> - specifies that no device should be mapped
# * '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
# * 'LaunchSpecification.KeyName'<~String> - Name of a keypair to add to booting instances
# * 'LaunchSpecification.Monitoring.Enabled'<~Boolean> - Enables monitoring, defaults to disabled
# * 'LaunchSpecification.Placement.AvailabilityZone'<~String> - Placement constraint for instances
# * 'LaunchSpecification.SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances
# * 'LaunchSpecification.UserData'<~String> - Additional data to provide to booting instances
# * 'Type'<~String> - spot instance request type in ['one-time', 'persistent']
# * 'ValidFrom'<~Time> - start date for request
# * 'ValidUntil'<~Time> - end date for request
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'requestId'<~String> - Id of request
# * 'spotInstanceRequestSet'<~Array>:
# * 'createTime'<~Time> - time of instance request creation
# * 'instanceId'<~String> - instance id if one has been launched to fulfill request
# * 'launchedAvailabilityZone'<~String> - availability zone of instance if one has been launched to fulfill request
# * 'launchSpecification'<~Hash>:
# * 'blockDeviceMapping'<~Hash> - list of block device mappings for instance
# * 'groupSet'<~String> - security group(s) for instance
# * 'keyName'<~String> - keypair name for instance
# * 'imageId'<~String> - AMI for instance
# * 'instanceType'<~String> - type for instance
# * 'monitoring'<~Boolean> - monitoring status for instance
# * 'productDescription'<~String> - general description of AMI
# * 'spotInstanceRequestId'<~String> - id of spot instance request
# * 'spotPrice'<~Float> - maximum price for instances to be launched
# * 'state'<~String> - spot instance request state
# * 'type'<~String> - spot instance request type
#
# {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RequestSpotInstances.html]
def request_spot_instances(image_id, instance_type, spot_price, options = {})
if block_device_mapping = options.delete('LaunchSpecification.BlockDeviceMapping')
block_device_mapping.each_with_index do |mapping, index|
for key, value in mapping
options.merge!({ format("LaunchSpecification.BlockDeviceMapping.%d.#{key}", index) => value })
end
end
end
if security_groups = options.delete('LaunchSpecification.SecurityGroup')
options.merge!(Fog::AWS.indexed_param('LaunchSpecification.SecurityGroup', [*security_groups]))
end
if options['LaunchSpecification.UserData']
options['LaunchSpecification.UserData'] = Base64.encode64(options['LaunchSpecification.UserData'])
end
request({
'Action' => 'RequestSpotInstances',
'LaunchSpecification.ImageId' => image_id,
'LaunchSpecification.InstanceType' => instance_type,
'SpotPrice' => spot_price,
:parser => Fog::Parsers::Compute::AWS::SpotInstanceRequests.new
}.merge!(options))
end
end
end
end
end

View file

@ -156,23 +156,33 @@ module Fog
# check that the attributes specified in args exist and is not nil
def requires(*args)
missing = missing_attributes(args)
if missing.length == 1
raise(ArgumentError, "#{missing.first} is required for this operation")
elsif missing.any?
raise(ArgumentError, "#{missing[0...-1].join(", ")} and #{missing[-1]} are required for this operation")
end
end
def requires_one(*args)
missing = missing_attributes(args)
if missing.length == args.length
raise(ArgumentError, "#{missing[0...-1].join(", ")} or #{missing[-1]} are required for this operation")
end
end
protected
def missing_attributes(args)
missing = []
for arg in [:connection] | args
unless send("#{arg}") || attributes.has_key?(arg)
missing << arg
end
end
unless missing.empty?
if missing.length == 1
raise(ArgumentError, "#{missing.first} is required for this operation")
else
raise(ArgumentError, "#{missing[0...-1].join(", ")} and #{missing[-1]} are required for this operation")
end
end
missing
end
protected
def dup_attributes!
@attributes = @attributes.dup
end

View file

@ -19,8 +19,7 @@ module Fog
end
def to_date_header
now = self.class.now.utc
now.strftime("#{DAYS[now.wday]}, %d #{MONTHS[now.month - 1]} %Y %H:%M:%S +0000")
self.utc.strftime("#{DAYS[self.utc.wday]}, %d #{MONTHS[self.utc.month - 1]} %Y %H:%M:%S +0000")
end
end

View file

@ -72,6 +72,10 @@ module Fog
class Mock
def self.arn(vendor, account_id, path, region = nil)
"arn:aws:#{vendor}:#{region}:#{account_id}:#{path}"
end
def self.availability_zone(region)
"#{region}#{Fog::Mock.random_selection('abcd', 1)}"
end

View file

@ -13,18 +13,19 @@ module Fog
rackspace_auth_url = options[:rackspace_auth_url] || "auth.api.rackspacecloud.com"
url = rackspace_auth_url.match(/^https?:/) ? \
rackspace_auth_url : 'https://' + rackspace_auth_url
uri = URI.parse(url)
connection = Fog::Connection.new(url)
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
response = connection.request({
:expects => 204,
:expects => [200, 204],
:headers => {
'X-Auth-Key' => @rackspace_api_key,
'X-Auth-User' => @rackspace_username
},
:host => rackspace_auth_url,
:host => uri.host,
:method => 'GET',
:path => 'v1.0'
:path => (uri.path and not uri.path.empty?) ? uri.path : 'v1.0'
})
response.headers.reject do |key, value|
!['X-Server-Management-Url', 'X-Storage-Url', 'X-CDN-Management-Url', 'X-Auth-Token'].include?(key)

View file

@ -60,7 +60,7 @@ module Fog
metadata[:body] = data
metadata[:headers]['Content-Length'] = get_body_size(data)
if data.respond_to?(:path)
if data.respond_to?(:path) and !data.path.nil?
filename = ::File.basename(data.path)
unless (mime_types = MIME::Types.of(filename)).empty?
metadata[:headers]['Content-Type'] = mime_types.first.content_type

View file

@ -30,6 +30,8 @@ module Fog
request :get_object
request :get_object_acl
request :get_object_torrent
request :get_object_http_url
request :get_object_https_url
request :get_object_url
request :get_request_payment
request :get_service
@ -60,7 +62,22 @@ module Fog
)
end
def http_url(params, expires)
"http://" << host_path_query(params, expires)
end
def https_url(params, expires)
"https://" << host_path_query(params, expires)
end
def url(params, expires)
Formatador.display_line("[yellow][WARN] #{Fog::Storage::AWS} => #url is deprecated, use #https_url instead[/] [light_black](#{caller.first})[/]")
https_url(params, expires)
end
private
def host_path_query(params, expires)
params[:headers] ||= {}
params[:headers]['Date'] = expires.to_i
params[:path] = Fog::AWS.escape(params[:path]).gsub('%2F', '/')
@ -73,7 +90,7 @@ module Fog
query << "AWSAccessKeyId=#{@aws_access_key_id}"
query << "Signature=#{Fog::AWS.escape(signature(params))}"
query << "Expires=#{params[:headers]['Date']}"
"https://#{@host}/#{params[:path]}?#{query.join('&')}"
"#{@host}/#{params[:path]}?#{query.join('&')}"
end
end

View file

@ -20,6 +20,8 @@ module Fog
request :get_object
request :get_object_acl
request :get_object_torrent
request :get_object_http_url
request :get_object_https_url
request :get_object_url
request :get_service
request :head_object
@ -30,14 +32,30 @@ module Fog
module Utils
def http_url(params, expires)
"http://" << host_path_query(params, expires)
end
def https_url(params, expires)
"https://" << host_path_query(params, expires)
end
def url(params, expires)
Formatador.display_line("[yellow][WARN] Fog::Storage::Google => #url is deprecated, use #https_url instead[/] [light_black](#{caller.first})[/]")
https_url(params, expires)
end
private
def host_path_query(params, expires)
params[:headers]['Date'] = expires.to_i
params[:path] = CGI.escape(params[:path]).gsub('%2F', '/')
query = [params[:query]].compact
query << "GoogleAccessKeyId=#{@google_storage_access_key_id}"
query << "Signature=#{CGI.escape(signature(params))}"
query << "Expires=#{params[:headers]['Date']}"
"http://#{params[:host]}/#{params[:path]}?#{query.join('&')}"
"#{params[:host]}/#{params[:path]}?#{query.join('&')}"
end
end

View file

@ -92,9 +92,9 @@ module Fog
requires :directory, :key
if connection.get_object_acl(directory.key, key).body['AccessControlList'].detect {|grant| grant['Grantee']['URI'] == 'http://acs.amazonaws.com/groups/global/AllUsers' && grant['Permission'] == 'READ'}
if directory.key.to_s =~ /^(?:[a-z]|\d(?!\d{0,2}(?:\.\d{1,3}){3}$))(?:[a-z0-9]|\.(?![\.\-])|\-(?![\.])){1,61}[a-z0-9]$/
"https://#{directory.key}.s3.amazonaws.com/#{key}"
"https://#{directory.key}.s3.amazonaws.com/#{Fog::AWS.escape(key)}"
else
"https://s3.amazonaws.com/#{directory.key}/#{key}"
"https://s3.amazonaws.com/#{directory.key}/#{Fog::AWS.escape(key)}"
end
else
nil

View file

@ -6,6 +6,8 @@ module Fog
class AWS
class Files < Fog::Collection
extend Fog::Deprecation
deprecate :get_url, :get_https_url
attribute :common_prefixes, :aliases => 'CommonPrefixes'
attribute :delimiter, :aliases => 'Delimiter'
@ -76,9 +78,14 @@ module Fog
end
end
def get_url(key, expires)
def get_http_url(key, expires)
requires :directory
connection.get_object_url(directory.key, key, expires)
connection.get_object_http_url(directory.key, key, expires)
end
def get_https_url(key, expires)
requires :directory
connection.get_object_https_url(directory.key, key, expires)
end
def head(key, options = {})

View file

@ -6,6 +6,8 @@ module Fog
class Google
class Files < Fog::Collection
extend Fog::Deprecation
deprecate :get_url, :get_https_url
attribute :common_prefixes, :aliases => 'CommonPrefixes'
attribute :delimiter, :aliases => 'Delimiter'
@ -68,9 +70,14 @@ module Fog
nil
end
def get_url(key, expires)
def get_http_url(key, expires)
requires :directory
connection.get_object_url(directory.key, key, expires)
connection.get_object_http_url(directory.key, key, expires)
end
def get_https_url(key, expires)
requires :directory
connection.get_object_https_url(directory.key, key, expires)
end
def head(key, options = {})

View file

@ -55,9 +55,18 @@ module Fog
def save
requires :key
connection.put_container(key)
if @public
# if user set cont as public but wed don't have a CDN connnection
# then error out.
if @public and !@connection.cdn
raise(Fog::Storage::Rackspace::Error.new("Directory can not be set as :public without a CDN provided"))
# if we set as public then set it and we sure we have connection.cdn
# or it would have error out.
elsif @public
@public_url = connection.cdn.put_container(key, 'X-CDN-Enabled' => 'True').headers['X-CDN-URI']
else
# if we have cdn connectio but cont has not been public then let the
# CDN knows about it
elsif @connection.cdn
connection.cdn.put_container(key, 'X-CDN-Enabled' => 'False')
@public_url = nil
end

View file

@ -30,8 +30,12 @@ module Fog
@cdn ||= Fog::CDN.new(
:provider => 'Rackspace',
:rackspace_api_key => @rackspace_api_key,
:rackspace_auth_url => @rackspace_auth_url,
:rackspace_username => @rackspace_username
)
if @cdn.enabled?
return @cdn
end
end
end
@ -75,6 +79,7 @@ module Fog
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_cdn_ssl = options[:rackspace_cdn_ssl]
@rackspace_auth_url = options[:rackspace_auth_url]
credentials = Fog::Rackspace.authenticate(options)
@auth_token = credentials['X-Auth-Token']

View file

@ -39,9 +39,13 @@ module Fog
query = {'versionId' => version_id}
end
headers = {}
headers['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header if options['If-Modified-Since']
headers['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header if options['If-Modified-Since']
headers.merge!(options)
if headers['If-Modified-Since']
headers['If-Modified-Since'] = Fog::Time.at(headers['If-Modified-Since'].to_i).to_date_header
end
if headers['If-Unmodified-Since']
headers['If-Unmodified-Since'] = Fog::Time.at(headers['If-Unmodified-Since'].to_i).to_date_header
end
request({
:expects => [ 200, 206 ],
:headers => headers,

View file

@ -0,0 +1,51 @@
module Fog
module Storage
class AWS
module GetObjectHttpUrl
def get_object_http_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
http_url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
end
end
class Real
# Get an expiring object http url from S3
#
# ==== Parameters
# * bucket_name<~String> - Name of bucket containing object
# * object_name<~String> - Name of object to get expiring url for
# * expires<~Time> - An expiry time for this url
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~String> - url for object
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
include GetObjectHttpUrl
end
class Mock # :nodoc:all
include GetObjectHttpUrl
end
end
end
end

View file

@ -0,0 +1,51 @@
module Fog
module Storage
class AWS
module GetObjectHttpsUrl
def get_object_https_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
https_url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
end
end
class Real
# Get an expiring object https url from S3
#
# ==== Parameters
# * bucket_name<~String> - Name of bucket containing object
# * object_name<~String> - Name of object to get expiring url for
# * expires<~Time> - An expiry time for this url
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~String> - url for object
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
include GetObjectHttpsUrl
end
class Mock # :nodoc:all
include GetObjectHttpsUrl
end
end
end
end

View file

@ -18,18 +18,8 @@ module Fog
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
def get_object_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
Formatador.display_line("[yellow][WARN] Fog::Storage::AWS => #get_object_url is deprecated, use #get_object_https_url instead[/] [light_black](#{caller.first})[/]")
get_object_https_url(bucket_name, object_name, expires)
end
end
@ -37,18 +27,8 @@ module Fog
class Mock # :nodoc:all
def get_object_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
Formatador.display_line("[yellow][WARN] Fog::Storage::AWS => #get_object_url is deprecated, use #get_object_https_url instead[/] [light_black](#{caller.first})[/]")
get_object_https_url(bucket_name, object_name, expires)
end
end

View file

@ -0,0 +1,51 @@
module Fog
module Storage
class Google
module GetObjectHttpUrl
def get_object_http_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
http_url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
end
end
class Real
# Get an expiring object http url from S3
#
# ==== Parameters
# * bucket_name<~String> - Name of bucket containing object
# * object_name<~String> - Name of object to get expiring url for
# * expires<~Time> - An expiry time for this url
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~String> - url for object
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
include GetObjectHttpUrl
end
class Mock # :nodoc:all
include GetObjectHttpUrl
end
end
end
end

View file

@ -0,0 +1,51 @@
module Fog
module Storage
class AWS
module GetObjectHttpsUrl
def get_object_https_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
https_url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
end
end
class Real
# Get an expiring object https url from Google Storage
#
# ==== Parameters
# * bucket_name<~String> - Name of bucket containing object
# * object_name<~String> - Name of object to get expiring url for
# * expires<~Time> - An expiry time for this url
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~String> - url for object
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
include GetObjectHttpsUrl
end
class Mock # :nodoc:all
include GetObjectHttpsUrl
end
end
end
end

View file

@ -14,38 +14,21 @@ module Fog
# * response<~Excon::Response>:
# * body<~String> - url for object
#
# ==== See Also
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/S3_QSAuth.html
def get_object_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
Formatador.display_line("[yellow][WARN] Fog::Storage::Google => ##{get_object_url} is deprecated, use ##{get_object_https_url} instead[/] [light_black](#{caller.first})[/]")
get_object_https_url(bucket_name, object_name, expires)
end
end
class Mock
class Mock # :nodoc:all
def get_object_url(bucket_name, object_name, expires)
unless bucket_name
raise ArgumentError.new('bucket_name is required')
end
unless object_name
raise ArgumentError.new('object_name is required')
end
url({
:headers => {},
:host => @host,
:method => 'GET',
:path => "#{bucket_name}/#{object_name}"
}, expires)
Formatador.display_line("[yellow][WARN] Fog::Storage::Google => ##{get_object_url} is deprecated, use ##{get_object_https_url} instead[/] [light_black](#{caller.first})[/]")
get_object_https_url(bucket_name, object_name, expires)
end
end

View file

@ -2,8 +2,6 @@ Shindo.tests('AWS::ELB | load_balancer_tests', ['aws', 'elb']) do
@load_balancer_id = 'fog-test-elb'
tests('success') do
pending if Fog.mocking?
tests("#create_load_balancer").formats(AWS::ELB::Formats::CREATE_LOAD_BALANCER) do
zones = ['us-east-1a']
listeners = [{'LoadBalancerPort' => 80, 'InstancePort' => 80, 'Protocol' => 'http'}]
@ -61,15 +59,14 @@ Shindo.tests('AWS::ELB | load_balancer_tests', ['aws', 'elb']) do
tests("#set_load_balancer_policies_of_listener adds policy").formats(AWS::ELB::Formats::BASIC) do
port, policies = 80, ['fog-lb-expiry']
body = AWS[:elb].set_load_balancer_policies_of_listener(@load_balancer_id, port, policies).body
AWS[:elb].set_load_balancer_policies_of_listener(@load_balancer_id, port, policies).body
end
tests("#set_load_balancer_policies_of_listener removes policy").formats(AWS::ELB::Formats::BASIC) do
port = 80
body = AWS[:elb].set_load_balancer_policies_of_listener(@load_balancer_id, port, []).body
AWS[:elb].set_load_balancer_policies_of_listener(@load_balancer_id, port, []).body
end
tests("#delete_load_balancer_listeners").formats(AWS::ELB::Formats::BASIC) do
ports = [80, 443]
AWS[:elb].delete_load_balancer_listeners(@load_balancer_id, ports).body
@ -78,5 +75,13 @@ Shindo.tests('AWS::ELB | load_balancer_tests', ['aws', 'elb']) do
tests("#delete_load_balancer").formats(AWS::ELB::Formats::DELETE_LOAD_BALANCER) do
AWS[:elb].delete_load_balancer(@load_balancer_id).body
end
tests("#delete_load_balancer when non existant").formats(AWS::ELB::Formats::DELETE_LOAD_BALANCER) do
AWS[:elb].delete_load_balancer('non-existant').body
end
tests("#delete_load_balancer when already deleted").formats(AWS::ELB::Formats::DELETE_LOAD_BALANCER) do
AWS[:elb].delete_load_balancer(@load_balancer_id).body
end
end
end

View file

@ -2,8 +2,6 @@ Shindo.tests('AWS::ELB | models', ['aws', 'elb']) do
tests('success') do
pending if Fog.mocking?
tests('load_balancers') do
tests('getting a missing elb') do
returns(nil) { AWS[:elb].load_balancers.get('no-such-elb') }
@ -44,7 +42,7 @@ Shindo.tests('AWS::ELB | models', ['aws', 'elb']) do
raises(Fog::AWS::ELB::InvalidInstance) { elb.deregister_instances('i-00000000') }
end
server = Compute[:aws].servers.create
server = Fog::Compute[:aws].servers.create
tests('register instance') do
begin
elb.register_instances(server.id)
@ -183,5 +181,4 @@ Shindo.tests('AWS::ELB | models', ['aws', 'elb']) do
elb.destroy
end
end
end

View file

@ -1,7 +1,4 @@
Shindo.tests('AWS::IAM | server certificate requests', ['aws']) do
pending if Fog.mocking?
@key_name = 'fog-test'
@certificate_format = {
@ -10,11 +7,12 @@ Shindo.tests('AWS::IAM | server certificate requests', ['aws']) do
'ServerCertificateId' => String,
'ServerCertificateName' => String,
'UploadDate' => Time
}
}
@upload_format = {
'Certificate' => @certificate_format,
'RequestId' => String
}
tests('#upload_server_certificate').formats(@upload_format) do
public_key = AWS::IAM::SERVER_CERT_PUBLIC_KEY
private_key = AWS::IAM::SERVER_CERT_PRIVATE_KEY

View file

@ -13,10 +13,21 @@ Shindo.tests("Fog::Compute[:aws] | volume", ['aws']) do
@instance.wait_for { state == 'in-use' }
tests('#server').succeeds do
@instance.server
end
tests('#server = nil').succeeds do
@instance.server = nil
end
@instance.server = @server
@instance.wait_for { state == 'in-use' }
tests('#force_detach').succeeds do
@instance.force_detach
end
@instance.wait_for { ready? }
end

View file

@ -0,0 +1,48 @@
Shindo.tests('Fog::Compute[:aws] | spot datafeed subscription requests', ['aws']) do
@spot_datafeed_subscription_format = {
'spotDatafeedSubscription' => {
'bucket' => String,
'ownerId' => String,
'prefix' => String,
'state' => String
},
'requestId' => String
}
@directory = Fog::Storage[:aws].directories.create(:key => 'fogspotdatafeedsubscriptiontests')
tests('success') do
tests("#create_spot_datafeed_subscription('fogspotdatafeedsubscriptiontests', 'fogspotdatafeedsubscription/')").formats(@spot_datafeed_subscription_format) do
Fog::Compute[:aws].create_spot_datafeed_subscription('fogspotdatafeedsubscriptiontests', 'fogspotdatafeedsubscription/').body
end
tests("duplicate #create_spot_datafeed_subscription('fogspotdatafeedsubscriptiontests', 'fogspotdatafeedsubscription/')").succeeds do
Fog::Compute[:aws].create_spot_datafeed_subscription('fogspotdatafeedsubscriptiontests', 'fogspotdatafeedsubscription/')
end
tests("#describe_spot_datafeed_subscription").formats(@spot_datafeed_subscription_format) do
Fog::Compute[:aws].describe_spot_datafeed_subscription.body
end
tests("#delete_spot_datafeed_subscription").formats(AWS::Compute::Formats::BASIC) do
Fog::Compute[:aws].delete_spot_datafeed_subscription.body
end
tests("duplicate #delete_spot_datafeed_subscription").succeeds do
Fog::Compute[:aws].delete_spot_datafeed_subscription
end
end
tests('failure') do
tests("#describe_spot_datafeed_subscription").raises(Fog::Compute::AWS::NotFound) do
Fog::Compute[:aws].describe_spot_datafeed_subscription
end
end
@directory.destroy
end

View file

@ -0,0 +1,51 @@
Shindo.tests('Fog::Compute[:aws] | spot instance requests', ['aws']) do
@spot_instance_requests_format = {
'spotInstanceRequestSet' => [{
'createTime' => Time,
'instanceId' => Fog::Nullable::String,
'launchedAvailabilityZone' => Fog::Nullable::String,
'launchSpecification' => {
'blockDeviceMapping' => [],
'groupSet' => [String],
'keyName' => Fog::Nullable::String,
'imageId' => String,
'instanceType' => String,
'monitoring' => Fog::Boolean
},
'productDescription' => String,
'spotInstanceRequestId' => String,
'spotPrice' => Float,
'state' => String,
'type' => String
}],
'requestId' => String
}
@cancel_spot_instance_request_format = {
'spotInstanceRequestSet' => [{
'spotInstanceRequestId' => String,
'state' => String
}],
'requestId' => String
}
tests('success') do
tests("#request_spot_instances('ami-3202f25b', 't1.micro', '0.001')").formats(@spot_instance_requests_format) do
data = Fog::Compute[:aws].request_spot_instances('ami-3202f25b', 't1.micro', '0.001').body
@spot_instance_request_id = data['spotInstanceRequestSet'].first['spotInstanceRequestId']
data
end
tests("#describe_spot_instance_requests").formats(@spot_instance_requests_format) do
Fog::Compute[:aws].describe_spot_instance_requests.body
end
tests("#cancel_spot_instance_requests('#{@spot_instance_request_id}')").formats(@cancel_spot_instance_request_format) do
Fog::Compute[:aws].cancel_spot_instance_requests(@spot_instance_request_id).body
end
end
end

View file

@ -0,0 +1,22 @@
Shindo.tests('Fog::Compute[:aws] | spot price history requests', ['aws']) do
@spot_price_history_format = {
'spotPriceHistorySet' => [{
'availabilityZone' => String,
'instanceType' => String,
'spotPrice' => Float,
'productDescription' => String,
'timestamp' => Time
}],
'requestId' => String
}
tests('success') do
tests("#describe_spot_price_history").formats(@spot_price_history_format) do
Fog::Compute[:aws].describe_spot_price_history.body
end
end
end

View file

@ -78,6 +78,10 @@ Shindo.tests('Fog::Compute[:aws] | volume requests', ['aws']) do
Fog::Compute[:aws].volumes.get(@volume_id).wait_for { state == 'in-use' }
tests("#describe_volume('attachment.device' => '/dev/sdh')").formats(@volumes_format) do
Fog::Compute[:aws].describe_volumes('attachment.device' => '/dev/sdh').body
end
tests("#detach_volume('#{@volume_id}')").formats(@volume_attachment_format) do
Fog::Compute[:aws].detach_volume(@volume_id).body
end

View file

@ -402,7 +402,8 @@ class Brightbox
"email_verified" => Fog::Boolean,
"accounts" => [Brightbox::Compute::Formats::Nested::ACCOUNT],
"default_account" => Fog::Brightbox::Nullable::Account,
"ssh_key" => Fog::Nullable::String
"ssh_key" => Fog::Nullable::String,
"messaging_pref" => Fog::Boolean
}
ZONE = {

View file

@ -3,13 +3,13 @@ Shindo.tests('Fog::Compute[:brightbox] | interface requests', ['brightbox']) do
tests('success') do
unless Fog.mocking?
server = Brightbox[:compute].servers.first
server = Fog::Compute[:brightbox].servers.first
@interface_id = server.interfaces.first["id"]
end
tests("#get_interface('#{@interface_id}')").formats(Brightbox::Compute::Formats::Full::INTERFACE) do
pending if Fog.mocking?
Brightbox[:compute].get_interface(@interface_id)
Fog::Compute[:brightbox].get_interface(@interface_id)
end
end
@ -18,12 +18,12 @@ Shindo.tests('Fog::Compute[:brightbox] | interface requests', ['brightbox']) do
tests("#get_interface('int-00000')").raises(Excon::Errors::Forbidden) do
pending if Fog.mocking?
Brightbox[:compute].get_interface('int-00000')
Fog::Compute[:brightbox].get_interface('int-00000')
end
tests("#get_interface()").raises(ArgumentError) do
pending if Fog.mocking?
Brightbox[:compute].get_interface()
Fog::Compute[:brightbox].get_interface()
end
end