1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

GH-690 Joyent Cloud Provider

Squashed from fog/joyent
This commit is contained in:
Kevin Chan 2012-02-10 23:10:49 +08:00 committed by geemus
parent 9926b99a6f
commit e403854446
54 changed files with 1464 additions and 1 deletions

View file

@ -64,6 +64,7 @@ require 'fog/bin/ecloud'
require 'fog/bin/glesys'
require 'fog/bin/go_grid'
require 'fog/bin/google'
require 'fog/bin/joyent'
require 'fog/bin/libvirt'
require 'fog/bin/linode'
require 'fog/bin/local'

31
lib/fog/bin/joyent.rb Normal file
View file

@ -0,0 +1,31 @@
class Joyent < Fog::Bin
class << self
def class_for(key)
case key
when :compute
Fog::Compute::Joyent
else
raise ArgumentError, "Unrecognized service: #{key}"
end
end
def [](service)
@@connections ||= Hash.new do |hash, key|
hash[key] = case key
when :compute
Fog::Logger.warning("Joyent[:compute] is not recommended, use Compute[:joyent] for portability")
Fog::Compute.new(:provider => 'Joyent')
else
raise ArgumentError, "Unrecognized service: #{key.inspect}"
end
end
@@connections[service]
end
def services
Fog::Joyent.services
end
end
end

View file

@ -32,6 +32,9 @@ module Fog
when :gogrid
require 'fog/go_grid/compute'
Fog::Compute::GoGrid.new(attributes)
when :joyent
require 'fog/joyent/compute'
Fog::Compute::Joyent.new(attributes)
when :libvirt
require 'fog/libvirt/compute'
Fog::Compute::Libvirt.new(attributes)

8
lib/fog/joyent.rb Normal file
View file

@ -0,0 +1,8 @@
module Fog
module Joyent
extend Fog::Provider
service(:compute, 'joyent/compute', 'Compute')
end
end

177
lib/fog/joyent/compute.rb Normal file
View file

@ -0,0 +1,177 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'brightbox'))
require 'fog/compute'
require 'multi_json'
module Fog
module Compute
class Joyent < Fog::Service
requires :cloudapi_username
recognizes :cloudapi_password
recognizes :cloudapi_url
recognizes :cloudapi_keyname
recognizes :cloudapi_keyfile
model_path 'fog/joyent/models/compute'
request_path 'fog/joyent/requests/compute'
# request :list_datacenters
# request :get_datacenter
# Keys
collection :keys
model :key
request :list_keys
request :get_key
request :create_key
request :delete_key
# Images
collection :images
model :image
request :list_datasets
request :get_dataset
# Flavors
collection :flavors
model :flavor
request :list_packages
request :get_package
# Servers
collection :servers
model :server
request :list_machines
request :get_machine
request :create_machine
request :start_machine
request :stop_machine
request :reboot_machine
request :resize_machine
request :delete_machine
# Snapshots
collection :snapshots
model :snapshot
request :create_machine_snapshot
request :start_machine_from_snapshot
request :list_machine_snapshots
request :get_machine_snapshot
request :delete_machine_snapshot
request :update_machine_metadata
request :get_machine_metadata
request :delete_machine_metadata
request :delete_all_machine_metadata
# MachineTags
request :add_machine_tags
request :list_machine_tags
request :get_machine_tag
request :delete_machine_tag
request :delete_all_machine_tags
class Mock
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {}
end
end
def data
self.class.data
end
def initialize(options = {})
@cloudapi_username = options[:cloudapi_username] || Fog.credentials[:cloudapi_username]
@cloudapi_password = options[:cloudapi_password] || Fog.credentials[:cloudapi_password]
end
def request(opts)
raise "Not Implemented"
end
end # Mock
class Real
def initialize(options = {})
@connection_options = options[:connection_options] || {}
@persistent = options[:persistent] || false
@cloudapi_url = options[:cloudapi_url] || 'https://us-sw-1.api.joyentcloud.com'
@cloudapi_version = options[:cloudapi_version] || '~6.5'
@cloudapi_username = options[:cloudapi_username]
unless @cloudapi_username
raise ArgumentError, "options[:cloudapi_username] required"
end
if options[:cloudapi_keyname] && options[:cloudapi_keyfile]
if File.exists?(options[:cloudapi_keyfile])
@cloudapi_keyname = options[:cloudapi_keyname]
@cloudapi_key = File.read(options[:cloudapi_keyfile])
@rsa = OpenSSL::PKey::RSA.new(@cloudapi_key)
@header_method = method(:header_for_signature)
else
raise ArgumentError, "options[:cloudapi_keyfile] provided does not exist."
end
elsif options[:cloudapi_password]
@cloudapi_password = options[:cloudapi_password]
@header_method = method(:header_for_basic)
else
raise ArgumentError, "Must provide either a cloudapi_password or cloudapi_keyname and cloudapi_keyfile pair"
end
@connection = Fog::Connection.new(
@cloudapi_url,
@persistent,
@connection_options
)
end
def request(request_options = {})
(request_options[:headers] ||= {}).merge!({
"X-Api-Version" => @cloudapi_version,
"Content-Type" => "application/json",
"Accept" => "application/json"
}).merge!(@header_method.call)
if request_options[:body]
request_options[:body] = MultiJson.encode(request_options[:body])
end
response = @connection.request(request_options)
if response.headers["Content-Type"] == "application/json"
response.body = MultiJson.decode(response.body)
end
response
end
private
def header_for_basic
{
"Authorization" => "Basic #{Base64.encode64("#{@cloudapi_username}:#{@cloudapi_password}").delete("\r\n")}"
}
end
def header_for_signature
date = Time.now.utc.httpdate
signature = Base64.encode64(@rsa.sign("sha256", date)).delete("\r\n")
key_id = "/#{@cloudapi_username}/keys/#{@cloudapi_keyname}"
{
"Date" => date,
"Authorization" => "Signature keyId=\"#{key_id}\",algorithm=\"rsa-sha256\" #{signature}"
}
end
end # Real
end
end
end

View file

@ -0,0 +1,17 @@
module Fog
module Compute
class Joyent
class Flavor < Fog::Model
identity :name
attribute :name
attribute :memory
attribute :swap
attribute :disk
attribute :default
end
end
end
end

View file

@ -0,0 +1,25 @@
require 'fog/core/collection'
require 'fog/joyent/models/compute/flavor'
module Fog
module Compute
class Joyent
class Flavors < Fog::Collection
model Fog::Compute::Joyent::Flavor
def all
load(connection.list_packages().body)
end
def get(id)
data = connection.get_package(id).body
new(data)
end
end
end # Joyent
end # Compute
end # Fog

View file

@ -0,0 +1,18 @@
module Fog
module Compute
class Joyent
class Image < Fog::Model
identity :id
attribute :name
attribute :os
attribute :type
attribute :version
attribute :created, :type => :time
attribute :default
end
end
end
end

View file

@ -0,0 +1,25 @@
require 'fog/core/collection'
require 'fog/joyent/models/compute/image'
module Fog
module Compute
class Joyent
class Images < Fog::Collection
model Fog::Compute::Joyent::Image
def all
load(connection.list_datasets().body)
end
def get(id)
data = connection.get_dataset(id).body
new(data)
end
end # Images
end # Joyent
end # Compute
end # Fog

View file

@ -0,0 +1,19 @@
module Fog
module Compute
class Joyent
class Key < Fog::Model
identity :name
attribute :name
attribute :key
attribute :created, :type => :time
def destroy
requires :name
self.connection.delete_key(name)
end
end
end
end
end

View file

@ -0,0 +1,34 @@
require 'fog/joyent/models/compute/key'
module Fog
module Compute
class Joyent
class Keys < Fog::Collection
model Fog::Compute::Joyent::Key
def all
data = connection.list_keys.body
load(data)
end
def get(keyname)
data = connection.get_key(keyname).body
if data
new(data)
else
nil
end
end
def create(params = {})
raise ArgumentError, "Key name required" unless params.key?(:name)
raise ArgumentError, "Key body required" unless params.key?(:body)
self.connection.create_key(params)
end
end
end
end
end

View file

@ -0,0 +1,117 @@
require 'fog/compute/models/server'
module Fog
module Compute
class Joyent
class Server < Fog::Compute::Server
identity :id
attribute :name
attribute :state
attribute :type
attribute :dataset
attribute :ips
attribute :memory
attribute :ips
attribute :disk
attribute :metadata
attribute :created, :type => :time
attribute :updated, :type => :time
def ready?
self.state == 'running'
end
def stopped?
requires :id
self.state == 'stopped'
end
def destroy
requires :id
self.connection.delete_machine(id)
true
end
def start
requires :id
self.connection.start_machine(id)
self.wait_for { ready? }
true
end
def stop
requires :id
self.connection.stop_machine(id)
self.wait_for { stopped? }
true
end
def resize(flavor)
requires :id
self.connection.resize(id, flavor)
true
end
def reboot
requires :id
self.connection.reboot_machine(id)
true
end
def snapshots
requires :id
self.connection.snapshots.all(id)
end
def update_metadata(data = {})
requires :id
self.connection.update_machine_metadata(self.id, data)
self.reload
true
end
def delete_metadata(keyname)
raise ArgumentError, "Must provide a key name to delete" if keyname.nil? || keyname.empty?
requires :id
self.connection.delete_machine_metadata(self.id, keyname)
true
end
def delete_all_metadata
requires :id
self.connection.delete_all_machine_metadata(self.id)
true
end
def tags
requires :id
self.connection.list_machine_tags(id).body
end
def add_tags(tags_hash = {})
requires :id
self.connection.add_machine_tags(self.id, tags_hash).body
end
def delete_tag(tagname)
requires :id
raise ArgumentError, "Must provide a tag name to delete" if tagname.nil? || tagname.empty?
self.connection.delete_machine_tag(self.id, tagname)
true
end
def delete_all_tags
requires :id
self.connection.delete_all_machine_tags(self.id)
true
end
end
end
end
end

View file

@ -0,0 +1,35 @@
require 'fog/core/collection'
require 'fog/joyent/models/compute/server'
module Fog
module Compute
class Joyent
class Servers < Fog::Collection
model Fog::Compute::Joyent::Server
def all
load(self.connection.list_machines().body)
end
def create(params = {})
data = self.connection.create_machine(params).body
server = new(data)
server.wait_for { ready? }
server
end
def bootstrap
# XXX TOXO
end
def get(machine_id)
data = self.connection.get_machine(machine_id).body
new(data)
end
end
end # Joyent
end # Compute
end # Fog

View file

@ -0,0 +1,45 @@
module Fog
module Compute
class Joyent
class Snapshot < Fog::Model
identity :name
attribute :name
attribute :state
attribute :machine_id
attribute :created, :type => :time
attribute :updated, :type => :time
def reload
requires :name
requires :machine_id
self.connection.snapshots.get(self.machine_id, self.name)
end
def start
requires :name
requires :machine_id
self.connection.start_machine_from_snapshot(self.machine_id, self.name)
true
end
def destroy
requires :name
requires :machine_id
self.connection.delete_machine_snapshot(self.machine_id, self.name)
true
end
def machine
requires :machine_id
self.connection.servers.get(self.machine_id)
end
end
end
end
end

View file

@ -0,0 +1,37 @@
require 'fog/joyent/models/compute/snapshot'
module Fog
module Compute
class Joyent
class Snapshots < Fog::Collection
model Fog::Compute::Joyent::Snapshot
def create(machine_id, snapshot_name)
data = self.connection.create_machine_snapshot(machine_id, snapshot_name).body
data['machine_id'] = machine_id
new(data)
end
def all(machine_id)
data = self.connection.list_machine_snapshots(machine_id).body.map do |m|
m["machine_id"] = machine_id
m
end
load(data)
end
def get(machine_id, snapshot_name)
data = self.connection.get_machine_snapshot(machine_id, snapshot_name).body
if data
data["machine_id"] = machine_id
new(data)
else
nil
end
end
end
end
end
end

View file

@ -0,0 +1,20 @@
module Fog
module Compute
class Joyent
class Real
# https://us-west-1.api.joyentcloud.com/docs#AddMachineTags
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
end
end
end
end

View file

