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 github.com:fog/fog into ssh_host

This commit is contained in:
Kyle Rames 2014-01-22 11:38:42 -06:00
commit 10f019cc7b
45 changed files with 816 additions and 237 deletions

View file

@ -57,7 +57,6 @@ Gem::Specification.new do |s|
s.add_development_dependency('rbvmomi')
s.add_development_dependency('yard')
s.add_development_dependency('thor')
s.add_development_dependency('rspec', '~>1.3.1')
s.add_development_dependency('rbovirt', '>=0.0.11')
s.add_development_dependency('shindo', '~>0.3.4')
s.add_development_dependency('fission')

View file

@ -140,7 +140,7 @@ module Fog
# valid new_publics: public_read, private
#
# @param [String] new_public
# @return [String] new_puplic
# @return [String] new_public
#
def public=(new_public)
if new_public

View file

@ -102,7 +102,6 @@ module Fog
:expects => 200,
:idempotent => idempotent,
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
:host => @host,
:method => 'POST',
:parser => parser
})

View file

@ -67,7 +67,7 @@ module Fog
options[:port] = uri.port
options[:scheme] = uri.scheme
end
@host = options[:host] || "dnsimple.com"
@host = options[:host] || "api.dnsimple.com"
@persistent = options[:persistent] || false
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@ -85,6 +85,9 @@ module Fog
"Accept" => "application/json",
"Content-Type" => "application/json" })
version = params.delete(:version) || 'v1'
params[:path] = "/#{version}#{params[:path]}"
response = @connection.request(params)
unless response.body.empty?

View file

@ -11,14 +11,14 @@ module Fog
identity :id
attribute :zone_id, :aliases => "domain_id"
attribute :name
attribute :value, :aliases => "content"
attribute :ttl
attribute :priority, :aliases => "prio"
attribute :type, :aliases => "record_type"
attribute :created_at
attribute :updated_at
attribute :zone_id, :aliases => "domain_id"
attribute :type, :aliases => "record_type"
attribute :priority, :aliases => "prio"
def initialize(attributes={})
super

View file

@ -4,21 +4,27 @@ module Fog
class Real
# Create a single domain in DNSimple in your account.
#
# ==== Parameters
# * name<~String> - domain name to host (ie example.com)
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'name'<~String>
# * 'domain'<~Hash> The representation of the domain.
def create_domain(name)
body = { "domain" => { "name" => name } }
body = {
"domain" => {
"name" => name
}
}
request(
:body => Fog::JSON.encode(body),
:expects => 201,
:method => 'POST',
:path => '/domains'
)
:body => Fog::JSON.encode(body),
:expects => 201,
:method => 'POST',
:path => "/domains"
)
end
end
@ -26,32 +32,30 @@ module Fog
class Mock
def create_domain(name)
response = Excon::Response.new
response.status = 201
body = {
"domain" => {
"auto_renew" => nil,
"created_at" => Time.now.iso8601,
"expires_on" => Date.today + 365,
"id" => Fog::Mock.random_numbers(1).to_i,
"user_id" => 1,
"registrant_id" => nil,
"name" => name,
"unicode_name" => name,
"token" => "4fIFYWYiJayvL2tkf_mkBkqC4L+4RtYqDA",
"state" => "registered",
"language" => nil,
"lockable" => true,
"name" => name,
"name_server_status" => "unknown",
"registrant_id" => nil,
"state" => "registered",
"token" => "4fIFYWYiJayvL2tkf_mkBkqC4L+4RtYqDA",
"unicode_name" => name,
"updated_at" => Time.now.iso8601,
"user_id" => 1,
"auto_renew" => nil,
"whois_protected" => false,
"record_count" => 0,
"service_count" => 0,
"private_whois?" => false
"expires_on" => Date.today + 365,
"created_at" => Time.now.iso8601,
"updated_at" => Time.now.iso8601,
}
}
self.data[:domains] << body
response = Excon::Response.new
response.status = 201
response.body = body
response
end

View file

