mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
Merge branch 'joyent-analytics' of git://github.com/6fusion/fog into 6fusion-joyent-analytics
Conflicts: lib/fog/joyent.rb
This commit is contained in:
commit
270fc4c0f4
60 changed files with 1189 additions and 35 deletions
|
@ -5,6 +5,8 @@ class Joyent < Fog::Bin
|
||||||
case key
|
case key
|
||||||
when :compute
|
when :compute
|
||||||
Fog::Compute::Joyent
|
Fog::Compute::Joyent
|
||||||
|
when :analytics
|
||||||
|
Fog::Joyent::Analytics
|
||||||
else
|
else
|
||||||
raise ArgumentError, "Unrecognized service: #{key}"
|
raise ArgumentError, "Unrecognized service: #{key}"
|
||||||
end
|
end
|
||||||
|
@ -16,6 +18,8 @@ class Joyent < Fog::Bin
|
||||||
when :compute
|
when :compute
|
||||||
Fog::Logger.warning("Joyent[:compute] is not recommended, use Compute[:joyent] for portability")
|
Fog::Logger.warning("Joyent[:compute] is not recommended, use Compute[:joyent] for portability")
|
||||||
Fog::Compute.new(:provider => 'Joyent')
|
Fog::Compute.new(:provider => 'Joyent')
|
||||||
|
when :analytics
|
||||||
|
Fog::Joyent::Analytics.new
|
||||||
else
|
else
|
||||||
raise ArgumentError, "Unrecognized service: #{key.inspect}"
|
raise ArgumentError, "Unrecognized service: #{key.inspect}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,6 +60,12 @@ module Fog
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
EOS
|
EOS
|
||||||
|
when :timestamp
|
||||||
|
class_eval <<-EOS, __FILE__, __LINE__
|
||||||
|
def #{name}=(new_#{name})
|
||||||
|
attributes[:#{name}] = Time.at(new_#{name}.to_i)
|
||||||
|
end
|
||||||
|
EOS
|
||||||
when :array
|
when :array
|
||||||
class_eval <<-EOS, __FILE__, __LINE__
|
class_eval <<-EOS, __FILE__, __LINE__
|
||||||
def #{name}=(new_#{name})
|
def #{name}=(new_#{name})
|
||||||
|
|
|
@ -1,2 +1,13 @@
|
||||||
require 'fog/joyent/compute'
|
require 'fog/joyent/compute'
|
||||||
require 'fog/joyent/errors'
|
require 'fog/joyent/errors'
|
||||||
|
require 'fog/core'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
extend Fog::Provider
|
||||||
|
|
||||||
|
service(:analytics, 'joyent/analytics', 'Analytics')
|
||||||
|
service(:compute, 'joyent/compute', 'Compute')
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
313
lib/fog/joyent/analytics.rb
Normal file
313
lib/fog/joyent/analytics.rb
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
require 'fog/joyent'
|
||||||
|
require 'fog/joyent/errors'
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics < Fog::Service
|
||||||
|
requires :joyent_username
|
||||||
|
|
||||||
|
recognizes :joyent_password
|
||||||
|
recognizes :joyent_url
|
||||||
|
|
||||||
|
recognizes :joyent_keyname
|
||||||
|
recognizes :joyent_keyfile
|
||||||
|
recognizes :joyent_keydata
|
||||||
|
recognizes :joyent_keyphrase
|
||||||
|
recognizes :joyent_version
|
||||||
|
request_path 'fog/joyent/requests/analytics'
|
||||||
|
|
||||||
|
request :describe_analytics
|
||||||
|
request :list_instrumentations
|
||||||
|
request :get_instrumentation
|
||||||
|
request :create_instrumentation
|
||||||
|
request :delete_instrumentation
|
||||||
|
request :get_instrumentation_value
|
||||||
|
|
||||||
|
model_path 'fog/joyent/models/analytics'
|
||||||
|
|
||||||
|
collection :joyent_modules
|
||||||
|
model :joyent_module
|
||||||
|
|
||||||
|
collection :metrics
|
||||||
|
model :metric
|
||||||
|
|
||||||
|
collection :fields
|
||||||
|
model :field
|
||||||
|
|
||||||
|
collection :types
|
||||||
|
model :type
|
||||||
|
|
||||||
|
collection :transformations
|
||||||
|
model :transformation
|
||||||
|
|
||||||
|
collection :instrumentations
|
||||||
|
model :instrumentation
|
||||||
|
|
||||||
|
model :value
|
||||||
|
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def self.data
|
||||||
|
@data ||= Hash.new do |hash, key|
|
||||||
|
hash[key] =case key
|
||||||
|
when :instrumentation
|
||||||
|
{ 'module' => "cpu",
|
||||||
|
'stat' => "usage",
|
||||||
|
'predicate' => {},
|
||||||
|
'decomposition' => ["zonename"],
|
||||||
|
'value-dimension' => 2,
|
||||||
|
'value-arity' => "discrete-decomposition",
|
||||||
|
'enabled' => true,
|
||||||
|
'retention-time' => 86400,
|
||||||
|
'idle-max' => 86400,
|
||||||
|
'transformations' => [],
|
||||||
|
'nsources' => 3,
|
||||||
|
'granularity' => 30,
|
||||||
|
'persist-data' => false,
|
||||||
|
'crtime' => 1388690982000,
|
||||||
|
'value-scope' => "point",
|
||||||
|
'id' => "63",
|
||||||
|
'uris' =>
|
||||||
|
[{ "uri" => "/#{@joyent_username}/analytics/instrumentations/63/value/raw",
|
||||||
|
"name" => "value_raw" }] }
|
||||||
|
when :values
|
||||||
|
{
|
||||||
|
'value' => { 'zoneid' => 0 },
|
||||||
|
'transformations' => {},
|
||||||
|
'start_time' => Time.now.utc - 600,
|
||||||
|
'duration' => 30,
|
||||||
|
'end_time' => Time.now.utc - 570,
|
||||||
|
'nsources' => 1,
|
||||||
|
'minreporting' => 1,
|
||||||
|
'requested_start_time' => Time.now.utc - 600,
|
||||||
|
'requested_duration' => 30,
|
||||||
|
'requested_end_time' => Time.now.utc - 570
|
||||||
|
}
|
||||||
|
when :describe_analytics
|
||||||
|
{
|
||||||
|
'fields' => {
|
||||||
|
'zonename' => {
|
||||||
|
'label' => 'zone name',
|
||||||
|
'type' => 'string'
|
||||||
|
},
|
||||||
|
'pid' => {
|
||||||
|
'label' => 'process identifier',
|
||||||
|
'type' => 'string'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'modules' => {
|
||||||
|
'cpu' => {
|
||||||
|
'label' => 'CPU'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'transformations' => {
|
||||||
|
'geolocate' => {
|
||||||
|
'label' => 'geolocate IP addresses',
|
||||||
|
'fields' => ['raddr'] }
|
||||||
|
},
|
||||||
|
'metrics' => [{
|
||||||
|
"module" => "cpu",
|
||||||
|
"stat" => "thread_executions",
|
||||||
|
"label" => "thread executions",
|
||||||
|
"interval" => "interval",
|
||||||
|
"fields" => ["hostname", "zonename", "runtime"],
|
||||||
|
"unit" => "operations"
|
||||||
|
}],
|
||||||
|
'types' => {
|
||||||
|
'string' => {
|
||||||
|
'arity' => "discrete",
|
||||||
|
'unit' => ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def data
|
||||||
|
self.class.data
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(options = {})
|
||||||
|
@joyent_username = options[:joyent_username] || Fog.credentials[:joyent_username]
|
||||||
|
@joyent_password = options[:joyent_password] || Fog.credentials[:joyent_password]
|
||||||
|
@joyent_url = 'https://us-sw-1.api.joyentcloud.com'
|
||||||
|
@joyent_version = '~7'
|
||||||
|
end
|
||||||
|
|
||||||
|
def request(opts)
|
||||||
|
raise "Not Implemented"
|
||||||
|
end
|
||||||
|
end # Mock
|
||||||
|
|
||||||
|
class Real
|
||||||
|
def initialize(options = {})
|
||||||
|
@mutex = Mutex.new
|
||||||
|
@connection_options = options[:connection_options] || {}
|
||||||
|
@persistent = options[:persistent] || false
|
||||||
|
|
||||||
|
@joyent_url = options[:joyent_url] || 'https://us-sw-1.api.joyentcloud.com'
|
||||||
|
@joyent_version = options[:joyent_version] || '~7'
|
||||||
|
@joyent_username = options[:joyent_username]
|
||||||
|
|
||||||
|
unless @joyent_username
|
||||||
|
raise ArgumentError, "options[:joyent_username] required"
|
||||||
|
end
|
||||||
|
|
||||||
|
if options[:joyent_keyname]
|
||||||
|
@joyent_keyname = options[:joyent_keyname]
|
||||||
|
@joyent_keyphrase = options[:joyent_keyphrase]
|
||||||
|
@key_manager = Net::SSH::Authentication::KeyManager.new(nil, {
|
||||||
|
:keys_only => true,
|
||||||
|
:passphrase => @joyent_keyphrase
|
||||||
|
})
|
||||||
|
@header_method = method(:header_for_signature_auth)
|
||||||
|
|
||||||
|
if options[:joyent_keyfile]
|
||||||
|
if File.exists?(options[:joyent_keyfile])
|
||||||
|
@joyent_keyfile = options[:joyent_keyfile]
|
||||||
|
@key_manager.add(@joyent_keyfile)
|
||||||
|
else
|
||||||
|
raise ArgumentError, "options[:joyent_keyfile] provided does not exist."
|
||||||
|
end
|
||||||
|
elsif options[:joyent_keydata]
|
||||||
|
if options[:joyent_keydata].to_s.empty?
|
||||||
|
raise ArgumentError, 'options[:joyent_keydata] must not be blank'
|
||||||
|
else
|
||||||
|
@joyent_keydata = options[:joyent_keydata]
|
||||||
|
@key_manager.add_key_data(@joyent_keydata)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsif options[:joyent_password]
|
||||||
|
@joyent_password = options[:joyent_password]
|
||||||
|
@header_method = method(:header_for_basic_auth)
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Must provide either a joyent_password or joyent_keyname and joyent_keyfile pair"
|
||||||
|
end
|
||||||
|
|
||||||
|
@connection = Fog::Connection.new(
|
||||||
|
@joyent_url,
|
||||||
|
@persistent,
|
||||||
|
@connection_options
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def request(opts = {})
|
||||||
|
opts[:headers] = {
|
||||||
|
"X-Api-Version" => @joyent_version,
|
||||||
|
"Content-Type" => "application/json",
|
||||||
|
"Accept" => "application/json"
|
||||||
|
}.merge(opts[:headers] || {}).merge(@header_method.call)
|
||||||
|
|
||||||
|
if opts[:body]
|
||||||
|
opts[:body] = Fog::JSON.encode(opts[:body])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
response = @connection.request(opts)
|
||||||
|
if response.headers["Content-Type"] == "application/json"
|
||||||
|
response.body = json_decode(response.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
response
|
||||||
|
rescue Excon::Errors::HTTPStatusError => e
|
||||||
|
if e.response.headers["Content-Type"] == "application/json"
|
||||||
|
e.response.body = json_decode(e.response.body)
|
||||||
|
end
|
||||||
|
raise_if_error!(e.request, e.response)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def json_decode(body)
|
||||||
|
parsed = Fog::JSON.decode(body)
|
||||||
|
decode_time_attrs(parsed)
|
||||||
|
end
|
||||||
|
|
||||||
|
def header_for_basic_auth
|
||||||
|
{
|
||||||
|
"Authorization" => "Basic #{Base64.encode64("#{@joyent_username}:#{@joyent_password}").delete("\r\n")}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def header_for_signature_auth
|
||||||
|
date = Time.now.utc.httpdate
|
||||||
|
|
||||||
|
# Force KeyManager to load the key(s)
|
||||||
|
@mutex.synchronize do
|
||||||
|
@key_manager.each_identity {}
|
||||||
|
end
|
||||||
|
|
||||||
|
key = @key_manager.known_identities.keys.first
|
||||||
|
|
||||||
|
sig = if key.kind_of? OpenSSL::PKey::RSA
|
||||||
|
@key_manager.sign(key, date)[15..-1]
|
||||||
|
else
|
||||||
|
key = OpenSSL::PKey::DSA.new(File.read(@joyent_keyfile), @joyent_keyphrase)
|
||||||
|
key.sign('sha1', date)
|
||||||
|
end
|
||||||
|
|
||||||
|
key_id = "/#{@joyent_username}/keys/#{@joyent_keyname}"
|
||||||
|
key_type = key.class.to_s.split('::').last.downcase.to_sym
|
||||||
|
|
||||||
|
unless [:rsa, :dsa].include? key_type
|
||||||
|
raise Joyent::Errors::Unauthorized.new('Invalid key type -- only rsa or dsa key is supported')
|
||||||
|
end
|
||||||
|
|
||||||
|
signature = Base64.encode64(sig).delete("\r\n")
|
||||||
|
|
||||||
|
{
|
||||||
|
"Date" => date,
|
||||||
|
"Authorization" => "Signature keyId=\"#{key_id}\",algorithm=\"#{key_type}-sha1\" #{signature}"
|
||||||
|
}
|
||||||
|
rescue Net::SSH::Authentication::KeyManagerError => e
|
||||||
|
raise Joyent::Errors::Unauthorized.new('SSH Signing Error: :#{e.message}', e)
|
||||||
|
end
|
||||||
|
|
||||||
|
def decode_time_attrs(obj)
|
||||||
|
if obj.kind_of?(Hash)
|
||||||
|
obj["created"] = Time.parse(obj["created"]) unless obj["created"].nil? or obj["created"] == ''
|
||||||
|
obj["updated"] = Time.parse(obj["updated"]) unless obj["updated"].nil? or obj["updated"] == ''
|
||||||
|
elsif obj.kind_of?(Array)
|
||||||
|
obj.map do |o|
|
||||||
|
decode_time_attrs(o)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
obj
|
||||||
|
end
|
||||||
|
|
||||||
|
def raise_if_error!(request, response)
|
||||||
|
case response.status
|
||||||
|
when 401 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::Unauthorized.new('Invalid credentials were used', request, response)
|
||||||
|
when 403 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::Forbidden.new('No permissions to the specified resource', request, response)
|
||||||
|
when 404 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::NotFound.new('Requested resource was not found', request, response)
|
||||||
|
when 405 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::MethodNotAllowed.new('Method not supported for the given resource', request, response)
|
||||||
|
when 406 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::NotAcceptable.new('Try sending a different Accept header', request, response)
|
||||||
|
when 409 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::Conflict.new('Most likely invalid or missing parameters', request, response)
|
||||||
|
when 414 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::RequestEntityTooLarge.new('You sent too much data', request, response)
|
||||||
|
when 415 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::UnsupportedMediaType.new('You encoded your request in a format we don\'t understand', request, response)
|
||||||
|
when 420 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::PolicyNotForfilled.new('You are sending too many requests', request, response)
|
||||||
|
when 449 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::RetryWith.new('Invalid API Version requested; try with a different API Version', request, response)
|
||||||
|
when 503 then
|
||||||
|
raise Fog::Compute::Joyent::Errors::ServiceUnavailable.new('Either there\'s no capacity in this datacenter, or we\'re in a maintenance window', request, response)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end # Real
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,7 @@ require 'net/ssh'
|
||||||
module Fog
|
module Fog
|
||||||
module Compute
|
module Compute
|
||||||
class Joyent < Fog::Service
|
class Joyent < Fog::Service
|
||||||
|
|
||||||
requires :joyent_username
|
requires :joyent_username
|
||||||
|
|
||||||
recognizes :joyent_password
|
recognizes :joyent_password
|
||||||
|
@ -13,15 +14,22 @@ module Fog
|
||||||
|
|
||||||
recognizes :joyent_keyname
|
recognizes :joyent_keyname
|
||||||
recognizes :joyent_keyfile
|
recognizes :joyent_keyfile
|
||||||
|
recognizes :joyent_keydata
|
||||||
recognizes :joyent_keyphrase
|
recognizes :joyent_keyphrase
|
||||||
recognizes :joyent_version
|
recognizes :joyent_version
|
||||||
|
|
||||||
|
secrets :joyent_password, :joyent_keydata, :joyent_keyphrase
|
||||||
|
|
||||||
model_path 'fog/joyent/models/compute'
|
model_path 'fog/joyent/models/compute'
|
||||||
request_path 'fog/joyent/requests/compute'
|
request_path 'fog/joyent/requests/compute'
|
||||||
|
|
||||||
request :list_datacenters
|
request :list_datacenters
|
||||||
# request :get_datacenter
|
# request :get_datacenter
|
||||||
|
|
||||||
|
# Datacenters
|
||||||
|
collection :datacenters
|
||||||
|
model :datacenter
|
||||||
|
|
||||||
# Keys
|
# Keys
|
||||||
collection :keys
|
collection :keys
|
||||||
model :key
|
model :key
|
||||||
|
@ -36,6 +44,8 @@ module Fog
|
||||||
model :image
|
model :image
|
||||||
request :list_datasets
|
request :list_datasets
|
||||||
request :get_dataset
|
request :get_dataset
|
||||||
|
request :list_images
|
||||||
|
request :get_image
|
||||||
|
|
||||||
# Flavors
|
# Flavors
|
||||||
collection :flavors
|
collection :flavors
|
||||||
|
@ -102,6 +112,9 @@ module Fog
|
||||||
end # Mock
|
end # Mock
|
||||||
|
|
||||||
class Real
|
class Real
|
||||||
|
attr_accessor :joyent_version
|
||||||
|
attr_accessor :joyent_url
|
||||||
|
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
|
|
||||||
@connection_options = options[:connection_options] || {}
|
@connection_options = options[:connection_options] || {}
|
||||||
|
@ -115,24 +128,30 @@ module Fog
|
||||||
raise ArgumentError, "options[:joyent_username] required"
|
raise ArgumentError, "options[:joyent_username] required"
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:joyent_keyname] && options[:joyent_keyfile]
|
if options[:joyent_keyname]
|
||||||
if File.exists?(options[:joyent_keyfile])
|
@joyent_keyname = options[:joyent_keyname]
|
||||||
@joyent_keyname = options[:joyent_keyname]
|
@joyent_keyphrase = options[:joyent_keyphrase]
|
||||||
@joyent_keyfile = options[:joyent_keyfile]
|
@key_manager = Net::SSH::Authentication::KeyManager.new(nil, {
|
||||||
@joyent_keyphrase = options[:joyent_keyphrase]
|
|
||||||
|
|
||||||
@key_manager = Net::SSH::Authentication::KeyManager.new(nil, {
|
|
||||||
:keys_only => true,
|
:keys_only => true,
|
||||||
:passphrase => @joyent_keyphrase
|
:passphrase => @joyent_keyphrase
|
||||||
})
|
})
|
||||||
|
@header_method = method(:header_for_signature_auth)
|
||||||
|
|
||||||
@key_manager.add(@joyent_keyfile)
|
if options[:joyent_keyfile]
|
||||||
|
if File.exists?(options[:joyent_keyfile])
|
||||||
@header_method = method(:header_for_signature_auth)
|
@joyent_keyfile = options[:joyent_keyfile]
|
||||||
else
|
@key_manager.add(@joyent_keyfile)
|
||||||
raise ArgumentError, "options[:joyent_keyfile] provided does not exist."
|
else
|
||||||
|
raise ArgumentError, "options[:joyent_keyfile] provided does not exist."
|
||||||
|
end
|
||||||
|
elsif options[:joyent_keydata]
|
||||||
|
if options[:joyent_keydata].to_s.empty?
|
||||||
|
raise ArgumentError, 'options[:joyent_keydata] must not be blank'
|
||||||
|
else
|
||||||
|
@joyent_keydata = options[:joyent_keydata]
|
||||||
|
@key_manager.add_key_data(@joyent_keydata)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elsif options[:joyent_password]
|
elsif options[:joyent_password]
|
||||||
@joyent_password = options[:joyent_password]
|
@joyent_password = options[:joyent_password]
|
||||||
@header_method = method(:header_for_basic_auth)
|
@header_method = method(:header_for_basic_auth)
|
||||||
|
@ -166,6 +185,9 @@ module Fog
|
||||||
|
|
||||||
response
|
response
|
||||||
rescue Excon::Errors::HTTPStatusError => e
|
rescue Excon::Errors::HTTPStatusError => e
|
||||||
|
if e.response.headers["Content-Type"] == "application/json"
|
||||||
|
e.response.body = json_decode(e.response.body)
|
||||||
|
end
|
||||||
raise_if_error!(e.request, e.response)
|
raise_if_error!(e.request, e.response)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
14
lib/fog/joyent/models/analytics/field.rb
Normal file
14
lib/fog/joyent/models/analytics/field.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Field < Fog::Model
|
||||||
|
attribute :name
|
||||||
|
attribute :label
|
||||||
|
attribute :type
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/models/analytics/fields.rb
Normal file
26
lib/fog/joyent/models/analytics/fields.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'fog/joyent/models/analytics/field'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Fields < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Joyent::Analytics::Field
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.describe_analytics.body['fields']
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Joyent returns an odd data structure like this:
|
||||||
|
# { 'apache' => {'label' => 'Apache'}}
|
||||||
|
# where the key is the name of the module
|
||||||
|
def new(attributes = {})
|
||||||
|
name, other_attributes = attributes
|
||||||
|
super(other_attributes.merge('name' => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
83
lib/fog/joyent/models/analytics/instrumentation.rb
Normal file
83
lib/fog/joyent/models/analytics/instrumentation.rb
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Instrumentation < Fog::Model
|
||||||
|
identity :id
|
||||||
|
attribute :joyent_module, :aliases => 'module'
|
||||||
|
attribute :stat
|
||||||
|
attribute :predicate
|
||||||
|
attribute :decomposition, :type => :array
|
||||||
|
attribute :value_dimension, :aliases => 'value-dimension', :type => :integer
|
||||||
|
attribute :value_arity, :aliases => 'value-arity'
|
||||||
|
attribute :retention_time, :aliases => 'retention-time', :type => :integer
|
||||||
|
attribute :granularity, :type => :integer
|
||||||
|
attribute :idle_max, :aliases => 'idle-max', :type => :integer
|
||||||
|
attribute :transformations, :type => :array
|
||||||
|
attribute :persist_data, :aliases => 'persist-data', :type => :boolean
|
||||||
|
attribute :crtime
|
||||||
|
attribute :value_scope, :aliases => 'value-scope'
|
||||||
|
attribute :uris, :type => :array
|
||||||
|
|
||||||
|
def initialize(attributes={})
|
||||||
|
self.decomposition = []
|
||||||
|
self.value_arity = 'scalar'
|
||||||
|
self.retention_time = 600
|
||||||
|
self.idle_max = 3600
|
||||||
|
self.persist_data = false
|
||||||
|
self.value_scope = 'interval'
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def crtime=(new_crtime)
|
||||||
|
attributes[:crtime] = Time.at(new_crtime.to_i / 1000)
|
||||||
|
end
|
||||||
|
|
||||||
|
def decomposition=(value)
|
||||||
|
attributes[:decomposition] = value
|
||||||
|
self.value_dimension = self.decomposition.size + 1
|
||||||
|
self.decomposition
|
||||||
|
end
|
||||||
|
|
||||||
|
def save
|
||||||
|
requires :joyent_module, :stat
|
||||||
|
munged_attributes = self.attributes.dup
|
||||||
|
remap_attributes(munged_attributes, {
|
||||||
|
:joyent_module => 'module',
|
||||||
|
:value_dimension => 'value-dimension',
|
||||||
|
:value_arity => 'value-arity',
|
||||||
|
:retention_time => 'retention-time',
|
||||||
|
:idle_max => 'idle-max',
|
||||||
|
:persist_data => 'persist-data',
|
||||||
|
:value_scope => 'value-scope'
|
||||||
|
})
|
||||||
|
|
||||||
|
data = service.create_instrumentation(munged_attributes)
|
||||||
|
merge_attributes(data.body)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
requires :id
|
||||||
|
service.delete_instrumentation(self.identity)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get a set of datapoints back for an instrumentation
|
||||||
|
# use start_time and ndatapoints so we can get back a range of datapoints
|
||||||
|
# the interval between datapoints should correspond to the granularity of the instrumentation
|
||||||
|
# @param [Time] start_time
|
||||||
|
# @param [Integer] ndatapoints
|
||||||
|
def values(start_time, ndatapoints)
|
||||||
|
requires :id, :granularity
|
||||||
|
data = service.get_instrumentation_value(self.uris.find {|uri| uri['name'] == 'value_raw'}['uri'], start_time, ndatapoints, self.granularity).body
|
||||||
|
data.map do |datum|
|
||||||
|
Fog::Joyent::Analytics::Value.new(datum)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/models/analytics/instrumentations.rb
Normal file
26
lib/fog/joyent/models/analytics/instrumentations.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'fog/joyent/models/analytics/instrumentation'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Instrumentations < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Joyent::Analytics::Instrumentation
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.list_instrumentations.body
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(id)
|
||||||
|
data = service.get_instrumentation(id).body
|
||||||
|
new(data)
|
||||||
|
rescue Fog::Compute::Joyent::Errors::NotFound
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
lib/fog/joyent/models/analytics/joyent_module.rb
Normal file
15
lib/fog/joyent/models/analytics/joyent_module.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
|
||||||
|
# named 'JoyentModule' to avoid name conflicts with ruby's 'Module'
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class JoyentModule < Fog::Model
|
||||||
|
attribute :name
|
||||||
|
attribute :label
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/models/analytics/joyent_modules.rb
Normal file
26
lib/fog/joyent/models/analytics/joyent_modules.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'fog/joyent/models/analytics/joyent_module'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class JoyentModules < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Joyent::Analytics::JoyentModule
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.describe_analytics.body['modules']
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Joyent returns an odd data structure like this:
|
||||||
|
# { 'apache' => {'label' => 'Apache'}}
|
||||||
|
# where the key is the name of the module
|
||||||
|
def new(attributes = {})
|
||||||
|
name, other_attributes = attributes
|
||||||
|
super(other_attributes.merge('name' => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
18
lib/fog/joyent/models/analytics/metric.rb
Normal file
18
lib/fog/joyent/models/analytics/metric.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Metric < Fog::Model
|
||||||
|
attribute :module
|
||||||
|
attribute :stat
|
||||||
|
attribute :label
|
||||||
|
attribute :interval
|
||||||
|
attribute :fields
|
||||||
|
attribute :unit
|
||||||
|
attribute :type
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
18
lib/fog/joyent/models/analytics/metrics.rb
Normal file
18
lib/fog/joyent/models/analytics/metrics.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
require 'fog/joyent/models/analytics/metric'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Metrics < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Joyent::Analytics::Metric
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.describe_analytics.body['metrics']
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
13
lib/fog/joyent/models/analytics/transformation.rb
Normal file
13
lib/fog/joyent/models/analytics/transformation.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Transformation < Fog::Model
|
||||||
|
attribute :name
|
||||||
|
attribute :label
|
||||||
|
attribute :fields
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/models/analytics/transformations.rb
Normal file
26
lib/fog/joyent/models/analytics/transformations.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'fog/joyent/models/analytics/transformation'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Transformations < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Joyent::Analytics::Transformation
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.describe_analytics.body['transformations']
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Joyent returns an odd data structure like this:
|
||||||
|
# { 'apache' => {'label' => 'Apache'}}
|
||||||
|
# where the key is the name of the module
|
||||||
|
def new(attributes = {})
|
||||||
|
name, other_attributes = attributes
|
||||||
|
super(other_attributes.merge('name' => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
lib/fog/joyent/models/analytics/type.rb
Normal file
16
lib/fog/joyent/models/analytics/type.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Type < Fog::Model
|
||||||
|
attribute :name
|
||||||
|
attribute :arity
|
||||||
|
attribute :unit
|
||||||
|
attribute :abbr
|
||||||
|
attribute :base
|
||||||
|
attribute :power
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/models/analytics/types.rb
Normal file
26
lib/fog/joyent/models/analytics/types.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
require 'fog/joyent/models/analytics/type'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Types < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Joyent::Analytics::Type
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.describe_analytics.body['types']
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Joyent returns an odd data structure like this:
|
||||||
|
# { 'apache' => {'label' => 'Apache'}}
|
||||||
|
# where the key is the name of the module
|
||||||
|
def new(attributes = {})
|
||||||
|
name, other_attributes = attributes
|
||||||
|
super(other_attributes.merge('name' => name))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/fog/joyent/models/analytics/value.rb
Normal file
20
lib/fog/joyent/models/analytics/value.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
require 'fog/core/model'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Value < Fog::Model
|
||||||
|
attribute :value
|
||||||
|
attribute :transformations
|
||||||
|
attribute :start_time, :type => :timestamp
|
||||||
|
attribute :duration
|
||||||
|
attribute :end_time, :type => :timestamp
|
||||||
|
attribute :nsources
|
||||||
|
attribute :minreporting
|
||||||
|
attribute :requested_start_time, :type => :timestamp
|
||||||
|
attribute :requested_duration
|
||||||
|
attribute :requested_end_time, :type => :timestamp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
lib/fog/joyent/models/compute/datacenter.rb
Normal file
12
lib/fog/joyent/models/compute/datacenter.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Joyent
|
||||||
|
class Datacenter < Fog::Model
|
||||||
|
|
||||||
|
identity :name
|
||||||
|
|
||||||
|
attribute :url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
25
lib/fog/joyent/models/compute/datacenters.rb
Normal file
25
lib/fog/joyent/models/compute/datacenters.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require 'fog/core/collection'
|
||||||
|
require 'fog/joyent/models/compute/datacenter'
|
||||||
|
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
|
||||||
|
class Joyent
|
||||||
|
class Datacenters < Fog::Collection
|
||||||
|
|
||||||
|
model Fog::Compute::Joyent::Datacenter
|
||||||
|
|
||||||
|
def all
|
||||||
|
data = service.list_datacenters().body.map {|k,v| {:name => k, :url => v}}
|
||||||
|
load(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(id)
|
||||||
|
all[id]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end # Joyent
|
||||||
|
|
||||||
|
end # Compute
|
||||||
|
end # Fog
|
|
@ -3,13 +3,17 @@ module Fog
|
||||||
class Joyent
|
class Joyent
|
||||||
class Flavor < Fog::Model
|
class Flavor < Fog::Model
|
||||||
|
|
||||||
identity :name
|
identity :id
|
||||||
|
|
||||||
attribute :name
|
attribute :name
|
||||||
attribute :memory
|
attribute :memory
|
||||||
attribute :swap
|
attribute :swap
|
||||||
attribute :disk
|
attribute :disk
|
||||||
attribute :default
|
attribute :vcpus
|
||||||
|
attribute :default, :type => :boolean
|
||||||
|
attribute :description
|
||||||
|
attribute :version
|
||||||
|
attribute :group
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,10 +7,20 @@ module Fog
|
||||||
|
|
||||||
attribute :name
|
attribute :name
|
||||||
attribute :os
|
attribute :os
|
||||||
attribute :type
|
|
||||||
attribute :version
|
attribute :version
|
||||||
|
attribute :type
|
||||||
|
attribute :description
|
||||||
|
attribute :requirements
|
||||||
|
attribute :homepage
|
||||||
|
attribute :published_at, :type => :time
|
||||||
|
attribute :public, :type => :boolean
|
||||||
|
attribute :owner
|
||||||
|
attribute :state
|
||||||
|
attribute :tags
|
||||||
|
attribute :eula
|
||||||
|
attribute :acl
|
||||||
attribute :created, :type => :time
|
attribute :created, :type => :time
|
||||||
attribute :default
|
attribute :default, :type => :boolean
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,11 +10,20 @@ module Fog
|
||||||
model Fog::Compute::Joyent::Image
|
model Fog::Compute::Joyent::Image
|
||||||
|
|
||||||
def all
|
def all
|
||||||
load(service.list_datasets().body)
|
# the API call for getting images changed from 6.5 to 7.0. Joyent seems to still support the old url, but no idea for how long
|
||||||
|
if service.joyent_version.gsub(/[^0-9.]/,'').to_f < 7.0
|
||||||
|
load(service.list_datasets.body)
|
||||||
|
else
|
||||||
|
load(service.list_images.body)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(id)
|
def get(id)
|
||||||
data = service.get_dataset(id).body
|
data = if service.joyent_version.gsub(/[^0-9.]/,'').to_f < 7.0
|
||||||
|
service.get_dataset(id).body
|
||||||
|
else
|
||||||
|
service.get_image(id).body
|
||||||
|
end
|
||||||
new(data)
|
new(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@ module Fog
|
||||||
attribute :disk
|
attribute :disk
|
||||||
attribute :metadata
|
attribute :metadata
|
||||||
attribute :tags
|
attribute :tags
|
||||||
|
attribute :package
|
||||||
|
attribute :image
|
||||||
|
attribute :primary_ip, :aliases => 'primaryIp'
|
||||||
|
|
||||||
attribute :created, :type => :time
|
attribute :created, :type => :time
|
||||||
attribute :updated, :type => :time
|
attribute :updated, :type => :time
|
||||||
|
|
25
lib/fog/joyent/requests/analytics/create_instrumentation.rb
Normal file
25
lib/fog/joyent/requests/analytics/create_instrumentation.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Real
|
||||||
|
def create_instrumentation(values = {})
|
||||||
|
request(
|
||||||
|
:path => "#{@joyent_username}/analytics/instrumentations",
|
||||||
|
:method => "POST",
|
||||||
|
:body => values,
|
||||||
|
:expects => [200,201]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def create_instrumentation(values = {})
|
||||||
|
response = Excon::Response.new
|
||||||
|
response.status = 201
|
||||||
|
response.body = self.data[:instrumentation]
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
lib/fog/joyent/requests/analytics/delete_instrumentation.rb
Normal file
23
lib/fog/joyent/requests/analytics/delete_instrumentation.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Real
|
||||||
|
def delete_instrumentation(id)
|
||||||
|
request(
|
||||||
|
:path => "#{@joyent_username}/analytics/instrumentations/#{id}",
|
||||||
|
:method => "DELETE",
|
||||||
|
:expects => 204
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def delete_instrumentation(id)
|
||||||
|
response = Excon::Response.new
|
||||||
|
response.status = 204
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/requests/analytics/describe_analytics.rb
Normal file
26
lib/fog/joyent/requests/analytics/describe_analytics.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Real
|
||||||
|
def describe_analytics(force = false)
|
||||||
|
@describe_analytics = nil if force
|
||||||
|
@describe_analytics ||= request(
|
||||||
|
:path => "#{@joyent_username}/analytics",
|
||||||
|
:method => "GET",
|
||||||
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def describe_analytics(force = false)
|
||||||
|
response = Excon::Response.new
|
||||||
|
response.status = 200
|
||||||
|
response.body = self.data[:describe_analytics]
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/fog/joyent/requests/analytics/get_instrumentation.rb
Normal file
26
lib/fog/joyent/requests/analytics/get_instrumentation.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Real
|
||||||
|
def get_instrumentation(id)
|
||||||
|
request(
|
||||||
|
:path => "#{@joyent_username}/analytics/instrumentations/#{id}",
|
||||||
|
:method => "GET",
|
||||||
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def get_instrumentation(id)
|
||||||
|
raise Fog::Compute::Joyent::Errors::NotFound.new('not found') unless id == self.data[:instrumentation]['id']
|
||||||
|
response = Excon::Response.new
|
||||||
|
response.status = 200
|
||||||
|
response.body = self.data[:instrumentation]
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,30 @@
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Real
|
||||||
|
def get_instrumentation_value(url, requested_start_time, ndatapoints, duration)
|
||||||
|
request(
|
||||||
|
:path => url,
|
||||||
|
:method => 'GET',
|
||||||
|
:expects => 200,
|
||||||
|
:idempotent => true,
|
||||||
|
:query => {
|
||||||
|
:ndatapoints => ndatapoints,
|
||||||
|
:start_time => requested_start_time.to_i,
|
||||||
|
:duration => duration
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def get_instrumentation_value(url, requested_start_time, ndatapoints, duration)
|
||||||
|
response = Excon::Response.new
|
||||||
|
response.status = 200
|
||||||
|
response.body = [self.data[:values]]
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
25
lib/fog/joyent/requests/analytics/list_instrumentations.rb
Normal file
25
lib/fog/joyent/requests/analytics/list_instrumentations.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module Fog
|
||||||
|
module Joyent
|
||||||
|
class Analytics
|
||||||
|
class Real
|
||||||
|
def list_instrumentations
|
||||||
|
request(
|
||||||
|
:path => "#{@joyent_username}/analytics/instrumentations",
|
||||||
|
:method => "GET",
|
||||||
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def list_instrumentations
|
||||||
|
response = Excon::Response.new
|
||||||
|
response.status = 200
|
||||||
|
response.body = [self.data[:instrumentation]]
|
||||||
|
response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -18,7 +18,8 @@ module Fog
|
||||||
def get_dataset
|
def get_dataset
|
||||||
request(
|
request(
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:path => "/my/datasets"
|
:path => "/my/datasets",
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
30
lib/fog/joyent/requests/compute/get_image.rb
Normal file
30
lib/fog/joyent/requests/compute/get_image.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Joyent
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def get_image(id)
|
||||||
|
if ds = self.data[:datasets][id]
|
||||||
|
res = Excon::Response.new
|
||||||
|
res.status = 200
|
||||||
|
res.body = ds
|
||||||
|
else
|
||||||
|
raise Excon::Errors::NotFound
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Real
|
||||||
|
def get_image(id)
|
||||||
|
request(
|
||||||
|
:method => "GET",
|
||||||
|
:path => "/#{@joyent_username}/images/#{id}",
|
||||||
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,7 +20,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:path => "/my/keys/#{keyid}",
|
:path => "/my/keys/#{keyid}",
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:path => "/my/machines/#{uuid}",
|
:path => "/my/machines/#{uuid}",
|
||||||
:expects => [200, 410]
|
:expects => [200, 410],
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,7 +15,8 @@ module Fog
|
||||||
|
|
||||||
request(
|
request(
|
||||||
:path => "/my/machines/#{machine_id}/metadata",
|
:path => "/my/machines/#{machine_id}/metadata",
|
||||||
:query => query
|
:query => query,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ module Fog
|
||||||
def get_machine_snapshot(machine_id, snapshot_name)
|
def get_machine_snapshot(machine_id, snapshot_name)
|
||||||
request(
|
request(
|
||||||
:path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
|
:path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
|
||||||
:method => "GET"
|
:method => "GET",
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,8 @@ module Fog
|
||||||
:path => "/my/machines/#{machine_id}/tags/#{tagname}",
|
:path => "/my/machines/#{machine_id}/tags/#{tagname}",
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:headers => {"Accept" => "text/plain"},
|
:headers => {"Accept" => "text/plain"},
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:path => "/my/packages/#{name}",
|
:path => "/my/packages/#{name}",
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:expects => 200,
|
:expects => 200,
|
||||||
:method => :'GET',
|
:method => :'GET',
|
||||||
:path => '/my/datacenters'
|
:path => '/my/datacenters',
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end # Real
|
end # Real
|
||||||
|
|
|
@ -15,7 +15,8 @@ module Fog
|
||||||
def list_datasets
|
def list_datasets
|
||||||
request(
|
request(
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:path => "/my/datasets"
|
:path => "/my/datasets",
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
26
lib/fog/joyent/requests/compute/list_images.rb
Normal file
26
lib/fog/joyent/requests/compute/list_images.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module Fog
|
||||||
|
module Compute
|
||||||
|
class Joyent
|
||||||
|
|
||||||
|
class Mock
|
||||||
|
def list_images
|
||||||
|
res = Excon::Response.new
|
||||||
|
res.status = 200
|
||||||
|
res.body = self.data[:datasets].values
|
||||||
|
res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Real
|
||||||
|
def list_images
|
||||||
|
request(
|
||||||
|
:method => "GET",
|
||||||
|
:path => "/#{@joyent_username}/images",
|
||||||
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,7 +15,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:expects => 200,
|
:expects => 200,
|
||||||
:method => :'GET',
|
:method => :'GET',
|
||||||
:path => '/my/keys'
|
:path => '/my/keys',
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end # Real
|
end # Real
|
||||||
|
|
|
@ -5,7 +5,8 @@ module Fog
|
||||||
def list_machine_snapshots(machine_id)
|
def list_machine_snapshots(machine_id)
|
||||||
request(
|
request(
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:path => "/my/machines/#{machine_id}/snapshots"
|
:path => "/my/machines/#{machine_id}/snapshots",
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:path => "/my/machines/#{machine_id}/tags",
|
:path => "/my/machines/#{machine_id}/tags",
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,8 @@ module Fog
|
||||||
:path => "/my/machines",
|
:path => "/my/machines",
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:query => options,
|
:query => options,
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,8 @@ module Fog
|
||||||
:path => "/my/networks",
|
:path => "/my/networks",
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:query => options,
|
:query => options,
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,8 @@ module Fog
|
||||||
request(
|
request(
|
||||||
:path => "/my/packages",
|
:path => "/my/packages",
|
||||||
:method => "GET",
|
:method => "GET",
|
||||||
:expects => 200
|
:expects => 200,
|
||||||
|
:idempotent => true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end # Real
|
end # Real
|
||||||
|
|
10
tests/joyent/models/analytics/field_tests.rb
Normal file
10
tests/joyent/models/analytics/field_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | field", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@field = @analytics.fields.first
|
||||||
|
|
||||||
|
tests('read only') do
|
||||||
|
returns(false, 'should not save') { @field.respond_to?(:save)}
|
||||||
|
returns(false, 'should not allow creating a new one') { @field.respond_to?(:create)}
|
||||||
|
returns(false, 'should not allow destroying') { @field.respond_to?(:destroy)}
|
||||||
|
end
|
||||||
|
end
|
13
tests/joyent/models/analytics/fields_tests.rb
Normal file
13
tests/joyent/models/analytics/fields_tests.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | fields", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@fields = @analytics.fields
|
||||||
|
|
||||||
|
tests('#all').succeeds do
|
||||||
|
@fields.all
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#new').succeeds do
|
||||||
|
@fields.new(['apache', { 'label' => 'Apache', 'type' => 'string' }])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
13
tests/joyent/models/analytics/instrumentation_tests.rb
Normal file
13
tests/joyent/models/analytics/instrumentation_tests.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | instrumentation", %w{joyent }) do
|
||||||
|
model_tests(Fog::Joyent[:analytics].instrumentations, {:joyent_module => 'cpu', :stat => 'usage'}, true)
|
||||||
|
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@instrumentation = @analytics.instrumentations.first
|
||||||
|
|
||||||
|
tests('#values') do
|
||||||
|
@values = @instrumentation.values(Time.now.utc.to_i - 600, 5)
|
||||||
|
|
||||||
|
returns(Array) { @values.class }
|
||||||
|
returns(Fog::Joyent::Analytics::Value) { @values.first.class }
|
||||||
|
end
|
||||||
|
end
|
3
tests/joyent/models/analytics/instrumentations_tests.rb
Normal file
3
tests/joyent/models/analytics/instrumentations_tests.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | instrumentations", %w{joyent}) do
|
||||||
|
collection_tests(Fog::Joyent[:analytics].instrumentations, {:joyent_module => 'cpu', :stat => 'usage'}, true)
|
||||||
|
end
|
10
tests/joyent/models/analytics/joyent_module_tests.rb
Normal file
10
tests/joyent/models/analytics/joyent_module_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | joyent_module", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@joyent_module = @analytics.joyent_modules.first
|
||||||
|
|
||||||
|
tests('read only') do
|
||||||
|
returns(false, 'should not save') { @joyent_module.respond_to?(:save)}
|
||||||
|
returns(false, 'should not allow creating a new one') { @joyent_module.respond_to?(:create)}
|
||||||
|
returns(false, 'should not allow destroying') { @joyent_module.respond_to?(:destroy)}
|
||||||
|
end
|
||||||
|
end
|
13
tests/joyent/models/analytics/joyent_modules_tests.rb
Normal file
13
tests/joyent/models/analytics/joyent_modules_tests.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | joyent_modules", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@joyent_modules = @analytics.joyent_modules
|
||||||
|
|
||||||
|
tests('#all').succeeds do
|
||||||
|
@joyent_modules.all
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#new').succeeds do
|
||||||
|
@joyent_modules.new(['cpu', { 'label' => 'CPU' }])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
10
tests/joyent/models/analytics/metric_tests.rb
Normal file
10
tests/joyent/models/analytics/metric_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | metric", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@metric = @analytics.metrics.first
|
||||||
|
|
||||||
|
tests('read only') do
|
||||||
|
returns(false, 'should not save') { @metric.respond_to?(:save)}
|
||||||
|
returns(false, 'should not allow creating a new one') { @metric.respond_to?(:create)}
|
||||||
|
returns(false, 'should not allow destroying') { @metric.respond_to?(:destroy)}
|
||||||
|
end
|
||||||
|
end
|
20
tests/joyent/models/analytics/metrics_tests.rb
Normal file
20
tests/joyent/models/analytics/metrics_tests.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | metrics", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@metrics = @analytics.metrics
|
||||||
|
|
||||||
|
tests('#all').succeeds do
|
||||||
|
@metrics.all
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#new').succeeds do
|
||||||
|
@metrics.new({
|
||||||
|
"module" => "cpu",
|
||||||
|
"stat" => "thread_executions",
|
||||||
|
"label" => "thread executions",
|
||||||
|
"interval" => "interval",
|
||||||
|
"fields" => ["hostname", "zonename", "runtime"],
|
||||||
|
"unit" => "operations"
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
10
tests/joyent/models/analytics/transformation_tests.rb
Normal file
10
tests/joyent/models/analytics/transformation_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | transformation", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@transformation = @analytics.transformations.first
|
||||||
|
|
||||||
|
tests('read only') do
|
||||||
|
returns(false, 'should not save') { @transformation.respond_to?(:save)}
|
||||||
|
returns(false, 'should not allow creating a new one') { @transformation.respond_to?(:create)}
|
||||||
|
returns(false, 'should not allow destroying') { @transformation.respond_to?(:destroy)}
|
||||||
|
end
|
||||||
|
end
|
13
tests/joyent/models/analytics/transformations_tests.rb
Normal file
13
tests/joyent/models/analytics/transformations_tests.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | transformations", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@transformations = @analytics.transformations
|
||||||
|
|
||||||
|
tests('#all').succeeds do
|
||||||
|
@transformations.all
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#new').succeeds do
|
||||||
|
@transformations.new(['geolocate', { 'label' => 'geolocate IP addresses', "fields" => ["raddr"] }])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
10
tests/joyent/models/analytics/type_tests.rb
Normal file
10
tests/joyent/models/analytics/type_tests.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | type", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@type = @analytics.types.first
|
||||||
|
|
||||||
|
tests('read only') do
|
||||||
|
returns(false, 'should not save') { @type.respond_to?(:save)}
|
||||||
|
returns(false, 'should not allow creating a new one') { @type.respond_to?(:create)}
|
||||||
|
returns(false, 'should not allow destroying') { @type.respond_to?(:destroy)}
|
||||||
|
end
|
||||||
|
end
|
13
tests/joyent/models/analytics/types_tests.rb
Normal file
13
tests/joyent/models/analytics/types_tests.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | types", %w{joyent}) do
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
@types = @analytics.types
|
||||||
|
|
||||||
|
tests('#all').succeeds do
|
||||||
|
@types.all
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#new').succeeds do
|
||||||
|
@types.new(['string', {'arity' => 'discrete', 'unit' => ''}])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
44
tests/joyent/requests/analytics/instrumentation_tests.rb
Normal file
44
tests/joyent/requests/analytics/instrumentation_tests.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
Shindo.tests("Fog::Joyent[:analytics] | instrumentation requests", %w{joyent}) do
|
||||||
|
|
||||||
|
@analytics = Fog::Joyent[:analytics]
|
||||||
|
|
||||||
|
@instrumentation_schema = {
|
||||||
|
'id' => String,
|
||||||
|
'module' => String,
|
||||||
|
'stat' => String,
|
||||||
|
'predicate' => Hash,
|
||||||
|
'decomposition' => [String],
|
||||||
|
'value-dimension' => Integer,
|
||||||
|
'value-arity' => String,
|
||||||
|
'retention-time' => Integer,
|
||||||
|
'granularity' => Integer,
|
||||||
|
'idle-max' => Integer,
|
||||||
|
'transformations' => [String],
|
||||||
|
'persist-data' => Fog::Boolean,
|
||||||
|
'crtime' => Integer,
|
||||||
|
'value-scope' => String,
|
||||||
|
'uris' => [
|
||||||
|
{
|
||||||
|
'uri' => String,
|
||||||
|
'name' => String
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
tests('#create_instrumentation').data_matches_schema(@instrumentation_schema) do
|
||||||
|
@analytics.create_instrumentation.body
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#list_instrumentations') do
|
||||||
|
data_matches_schema(@instrumentation_schema) do
|
||||||
|
@analytics.list_instrumentations.body.first
|
||||||
|
end
|
||||||
|
|
||||||
|
returns(Array) { @analytics.list_instrumentations.body.class }
|
||||||
|
end
|
||||||
|
|
||||||
|
tests('#delete_instrumentation') do
|
||||||
|
returns(204) { @analytics.delete_instrumentation(Fog::Joyent::Analytics::Mock.data[:instrumentation]['id']).status }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue