This commit is contained in:
Paulo Henrique Lopes Ribeiro 2014-11-07 13:57:04 -02:00 коммит произвёл Paulo Henrique Lopes Ribeiro
Родитель a29fcd8a53
Коммит 6f89826e02
26 изменённых файлов: 2 добавлений и 923 удалений

Просмотреть файл

@ -59,6 +59,7 @@ Gem::Specification.new do |s|
s.add_dependency("fog-sakuracloud", ">= 0.0.4")
s.add_dependency("fog-radosgw", ">=0.0.2")
s.add_dependency("fog-profitbricks")
s.add_dependency("fog-voxel")
## List your development dependencies here. Development dependencies are
## those that are only needed during development

Просмотреть файл

@ -1,29 +0,0 @@
class Voxel < Fog::Bin
class << self
def class_for(key)
case key
when :compute
Fog::Compute::Voxel
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("Voxel[:compute] is not recommended, use Compute[:voxel] for portability")
Fog::Compute.new(:provider => 'Voxel')
else
raise ArgumentError, "Unrecognized service: #{key.inspect}"
end
end
@@connections[service]
end
def services
Fog::Voxel.services
end
end
end

Просмотреть файл

@ -1 +0,0 @@
require 'fog/voxel/compute'

Просмотреть файл

@ -1,122 +0,0 @@
require 'fog/voxel/core'
module Fog
module Compute
class Voxel < Fog::Service
requires :voxel_api_key, :voxel_api_secret
recognizes :host, :port, :scheme, :persistent
model_path 'fog/voxel/models/compute'
model :image
collection :images
model :server
collection :servers
request_path 'fog/voxel/requests/compute'
request :images_list
request :devices_list
request :devices_power
request :voxcloud_create
request :voxcloud_status
request :voxcloud_delete
class Mock
include Collections
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {
:last_modified => { :servers => {}, :statuses => {}, :images => {} },
:servers => [],
:statuses => {},
:images => [
{'id' => 1, 'name' => "CentOS 4, 32-bit, base install"},
{'id' => 2, 'name' => "CentOS 4, 64-bit, base install"},
{'id' => 3, 'name' => "CentOS 5, 32-bit, base install"},
{'id' => 4, 'name' => "CentOS 5, 64-bit, base install"},
{'id' => 7, 'name' => "Fedora 10, 32-bit, base install"},
{'id' => 8, 'name' => "Fedora 10, 64-bit, base install"},
{'id' => 10, 'name' => "OpenSUSE 11, 64-bit, base install"},
{'id' => 11, 'name' => "Debian 5.0 \"lenny\", 32-bit, base install"},
{'id' => 12, 'name' => "Debian 5.0 \"lenny\", 64-bit, base install"},
{'id' => 13, 'name' => "Ubuntu 8.04 \"Hardy\", 32-bit, base install"},
{'id' => 14, 'name' => "Ubuntu 8.04 \"Hardy\", 64-bit, base install"},
{'id' => 15, 'name' => "Voxel Server Environment (VSE), 32-bit, base install"},
{'id' => 16, 'name' => "Voxel Server Environment (VSE), 64-bit, base install"},
{'id' => 32, 'name' => "Pantheon Official Mercury Stack for Drupal (based on VSE/64)"},
{'id' => 55, 'name' => "Ubuntu 10.04 \"Lucid\", 64-bit, base install"} ]
}
end
end
def self.reset
@data = nil
end
def initialize(options={})
@voxel_api_key = options[:voxel_api_key]
end
def data
self.class.data[@voxel_api_key]
end
def reset_data
self.class.data.delete(@voxel_api_key)
end
end
class Real
include Collections
def initialize(options = {})
require 'time'
require 'digest/md5'
@voxel_api_key = options[:voxel_api_key]
@voxel_api_secret = options[:voxel_api_secret]
@connection_options = options[:connection_options] || {}
@host = options[:host] || "api.voxel.net"
@port = options[:port] || 443
@scheme = options[:scheme] || 'https'
@persistent = options[:persistent] || false
@connection_options[:ssl_verify_peer] = false
@connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
end
def request(method_name, options = {})
begin
parser = options.delete(:parser)
options.merge!({ :method => method_name, :timestamp => Time.now.xmlschema, :key => @voxel_api_key })
options[:api_sig] = create_signature(@voxel_api_secret, options)
data = @connection.request(
:method => "POST",
:query => options,
:parser => parser,
:path => "/version/1.0/"
)
unless data.body['stat'] == 'ok'
raise Fog::Compute::Voxel::Error, "#{data.body['err']['msg']}"
end
data
rescue Excon::Errors::HTTPStatusError => error
raise case error
when Excon::Errors::NotFound
Fog::Compute::Voxel::NotFound.slurp(error)
else
error
end
end
end
def create_signature(secret, options)
to_sign = options.keys.map { |k| k.to_s }.sort.map { |k| "#{k}#{options[k.to_sym]}" }.join("")
Digest::MD5.hexdigest( secret + to_sign )
end
end
end
end
end