@ -6,40 +6,35 @@ module Fog
# Create a new host in the specified zone
#
# ==== Parameters
# * domain<~String>
# * domain<~String> - domain name or numeric ID
# * name<~String>
# * type<~String>
# * content<~String>
# * options<~Hash> - optional
# * priority<~Integer>
# * ttl<~Integer>
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>
# * name<~String>
# * ttl<~Integer>
# * created_at<~String>
# * special_type<~String>
# * updated_at<~String>
# * domain_id<~Integer>
# * id<~Integer>
# * content<~String>
# * record_type<~String>
# * prio<~Integer>
# * body<~Hash>:
# * 'record'<~Hash> The representation of the record.
def create_record(domain, name, type, content, options = {})
body = {
"record" => {
"name" => name,
"record_type" => type,
"content" => content } }
"content" => content
}
}
body["record"].merge!(options)
request( :body => Fog::JSON.encode(body),
:expects => 201,
:method => 'POST',
:path => "/domains/#{domain}/records" )
request(
:body => Fog::JSON.encode(body),
:expects => 201,
:method => 'POST',
:path => "/domains/#{domain}/records"
)
end
end
@ -47,23 +42,25 @@ module Fog
class Mock
def create_record(domain, name, type, content, options = {})
response = Excon::Response.new
response.status = 201
body = {
"record" => {
"id" => Fog::Mock.random_numbers(1).to_i,
"domain_id" => domain,
"name" => name,
"record_type" => type,
"content" => content,
"ttl" => 3600,
"prio" => nil,
"record_type" => type,
"system_record" => nil,
"created_at" => Time.now.iso8601,
"updated_at" => Time.now.iso8601,
"id" => Fog::Mock.random_numbers(1).to_i,
"domain_id" => domain
}.merge(options)
}
self.data[:records][domain] ||= []
self.data[:records][domain] << body
response = Excon::Response.new
response.status = 201
response.body = body
response
end

View file

@ -10,14 +10,14 @@ module Fog
# DNSimple this will not delete the domain from the registry.
#
# ==== Parameters
# * name<~String> - domain name or numeric ID
# * domain<~String> - domain name or numeric ID
#
def delete_domain(name)
def delete_domain(domain)
request(
:expects => 200,
:method => 'DELETE',
:path => "/domains/#{name}"
)
:expects => 200,
:method => 'DELETE',
:path => "/domains/#{domain}"
)
end
end
@ -27,6 +27,7 @@ module Fog
def delete_domain(name)
self.data[:records].delete name
self.data[:domains].reject! { |domain| domain["domain"]["name"] == name }
response = Excon::Response.new
response.status = 200
response

View file

@ -6,13 +6,14 @@ module Fog
# Delete the record with the given ID for the given domain.
#
# ==== Parameters
# * domain<~String>
# * domain<~String> - domain name or numeric ID
# * record_id<~String>
def delete_record(domain, record_id)
request( :expects => 200,
:method => "DELETE",
:path => "/domains/#{domain}/records/#{record_id}" )
request(
:expects => 200,
:method => "DELETE",
:path => "/domains/#{domain}/records/#{record_id}"
)
end
end
@ -21,6 +22,7 @@ module Fog
def delete_record(domain, record_id)
self.data[:records][domain].reject! { |record| record["record"]["id"] == record_id }
response = Excon::Response.new
response.status = 200
response

View file

@ -8,27 +8,18 @@ module Fog
# itself.
#
# ==== Parameters
# * id<~String> - domain name or numeric ID
# * domain<~String> - domain name or numeric ID
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'domain'<~Hash>
# * 'name'<~String>
# * 'expires_at'<~String>
# * 'created_at'<~String>
# * 'registration_status'<~String>
# * 'updated_at'<~String>
# * 'registrant_id'<~Integer>
# * 'id'<~Integer>
# * 'user_id'<~Integer>
# * 'name_server_status'<~String>
def get_domain(id)
# * 'domain'<~Hash> The representation of the domain.
def get_domain(domain)
request(
:expects => 200,
:method => "GET",
:path => "/domains/#{id}"
)
:expects => 200,
:method => "GET",
:path => "/domains/#{domain}"
)
end
end
@ -39,6 +30,7 @@ module Fog
domain = self.data[:domains].detect do |domain|
domain["domain"]["id"] == id || domain["domain"]["name"] == id
end
response = Excon::Response.new
response.status = 200
response.body = domain

View file

@ -6,26 +6,19 @@ module Fog
# Gets record from given domain.
#
# ==== Parameters
# * domain<~String>
# * domain<~String> - domain name or numeric ID
# * record_id<~String>
#
# ==== Returns
# * response<~Excon::Response>:
# * record<~Hash>
# * name<~String>
# * ttl<~Integer>
# * created_at<~String>
# * special_type<~String>
# * updated_at<~String>
# * domain_id<~Integer>
# * id<~Integer>
# * content<~String>
# * record_type<~String>
# * prio<~Integer>
# * body<~Hash>:
# * 'record'<~Hash> The representation of the record.
def get_record(domain, record_id)
request( :expects => 200,
:method => "GET",
:path => "/domains/#{domain}/records/#{record_id}" )
request(
:expects => 200,
:method => "GET",
:path => "/domains/#{domain}/records/#{record_id}"
)
end
end
@ -34,7 +27,8 @@ module Fog
def get_record(domain, record_id)
response = Excon::Response.new
if self.data[:records].has_key? domain
if self.data[:records].has_key?(domain)
response.status = 200
response.body = self.data[:records][domain].detect { |record| record["record"]["id"] == record_id }

View file

@ -5,28 +5,20 @@ module Fog
# Get the details for a specific domain in your account. You
# may pass either the domain numeric ID or the domain name itself.
#
# ==== Parameters
# * id<~String> - domain name or numeric ID
#
# ==== Returns
# * response<~Excon::Response>:
# * body<~Hash>:
# * 'domains'<~Array>
# * 'name'<~String>
# * 'expires_at'<~String>
# * 'created_at'<~String>
# * 'registration_status'<~String>
# * 'updated_at'<~String>
# * 'registrant_id'<~Integer>
# * 'id'<~Integer>
# * 'user_id'<~Integer>
# * 'name_server_status'<~String>
# * <~Array>:
# * 'domain'<~Hash> The representation of the domain.
def list_domains
request(
:expects => 200,
:method => 'GET',
:path => '/domains'
)
:expects => 200,
:method => 'GET',
:path => '/domains'
)
end
end

View file

@ -6,24 +6,19 @@ module Fog
# Get the list of records for the specific domain.
#
# ==== Parameters
# * domain<~String>
# * domain<~String> - domain name or numeric ID
#
# ==== Returns
# * response<~Excon::Response>:
# * records<Array~>
# * name<~String>
# * ttl<~Integer>
# * created_at<~String>
# * special_type<~String>
# * updated_at<~String>
# * domain_id<~Integer>
# * id<~Integer>
# * content<~String>
# * record_type<~String>
# * prio<~Integer>
# * body<~Hash>:
# * <~Array>:
# * 'record'<~Hash> The representation of the record.
def list_records(domain)
request( :expects => 200,
:method => "GET",
:path => "/domains/#{domain}/records" )
request(
:expects => 200,
:method => "GET",
:path => "/domains/#{domain}/records"
)
end
end

View file

@ -6,34 +6,29 @@ module Fog
# Update the given record for the given domain.
#
# ==== Parameters
# * domain<~String>
# * domain<~String> - domain name or numeric ID
# * record_id<~String>
# * options<~Hash> - optional
# * type<~String>
# * content<~String>
# * priority<~Integer>
# * ttl<~Integer>
#
# ==== Returns
# * response<~Excon::Response>:
# * record<~Hash>
# * name<~String>
# * ttl<~Integer>
# * created_at<~String>
# * special_type<~String>
# * updated_at<~String>
# * domain_id<~Integer>
# * id<~Integer>
# * content<~String>
# * record_type<~String>
# * prio<~Integer>
# * body<~Hash>:
# * 'record'<~Hash> The representation of the record.
def update_record(domain, record_id, options)
body = {
"record" => options
}
body = { "record" => options }
request( :body => Fog::JSON.encode(body),
:expects => 200,
:method => "PUT",
:path => "/domains/#{domain}/records/#{record_id}" )
request(
:body => Fog::JSON.encode(body),
:expects => 200,
:method => "PUT",
:path => "/domains/#{domain}/records/#{record_id}"
)
end
end

View file

@ -144,7 +144,7 @@ module Fog
# valid new_publics: public_read, private
#
# @param [String] new_public
# @return [String] new_puplic
# @return [String] new_public
#
def public=(new_public)
'public-read'

View file

@ -232,6 +232,23 @@ module Fog
def self.zulu_time
Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")
end
def self.stringify(message)
case message
when Symbol
message.to_s
when Hash
result = Hash.new
message.each do |key, value|
nk = stringify(key)
nv = stringify(value)
result[nk] = nv
end
result
else
message
end
end
end
end
end

View file

@ -94,6 +94,14 @@ module Fog
end
end
def initialize(new_attributes = {})
# A hack in support of the #messages= hack up above. #messages= requires #collection to
# be populated first to succeed, which is always the case in modern Rubies that preserve
# Hash ordering, but not in 1.8.7.
@collection = new_attributes.delete(:collection)
super(new_attributes)
end
private
def queue

View file

