class Fog::Compute::Joyent::Real

Attributes

joyent_url[RW]
joyent_version[RW]

Public Class Methods

new(options = {}) click to toggle source
# File lib/fog/joyent/compute.rb, line 115
def initialize(options = {})
  @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] || '~6.5'
  @joyent_username = options[:joyent_username]

  unless @joyent_username
    raise ArgumentError, "options[:joyent_username] required"
  end

  if options[:joyent_keyname]
    begin
      require "net/ssh"
    rescue LoadError
      Fog::Logger.warning("'net/ssh' missing, please install and try again.")
      exit(1)
    end
    @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

add_machine_tags(machine_id, tags={}) click to toggle source

us-west-1.api.joyentcloud.com/docs#AddMachineTags

# File lib/fog/joyent/requests/compute/add_machine_tags.rb, line 6
def add_machine_tags(machine_id, tags={})
  raise ArgumentError, "tags must be a Hash of tags" unless tags.is_a?(Hash)

  request(
    :path => "/my/machines/#{machine_id}/tags",
    :method => "POST",
    :body => tags,
    :expects => 200
  )
end
create_key(params={}) click to toggle source

Creates a new SSH Key

Parameters

  • name<~String> - Name to assign to this key

  • key<~String> - OpenSSH formatted public key

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • 'name'<~String> - Name for this key

      • 'key'<~String> - OpenSSH formatted public key

# File lib/fog/joyent/requests/compute/create_key.rb, line 40
def create_key(params={})
  raise ArgumentError, "error creating key: [name] is required" unless params[:name]
  raise ArgumentError, "error creating key: [key] is required" unless params[:key]

  request(
    :method => "POST",
    :path => "/my/keys",
    :body => { "name" => params[:name], "key" => params[:key] },
    :expects => 201
  )
end
create_machine(params = {}) click to toggle source
# File lib/fog/joyent/requests/compute/create_machine.rb, line 5
def create_machine(params = {})
  request(
    :method => "POST",
    :path => "/my/machines",
    :body => params,
    :expects => [200, 201, 202]
  )
end
create_machine_snapshot(machine_id, snapshot_name) click to toggle source
# File lib/fog/joyent/requests/compute/create_machine_snapshot.rb, line 5
def create_machine_snapshot(machine_id, snapshot_name)
  request(
    :method => "POST",
    :path => "/my/machines/#{machine_id}/snapshots",
    :body => {"name" => snapshot_name },
    :expects => [201]
  )
end
delete_all_machine_metadata(machine_id) click to toggle source

us-west-1.api.joyentcloud.com/docs#DeleteMachineMetadata

# File lib/fog/joyent/requests/compute/delete_all_machine_metadata.rb, line 6
def delete_all_machine_metadata(machine_id)
  request(
    :method => "DELETE",
    :path => "/my/machines/#{machine_id}/metadata",
    :expects => 204
  )
end
delete_all_machine_tags(machine_id) click to toggle source
# File lib/fog/joyent/requests/compute/delete_all_machine_tags.rb, line 5
def delete_all_machine_tags(machine_id)
  request(
    :path => "/my/machines/#{machine_id}/tags",
    :method => "DELETE",
    :expects => 204
  )
end
delete_key(name) click to toggle source
# File lib/fog/joyent/requests/compute/delete_key.rb, line 17
def delete_key(name)
  request(
    :method => "DELETE",
    :path => "/my/keys/#{name}",
    :expects => 204
  )
end
delete_machine(machine_id) click to toggle source
# File lib/fog/joyent/requests/compute/delete_machine.rb, line 5
def delete_machine(machine_id)
  request(
    :path => "/my/machines/#{machine_id}",
    :method => "DELETE",
    :expects => [200, 204, 410]
  )
end
delete_machine_metadata(machine_id, key) click to toggle source

us-west-1.api.joyentcloud.com/docs#DeleteAllMachineMetadata

# File lib/fog/joyent/requests/compute/delete_machine_metadata.rb, line 6
def delete_machine_metadata(machine_id, key)
  request(
    :method => "DELETE",
    :path => "/my/machines/#{machine_id}/metadata/#{key}",
    :expects => [200, 204]
  )
end
delete_machine_snapshot(machine_id, snapshot) click to toggle source
# File lib/fog/joyent/requests/compute/delete_machine_snapshot.rb, line 5
def delete_machine_snapshot(machine_id, snapshot)
  request(
    :method => "DELETE",
    :path => "/my/machines/#{machine_id}/snapshots/#{snapshot}",
    :expects => [200, 204]
  )
end
delete_machine_tag(machine_id, tagname) click to toggle source
# File lib/fog/joyent/requests/compute/delete_machine_tag.rb, line 5
def delete_machine_tag(machine_id, tagname)
  request(
    :path => "/my/machines/#{machine_id}/tags/#{tagname}",
    :method => "DELETE",
    :expects => 204
  )
end
get_dataset() click to toggle source
# File lib/fog/joyent/requests/compute/get_dataset.rb, line 17
def get_dataset
  request(
    :method => "GET",
    :path => "/my/datasets",
    :idempotent => true
  )
end
get_image(id) click to toggle source
# File lib/fog/joyent/requests/compute/get_image.rb, line 17
def get_image(id)
  request(
      :method => "GET",
      :path => "/#{@joyent_username}/images/#{id}",
      :expects => 200,
      :idempotent => true
  )
end
get_key(keyid) click to toggle source
# File lib/fog/joyent/requests/compute/get_key.rb, line 18
def get_key(keyid)
  request(
    :method => "GET",
    :path => "/my/keys/#{keyid}",
    :expects => 200,
    :idempotent => true
  )
end
get_machine(uuid) click to toggle source
# File lib/fog/joyent/requests/compute/get_machine.rb, line 18
def get_machine(uuid)
  request(
    :method => "GET",
    :path => "/my/machines/#{uuid}",
    :expects => [200, 410],
    :idempotent => true
  )
end
get_machine_metadata(machine_id, options = {}) click to toggle source
# File lib/fog/joyent/requests/compute/get_machine_metadata.rb, line 5
def get_machine_metadata(machine_id, options = {})
  query = {}
  if options[:credentials]
    if options[:credentials].is_a?(Boolean)
      query[:credentials] = options[:credentials]
    else
      raise ArgumentError, "options[:credentials] must be a Boolean or nil"
    end
  end

  request(
    :path => "/my/machines/#{machine_id}/metadata",
    :query => query,
    :idempotent => true
  )
end
get_machine_snapshot(machine_id, snapshot_name) click to toggle source
# File lib/fog/joyent/requests/compute/get_machine_snapshot.rb, line 5
def get_machine_snapshot(machine_id, snapshot_name)
  request(
    :path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
    :method => "GET",
    :idempotent => true
  )
end
get_machine_tag(machine_id, tagname) click to toggle source

us-west-1.api.joyentcloud.com/docs#GetMachineTag

# File lib/fog/joyent/requests/compute/get_machine_tag.rb, line 6
def get_machine_tag(machine_id, tagname)
  request(
    :path => "/my/machines/#{machine_id}/tags/#{tagname}",
    :method => "GET",
    :headers => {"Accept" => "text/plain"},
    :expects => 200,
    :idempotent => true
  )
end
get_package(name) click to toggle source
# File lib/fog/joyent/requests/compute/get_package.rb, line 20
def get_package(name)
  name = URI.escape(name)
  request(
    :method => "GET",
    :path => "/my/packages/#{name}",
    :expects => 200,
    :idempotent => true
  )
end
list_datacenters() click to toggle source
# File lib/fog/joyent/requests/compute/list_datacenters.rb, line 5
def list_datacenters
  request(
    :expects => 200,
    :method => :'GET',
    :path => '/my/datacenters',
    :idempotent => true
  )
end
list_datasets() click to toggle source
# File lib/fog/joyent/requests/compute/list_datasets.rb, line 14
def list_datasets
  request(
    :method => "GET",
    :path => "/my/datasets",
    :idempotent => true
  )
end
list_images() click to toggle source
# File lib/fog/joyent/requests/compute/list_images.rb, line 14
def list_images
  request(
      :method => "GET",
      :path => "/#{@joyent_username}/images",
      :expects => 200,
      :idempotent => true
  )
end
list_keys() click to toggle source
# File lib/fog/joyent/requests/compute/list_keys.rb, line 14
def list_keys
  request(
    :expects => 200,
    :method => :'GET',
    :path => '/my/keys',
    :idempotent => true
  )
end
list_machine_snapshots(machine_id) click to toggle source
# File lib/fog/joyent/requests/compute/list_machine_snapshots.rb, line 5
def list_machine_snapshots(machine_id)
  request(
    :method => "GET",
    :path => "/my/machines/#{machine_id}/snapshots",
    :idempotent => true
  )
end
list_machine_tags(machine_id) click to toggle source

us-west-1.api.joyentcloud.com/docs#ListMachineTags

# File lib/fog/joyent/requests/compute/list_machine_tags.rb, line 6
def list_machine_tags(machine_id)
  request(
    :path => "/my/machines/#{machine_id}/tags",
    :method => "GET",
    :expects => 200,
    :idempotent => true
  )
end
list_machines(options={}) click to toggle source
# File lib/fog/joyent/requests/compute/list_machines.rb, line 14
def list_machines(options={})
  request(
    :path => "/my/machines",
    :method => "GET",
    :query => options,
    :expects => 200,
    :idempotent => true
  )
end
list_networks(options={}) click to toggle source
# File lib/fog/joyent/requests/compute/list_networks.rb, line 14
def list_networks(options={})
  request(
    :path => "/my/networks",
    :method => "GET",
    :query => options,
    :expects => 200,
    :idempotent => true
  )
end
list_packages() click to toggle source

Lists all the packages available to the authenticated user

Returns

Exon::Response<Array>

  • name<~String> The “friendly name for this package

  • memory<~Number> How much memory will by available (in Mb)

  • disk<~Number> How much disk space will be available (in Gb)

  • swap<~Number> How much swap memory will be available (in Mb)

  • default<~Boolean> Whether this is the default package in this datacenter“

# File lib/fog/joyent/requests/compute/list_packages.rb, line 23
def list_packages
  request(
    :path => "/my/packages",
    :method => "GET",
    :expects => 200,
    :idempotent => true
  )
end
reboot_machine(id) click to toggle source
# File lib/fog/joyent/requests/compute/reboot_machine.rb, line 5
def reboot_machine(id)
  request(
    :method => "POST",
    :query => {"action" => "reboot"},
    :path => "/my/machines/#{id}"
  )
end
request(opts = {}) click to toggle source
# File lib/fog/joyent/compute.rb, line 171
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
resize_machine(id, package) click to toggle source
# File lib/fog/joyent/requests/compute/resize_machine.rb, line 5
def resize_machine(id, package)
  request(
    :method => "POST",
    :path => "/my/machines/#{id}",
    :query => {"action" => "resize", "package" => package},
    :expects => [202]
  )
end
start_machine(id) click to toggle source
# File lib/fog/joyent/requests/compute/start_machine.rb, line 5
def start_machine(id)
  request(
    :method => "POST",
    :path => "/my/machines/#{id}",
    :query => {"action" => "start"},
    :expects => 202
  )
end
start_machine_from_snapshot(machine_id, snapshot_name) click to toggle source
# File lib/fog/joyent/requests/compute/start_machine_from_snapshot.rb, line 5
def start_machine_from_snapshot(machine_id, snapshot_name)
  request(
    :method => "POST",
    :path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
    :expects => 202
  )
end
stop_machine(uuid) click to toggle source
# File lib/fog/joyent/requests/compute/stop_machine.rb, line 5
def stop_machine(uuid)
  request(
    :method => "POST",
    :path => "/my/machines/#{uuid}",
    :query => {"action" => "stop"},
    :expects => 202
  )
end
update_machine_metadata(machine_id, metadata) click to toggle source
# File lib/fog/joyent/requests/compute/update_machine_metadata.rb, line 5
def update_machine_metadata(machine_id, metadata)
  request(
    :method => "POST",
    :path => "/my/machines/#{machine_id}/metadata",
    :body => metadata
  )
end

Private Instance Methods

decode_time_attrs(obj) click to toggle source
# File lib/fog/joyent/compute.rb, line 240
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/compute.rb, line 202
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/compute.rb, line 208
def header_for_signature_auth
  date = Time.now.utc.httpdate

  # Force KeyManager to load the key(s)
  @key_manager.each_identity {}

  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/compute.rb, line 197
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/compute.rb, line 253
def raise_if_error!(request, response)
  case response.status
  when 400 then
    raise Joyent::Errors::BadRequest.new('Bad Request', request, response)
  when 401 then
    raise Joyent::Errors::Unauthorized.new('Invalid credentials were used', request, response)
  when 403 then
    raise Joyent::Errors::Forbidden.new('No permissions to the specified resource', request, response)
  when 404 then
    raise Joyent::Errors::NotFound.new('Requested resource was not found', request, response)
  when 405 then
    raise Joyent::Errors::MethodNotAllowed.new('Method not supported for the given resource', request, response)
  when 406 then
    raise Joyent::Errors::NotAcceptable.new('Try sending a different Accept header', request, response)
  when 409 then
    raise Joyent::Errors::Conflict.new('Most likely invalid or missing parameters', request, response)
  when 414 then
    raise Joyent::Errors::RequestEntityTooLarge.new('You sent too much data', request, response)
  when 415 then
    raise Joyent::Errors::UnsupportedMediaType.new('You encoded your request in a format we don\t understand', request, response)
  when 420 then
    raise Joyent::Errors::PolicyNotForfilled.new('You are sending too many requests', request, response)
  when 449 then
    raise Joyent::Errors::RetryWith.new('Invalid API Version requested; try with a different API Version', request, response)
  when 503 then
    raise Joyent::Errors::ServiceUnavailable.new('Either there\s no capacity in this datacenter, or we\re in a maintenance window', request, response)
  end
end