Просмотреть файл

@ -1,16 +0,0 @@
require 'fog/core'
require 'fog/xml'
require 'digest/md5'
module Fog
module Voxel
extend Fog::Provider
service(:compute, 'Compute')
def self.create_signature(secret, options)
to_sign = options.keys.map { |k| k.to_s }.sort.map { |k| "#{k}#{options[k.to_sym]}" }.join("")
Digest::MD7.hexdigest( secret + to_sign )
end
end
end

Просмотреть файл

@ -1,13 +0,0 @@
require 'fog/core/model'
module Fog
module Compute
class Voxel
class Image < Fog::Model
identity :id
attribute :summary
end
end
end
end

Просмотреть файл

@ -1,27 +0,0 @@
require 'fog/core/collection'
require 'fog/voxel/models/compute/image'
module Fog
module Compute
class Voxel
class Images < Fog::Collection
model Fog::Compute::Voxel::Image
def all
data = service.images_list.body['images']
load(data)
end
def get(image_id)
data = service.images_list(image_id).body['images']
if data.empty?
nil
else
new(data.first)
end
end
end
end
end
end

Просмотреть файл

@ -1,73 +0,0 @@
require 'fog/compute/models/server'
module Fog
module Compute
class Voxel
class Server < Fog::Compute::Server
identity :id
attribute :name
attribute :processing_cores
attribute :image_id
attribute :facility
attribute :disk_size
attribute :ip_assignments, :aliases => 'ipassignments'
def initialize(attributes={})
self.image_id ||= '55' # Ubuntu 10.04 LTS 64bit
super
end
def destroy
requires :id
service.voxcloud_delete(id)
true
end
def image
requires :image_id
service.images.get(image_id)
end
def ready?
self.state == 'SUCCEEDED'
end
def private_ip_address
ip_assignments.select {|ip_assignment| ip_assignment['type'] == 'internal'}.first
end
def public_ip_address
ip_assignments.select {|ip_assignment| ip_assignment['type'] == 'external'}.first
end
def reboot
requires :id
service.devices_power(id, :reboot)
true
end
def state
@state ||= service.voxcloud_status(id).body['devices'].first['status']
end
def save
raise Fog::Errors::Error.new('Resaving an existing object may create a duplicate') if persisted?
requires :name, :image_id, :processing_cores, :facility, :disk_size
data = service.voxcloud_create({
:disk_size => disk_size,
:facility => facility,
:hostname => name,
:image_id => image_id,
:processing_cores => processing_cores
}).body
merge_attributes(data['device'])
true
end
end
end
end
end

Просмотреть файл

@ -1,29 +0,0 @@
require 'fog/core/collection'
require 'fog/voxel/models/compute/server'
module Fog
module Compute
class Voxel
class Servers < Fog::Collection
model Fog::Compute::Voxel::Server
def all
data = service.devices_list.body['devices'].select {|device| device['type']['id'] == '3'}
load(data)
end
def get(device_id)
if device_id && server = service.devices_list(device_id).body['devices']
new(server.first)
end
rescue Fog::Service::Error => error
if error.message == "The device_id passed in can't be matched to a valid device."
nil
else
raise error
end
end
end
end
end
end

Просмотреть файл

@ -1,27 +0,0 @@
module Fog
module Parsers
module Compute
module Voxel
class Basic < Fog::Parsers::Base
def reset
@response = {}
end
def start_element(name, attrs = [])
super
case name
when 'err'
@response['err'] = {
'code' => attr_value('code', attrs),
'msg' => attr_value('msg', attrs)
}
when 'rsp'
@response['stat'] = attr_value('stat', attrs)
end
end
end
end
end
end
end

Просмотреть файл