@ -42,23 +42,8 @@ module Fog
request :update_claim
request :delete_claim
class Mock < Fog::Rackspace::Service
def request(params)
Fog::Mock.not_implemented
end
end
class Real < Fog::Rackspace::Service
def service_name
:cloudQueues
end
def region
@rackspace_region
end
def initialize(options = {})
module Common
def apply_options(options)
@rackspace_api_key = options[:rackspace_api_key]
@rackspace_username = options[:rackspace_username]
@rackspace_queues_client_id = options[:rackspace_queues_client_id] || Fog::UUID.uuid
@ -70,25 +55,14 @@ module Fog
unless v2_authentication?
raise Fog::Errors::NotImplemented.new("V2 authentication required for Queues")
end
authenticate
@persistent = options[:persistent] || false
@connection = Fog::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true, &block)
super(params, parse_json, &block)
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::MethodNotAllowed => error
raise MethodNotAllowed.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
def service_name
:cloudQueues
end
def region
@rackspace_region
end
def endpoint_uri(service_endpoint_url=nil)
@ -112,6 +86,316 @@ module Fog
@rackspace_queues_client_id = client_id
end
end
class Mock < Fog::Rackspace::Service
include Common
PATH_BASE = "/v1/queues"
# An in-memory Queue implementation.
class MockQueue
attr_accessor :name, :metadata, :messages, :claims
def initialize(name)
@name, @metadata = name, {}
@messages, @claims = [], {}
@id_counter = Fog::Mock.random_hex(24).to_i(16)
end
# The total number of messages currently on the queue.
#
# @return [Integer]
def total
@messages.size
end
# The number of messages currently held by a claim.
#
# @return [Integer]
def claimed
@messages.count { |msg| msg.claimed? }
end
# The number of messages not held by any claim.
#
# @return [Integer]
def free
@messages.count { |msg| ! msg.claimed? }
end
# The oldest published message on this queue, or `nil`.
#
# @return [MockMessage|UndefinedObject]
def oldest
@messages.first
end
# The most recently published message on this queue, or `nil`.
#
# @return [MockMessage|UndefinedObject]
def newest
@messages.last
end
# Append a new message to the queue.
#
# @param client_id [String] UUID for the service object.
# @param data [Hash] Message payload.
# @param ttl [Integer] Number of seconds that the message should exist.
# @return [MockMessage] The message object that was created.
def add_message(client_id, data, ttl)
id = @id_counter.to_s(16)
@id_counter += 1
message = MockMessage.new(id, self, client_id, data, ttl)
@messages << message
message
end
# Create a new MockClaim.
#
# @param ttl [Integer] Time-to-live for the claim.
# @param grace [Integer] Grace period that's added to messages included in this claim.
def add_claim(ttl, grace)
claim = MockClaim.new(self, ttl, grace)
claims[claim.id] = claim
claim
end
# Access an existing MockClaim by id.
#
# @param claim_id [String] An ID of an existing claim.
# @raises [Fog::Rackspace::Queues::NotFound] If no MockClaim with this ID exists.
# @return [MockClaim] The requested MockClaim.
def claim!(claim_id)
claims[claim_id] or raise NotFound.new
end
# Remove any messages or claims whose ttls have expired.
def ageoff
messages.reject! { |m| m.expired? }
claims.keys.dup.each do |id|
claim = claims[id]
if claim.expired? || claim.messages.empty?
claim.messages.each { |m| m.claim = nil }
claims.delete(id)
end
end
end
end
# A single message posted to an in-memory MockQueue.
class MockMessage
attr_accessor :id, :queue, :data, :ttl, :producer_id
attr_accessor :claim, :created
# Create a new message. Use {MockQueue#add_message} instead.
def initialize(id, queue, client_id, data, ttl)
@id, @queue, @producer_id = id, queue, client_id
@data, @ttl = data, ttl
@created = Time.now.to_i
@claim = nil
end
# Determine how long ago this message was created, in seconds.
#
# @return [Integer]
def age
Time.now.to_i - @created
end
# Generate a URI segment that identifies this message.
#
# @return [String]
def href
"#{PATH_BASE}/#{@queue.name}/messages/#{@id}"
end
# Return true if this message has been claimed.
#
# @return [Boolean]
def claimed?
! @claim.nil?
end
# Determine if this message has lived longer than its designated ttl.
#
# @return [Boolean]
def expired?
age > ttl
end
# Extend the {#ttl} of this message to include the lifetime of the claim it belongs to,
# plus the claim's grace period.
def extend_life
return unless @claim
extended = claim.message_end_of_life - @created
@ttl = extended if extended > @ttl
end
# Convert this message to a GET payload.
#
# @return [Hash]
def to_h
{
"body" => @data,
"age" => age,
"ttl" => @ttl,
"href" => href
}
end
end
# Reservation indicating that a consumer is in the process of handling a collection of
# messages from a queue.
class MockClaim
attr_accessor :id, :queue, :ttl, :grace
# Create a new MockClaim. Clients should use {MockQueue#add_claim} instead.
#
# @param queue [MockQueue] The queue that owns this claim.
# @param ttl [Integer] Duration, in seconds, that this queue should last.
# @param grace [Integer] Extra life granted to messages within this claim after this
# claim expires, to give another consumer a chance to process it.
def initialize(queue, ttl, grace)
@queue = queue
@id = Fog::Mock.random_hex(24)
@ttl, @grace = ttl, grace
touch!
end
# Set or reset the creation time of the claim to the present.
def touch!
@created = Time.now.to_i
end
# Calculate the time at which messages belonging to this claim should expire.
#
# @return [Integer] Seconds since the epoch.
def message_end_of_life
@created + @ttl + @grace
end
# Determine how long ago this claim was created, in seconds.
#
# @return [Integer]
def age
Time.now.to_i - @created
end
# Determine if this claim has lasted longer than its designated ttl.
#
# @return [Boolean]
def expired?
age > ttl
end
# Access the collection of messages owned by this claim.
#
# @return [Array<Message>]
def messages
@queue.messages.select { |m| m.claim == self }
end
# Convert this claim into a GET payload.
#
# @return [Hash]
def to_h
ms = messages.map { |m| m.to_h }
{
"age" => age,
"href" => "#{PATH_BASE}/#{@queue.name}/claims/#{@id}",
"ttl" => @ttl,
"messages" => ms
}
end
end
def initialize(options = {})
apply_options(options)
authenticate
endpoint_uri
end
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {}
end
end
def data
self.class.data[@rackspace_username]
end
# Create and remember a MockQueue with a given name. An existing MockQueue with the same
# name will be overridden without warning.
#
# @param [String] Valid queue name.
# @return [MockQueue] The MockQueue that was created.
def add_queue(queue_name)
queue = MockQueue.new(queue_name)
data[queue_name] = queue
queue
end
# Access a MockQueue with the specified name, or return `nil`.
#
# @param queue_name [String] Valid queue name.
# @return [MockQueue|UndefinedObject] The queue with the specified name, or `nil` if
# it doesn't exist.
def mock_queue(queue_name)
data[queue_name]
end
# Access a MockQueue with the specified name, raising an exception if it doesn't exist.
#
# @param queue_name [String] Valid queue name.
# @raises [Fog::Rackspace::Queue::NotFound] If there is no queue with the specified name.
# @return [MockQueue] The queue with the specified name.
def mock_queue!(queue_name)
mock_queue(queue_name) or raise NotFound.new
end
# Remove any messages or expire any claims that have exceeded their ttl values. Invoked
# before every request.
def ageoff
data.values.each { |q| q.ageoff }
end
def request(params)
ageoff
super
end
end
class Real < Fog::Rackspace::Service
include Common
def initialize(options = {})
apply_options(options)
authenticate
@persistent = options[:persistent] || false
@connection = Fog::Connection.new(endpoint_uri.to_s, @persistent, @connection_options)
end
def request(params, parse_json = true, &block)
super(params, parse_json, &block)
rescue Excon::Errors::NotFound => error
raise NotFound.slurp(error, self)
rescue Excon::Errors::BadRequest => error
raise BadRequest.slurp(error, self)
rescue Excon::Errors::InternalServerError => error
raise InternalServerError.slurp(error, self)
rescue Excon::Errors::MethodNotAllowed => error
raise MethodNotAllowed.slurp(error, self)
rescue Excon::Errors::HTTPStatusError => error
raise ServiceError.slurp(error, self)
end
end
end
end
end