@ -0,0 +1,54 @@
module Fog
module Compute
class Joyent
class Mock
#
# https://us-west-1.api.joyentcloud.com/docs#CreateKey
#
def create_key(params)
name = params[:name]
key = params[:key]
record = {
"name" => name,
"key" => key,
"created" => Time.now.utc
}
self.data[:keys][name] = record
response = Excon::Response.new
response.status = 201
response.body = record
response
end
end # Mock
class Real
# 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
#
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], "body" => params[:body] },
:expects => 201
)
end
end
end
end
end

View file

@ -0,0 +1,16 @@
module Fog
module Compute
class Joyent
class Real
def create_machine(params = {})
request(
:method => "POST",
:path => "/my/machines",
:body => params,
:expects => [200, 201, 202]
)
end
end
end
end
end

View file

@ -0,0 +1,18 @@
module Fog
module Compute
class Joyent
class Real
def create_machine_snapshot(machine_id, snapshot_name)
request(
:method => "POST",
:path => "/my/machines/#{machine_id}/snapshots",
:body => {"name" => snapshot_name },
:expects => [201]
)
end
end
end
end
end

View file

@ -0,0 +1,16 @@
module Fog
module Compute
class Joyent
class Real
# https://us-west-1.api.joyentcloud.com/docs#DeleteMachineMetadata
def delete_all_machine_metadata(machine_id)
request(
:method => "DELETE",
:path => "/my/machines/#{machine_id}/metadata",
:expects => 204
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Compute
class Joyent
class Real
def delete_all_machine_tags(machine_id)
request(
:path => "/my/machines/#{machine_id}/tags",
:method => "DELETE",
:expects => 204
)
end
end
end
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Compute
class Joyent
class Mock
def delete_key(keyname)
if self.data[:keys].delete(keyname)
response = Excon::Response.new
response.status = 200
response
else
raise Excon::Errors::NotFound, "Not Found"
end
end
end
class Real
def delete_key(keyname)
request(
:method => "DELETE",
:path => "/my/keys/#{name}",
:expects => 200
)
end
end # Real
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Compute
class Joyent
class Real
def delete_machine(machine_id)
request(
:path => "/my/machines/#{machine_id}",
:method => "DELETE",
:expects => [200, 204]
)
end
end
end
end
end

View file

@ -0,0 +1,18 @@
module Fog
module Compute
class Joyent
class Real
# https://us-west-1.api.joyentcloud.com/docs#DeleteAllMachineMetadata
def delete_machine_metadata(machine_id, key)
request(
:method => "DELETE",
:path => "/my/machines/#{machine_id}/metadata/#{key}",
:expects => [200, 204]
)
end
end
end
end
end

View file

@ -0,0 +1,21 @@
module Fog
module Compute
class Joyent
class Real
def delete_machine_snapshot(machine_id, snapshot)
request(
:method => "DELETE",
:path => "/my/machines/#{machine_id}/snapshots/#{snapshot}",
:expects => [200, 204]
)
end
end
class Mock
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Compute
class Joyent
class Real
def delete_machine_tag(machine_id, tagname)
request(
:path => "/my/machines/#{machine_id}/tags/#{tagname}",
:method => "DELETE",
:expects => 204
)
end
end
end
end
end

View file

@ -0,0 +1,28 @@
module Fog
module Compute
class Joyent
class Mock
def get_dataset(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_dataset
request(
:method => "GET",
:path => "/my/datasets"
)
end
end
end
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Compute
class Joyent
class Mock
def get_key(keyid)
if key = self.data[:keys][keyid]
response = Excon::Response.new
response.status = 200
response.body = key
response
else
raise Excon::Errors::NotFound
end
end
end
class Real
def get_key(keyid)
request(
:method => "GET",
:path => "/my/keys/#{keyid}",
:expects => 200
)
end
end
end
end
end

View file

@ -0,0 +1,27 @@
module Fog
module Compute
class Joyent
class Mock
def get_machine(uuid)
if machine = self.data[:machines][uuid]
res = Excon::Response.new
res.status = 200
res.body = machine
else
raise Excon::Errors::NotFound, "Not Found"
end
end
end
class Real
def get_machine(uuid)
request(
:method => "GET",
:path => "/my/machines/#{uuid}"
)
end
end
end
end
end

View file

@ -0,0 +1,25 @@
module Fog
module Compute
class Joyent
class Real
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
)
end
end
end
end
end

View file

@ -0,0 +1,14 @@
module Fog
module Compute
class Joyent
class Real
def get_machine_snapshot(machine_id, snapshot_name)
request(
:path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
:method => "GET"
)
end
end
end
end
end

View file

@ -0,0 +1,19 @@
module Fog
module Compute
class Joyent
class Real
# https://us-west-1.api.joyentcloud.com/docs#GetMachineTag
def get_machine_tag(machine_id, tagname)
request(
:path => "/my/machines/#{machine_id}/tags/#{tagname}",
:method => "GET",
:headers => {"Accept" => "text/plain"},
:expects => 200
)
end
end
end
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Compute
class Joyent
class Mock
def get_package(name)
if pkg = self.data[:packages][name]
response = Excon::Response.new
response.body = pkg
response.status = 200
response
else
raise Excon::Errors::NotFound
end
end
end
class Real
def get_package(name)
request(
:method => "GET",
:path => "/my/packages/#{name}"
)
end
end
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Compute
class Joyent
class Mock
def list_datasets
res = Excon::Response.new
res.status = 200
res.body = self.data[:datasets].values
res
end
end
class Real
def list_datasets
request(
:method => "GET",
:path => "/my/datasets"
)
end
end
end
end
end

View file

@ -0,0 +1,25 @@
module Fog
module Compute
class Joyent
class Mock
def list_keys
response = Excon::Response.new
response.status = 200
response.body = self.data[:keys].values
response
end
end
class Real
def list_keys
request(
:expects => 200,
:method => :'GET',
:path => '/my/keys'
)
end
end # Real
end
end
end

View file

@ -0,0 +1,14 @@
module Fog
module Compute
class Joyent
class Real
def list_machine_snapshots(machine_id)
request(
:method => "GET",
:path => "/my/machines/#{machine_id}/snapshots"
)
end
end
end
end
end

View file

@ -0,0 +1,20 @@
module Fog
module Compute
class Joyent
class Real
# https://us-west-1.api.joyentcloud.com/docs#ListMachineTags
def list_machine_tags(machine_id)
request(
:path => "/my/machines/#{machine_id}/tags",
:method => "GET",
:expects => 200
)
end
end
class Mock
end
end
end
end

View file

@ -0,0 +1,25 @@
module Fog
module Compute
class Joyent
class Mock
def list_machines(options={})
res = Excon::Response.new
res.status = 200
res.body = self.data[:machines].values
res
end
end
class Real
def list_machines(options={})
request(
:path => "/my/machines",
:method => "GET",
:query => options
)
end
end
end
end
end

View file

@ -0,0 +1,35 @@
module Fog
module Compute
class Joyent
class Mock
def list_packages
response = Excon::Response.new()
response.status = 200
response.body = self.data[:packages].values
response
end
end
class Real
# 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"
#
def list_packages
request(
:path => "/my/packages",
:method => "GET"
)
end
end # Real
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Compute
class Joyent
class Real
def reboot_machine(id)
request(
:method => "POST",
:query => {"action" => "reboot"},
:path => "/my/machines/#{id}"
)
end
end
end
end
end

View file

@ -0,0 +1,13 @@
module Fog
module Compute
class Joyent
def resize_machine(id, package)
request(
:method => "POST",
:path => "/my/machines/#{id}",
:query => {"action" => "resize", "package" => package}
)
end
end
end
end

View file

@ -0,0 +1,16 @@
module Fog
module Compute
class Joyent
class Real
def start_machine(id)
request(
:method => "POST",
:path => "/my/machines/#{id}",
:query => {"action" => "start"},
:expects => 202
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Compute
class Joyent
class Real
def start_machine_from_snapshot(machine_id, snapshot_name)
request(
:method => "POST",
:path => "/my/machines/#{machine_id}/snapshots/#{snapshot_name}",
:expects => 202
)
end
end
end
end
end

View file

@ -0,0 +1,16 @@
module Fog
module Compute
class Joyent
class Real
def stop_machine(uuid)
request(
:method => "POST",
:path => "/my/machines/#{uuid}",
:query => {"action" => "stop"},
:expects => 202
)
end
end
end
end
end

View file

@ -0,0 +1,15 @@
module Fog
module Compute
class Joyent
class Real
def update_machine_metadata(machine_id, metadata)
request(
:method => "POST",
:path => "/my/machines/#{machine_id}/metadata",
:body => metadata
)
end
end
end
end
end

View file

@ -10,6 +10,7 @@ require 'fog/ecloud'
require 'fog/glesys'
require 'fog/go_grid'
require 'fog/google'
require 'fog/joyent'
require 'fog/libvirt'
require 'fog/linode'
require 'fog/local'

9
lib/test.rb Normal file
View file

@ -0,0 +1,9 @@
require './fog'
c = Fog::Compute.new(:provider => "Joyent",
:cloudapi_url => "https://10.99.99.26",
:cloudapi_username => "admin",
:cloudapi_password => "joypass123")
puts c.servers.inspect
puts c.keys.inspect
puts c.images.inspect
puts c.flavors.inspect

View file

@ -22,6 +22,9 @@ def compute_providers
:glesys => {
:mocked => false
},
:joyent => {
:mocked => false
},
:ninefold => {
:mocked => false
},

View file

@ -12,7 +12,7 @@ def array_differences(array_a, array_b)
end
# check to see which credentials are available and add others to the skipped tags list
all_providers = ['aws', 'bluebox', 'brightbox', 'dnsimple', 'dnsmadeeasy', 'dynect', 'ecloud', 'glesys', 'gogrid', 'google', 'linode', 'local', 'ninefold', 'newservers', 'openstack', 'ovirt', 'rackspace', 'slicehost', 'stormondemand', 'voxel', 'vsphere', 'zerigo']
all_providers = ['aws', 'bluebox', 'brightbox', 'dnsimple', 'dnsmadeeasy', 'dynect', 'ecloud', 'glesys', 'gogrid', 'google', 'joyent', 'linode', 'local', 'ninefold', 'newservers', 'openstack', 'ovirt', 'rackspace', 'slicehost', 'stormondemand', 'voxel', 'vsphere', 'zerigo']
available_providers = Fog.available_providers.map {|provider| provider.downcase}
for provider in (all_providers - available_providers)
Formatador.display_line("[yellow]Skipping tests for [bold]#{provider}[/] [yellow]due to lacking credentials (add some to '~/.fog' to run them)[/]")

View file

@ -17,6 +17,8 @@ if Fog.mock?
:brightbox_secret => 'brightbox_secret',
:clodo_api_key => 'clodo_api_key',
:clodo_username => 'clodo_username',
:cloudapi_username => "cloudapi_user",
:cloudapi_password => "cloudapi_pass",
:dnsimple_email => 'dnsimple_email',
:dnsimple_password => 'dnsimple_password',
:dnsmadeeasy_api_key => 'dnsmadeeasy_api_key',

View file

@ -0,0 +1,47 @@
Shindo.tests("Fog::Compute[:joyent] | dataset requests", ["joyent"]) do
@dataset_format = {
"name" => String,
"version" => String,
"os" => String,
"id" => String,
"urn" => String,
"default" => Fog::Boolean,
"type" => String,
"created" => Time
}
if Fog.mock?
Fog::Compute[:joyent].data[:datasets] = {
"7456f2b0-67ac-11e0-b5ec-832e6cf079d5" => {
"name" => "nodejs",
"version" => "1.1.3",
"os" => "smartos",
"id" => "7456f2b0-67ac-11e0-b5ec-832e6cf079d5",
"urn" => "sdc:sdc:nodejs:1.1.3",
"default" => true,
"type" => "smartmachine",
"created" => Time.parse("2011-04-15T22:04:12+00:00")
},
"febaa412-6417-11e0-bc56-535d219f2590" => {
"name" => "smartos",
"version" => "1.3.12",
"os" => "smartos",
"id" => "febaa412-6417-11e0-bc56-535d219f2590",
"urn" => "sdc:sdc:smartos:1.3.23",
"default" => false,
"type" => "smartmachine",
"created" => Time.parse("2011-04-11T08:45:00+00:00")
}
}
end
tests("#list_datasets") do
formats(@dataset_format) do
Fog::Compute[:joyent].list_datasets.body.first
end
returns(Fog::Compute[:joyent].data[:datasets].length) do
Fog::Compute[:joyent].list_datasets.body.length
end
end
end

View file

@ -0,0 +1,48 @@
Shindo.tests("Fog::Compute::Joyent | key requests", ['joyent']) do
@key_format = {
"name" => String,
"key" => String,
"created" => Time
}
before do
Fog::Compute[:joyent].create_key(
:name => "key1",
:key => "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAlau1...")
Fog::Compute[:joyent].create_key(
:name => "key2",
:key => "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAlau1...")
end
tests("#list_keys").formats([@key_format]) do
Fog::Compute[:joyent].list_keys.body
end
tests("#list_keys") do
returns(2) do
Fog::Compute[:joyent].list_keys.body.length
end
end
tests("#get_key").formats(@key_format) do
Fog::Compute[:joyent].get_key('key1').body
end
tests("#get_key").formats(@key_format) do
Fog::Compute[:joyent].get_key('key2').body
end
tests("#delete_key") do
returns(200, "returns status code 200") do
Fog::Compute[:joyent].delete_key("key1").status
end
raises(Excon::Errors::NotFound, "when a key no longer exists") do
Fog::Compute[:joyent].delete_key("key1")
Fog::Compute[:joyent].delete_key("key1")
end
end
end

View file

@ -0,0 +1,60 @@
Shindo.tests("Fog::Compute[:joyent] | machine requests", ["joyent"]) do
@machine_format = {
"id" => String,
"name" => String,
"type" => String,
"state" => String,
"dataset" => String,
"memory" => Integer,
"disk" => Integer,
"ips" => Array,
"metadata" => Hash,
"created" => Time,
"updated" => Time
}
@machines = Fog::Compute[:joyent].data[:machines] = {
"15080eca-3786-4bb8-a4d0-f43e1981cd72" => {
"id" => "15080eca-3786-4bb8-a4d0-f43e1981cd72",
"name" => "getting-started",
"type" => "smartmachine",
"state" => "running",
"dataset" => "sdc:sdc:smartos:1.3.15",
"memory" => 256,
"disk" => 5120,
"ips" => ["10.88.88.50"],
"metadata" => {},
"created" => Time.parse("2011-06-03T00:02:31+00:00"),
"updated" => Time.parse("2011-06-03T00:02:31+00:00")
}
}
@provider = Fog::Compute[:joyent]
# https://us-west-1.api.joyentcloud.com/docs#ListMachines
tests("#list_machines") do
if Fog.mock?
returns(@machines.length, "correct number of machines") do
@provider.list_machines.body.length
end
end
returns(Array, "returns an Array of machines") do
@provider.list_machines.body.class
end
formats([@machine_format]) do
@provider.list_machines.body
end
end
# https://us-west-1.api.joyentcloud.com/docs#GetMachine
tests("#get_machine") do
formats(@machine_format) do
id = @provider.list_machines.body.first["id"]
@provider.get_machine(id)
end
end
end

View file

@ -0,0 +1,60 @@
Shindo.tests("Fog::Compute[:joyent] | package requests", ["joyent"]) do
@data = Fog::Compute[:joyent].data
@package_format = {
'name' => String,
'vcpus' => Integer,
'memory' => Integer,
'disk' => Integer,
'swap' => Integer,
'default' => Fog::Boolean
}
if Fog.mock?
@data[:packages] = {
"regular_128" => {
"name" => "regular_128",
"memory" => 128,
"disk" => 5120,
"vcpus" => 1,
"swap" => 256,
"default" => true
},
"regular_256" => {
"name" => "regular_256",
"memory" => 256,
"disk" => 5120,
"vcpus" => 1,
"swap" => 512,
"default" => false
},
"regular_512" => {
"name" => "regular_512",
"memory" => 512,
"disk" => 10240,
"vcpus" => 1,
"swap" => 1024,
"default" => false
}
}
end
tests("#list_packages") do
formats([@package_format]) do
Fog::Compute[:joyent].list_packages.body
end
actual = @data[:packages].values.length
returns(actual, "has correct number of packages") do
Fog::Compute[:joyent].list_packages.body.length
end
end
tests("#get_package") do
pkgid = @data[:packages].keys.first
formats(@package_format) do
Fog::Compute[:joyent].get_package(pkgid).body
end
end
end