@ -1,107 +0,0 @@
module Fog
module Parsers
module Compute
module Voxel
class DevicesList < Fog::Parsers::Base
def reset
@device = {}
@response = { 'devices' => [] }
@in_storage = false
end
def start_element(name, attrs = [])
super
case name
when 'accessmethod'
@access_method = { 'type' => attr_value('type', attrs) }
when 'accessmethods'
@device['access_methods'] = []
when 'device'
@device = {
'id' => attr_value('id', attrs),
'label' => attr_value('label', attrs),
'status' => attr_value('status', attrs)
}
when 'err'
@response['err'] = {
'code' => attr_value('code', attrs),
'msg' => attr_value('msg', attrs)
}
when 'cage', 'facility', 'rack', 'row', 'zone'
@device['location'][name] = { 'id' => attr_value('id', attrs) }
if code = attr_value('code', attrs)
@device['location'][name]['code'] = code
end
when 'drive'
@drive = { 'position' => attr_value('position', attrs) }
when 'ipassignment'
type = attr_value('type', attrs)
@device['ipassignments'] = []
@device['ipassignments'] << {
'id' => attr_value('id', attrs),
'type' => attr_value('type', attrs),
'description' => attr_value('description', attrs),
}
when 'ipassignments'
@device['ipassignments'] = {}
when 'location'
@device['location'] = {}
when 'memory'
@device['memory'] = { 'size' => attr_value('size', attrs).to_i }
when 'model', 'type'
@device[name] = { 'id' => attr_value('id', attrs) }
when 'operating_system'
@device['operating_system'] = {}
when 'power_consumption'
@device[name] = attr_value('unit', attrs)
when 'processor'
@device['processor'] = {}
when 'rsp'
@response['stat'] = attr_value('stat', attrs)
when 'storage'
@device['drives'] = []
end
end
def end_element(name)
case name
when 'access_method'
@device['access_methods'] << @access_method
when 'architecture'
@device['operating_system'][name] = value.to_i
when 'cage', 'facility', 'rack', 'row', 'zone'
@device['location'][name]['value'] = value
when 'cores'
@device['processor'][name] = value.to_i
when 'description'
@device[name] = value
when 'device'
@response['devices'] << @device
@device = {}
when 'drive'
@device['drives'] << @drive
@drive = {}
when 'cores'
@device['processing_cores'] = value.to_i
when 'ipassignment'
@device['ipassignments'].last['value'] = value
when 'model', 'type'
@device[name]['value'] = value
when 'name'
@device['operating_system'][name] = value
when 'position'
@device['location'][name] = value
when 'power_consumption'
@device[name] = [value, @device[name]].join(' ')
when 'size'
@drive[name] = value.to_i
when 'host', 'password', 'protocol', 'username'
@access_method[name] = value
end
end
end
end
end
end
end

Просмотреть файл

@ -1,55 +0,0 @@
module Fog
module Parsers
module Compute
module Voxel
class ImagesList < Fog::Parsers::Base
def reset
@image = {}
@response = { 'images' => [] }
end
def start_element(name, attrs = [])
super
case name
when 'err'
@response['err'] = {
'code' => attr_value('code', attrs),
'msg' => attr_value('msg', attrs)
}
when 'size'
@image['filesystem']['units'] = attr_value('units', attrs)
when 'image'
@image = {
'id' => attr_value('id', attrs).to_i,
'summary' => attr_value('summary', attrs)
}
when 'filesystem', 'operating_system'
@image[name] = {}
when 'rsp'
@response['stat'] = attr_value('stat', attrs)
end
end
def end_element(name)
case name
when 'architecture'
@image['operating_system'][name] = value.to_i
when 'admin_username', 'family', 'product_family', 'product_version', 'version'
@image['operating_system'][name] = value
when 'description'
@image[name] = value
when 'image'
@response['images'] << @image
@image = {}
when 'size'
@image['filesystem'][name] = value.to_i
when 'type'
@image['filesystem'][name] = value
end
end
end
end
end
end
end

Просмотреть файл

@ -1,36 +0,0 @@
module Fog
module Parsers
module Compute
module Voxel
class VoxcloudCreate < Fog::Parsers::Base
def reset
@response = { 'device' => {} }
end
def start_element(name, attrs = [])
super
case name
when 'err'
@response['err'] = {
'code' => attr_value('code', attrs),
'msg' => attr_value('msg', attrs)
}
when 'rsp'
@response['stat'] = attr_value('stat', attrs)
end
end
def end_element(name)
case name
when 'id'
@response['device'][name] = value
when 'last_update'
@response['device'][name] = Time.at(value.to_i)
end
end
end
end
end
end
end

Просмотреть файл

@ -1,27 +0,0 @@
module Fog
module Parsers
module Compute
module Voxel
class VoxcloudDelete < Fog::Parsers::Base
def reset
@response = {}
end
def start_element(name, attrs = [])
super
case name
when 'rsp'
@response['stat'] = attr_value('stat', attrs)
when 'err'
@response['err'] = {
'code' => attr_value('code', attrs),
'msg' => attr_value('msg', attrs)
}
end
end
end
end
end
end
end

Просмотреть файл

@ -1,42 +0,0 @@
module Fog
module Parsers
module Compute
module Voxel
class VoxcloudStatus < Fog::Parsers::Base
def reset
@response = { 'devices' => [] }
@device = {}
end
def start_element(name, attrs = [])
super
case name
when 'rsp'
@response['stat'] = attr_value('stat', attrs)
when 'err'
@response['err'] = {
'code' => attr_value('code', attrs),
'msg' => attr_value('msg', attrs)
}
when 'device'
@device = {}
end
end
def end_element(name)
case name
when 'device'
@response['devices'] << @device
@device = {}
when 'id', 'status'
@device[name] = value
when 'last_update'
@device[name] = Time.at(value.to_i)
end
end
end
end
end
end
end

Просмотреть файл

@ -1,22 +0,0 @@
module Fog
module Compute
class Voxel
class Real
require 'fog/voxel/parsers/compute/devices_list'
def devices_list(device_id = nil)
options = {
:parser => Fog::Parsers::Compute::Voxel::DevicesList.new,
:verbosity => 'normal'
}
unless device_id.nil?
options[:device_id] = device_id
end
request("voxel.devices.list", options)
end
end
end
end
end

Просмотреть файл

@ -1,20 +0,0 @@
module Fog
module Compute
class Voxel
class Real
require 'fog/voxel/parsers/compute/basic'
def devices_power(device_id, power_action)
options = {
:device_id => device_id,
:parser => Fog::Parsers::Compute::Voxel::Basic.new,
:power_action => power_action,
:verbosity => 'normal'
}
request("voxel.devices.power", options)
end
end
end
end
end

Просмотреть файл

@ -1,29 +0,0 @@
module Fog
module Compute
class Voxel
class Real
require 'fog/voxel/parsers/compute/images_list'
def images_list(image_id = nil)
options = {
:parser => Fog::Parsers::Compute::Voxel::ImagesList.new,
:verbosity => 'compact'
}
unless image_id.nil?
options[:verbosity] = 'extended'
options[:image_id] = image_id
end
data = request("voxel.images.list", options)
if data.body['stat'] == "ok"
data
else
raise Fog::Compute::Voxel::NotFound
end
end
end
end
end
end

Просмотреть файл

@ -1,20 +0,0 @@
module Fog
module Compute
class Voxel
class Real
require 'fog/voxel/parsers/compute/voxcloud_create'
def voxcloud_create(options)
options[:parser] = Fog::Parsers::Compute::Voxel::VoxcloudCreate.new
if options.key?(:password)
options[:admin_password] = options[:password]
options.delete(:password)
end
request("voxel.voxcloud.create", options)
end
end
end
end
end

Просмотреть файл

@ -1,18 +0,0 @@
module Fog
module Compute
class Voxel
class Real
require 'fog/voxel/parsers/compute/voxcloud_delete'
def voxcloud_delete(device_id)
options = {
:device_id => device_id,
:parser => Fog::Parsers::Compute::Voxel::VoxcloudDelete.new
}
request("voxel.voxcloud.delete", options)
end
end
end
end
end

Просмотреть файл

@ -1,22 +0,0 @@
module Fog
module Compute
class Voxel
class Real
require 'fog/voxel/parsers/compute/voxcloud_status'
def voxcloud_status(device_id = nil)
options = {
:parser => Fog::Parsers::Compute::Voxel::VoxcloudStatus.new,
:verbosity => 'compact'
}
unless device_id.nil?
options[:device_id] = device_id
end
request("voxel.voxcloud.status", options)
end
end
end
end
end

Просмотреть файл

@ -129,16 +129,6 @@ def compute_providers
:name => "fog_#{Time.now.to_i}"
},
:mocked => true
},
:voxel => {
:server_attributes => {
:name => "fog.#{Time.now.to_i}",
:disk_size => 10,
:processing_cores => 1,
:image_id => 55, # image 55 = Ubuntu 10.04 (Lucid), 64-bit, base install
:facility => "LDJ1"
},
:mocked => false
}
}
end

Просмотреть файл

@ -1,6 +1,6 @@
for provider, config in compute_providers
next if [:glesys, :voxel, :ibm, :ecloud].include?(provider)
next if [:glesys, :ibm, :ecloud].include?(provider)
Shindo.tests("Fog::Compute[:#{provider}] | flavors", [provider.to_s]) do