View file

@ -15,7 +15,7 @@ module Fog
request(
:method => 'DELETE',
:expects => 202,
:path => "/os-keypairs/#{key_name}"
:path => "/os-keypairs/#{URI.escape(key_name)}"
)
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation claims a set of messages (up to the value of the limit parameter) from oldest to newest and skips any messages that are already claimed.
@ -33,7 +34,43 @@ module Fog
:query => query
)
end
end
class Mock
def create_claim(queue_name, ttl, grace, options = {})
queue = mock_queue!(queue_name)
limit = options[:limit] || 10
claim = queue.add_claim(ttl, grace)
claimed = queue.messages.select do |message|
! message.claimed?
end.first(limit)
if claimed.empty?
response = Excon::Response.new
response.status = 204
return response
end
claimed.each do |message|
message.claim = claim
# Extend the message's lifetime to include the lifetime of the claim, plus the claim's
# grace period.
message.extend_life
end
response = Excon::Response.new
response.status = 201
response.body = claimed.map { |msg| msg.to_h }
response.headers['Location'] = "#{PATH_BASE}/#{queue_name}/claims/#{claim.id}"
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation posts the specified message or messages.
@ -31,6 +32,28 @@ module Fog
)
end
end
class Mock
def create_message(client_id, queue_name, body, ttl)
queue = mock_queue!(queue_name)
raise BadRequest.new if body.nil? || body.empty?
# Ensure that any Symbol keys within +body+ are converted to Strings, just as being
# round-tripped through the API will.
converted = MockData.stringify(body)
message = queue.add_message(client_id, converted, ttl)
response = Excon::Response.new
response.status = 201
response.body = {
"partial" => false,
"resources" => ["#{PATH_BASE}/#{queue_name}/messages/#{message.id}"]
}
response
end
end
end
end
end

View file

