class Fog::Joyent::Analytics::Real

Public Class Methods

new(options = {}) click to toggle source
# File lib/fog/joyent/analytics.rb, line 146
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.exist?(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::XML::Connection.new(
      @joyent_url,
      @persistent,
      @connection_options
  )
end

Public Instance Methods

create_instrumentation(values = {}) click to toggle source
# File lib/fog/joyent/requests/analytics/create_instrumentation.rb, line 5
def create_instrumentation(values = {})
  request(
      :path => "#{@joyent_username}/analytics/instrumentations",
      :method => "POST",
      :body => values,
      :expects => [200,201]
  )
end
delete_instrumentation(id) click to toggle source
# File lib/fog/joyent/requests/analytics/delete_instrumentation.rb, line 5
def delete_instrumentation(id)
  request(
      :path => "#{@joyent_username}/analytics/instrumentations/#{id}",
      :method => "DELETE",
      :expects => 204
  )
end
describe_analytics(force = false) click to toggle source
# File lib/fog/joyent/requests/analytics/describe_analytics.rb, line 5
def describe_analytics(force = false)
  @describe_analytics = nil if force
  @describe_analytics ||= request(
      :path => "#{@joyent_username}/analytics",
      :method => "GET",
      :expects => 200,
      :idempotent => true
  )
end
get_instrumentation(id) click to toggle source
# File lib/fog/joyent/requests/analytics/get_instrumentation.rb, line 5
def get_instrumentation(id)
  request(
      :path => "#{@joyent_username}/analytics/instrumentations/#{id}",
      :method => "GET",
      :expects => 200,
      :idempotent => true
  )
end
get_instrumentation_value(url, requested_start_time, ndatapoints, duration) click to toggle source
# File lib/fog/joyent/requests/analytics/get_instrumentation_value.rb, line 5
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
list_instrumentations() click to toggle source
# File lib/fog/joyent/requests/analytics/list_instrumentations.rb, line 5
def list_instrumentations
  request(
      :path => "#{@joyent_username}/analytics/instrumentations",
      :method => "GET",
      :expects => 200,
      :idempotent => true
  )
end
request(opts = {}) click to toggle source
# File lib/fog/joyent/analytics.rb, line 197
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 Instance Methods

decode_time_attrs(obj) click to toggle source
# File lib/fog/joyent/analytics.rb, line 268
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
header_for_basic_auth() click to toggle source
# File lib/fog/joyent/analytics.rb, line 228
def header_for_basic_auth
  {
      "Authorization" => "Basic #{Base64.encode64("#{@joyent_username}:#{@joyent_password}").delete("\r\n")}"
  }
end
header_for_signature_auth() click to toggle source
# File lib/fog/joyent/analytics.rb, line 234
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
json_decode(body) click to toggle source
# File lib/fog/joyent/analytics.rb, line 223
def json_decode(body)
  parsed = Fog::JSON.decode(body)
  decode_time_attrs(parsed)
end
raise_if_error!(request, response) click to toggle source
# File lib/fog/joyent/analytics.rb, line 281
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