Просмотреть файл

@ -93,8 +93,6 @@ if Fog.mock?
:vcloud_director_host => 'vcloud-director-host',
:vcloud_director_password => 'vcloud_director_password',
:vcloud_director_username => 'vcd_user@vcd_org_name',
:voxel_api_key => 'voxel_api_key',
:voxel_api_secret => 'voxel_api_secret',
:zerigo_email => 'zerigo_email',
:zerigo_token => 'zerigo_token',
:dynect_customer => 'dynect_customer',

Просмотреть файл

@ -1,52 +0,0 @@
Shindo.tests('Fog::Compute[:voxel] | image requests', ['voxel']) do
@images_format = {
'images' => [{
'id' => Integer,
'summary' => String
}],
'stat' => String
}
@image_format = {
'images' => [{
'description' => String,
'id' => Integer,
'filesystem' => {
'size' => Integer,
'type' => String,
'units' => String,
},
'operating_system' => {
'admin_username' => String,
'architecture' => Integer,
'family' => String,
'product_family' => String,
'product_version' => String,
'version' => String
},
'summary' => String
}],
'stat' => String
}
tests('success') do
tests('#images_list').formats(@images_format) do
pending if Fog.mocking?
Fog::Compute[:voxel].images_list.body
end
tests('#images_list(1)').formats(@image_format) do
pending if Fog.mocking?
Fog::Compute[:voxel].images_list(1).body
end
end
tests('failure') do
tests('#images_list(0)').raises(Fog::Compute::Voxel::Error) do
pending if Fog.mocking?
Fog::Compute[:voxel].images_list(0).body
end
end
end

Просмотреть файл

@ -1,123 +0,0 @@
Shindo.tests('Fog::Compute[:voxel] | server requests', ['voxel']) do
@server_format = {
'device' => {
'id' => String,
'last_update' => Time
},
'stat' => String
}
@devices_format = {
'devices' => [{
'access_methods' => [],
'description' => String,
'drives' => [{
'position' => Fog::Nullable::String,
'size' => Integer
}],
'id' => String,
'ipassignments' => [{
'description' => String,
'id' => String,
'type' => String,
'value' => String
}],
'label' => String,
'location' => {
'cage' => {
'id' => String,
'value' => String
},
'facility' => {
'code' => String,
'id' => String,
'value' => String
},
'position' => Fog::Nullable::String,
'rack' => {
'id' => String,
'value' => String
},
'row' => {
'id' => String,
'value' => String
},
'zone' => {
'id' => String,
'value' => String
}
},
'memory' => { 'size' => Integer },
'model' => {
'id' => String,
'value' => String
},
'operating_system' => {
'architecture' => Integer,
'name' => String
},
'power_consumption' => String,
'processor' => {
'cores' => Integer
},
'status' => String,
'type' => {
'id' => String,
'value' => String
},
}],
'stat' => String,
}
tests('success') do
@server_id = nil
@name = "fog.#{Time.now.to_i}"
tests("#voxcloud_create( :hostname => '#{@name}', :disk_size => 10, :processing_cores => 1, :image_id => 55, :facility => 'LDJ1' )").formats(@server_format) do
pending if Fog.mocking?
data = Fog::Compute[:voxel].voxcloud_create( :hostname => @name, :disk_size => 10, :processing_cores => 1, :image_id => 55, :facility => "LDJ1" ).body
@server_id = data['device']['id']
data
end
unless Fog.mocking?
Fog::Compute[:voxel].servers.get(@server_id).wait_for { ready? }
end
tests('#devices_list').formats(@devices_format) do
pending if Fog.mocking?
Fog::Compute[:voxel].devices_list.body
end
tests('#devices_list(@server_id)').formats(@devices_format) do
pending if Fog.mocking?
Fog::Compute[:voxel].devices_list(@server_id).body
end
tests("#voxcloud_delete(#{@server_id})").succeeds do
pending if Fog.mocking?
Fog::Compute[:voxel].voxcloud_delete(@server_id)
end
end
tests('failure') do
tests('#voxcloud_delete(0)').raises(Fog::Compute::Voxel::Error) do
pending if Fog.mocking?
Fog::Compute[:voxel].voxcloud_delete(0)
end
tests('#voxcloud_status(0)').raises(Fog::Compute::Voxel::Error) do
pending if Fog.mocking?
Fog::Compute[:voxel].voxcloud_status(0)
end
tests('#devices_list(0)').raises(Fog::Compute::Voxel::Error) do
pending if Fog.mocking?
Fog::Compute[:voxel].devices_list(0)
end
end
end