@ -1,8 +1,8 @@
module Fog
module Rackspace
class Queues
class Real
class Real
# This operation creates a new queue.
# The body of the request is empty.
#
@ -22,6 +22,20 @@ module Fog
)
end
end
class Mock
def create_queue(queue_name)
raise MethodNotAllowed.new if queue_name.nil? || queue_name.empty?
existed = ! mock_queue(queue_name).nil?
add_queue(queue_name) unless existed
response = Excon::Response.new
response.status = existed ? 201 : 204
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation immediately releases a claim, making any remaining, undeleted) messages that are associated with the claim available to other workers.
@ -22,6 +23,23 @@ module Fog
)
end
end
class Mock
def delete_claim(queue_name, claim_id)
queue = mock_queue!(queue_name)
claim = queue.claim!(claim_id)
claim.messages.each do |message|
message.claim = nil
end
queue.claims.delete(claim_id)
response = Excon::Response.new
response.status = 204
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation immediately deletes the specified message.
@ -26,7 +27,40 @@ module Fog
:query => query
)
end
end
class Mock
def delete_message(queue_name, message_id, options = {})
queue = mock_queue!(queue_name)
claim_id = options[:claim_id]
message = queue.messages.detect { |m| m.id == message_id }
perform_delete = true
if message && message.claimed?
unless message.claim.id == claim_id
# Currently returns a 204 without deleting!
perform_delete = false
end
else
if claim_id
# Currently returns a 204 without deleting!
perform_delete = false
end
end
if perform_delete
queue.messages.reject! { |m| m.id == message_id }
end
response = Excon::Response.new
response.status = 204
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation immediately deletes a queue and all of its existing messages.
@ -19,7 +20,18 @@ module Fog
:path => "queues/#{queue_name}"
)
end
end
class Mock
def delete_queue(queue_name)
data.delete(queue_name)
response = Excon::Response.new
response.status = 204
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation queries the specified claim for the specified queue. Claims with malformed IDs or claims that are not found by ID are ignored.
@ -20,7 +21,21 @@ module Fog
:path => "queues/#{queue_name}/claims/#{claim_id}"
)
end
end
class Mock
def get_claim(queue_name, claim_id)
queue = mock_queue!(queue_name)
claim = queue.claim!(claim_id)
response = Excon::Response.new
response.status = 200
response.body = claim.to_h
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation gets the specified message from the specified queue.
@ -22,7 +23,23 @@ module Fog
:headers => { 'Client-ID' => client_id }
)
end
end
class Mock
def get_message(client_id, queue_name, message_id)
queue = mock_queue!(queue_name)
message = queue.messages.find { |msg| msg.id == message_id }
raise NotFound.new unless message
response = Excon::Response.new
response.status = 200
response.body = message.to_h
response
end
end
end
end
end

View file

@ -1,8 +1,8 @@
module Fog
module Rackspace
class Queues
class Real
class Real
# This operation verifies whether the specified queue exists.
#
# @param [String] queue_name Specifies the name of the queue.
@ -20,6 +20,19 @@ module Fog
)
end
end
class Mock
def get_queue(queue_name)
if mock_queue(queue_name).nil?
raise NotFound.new
else
response = Excon::Response.new
response.status = 204
response
end
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation returns queue statistics, including how many messages are in the queue, categorized by status.
@ -19,7 +20,42 @@ module Fog
:path => "queues/#{queue_name}/stats"
)
end
end
class Mock
def get_queue_stats(queue_name)
queue = mock_queue!(queue_name)
payload = {
"claimed" => queue.claimed,
"total" => queue.total,
"free" => queue.free
}
report_message(payload, "oldest", queue.oldest)
report_message(payload, "newest", queue.newest)
response = Excon::Response.new
response.status = 200
response.body = { "messages" => payload }
response
end
private
def report_message(payload, description, element)
return unless element
ctime = Time.at(element.created).utc
payload[description] = {
"age" => element.age,
"href" => element.href,
"created" => ctime.strftime("%Y-%m-%dT%I:%M:%SZ")
}
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation gets the message or messages in the specified queue.
@ -38,6 +39,38 @@ module Fog
)
end
end
class Mock
def list_messages(client_id, queue_name, options = {})
queue = mock_queue!(queue_name)
marker = (options[:marker] || "0").to_i
limit = options[:limit] || 10
echo = options[:echo] || false
include_claimed = options[:include_claimed] || false
next_marker = marker + limit + 1
messages = queue.messages[marker...next_marker]
messages.reject! { |m| m.producer_id == client_id } unless echo
messages.reject! { |m| m.claimed? } unless include_claimed
response = Excon::Response.new
if queue.messages.empty?
response.status = 204
else
response.status = 200
response.body = {
"messages" => messages.map { |m| m.to_h },
"links" => [{
"href" => "#{PATH_BASE}/#{queue_name}/messages?marker=#{next_marker}",
"rel" => "next"
}]
}
end
response
end
end
end
end
end

