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
|
||||
when :compute
|
||||
Fog::Compute::Joyent
|
||||
when :analytics
|
||||
Fog::Joyent::Analytics
|
||||
else
|
||||
raise ArgumentError, "Unrecognized service: #{key}"
|
||||
end
|
||||
|
@ -16,6 +18,8 @@ class Joyent < Fog::Bin
|
|||
when :compute
|
||||
Fog::Logger.warning("Joyent[:compute] is not recommended, use Compute[:joyent] for portability")
|
||||
Fog::Compute.new(:provider => 'Joyent')
|
||||
when :analytics
|
||||
Fog::Joyent::Analytics.new
|
||||
else
|
||||
raise ArgumentError, "Unrecognized service: #{key.inspect}"
|
||||
end
|
||||
|
|
|
@ -60,6 +60,12 @@ module Fog
|
|||
end
|
||||
end
|
||||
EOS
|
||||
when :timestamp
|
||||
class_eval <<-EOS, __FILE__, __LINE__
|
||||
def #{name}=(new_#{name})
|
||||
attributes[:#{name}] = Time.at(new_#{name}.to_i)
|
||||
end
|
||||
EOS
|
||||
when :array
|
||||
class_eval <<-EOS, __FILE__, __LINE__
|
||||
def #{name}=(new_#{name})
|
||||
|
|
|
@ -1,2 +1,13 @@
|
|||
require 'fog/joyent/compute'
|
||||
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 Compute
|
||||
class Joyent < Fog::Service
|
||||
|
||||
requires :joyent_username
|
||||
|
||||
recognizes :joyent_password
|
||||
|
@ -13,15 +14,22 @@ module Fog
|
|||
|
||||
recognizes :joyent_keyname
|
||||
recognizes :joyent_keyfile
|
||||
recognizes :joyent_keydata
|
||||
recognizes :joyent_keyphrase
|
||||
recognizes :joyent_version
|
||||
|
||||
secrets :joyent_password, :joyent_keydata, :joyent_keyphrase
|
||||
|
||||
model_path 'fog/joyent/models/compute'
|
||||
request_path 'fog/joyent/requests/compute'
|
||||
|
||||
request :list_datacenters
|
||||
# request :get_datacenter
|
||||
|
||||
# Datacenters
|
||||
collection :datacenters
|
||||
model :datacenter
|
||||
|
||||
# Keys
|
||||
collection :keys
|
||||
model :key
|
||||
|
@ -36,6 +44,8 @@ module Fog
|
|||
model :image
|
||||
request :list_datasets
|
||||
request :get_dataset
|
||||
request :list_images
|
||||
request :get_image
|
||||
|
||||
# Flavors
|
||||
collection :flavors
|
||||
|
@ -102,6 +112,9 @@ module Fog
|
|||
end # Mock
|
||||
|
||||
class Real
|
||||
attr_accessor :joyent_version
|
||||
attr_accessor :joyent_url
|
||||
|
||||
def initialize(options = {})
|
||||
|
||||
@connection_options = options[:connection_options] || {}
|
||||
|
@ -115,24 +128,30 @@ module Fog
|
|||
raise ArgumentError, "options[:joyent_username] required"
|
||||
end
|
||||
|
||||
if options[:joyent_keyname] && options[:joyent_keyfile]
|
||||
if File.exists?(options[:joyent_keyfile])
|
||||
@joyent_keyname = options[:joyent_keyname]
|
||||
@joyent_keyfile = options[:joyent_keyfile]
|
||||
@joyent_keyphrase = options[:joyent_keyphrase]
|
||||
|
||||
@key_manager = Net::SSH::Authentication::KeyManager.new(nil, {
|
||||
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)
|
||||
|
||||
@key_manager.add(@joyent_keyfile)
|
||||
|
||||
@header_method = method(:header_for_signature_auth)
|
||||
else
|
||||
raise ArgumentError, "options[:joyent_keyfile] provided does not exist."
|
||||
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)
|
||||
|
@ -166,6 +185,9 @@ module Fog
|
|||
|
||||
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
|
||||
|
||||
|
|
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 Flavor < Fog::Model
|
||||
|
||||
identity :name
|
||||
identity :id
|
||||
|
||||
attribute :name
|
||||
attribute :memory
|
||||
attribute :swap
|
||||
attribute :disk
|
||||
attribute :default
|
||||
attribute :vcpus
|
||||
attribute :default, :type => :boolean
|
||||
attribute :description
|
||||
attribute :version
|
||||
attribute :group
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,20 @@ module Fog
|
|||
|
||||
attribute :name
|
||||
attribute :os
|
||||
attribute :type
|
||||
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 :default
|
||||
attribute :default, :type => :boolean
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,11 +10,20 @@ module Fog
|
|||
model Fog::Compute::Joyent::Image
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
end
|
||||
|
||||
|
|
|
@ -15,6 +15,9 @@ module Fog
|
|||
attribute :disk
|
||||
attribute :metadata
|
||||
attribute :tags
|
||||
attribute :package
|
||||
attribute :image
|
||||
attribute :primary_ip, :aliases => 'primaryIp'
|
||||
|
||||
attribute :created, :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
|
||||
request(
|
||||
:method => "GET",
|
||||
:path => "/my/datasets"
|
||||
:path => "/my/datasets",
|
||||
:idempotent => true
|
||||
)
|
||||
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(
|
||||
:method => "GET",
|
||||
:path => "/my/keys/#{keyid}",
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,8 @@ module Fog
|
|||
request(
|
||||
:method => "GET",
|
||||
:path => "/my/machines/#{uuid}",
|
||||
:expects => [200, 410]
|
||||
:expects => [200, 410],
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,8 @@ module Fog
|
|||
|
||||
request(
|
||||
:path => "/my/machines/#{machine_id}/metadata",
|
||||
:query => query
|
||||
:query => query,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ module Fog
|
|||
def get_machine_snapshot(machine_id, snapshot_name)
|
||||
request(
|
||||
:path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
|
||||
:method => "GET"
|
||||
:method => "GET",
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,8 @@ module Fog
|
|||
:path => "/my/machines/#{machine_id}/tags/#{tagname}",
|
||||
:method => "GET",
|
||||
:headers => {"Accept" => "text/plain"},
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ module Fog
|
|||
request(
|
||||
:method => "GET",
|
||||
:path => "/my/packages/#{name}",
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ module Fog
|
|||
request(
|
||||
:expects => 200,
|
||||
:method => :'GET',
|
||||
:path => '/my/datacenters'
|
||||
:path => '/my/datacenters',
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end # Real
|
||||
|
|
|
@ -15,7 +15,8 @@ module Fog
|
|||
def list_datasets
|
||||
request(
|
||||
:method => "GET",
|
||||
:path => "/my/datasets"
|
||||
:path => "/my/datasets",
|
||||
:idempotent => true
|
||||
)
|
||||
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(
|
||||
:expects => 200,
|
||||
:method => :'GET',
|
||||
:path => '/my/keys'
|
||||
:path => '/my/keys',
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end # Real
|
||||
|
|
|
@ -5,7 +5,8 @@ module Fog
|
|||
def list_machine_snapshots(machine_id)
|
||||
request(
|
||||
:method => "GET",
|
||||
:path => "/my/machines/#{machine_id}/snapshots"
|
||||
:path => "/my/machines/#{machine_id}/snapshots",
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,7 +7,8 @@ module Fog
|
|||
request(
|
||||
:path => "/my/machines/#{machine_id}/tags",
|
||||
:method => "GET",
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,8 @@ module Fog
|
|||
:path => "/my/machines",
|
||||
:method => "GET",
|
||||
:query => options,
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,8 @@ module Fog
|
|||
:path => "/my/networks",
|
||||
:method => "GET",
|
||||
:query => options,
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,7 +25,8 @@ module Fog
|
|||
request(
|
||||
:path => "/my/packages",
|
||||
:method => "GET",
|
||||
:expects => 200
|
||||
:expects => 200,
|
||||
:idempotent => true
|
||||
)
|
||||
end
|
||||
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
Reference in a new issue