View file

@ -1,8 +1,8 @@
module Fog
module Rackspace
class Queues
class Real
class Real
# This operation lists queues for the project. The queues are sorted alphabetically by name.
# @note A request to list queues when you have no queues in your account returns 204, instead of 200, because there was no information to send back.
#
@ -25,6 +25,40 @@ module Fog
)
end
end
class Mock
def list_queues(options={})
limit = options[:limit] || 10
marker = options[:marker]
detailed = options[:detailed] || false
queue_names = data.keys.sort
start_index = marker.nil? ? 0 : queue_names.count { |name| name <= marker }
stop_index = start_index + limit
queue_names = queue_names[start_index..stop_index]
queue_data = queue_names.map do |qname|
{ "href" => "#{PATH_BASE}/#{qname}", "name" => qname }
end
if detailed
queue_data.each { |d| d["metadata"] = data[d["name"]].metadata }
end
response = Excon::Response.new
if data.empty?
response.status = 204
else
response.status = 200
response.body = {
"queues" => queue_data,
"links" => [{ "href" => "#{PATH_BASE}?marker=#{queue_names.last}", "rel" => "next" }]
}
end
response
end
end
end
end
end

View file

@ -1,6 +1,7 @@
module Fog
module Rackspace
class Queues
class Real
# This operation posts the specified message or messages.
@ -20,7 +21,23 @@ module Fog
:path => "queues/#{queue_name}/claims/#{claim_id}"
)
end
end
class Mock
def update_claim(queue_name, claim_id, ttl)
queue = mock_queue!(queue_name)
claim = queue.claim!(claim_id)
claim.touch!
claim.ttl = ttl
response = Excon::Response.new
response.status = 204
response
end
end
end
end
end

View file

@ -0,0 +1,39 @@
require 'fog'
module Fog
module Storage
class Rackspace
class Real
# Extract Archive
#
# @see http://docs.rackspace.com/files/api/v1/cf-devguide/content/Extract_Archive-d1e2338.html
#
# ==== Parameters
# * container<~String> - Name for container, should be < 256 bytes and must not contain '/'
# * data<~String|File> - file to upload
# * archive_format<~String> - "tar", "tar.gz", or "tar.bz2"
# @raise [Fog::Storage::Rackspace::NotFound] - HTTP 404
# @raise [Fog::Storage::Rackspace::BadRequest] - HTTP 400
# @raise [Fog::Storage::Rackspace::InternalServerError] - HTTP 500
# @raise [Fog::Storage::Rackspace::ServiceError]
def extract_archive(container, data, archive_format)
data = Fog::Storage.parse_data(data)
headers = data[:headers]
headers["Content-Type"] = ""
params = { :body => data[:body], :query => {"extract-archive" => archive_format} }
params.merge!(
:expects => 200,
:idempotent => true,
:headers => headers,
:method => 'PUT',
:path => "#{Fog::Rackspace.escape(container.to_s)}"
)
request(params)
end
end
end
end
end

View file

@ -41,6 +41,7 @@ module Fog
request :put_dynamic_obj_manifest
request :put_static_obj_manifest
request :post_set_meta_temp_url_key
request :extract_archive
module Common
def apply_options(options)

View file

@ -1,7 +1,5 @@
Shindo.tests('Fog::Rackspace::Queues | claim', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_queue_#{Time.now.to_i.to_s}",
@ -17,7 +15,7 @@ Shindo.tests('Fog::Rackspace::Queues | claim', ['rackspace']) do
}
begin
model_tests(queue.claims, params, false) do
model_tests(queue.claims, params) do
tests('#messages') do
returns(1) { @instance.messages.length }
returns('body') { @instance.messages.first.body['random'] }

View file

@ -1,7 +1,5 @@
Shindo.tests('Fog::Rackspace::Queues | claims', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_queue_#{Time.now.to_i.to_s}",
@ -16,7 +14,7 @@ Shindo.tests('Fog::Rackspace::Queues | claims', ['rackspace']) do
}
begin
collection_tests(queue.claims, params, false)
collection_tests(queue.claims, params)
tests('creating claims when there are no messages') do

View file

@ -1,7 +1,5 @@
Shindo.tests('Fog::Rackspace::Queues | message', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_instance_#{Time.now.to_i.to_s}",
@ -11,7 +9,7 @@ Shindo.tests('Fog::Rackspace::Queues | message', ['rackspace']) do
:body => { :key => 'value' }
}
begin
model_tests(queue.messages, options, false) do
model_tests(queue.messages, options) do
tests('#href').returns(true) do
!@instance.href.nil?
end

View file

@ -1,7 +1,5 @@
Shindo.tests('Fog::Rackspace::Queues | messages', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue = service.queues.create({
:name => "fog_queue_#{Time.now.to_i.to_s}",
@ -12,7 +10,7 @@ Shindo.tests('Fog::Rackspace::Queues | messages', ['rackspace']) do
:body => "blah"
}
collection_tests(queue.messages, options, false)
collection_tests(queue.messages, options)
queue.destroy
end

View file

@ -1,12 +1,10 @@
Shindo.tests('Fog::Rackspace::Queues | queue', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
options = {
:name => "fog_instance_#{Time.now.to_i.to_s}",
}
model_tests(service.queues, options, false) do
model_tests(service.queues, options) do
tests('#stats').formats(QUEUE_STATS_FORMAT['messages']) do
@instance.stats

View file

@ -1,10 +1,8 @@
Shindo.tests('Fog::Rackspace::Queues | queues', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
options = {
:name => "fog_instance_#{Time.now.to_i.to_s}",
}
collection_tests(service.queues, options, false)
collection_tests(service.queues, options)
end

View file

@ -1,8 +1,5 @@
Shindo.tests('Fog::Rackspace::Queues', ['rackspace']) do
pending if Fog.mocking?
def assert_method(url, method)
@service.instance_variable_set "@rackspace_auth_url", url
returns(method) { @service.send :authentication_method }
@ -25,16 +22,12 @@ Shindo.tests('Fog::Rackspace::Queues', ['rackspace']) do
end
tests('authentication v1') do
pending if Fog.mocking?
raises(Fog::Errors::NotImplemented) do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v1.0'
end
end
tests('authentication v2') do
pending if Fog.mocking?
tests('variables populated').succeeds do
@service = Fog::Rackspace::Queues.new :rackspace_auth_url => 'https://identity.api.rackspacecloud.com/v2.0', :connection_options => { :ssl_verify_peer => true }
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
@ -63,8 +56,6 @@ Shindo.tests('Fog::Rackspace::Queues', ['rackspace']) do
end
tests('default auth') do
pending if Fog.mocking?
tests('no params').succeeds do
#We consistently use DFW as our default but queues doesn't have a DFW default region yet.
# We can enable this test once they have a DFW region (which they will)
@ -83,8 +74,6 @@ Shindo.tests('Fog::Rackspace::Queues', ['rackspace']) do
end
tests('reauthentication') do
pending if Fog.mocking?
@service = Fog::Rackspace::Queues.new
returns(true, "auth token populated") { !@service.send(:auth_token).nil? }
@service.instance_variable_set("@auth_token", "bad_token")
@ -99,8 +88,6 @@ Shindo.tests('Fog::Rackspace::Queues', ['rackspace']) do
end
tests('client_id') do
pending if Fog.mocking?
tests('should generate uuid if a client id is not provided').succeeds do
pending unless Fog::UUID.supported?
service = Fog::Rackspace::Queues.new

View file

@ -1,6 +1,4 @@
Shindo.tests('Fog::Rackspace::Queues | claim_tests', ['rackspace']) do
pending if Fog.mocking?
Shindo.tests('Fog::Rackspace::Queues | claim_tests', ['rackspace']) do
service = Fog::Rackspace::Queues.new

View file

@ -1,7 +1,4 @@
Shindo.tests('Fog::Rackspace::Queues | messages_tests', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
queue_name = 'fog' + Time.now.to_i.to_s
@ -11,10 +8,7 @@ Shindo.tests('Fog::Rackspace::Queues | messages_tests', ['rackspace']) do
service.create_queue(queue_name)
begin
tests('success') do
tests("#list_message(#{client_id}, #{queue_name}, {:echo => true}) => No Content").returns(204) do
service.list_messages(client_id, queue_name, {:echo => true}).status
end

View file

@ -1,11 +1,7 @@
Shindo.tests('Fog::Rackspace::Queues | queue_tests', ['rackspace']) do
pending if Fog.mocking?
service = Fog::Rackspace::Queues.new
tests('success') do
queue_name = 'fog' + Time.now.to_i.to_s
tests("#create_queue(#{queue_name})").succeeds do
@ -38,6 +34,5 @@ Shindo.tests('Fog::Rackspace::Queues | queue_tests', ['rackspace']) do
tests("#get_queue('nonexistentqueue') => Does not exist").raises(Fog::Rackspace::Queues::NotFound) do
service.get_queue('nonexistentqueue')
end
end
end

View file

@ -1,11 +1,3 @@
begin
require 'rspec'
require 'rspec/mocks'
rescue LoadError
require 'spec'
require 'spec/mocks'
end
Shindo.tests("Vcloud::Compute | disk_requests", ['vcloud']) do
@xmlns = {