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

[ecloud|compute] re-namespace terremark ecloud

This commit is contained in:
geemus 2011-02-17 10:44:46 -08:00
parent 4da8bc58eb
commit e72831d99b
181 changed files with 3718 additions and 3907 deletions

View file

@ -35,11 +35,6 @@ else
Formatador.display_line('Welcome to fog interactive!')
Formatador.display_line(":#{Fog.credential} provides #{providers}")
providers = Fog.providers
Fog.modules.each do |_module_|
if _module_.respond_to?(:startup_notice)
_module_.send(:startup_notice)
end
end
catch(:IRB_EXIT) { @irb.eval_input }

View file

@ -11,7 +11,6 @@ end
# FIXME: these should go away (force usage of Fog::[Compute, CDN, DNS, Storage] etc)
require 'fog/providers'
require 'fog/terremark'
require 'fog/vcloud'
require 'fog/compute'
require 'fog/cdn'

View file

@ -7,12 +7,6 @@ module Fog
@providers.select {|provider| eval("::#{provider.to_s.split('::').last}").available?}
end
def modules
[
::Vcloud
].select {|_module_| _module_.initialized?}
end
end
class Bin
@ -62,6 +56,7 @@ end
require 'fog/bin/aws'
require 'fog/bin/bluebox'
require 'fog/bin/brightbox'
require 'fog/bin/ecloud'
require 'fog/bin/go_grid'
require 'fog/bin/google'
require 'fog/bin/linode'
@ -70,5 +65,4 @@ require 'fog/bin/new_servers'
require 'fog/bin/rackspace'
require 'fog/bin/slicehost'
require 'fog/bin/terremark'
require 'fog/bin/vcloud'
require 'fog/bin/zerigo'

30
lib/fog/bin/ecloud.rb Normal file
View file

@ -0,0 +1,30 @@
class Ecloud < Fog::Bin
class << self
def class_for(key)
case key
when :compute
Fog::Ecloud::Compute
else
raise ArgumentError, "Unrecognized service: #{key}"
end
end
def [](service)
@@connections ||= Hash.new do |hash, key|
hash[key] = case key
when :compute
Fog::Compute.new(:provider => 'Ecloud')
else
raise ArgumentError, "Unrecognized service: #{key.inspect}"
end
end
@@connections[service]
end
def services
Fog::Ecloud.services
end
end
end

View file

@ -1,59 +0,0 @@
module Vcloud
class << self
def services
if Fog.credentials.has_key?(:vcloud)
Fog.credentials[:vcloud].keys.sort { |a,b| a.to_s <=> b.to_s }
else
[]
end
end
def registered_services
Vcloud.services.map { |service| ":" << service.to_s }.join(", ")
end
def complete_service_options?(service)
if Fog.credentials.has_key?(:vcloud)
if Fog.credentials[:vcloud].has_key?(service)
service = Fog.credentials[:vcloud][service]
if Fog::Vcloud.requirements.all? { |option| service.has_key?(option) }
return true
end
end
end
false
end
if Vcloud.services.any? && Vcloud.services.all? { |service| Vcloud.complete_service_options?(service) }
def initialized?
true
end
def startup_notice
Formatador.display_line("You have access to the following Vcloud services: #{Vcloud.registered_services}.")
end
def [](service)
@@connections ||= Hash.new do |hash, key|
if credentials = Fog.credentials[:vcloud][key]
credentials = credentials.dup
_module_ = eval(credentials.delete(:module))
hash[key] = _module_.new(credentials)
else
raise ArgumentError.new("Unregistered service: #{key.inspect}. Registered services are: #{Vcloud.registered_services}")
end
end
@@connections[service]
end
else
def initialized?
false
end
end
end
end

View file

@ -13,6 +13,9 @@ module Fog
when 'Brightbox'
require 'fog/compute/brightbox'
Fog::Brightbox::Compute.new(attributes)
when 'Ecloud'
require 'fog/compute/ecloud'
Fog::Ecloud::Compute.new(attributes)
when 'GoGrid'
require 'fog/compute/go_grid'
Fog::GoGrid::Compute.new(attributes)

View file

@ -8,7 +8,7 @@ class IPAddr
end
module Fog
class Vcloud < Fog::Service
module Ecloud
class Collection < Fog::Collection
def load(objects)
@ -39,7 +39,7 @@ module Fog
end
module Fog
class Vcloud
module Ecloud
module MockDataClasses
class Base < Hash
def self.base_url=(url)
@ -800,7 +800,7 @@ end
module Fog
class Vcloud < Fog::Service
module Ecloud
class Model < Fog::Model
attr_accessor :loaded
@ -823,486 +823,484 @@ module Fog
end
module Fog
class Vcloud
module Terremark
class Ecloud < Fog::Service
module Ecloud
class Compute < Fog::Service
class UnsupportedVersion < Exception ; end
class UnsupportedVersion < Exception ; end
requires :username, :password, :versions_uri
recognizes :module, :version
requires :ecloud_username, :ecloud_password, :ecloud_versions_uri
recognizes :ecloud_version
recognizes :provider # remove post deprecation
model_path 'fog/vcloud/terremark/ecloud/models'
model :catalog_item
model :catalog
model :firewall_acl
collection :firewall_acls
model :internet_service
collection :internet_services
model :backup_internet_service
collection :backup_internet_services
model :ip
collection :ips
model :network
collection :networks
model :node
collection :nodes
model :public_ip
collection :public_ips
model :server
collection :servers
model :task
collection :tasks
model :vdc
collection :vdcs
model_path 'fog/compute/models/ecloud'
model :catalog_item
model :catalog
model :firewall_acl
collection :firewall_acls
model :internet_service
collection :internet_services
model :backup_internet_service
collection :backup_internet_services
model :ip
collection :ips
model :network
collection :networks
model :node
collection :nodes
model :public_ip
collection :public_ips
model :server
collection :servers
model :task
collection :tasks
model :vdc
collection :vdcs
request_path 'fog/vcloud/terremark/ecloud/requests'
request :add_internet_service
request :add_backup_internet_service
request :add_node
request :clone_vapp
request :configure_internet_service
request :configure_network
request :configure_network_ip
request :configure_node
request :configure_vapp
request :delete_internet_service
request :delete_node
request :delete_vapp
request :get_catalog
request :get_catalog_item
request :get_customization_options
request :get_firewall_acls
request :get_firewall_acl
request :get_internet_services
request :get_network
request :get_network_ip
request :get_network_ips
request :get_network_extensions
request :get_organization
request :get_node
request :get_nodes
request :get_public_ip
request :get_public_ips
request :get_task
request :get_task_list
request :get_vapp
request :get_vapp_template
request :get_vdc
request :get_versions
request :instantiate_vapp_template
request :login
request :power_off
request :power_on
request :power_reset
request :power_shutdown
request_path 'fog/compute/requests/ecloud'
request :add_internet_service
request :add_backup_internet_service
request :add_node
request :clone_vapp
request :configure_internet_service
request :configure_network
request :configure_network_ip
request :configure_node
request :configure_vapp
request :delete_internet_service
request :delete_node
request :delete_vapp
request :get_catalog
request :get_catalog_item
request :get_customization_options
request :get_firewall_acls
request :get_firewall_acl
request :get_internet_services
request :get_network
request :get_network_ip
request :get_network_ips
request :get_network_extensions
request :get_organization
request :get_node
request :get_nodes
request :get_public_ip
request :get_public_ips
request :get_task
request :get_task_list
request :get_vapp
request :get_vapp_template
request :get_vdc
request :get_versions
request :instantiate_vapp_template
request :login
request :power_off
request :power_on
request :power_reset
request :power_shutdown
module Shared
module Shared
attr_reader :versions_uri
attr_reader :versions_uri
def default_organization_uri
@default_organization_uri ||= begin
unless @login_results
do_login
end
case @login_results.body[:Org]
when Array
@login_results.body[:Org].first[:href]
when Hash
@login_results.body[:Org][:href]
else
nil
end
end
end
# login handles the auth, but we just need the Set-Cookie
# header from that call.
def do_login
@login_results = login
@cookie = @login_results.headers['Set-Cookie']
end
def ecloud_xmlns
{
"xmlns" => "urn:tmrk:eCloudExtensions-2.6",
"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance"
}
end
def ensure_unparsed(uri)
if uri.is_a?(String)
uri
else
uri.to_s
end
end
def supported_versions
@supported_versions ||= get_versions(@versions_uri).body[:VersionInfo]
end
def xmlns
{ "xmlns" => "http://www.vmware.com/vcloud/v0.8",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
end
end
class Mock
include Shared
include MockDataClasses
def self.base_url
"https://fakey.com/api/v0.8b-ext2.6"
end
def self.data_reset
@mock_data = nil
end
def self.data( base_url = self.base_url )
@mock_data ||= MockData.new.tap do |vcloud_mock_data|
vcloud_mock_data.versions.clear
vcloud_mock_data.versions << MockVersion.new(:version => "v0.8b-ext2.6", :supported => true)
vcloud_mock_data.organizations << MockOrganization.new(:name => "Boom Inc.").tap do |mock_organization|
mock_organization.vdcs << MockVdc.new(:name => "Boomstick").tap do |mock_vdc|
mock_vdc.catalog.items << MockCatalogItem.new(:name => "Item 0").tap do |mock_catalog_item|
mock_catalog_item.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
end
mock_vdc.catalog.items << MockCatalogItem.new(:name => "Item 1").tap do |mock_catalog_item|
mock_catalog_item.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
end
mock_vdc.catalog.items << MockCatalogItem.new(:name => "Item 2").tap do |mock_catalog_item|
mock_catalog_item.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
end
mock_vdc.networks << MockNetwork.new({ :subnet => "1.2.3.0/24" }, mock_vdc)
mock_vdc.networks << MockNetwork.new({ :subnet => "4.5.6.0/24" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Broom 1", :ip => "1.2.3.3" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Broom 2", :ip => "1.2.3.4" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Email!", :ip => "1.2.3.10" }, mock_vdc)
end
mock_organization.vdcs << MockVdc.new(:name => "Rock-n-Roll", :storage_allocated => 150, :storage_used => 40, :cpu_allocated => 1000, :memory_allocated => 2048).tap do |mock_vdc|
mock_vdc.networks << MockNetwork.new({ :subnet => "7.8.9.0/24" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Master Blaster", :ip => "7.8.9.10" }, mock_vdc)
end
end
vcloud_mock_data.organizations.detect {|o| o.name == "Boom Inc." }.tap do |mock_organization|
mock_organization.vdcs.detect {|v| v.name == "Boomstick" }.tap do |mock_vdc|
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.1.2.3").tap do |mock_public_ip|
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "HTTP",
:port => 80,
:name => "Web Site",
:description => "Web Servers",
:redirect_url => "http://fakey.com"
}, mock_public_ip.internet_service_collection
).tap do |mock_public_ip_service|
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({:ip_address => "1.2.3.5", :name => "Test Node 1", :description => "web 1"}, mock_public_ip_service.node_collection)
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({:ip_address => "1.2.3.6", :name => "Test Node 2", :description => "web 2"}, mock_public_ip_service.node_collection)
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({:ip_address => "1.2.3.7", :name => "Test Node 3", :description => "web 3"}, mock_public_ip_service.node_collection)
end
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "TCP",
:port => 7000,
:name => "An SSH Map",
:description => "SSH 1"
}, mock_public_ip.internet_service_collection
).tap do |mock_public_ip_service|
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({ :ip_address => "1.2.3.5", :port => 22, :name => "SSH", :description => "web ssh" }, mock_public_ip_service.node_collection)
end
end
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.1.2.4").tap do |mock_public_ip|
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "HTTP",
:port => 80,
:name => "Web Site",
:description => "Web Servers",
:redirect_url => "http://fakey.com"
}, mock_public_ip.internet_service_collection
)
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "TCP",
:port => 7000,
:name => "An SSH Map",
:description => "SSH 2"
}, mock_public_ip.internet_service_collection
)
end
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.1.9.7")
mock_vdc.internet_service_collection.backup_internet_services << MockBackupInternetService.new({ :port => 10000, :protocol => "TCP"}, self)
end
mock_organization.vdcs.detect {|v| v.name == "Rock-n-Roll" }.tap do |mock_vdc|
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.99.99.99")
end
end
vcloud_mock_data.organizations.each do |organization|
organization.vdcs.each do |vdc|
vdc.networks.each do |network|
network[:rnat] = vdc.public_ip_collection.items.first.name
end
vdc.virtual_machines.each do |virtual_machine|
virtual_machine.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
virtual_machine.disks << MockVirtualMachineDisk.new(:size => 50 * 1024)
end
end
end
end
end
def initialize(options = {})
require 'builder'
require 'fog/core/parser'
@versions_uri = URI.parse('https://vcloud.fakey.com/api/versions')
end
def mock_data
Fog::Vcloud::Terremark::Ecloud::Mock.data
end
def mock_error(expected, status, body='', headers={})
raise Excon::Errors::Unauthorized.new("Expected(#{expected}) <=> Actual(#{status})")
end
def mock_it(status, mock_data, mock_headers = {})
response = Excon::Response.new
#Parse the response body into a hash
if mock_data.empty?
response.body = mock_data
else
document = Fog::ToHashDocument.new
parser = Nokogiri::XML::SAX::PushParser.new(document)
parser << mock_data
parser.finish
response.body = document.body
end
response.status = status
response.headers = mock_headers
response
end
end
class Real
include Shared
class << self
def basic_request(*args)
self.class_eval <<-EOS, __FILE__,__LINE__
def #{args[0]}(uri)
request({
:expects => #{args[1] || 200},
:method => '#{args[2] || 'GET'}',
:headers => #{args[3] ? args[3].inspect : '{}'},
:body => '#{args[4] ? args[4] : ''}',
:parse => true,
:uri => uri })
end
EOS
end
def unauthenticated_basic_request(*args)
self.class_eval <<-EOS, __FILE__,__LINE__
def #{args[0]}(uri)
unauthenticated_request({
:expects => #{args[1] || 200},
:method => '#{args[2] || 'GET'}',
:headers => #{args[3] ? args[3].inspect : '{}'},
:parse => true,
:uri => uri })
end
EOS
end
end
def initialize(options = {})
require 'builder'
require 'fog/core/parser'
@connections = {}
@versions_uri = URI.parse(options[:versions_uri])
@module = options[:module]
@version = options[:version]
@username = options[:username]
@password = options[:password]
@persistent = options[:persistent]
end
def default_organization_uri
@default_organization_uri ||= begin
unless @login_results
do_login
end
case @login_results.body[:Org]
when Array
@login_results.body[:Org].first[:href]
when Hash
@login_results.body[:Org][:href]
else
nil
end
end
end
def reload
@connections.each_value { |k,v| v.reset if v }
end
# If the cookie isn't set, do a get_organizations call to set it
# and try the request.
# If we get an Unauthorized error, we assume the token expired, re-auth and try again
def request(params)
unless @cookie
def default_organization_uri
@default_organization_uri ||= begin
unless @login_results
do_login
end
begin
do_request(params)
rescue Excon::Errors::Unauthorized => e
do_login
do_request(params)
end
end
def supporting_versions
["v0.8b-ext2.6", "0.8b-ext2.6"]
end
private
def ensure_parsed(uri)
if uri.is_a?(String)
URI.parse(uri)
else
uri
end
end
def supported_version_numbers
case supported_versions
case @login_results.body[:Org]
when Array
supported_versions.map { |version| version[:Version] }
@login_results.body[:Org].first[:href]
when Hash
[ supported_versions[:Version] ]
end
end
def get_login_uri
check_versions
URI.parse case supported_versions
when Array
supported_versions.detect {|version| version[:Version] == @version }[:LoginUrl]
when Hash
supported_versions[:LoginUrl]
end
end
# If we don't support any versions the service does, then raise an error.
# If the @version that super selected isn't in our supported list, then select one that is.
def check_versions
if @version
unless supported_version_numbers.include?(@version.to_s)
raise UnsupportedVersion.new("#{@version} is not supported by the server.")
end
unless supporting_versions.include?(@version.to_s)
raise UnsupportedVersion.new("#{@version} is not supported by #{self.class}")
end
@login_results.body[:Org][:href]
else
unless @version = (supported_version_numbers & supporting_versions).sort.first
raise UnsupportedVersion.new("\nService @ #{@versions_uri} supports: #{supported_version_numbers.join(', ')}\n" +
"#{self.class} supports: #{supporting_versions.join(', ')}")
end
nil
end
end
end
# Don't need to set the cookie for these or retry them if the cookie timed out
def unauthenticated_request(params)
do_request(params)
# login handles the auth, but we just need the Set-Cookie
# header from that call.
def do_login
@login_results = login
@cookie = @login_results.headers['Set-Cookie']
end
def ecloud_xmlns
{
"xmlns" => "urn:tmrk:eCloudExtensions-2.6",
"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance"
}
end
def ensure_unparsed(uri)
if uri.is_a?(String)
uri
else
uri.to_s
end
end
# Use this to set the Authorization header for login
def authorization_header
"Basic #{Base64.encode64("#{@username}:#{@password}").chomp!}"
end
def login_uri
@login_uri ||= get_login_uri
end
# login handles the auth, but we just need the Set-Cookie
# header from that call.
def do_login
@login_results = login
@cookie = @login_results.headers['Set-Cookie']
end
# Actually do the request
def do_request(params)
# Convert the uri to a URI if it's a string.
if params[:uri].is_a?(String)
params[:uri] = URI.parse(params[:uri])
end
host_url = "#{self.scheme}://#{self.host}#{self.port ? ":#{self.port}" : ''}"
# Hash connections on the host_url ... There's nothing to say we won't get URI's that go to
# different hosts.
@connections[host_url] ||= Fog::Connection.new(host_url, @persistent)
# Set headers to an empty hash if none are set.
headers = params[:headers] || {}
# Add our auth cookie to the headers
if @cookie
headers.merge!('Cookie' => @cookie)
end
# Make the request
response = @connections[host_url].request({
:body => params[:body] || '',
:expects => params[:expects] || 200,
:headers => headers,
:method => params[:method] || 'GET',
:path => params[:uri].path
})
# Parse the response body into a hash
#puts response.body
unless response.body.empty?
if params[:parse]
document = Fog::ToHashDocument.new
parser = Nokogiri::XML::SAX::PushParser.new(document)
parser << response.body
parser.finish
response.body = document.body
end
end
response
end
def supported_versions
@supported_versions ||= get_versions(@versions_uri).body[:VersionInfo]
end
def xmlns
{ "xmlns" => "http://www.vmware.com/vcloud/v0.8",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema" }
end
end
class Mock
include Shared
include MockDataClasses
def self.base_url
"https://fakey.com/api/v0.8b-ext2.6"
end
def self.data_reset
@mock_data = nil
end
def self.data( base_url = self.base_url )
@mock_data ||= MockData.new.tap do |vcloud_mock_data|
vcloud_mock_data.versions.clear
vcloud_mock_data.versions << MockVersion.new(:version => "v0.8b-ext2.6", :supported => true)
vcloud_mock_data.organizations << MockOrganization.new(:name => "Boom Inc.").tap do |mock_organization|
mock_organization.vdcs << MockVdc.new(:name => "Boomstick").tap do |mock_vdc|
mock_vdc.catalog.items << MockCatalogItem.new(:name => "Item 0").tap do |mock_catalog_item|
mock_catalog_item.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
end
mock_vdc.catalog.items << MockCatalogItem.new(:name => "Item 1").tap do |mock_catalog_item|
mock_catalog_item.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
end
mock_vdc.catalog.items << MockCatalogItem.new(:name => "Item 2").tap do |mock_catalog_item|
mock_catalog_item.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
end
mock_vdc.networks << MockNetwork.new({ :subnet => "1.2.3.0/24" }, mock_vdc)
mock_vdc.networks << MockNetwork.new({ :subnet => "4.5.6.0/24" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Broom 1", :ip => "1.2.3.3" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Broom 2", :ip => "1.2.3.4" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Email!", :ip => "1.2.3.10" }, mock_vdc)
end
mock_organization.vdcs << MockVdc.new(:name => "Rock-n-Roll", :storage_allocated => 150, :storage_used => 40, :cpu_allocated => 1000, :memory_allocated => 2048).tap do |mock_vdc|
mock_vdc.networks << MockNetwork.new({ :subnet => "7.8.9.0/24" }, mock_vdc)
mock_vdc.virtual_machines << MockVirtualMachine.new({ :name => "Master Blaster", :ip => "7.8.9.10" }, mock_vdc)
end
end
vcloud_mock_data.organizations.detect {|o| o.name == "Boom Inc." }.tap do |mock_organization|
mock_organization.vdcs.detect {|v| v.name == "Boomstick" }.tap do |mock_vdc|
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.1.2.3").tap do |mock_public_ip|
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "HTTP",
:port => 80,
:name => "Web Site",
:description => "Web Servers",
:redirect_url => "http://fakey.com"
}, mock_public_ip.internet_service_collection
).tap do |mock_public_ip_service|
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({:ip_address => "1.2.3.5", :name => "Test Node 1", :description => "web 1"}, mock_public_ip_service.node_collection)
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({:ip_address => "1.2.3.6", :name => "Test Node 2", :description => "web 2"}, mock_public_ip_service.node_collection)
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({:ip_address => "1.2.3.7", :name => "Test Node 3", :description => "web 3"}, mock_public_ip_service.node_collection)
end
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "TCP",
:port => 7000,
:name => "An SSH Map",
:description => "SSH 1"
}, mock_public_ip.internet_service_collection
).tap do |mock_public_ip_service|
mock_public_ip_service.node_collection.items << MockPublicIpInternetServiceNode.new({ :ip_address => "1.2.3.5", :port => 22, :name => "SSH", :description => "web ssh" }, mock_public_ip_service.node_collection)
end
end
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.1.2.4").tap do |mock_public_ip|
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "HTTP",
:port => 80,
:name => "Web Site",
:description => "Web Servers",
:redirect_url => "http://fakey.com"
}, mock_public_ip.internet_service_collection
)
mock_public_ip.internet_service_collection.items << MockPublicIpInternetService.new({
:protocol => "TCP",
:port => 7000,
:name => "An SSH Map",
:description => "SSH 2"
}, mock_public_ip.internet_service_collection
)
end
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.1.9.7")
mock_vdc.internet_service_collection.backup_internet_services << MockBackupInternetService.new({ :port => 10000, :protocol => "TCP"}, self)
end
mock_organization.vdcs.detect {|v| v.name == "Rock-n-Roll" }.tap do |mock_vdc|
mock_vdc.public_ip_collection.items << MockPublicIp.new(:name => "99.99.99.99")
end
end
vcloud_mock_data.organizations.each do |organization|
organization.vdcs.each do |vdc|
vdc.networks.each do |network|
network[:rnat] = vdc.public_ip_collection.items.first.name
end
vdc.virtual_machines.each do |virtual_machine|
virtual_machine.disks << MockVirtualMachineDisk.new(:size => 25 * 1024)
virtual_machine.disks << MockVirtualMachineDisk.new(:size => 50 * 1024)
end
end
end
end
end
def initialize(options = {})
require 'builder'
require 'fog/core/parser'
@versions_uri = URI.parse('https://vcloud.fakey.com/api/versions')
end
def mock_data
Fog::Ecloud::Compute::Mock.data
end
def mock_error(expected, status, body='', headers={})
raise Excon::Errors::Unauthorized.new("Expected(#{expected}) <=> Actual(#{status})")
end
def mock_it(status, mock_data, mock_headers = {})
response = Excon::Response.new
#Parse the response body into a hash
if mock_data.empty?
response.body = mock_data
else
document = Fog::ToHashDocument.new
parser = Nokogiri::XML::SAX::PushParser.new(document)
parser << mock_data
parser.finish
response.body = document.body
end
response.status = status
response.headers = mock_headers
response
end
end
class Real
include Shared
class << self
def basic_request(*args)
self.class_eval <<-EOS, __FILE__,__LINE__
def #{args[0]}(uri)
request({
:expects => #{args[1] || 200},
:method => '#{args[2] || 'GET'}',
:headers => #{args[3] ? args[3].inspect : '{}'},
:body => '#{args[4] ? args[4] : ''}',
:parse => true,
:uri => uri })
end
EOS
end
def unauthenticated_basic_request(*args)
self.class_eval <<-EOS, __FILE__,__LINE__
def #{args[0]}(uri)
unauthenticated_request({
:expects => #{args[1] || 200},
:method => '#{args[2] || 'GET'}',
:headers => #{args[3] ? args[3].inspect : '{}'},
:parse => true,
:uri => uri })
end
EOS
end
end
def initialize(options = {})
require 'builder'
require 'fog/core/parser'
@connections = {}
@versions_uri = URI.parse(options[:ecloud_versions_uri])
@version = options[:ecloud_version]
@username = options[:ecloud_username]
@password = options[:ecloud_password]
@persistent = options[:persistent]
end
def default_organization_uri
@default_organization_uri ||= begin
unless @login_results
do_login
end
case @login_results.body[:Org]
when Array
@login_results.body[:Org].first[:href]
when Hash
@login_results.body[:Org][:href]
else
nil
end
end
end
def reload
@connections.each_value { |k,v| v.reset if v }
end
# If the cookie isn't set, do a get_organizations call to set it
# and try the request.
# If we get an Unauthorized error, we assume the token expired, re-auth and try again
def request(params)
unless @cookie
do_login
end
begin
do_request(params)
rescue Excon::Errors::Unauthorized => e
do_login
do_request(params)
end
end
def supporting_versions
["v0.8b-ext2.6", "0.8b-ext2.6"]
end
private
def ensure_parsed(uri)
if uri.is_a?(String)
URI.parse(uri)
else
uri
end
end
def supported_version_numbers
case supported_versions
when Array
supported_versions.map { |version| version[:Version] }
when Hash
[ supported_versions[:Version] ]
end
end
def get_login_uri
check_versions
URI.parse case supported_versions
when Array
supported_versions.detect {|version| version[:Version] == @version }[:LoginUrl]
when Hash
supported_versions[:LoginUrl]
end
end
# If we don't support any versions the service does, then raise an error.
# If the @version that super selected isn't in our supported list, then select one that is.
def check_versions
if @version
unless supported_version_numbers.include?(@version.to_s)
raise UnsupportedVersion.new("#{@version} is not supported by the server.")
end
unless supporting_versions.include?(@version.to_s)
raise UnsupportedVersion.new("#{@version} is not supported by #{self.class}")
end
else
unless @version = (supported_version_numbers & supporting_versions).sort.first
raise UnsupportedVersion.new("\nService @ #{@versions_uri} supports: #{supported_version_numbers.join(', ')}\n" +
"#{self.class} supports: #{supporting_versions.join(', ')}")
end
end
end
# Don't need to set the cookie for these or retry them if the cookie timed out
def unauthenticated_request(params)
do_request(params)
end
# Use this to set the Authorization header for login
def authorization_header
"Basic #{Base64.encode64("#{@username}:#{@password}").chomp!}"
end
def login_uri
@login_uri ||= get_login_uri
end
# login handles the auth, but we just need the Set-Cookie
# header from that call.
def do_login
@login_results = login
@cookie = @login_results.headers['Set-Cookie']
end
# Actually do the request
def do_request(params)
# Convert the uri to a URI if it's a string.
if params[:uri].is_a?(String)
params[:uri] = URI.parse(params[:uri])
end
host_url = "#{params[:uri].scheme}://#{params[:uri].host}#{params[:uri].port ? ":#{params[:uri].port}" : ''}"
# Hash connections on the host_url ... There's nothing to say we won't get URI's that go to
# different hosts.
@connections[host_url] ||= Fog::Connection.new(host_url, @persistent)
# Set headers to an empty hash if none are set.
headers = params[:headers] || {}
# Add our auth cookie to the headers
if @cookie
headers.merge!('Cookie' => @cookie)
end
# Make the request
response = @connections[host_url].request({
:body => params[:body] || '',
:expects => params[:expects] || 200,
:headers => headers,
:method => params[:method] || 'GET',
:path => params[:uri].path
})
# Parse the response body into a hash
#puts response.body
unless response.body.empty?
if params[:parse]
document = Fog::ToHashDocument.new
parser = Nokogiri::XML::SAX::PushParser.new(document)
parser << response.body
parser.finish
response.body = document.body
end
end
response
end
end
end
end
end

View file

@ -0,0 +1,56 @@
module Fog
module Ecloud
class Compute
class BackupInternetService < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
attribute :protocol, :aliases => :Protocol
attribute :enabled, :aliases => :Enabled
attribute :description, :aliases => :Description
attribute :timeout, :aliases => :Timeout
attribute :redirect_url, :aliases => :RedirectURL
attribute :monitor, :aliases => :Monitor
def delete
requires :href
connection.delete_internet_service( href )
end
def monitor=(new_monitor = {})
if new_monitor.nil? || new_monitor.empty?
attributes[:monitor] = nil
end
end
def save
if new_record?
result = connection.add_backup_internet_service( collection.href, _compose_service_data )
merge_attributes(result.body)
else
connection.configure_backup_internet_service( href, _compose_service_data )
end
end
def nodes
@nodes ||= Fog::Ecloud::Compute::Nodes.new( :connection => connection, :href => href + "/nodeServices" )
end
private
def _compose_service_data
#For some reason inject didn't work
service_data = {}
self.class.attributes.select{ |attribute| !send(attribute).nil? }.each { |attribute| service_data[attribute] = send(attribute) }
service_data
end
end
end
end
end

View file

@ -0,0 +1,33 @@
require 'fog/compute/models/ecloud/backup_internet_service'
module Fog
module Ecloud
class Compute
class BackupInternetServices < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::BackupInternetService
attribute :href, :aliases => :Href
def all
check_href! :message => "the Internet Services for the Vdc you want to enumerate"
if data = connection.get_internet_services(href).body[:InternetService].find_all {|i| i[:IsBackupService] == "true" }
load(data)
end
end
# Optimize later, no need to get_internet_services again?
def get(uri)
internet_services = connection.get_internet_services(href).body[:InternetService]
internet_services = [ internet_services ] if internet_services.is_a?(Hash)
if data = internet_services.detect { |service| service[:Href] == uri }
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,28 @@
module Fog
module Ecloud
class Compute
class Catalog < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::CatalogItem
attribute :href, :aliases => :Href
def all
check_href!
if data = connection.get_catalog(href).body[:CatalogItems][:CatalogItem]
load(data)
end
end
def get(uri)
if data = connection.get_catalog_item(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Ecloud
class Compute
class CatalogItem < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type
attribute :name
attribute :entity, :aliases => :Entity
attribute :link, :aliases => :Link
attribute :property, :aliases => :Property
def customization_options
load_unless_loaded!
if data = connection.get_customization_options( link[:href] ).body
data.delete_if { |key, value| [:xmlns_i, :xmlns].include?(key) }
data
else
nil
end
end
end
end
end
end

View file

@ -0,0 +1,24 @@
module Fog
module Ecloud
class Compute
class FirewallAcl < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
attribute :protocol, :aliases => :Protocol
attribute :source, :aliases => :Source
attribute :destination, :aliases => :Destination
attribute :permission, :aliases => :Permission
attribute :port_start, :aliases => :PortStart
attribute :port_end, :aliases => :PortEnd
attribute :port_type, :aliases => :PortType
attribute :type, :aliases => :Type
end
end
end
end

View file

@ -0,0 +1,31 @@
require 'fog/compute/models/ecloud/firewall_acl'
module Fog
module Ecloud
class Compute
class FirewallAcls < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::FirewallAcl
attribute :href, :aliases => :Href
def all
check_href! :message => "the Firewall ACL href for the network you want to enumerate"
if data = connection.get_firewall_acls(href).body[:FirewallAcl]
data = [ data ] if data.is_a?(Hash)
load(data)
end
end
def get(uri)
if data = connection.get_firewall_acl(uri).body
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,117 @@
module Fog
module Ecloud
class Compute
class InternetService < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
attribute :protocol, :aliases => :Protocol
attribute :port, :aliases => :Port
attribute :enabled, :aliases => :Enabled
attribute :description, :aliases => :Description
attribute :public_ip, :aliases => :PublicIpAddress
attribute :timeout, :aliases => :Timeout
attribute :redirect_url, :aliases => :RedirectURL
attribute :monitor, :aliases => :Monitor
attribute :backup_service_data, :aliases => :BackupService
def delete
requires :href
connection.delete_internet_service( href )
end
def save
if new_record?
result = connection.add_internet_service( collection.href, _compose_service_data )
merge_attributes(result.body)
else
connection.configure_internet_service( href, _compose_service_data, _compose_ip_data )
end
end
# disables monitoring for this service
def disable_monitor
if self.monitor and self.monitor[:type] == "Disabled"
raise RuntimeError.new("Monitoring already disabled")
else
self.monitor = {:type => "Disabled", :is_enabled => "true"}
self.save
end
end
# enable default ping monitoring, use monitor= for more exotic forms (ECV & HTTP)
def enable_ping_monitor
self.monitor = nil
self.save
end
def monitor=(new_monitor = {})
if new_monitor.nil? || new_monitor.empty?
attributes[:monitor] = nil
elsif new_monitor.is_a?(Hash)
attributes[:monitor] = {}
attributes[:monitor][:type] = new_monitor[:MonitorType] || new_monitor[:type]
attributes[:monitor][:url_send_string] = new_monitor[:UrlSendString] || new_monitor[:url_send_string]
attributes[:monitor][:http_headers] = new_monitor[:HttpHeader] || new_monitor[:http_headers]
if attributes[:monitor][:http_headers]
if attributes[:monitor][:http_headers].is_a?(String)
attributes[:monitor][:http_headers] = attributes[:monitor][:http_headers].split("\n")
else
attributes[:monitor][:http_headers] = attributes[:monitor][:http_headers]
end
end
attributes[:monitor][:receive_string] = new_monitor[:ReceiveString] || new_monitor[:receive_string]
attributes[:monitor][:interval] = new_monitor[:Interval] || new_monitor[:interval]
attributes[:monitor][:response_timeout] = new_monitor[:ResponseTimeOut] || new_monitor[:response_timeout]
attributes[:monitor][:downtime] = new_monitor[:DownTime] || new_monitor[:downtime]
attributes[:monitor][:retries] = new_monitor[:Retries] || new_monitor[:retries]
attributes[:monitor][:is_enabled] = new_monitor[:IsEnabled] || new_monitor[:is_enabled]
else
raise RuntimeError.new("monitor needs to either be nil or a Hash")
end
end
def nodes
@nodes ||= Fog::Ecloud::Compute::Nodes.new( :connection => connection, :href => href + "/nodeServices" )
end
def backup_service_uri
if backup_service_data
backup_service_data[:Href]
end
end
def backup_service_uri=(new_value)
self.backup_service_data = {
:Href => new_value
}
end
private
def _compose_service_data
#For some reason inject didn't work
service_data = {}
self.class.attributes.select{ |attribute| attribute != :backup_service_data }.each { |attribute| service_data[attribute] = send(attribute) }
service_data[:backup_service_uri] = backup_service_uri
service_data.reject! {|k, v| v.nil? }
service_data
end
def _compose_ip_data
if public_ip.nil?
{}
else
{ :id => public_ip[:Id], :href => public_ip[:Href], :name => public_ip[:Name] }
end
end
end
end
end
end

View file

@ -0,0 +1,33 @@
require 'fog/compute/models/ecloud/internet_service'
module Fog
module Ecloud
class Compute
class InternetServices < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::InternetService
attribute :href, :aliases => :Href
def all
check_href! :message => "the Internet Services for the Vdc you want to enumerate"
if internet_service_data = connection.get_internet_services(href).body[:InternetService]
load(Array[internet_service_data].flatten.find_all {|i| i[:IsBackupService] == "false" })
end
end
# Optimize later, no need to get_internet_services again?
def get(uri)
internet_services = connection.get_internet_services(href).body[:InternetService]
internet_services = [ internet_services ] if internet_services.is_a?(Hash)
if data = internet_services.detect { |service| service[:Href] == uri }
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,49 @@
module Fog
module Ecloud
class Compute
class Ip < Fog::Ecloud::Model
ignore_attributes :xmlns_i, :xmlns
identity :href, :aliases => :Href
attribute :name, :aliases => :Name
attribute :status, :aliases => :Status
attribute :server, :aliases => :Server
attribute :rnat, :aliases => :RnatAddress
attribute :id, :aliases => :Id, :type => :integer
def rnat=(new_rnat)
attributes[:rnat] = new_rnat
@changed = true
end
def save
if @changed
connection.configure_network_ip( href, _compose_network_ip_data )
end
true
end
def reload
super
@changed = false
self
end
private
def _compose_network_ip_data
{
:id => id,
:href => href,
:name => name,
:status => status,
:server => server,
:rnat => rnat
}
end
end
end
end
end

View file

@ -0,0 +1,32 @@
require 'fog/compute/models/ecloud/ip'
module Fog
module Ecloud
class Compute
class Ips < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::Ip
undef_method :create
attribute :href
def all
check_href!( :messages => "Ips href of a Network you want to enumerate" )
if data = connection.get_network_ips(href).body[:IpAddress]
load(data)
end
end
def get(uri)
if data = connection.get_network_ip(uri).body
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,72 @@
module Fog
module Ecloud
class Compute
class Network < Fog::Ecloud::Model
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd, :xmlns_i, :Configuration, :Id
attribute :name, :aliases => :Name
#attribute :id, :aliases => :Id
attribute :features, :aliases => :Features, :type => :array
attribute :links, :aliases => :Link, :type => :array
attribute :type
attribute :gateway, :aliases => :GatewayAddress
attribute :broadcast, :aliases => :BroadcastAddress
attribute :address, :aliases => :Address
attribute :rnat, :aliases => :RnatAddress
attribute :extension_href, :aliases => :Href
attribute :network_type, :aliases => :NetworkType
attribute :vlan, :aliases => :Vlan
attribute :friendly_name, :aliases => :FriendlyName
def ips
load_unless_loaded!
Fog::Ecloud::Compute::Ips.new( :connection => connection,
:href => links.detect { |link| link[:name] == "IP Addresses" }[:href] )
end
def rnat=(new_rnat)
attributes[:rnat] = new_rnat
@changed = true
end
def save
if @changed
connection.configure_network( extension_href, _compose_network_data )
end
true
end
def reload
super
merge_attributes(extension_data.body)
self
end
private
def extension_data
connection.get_network_extensions( extensions_link[:href] )
end
def extensions_link
links.detect { |link| link[:name] == name }
end
def _compose_network_data
{
:id => id,
:href => extension_href,
:name => name,
:rnat => rnat,
:address => address,
:broadcast => broadcast,
:gateway => gateway
}
end
end
end
end
end

View file

@ -0,0 +1,33 @@
require 'fog/compute/models/ecloud/network'
module Fog
module Ecloud
class Compute
class Networks < Fog::Ecloud::Collection
undef_method :create
model Fog::Ecloud::Compute::Network
attribute :href
def all
check_href!("Vdc")
if data = connection.get_vdc(href).body[:AvailableNetworks][:Network]
load(data)
end
end
def get(uri)
if data = connection.get_network(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,43 @@
module Fog
module Ecloud
class Compute
class Node < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :ip_address, :aliases => :IpAddress
attribute :description, :aliases => :Description
attribute :name, :aliases => :Name
attribute :port, :aliases => :Port
attribute :enabled, :aliases => :Enabled
attribute :id, :aliases => :Id
def delete
requires :href
connection.delete_node( href )
end
def save
if new_record?
result = connection.add_node( collection.href, _compose_node_data )
merge_attributes(result.body)
else
connection.configure_node( href, _compose_node_data )
end
end
private
def _compose_node_data
node_data = {}
self.class.attributes.select{ |attribute| !send(attribute).nil? }.each { |attribute| node_data[attribute] = send(attribute).to_s }
node_data
end
end
end
end
end

View file

@ -0,0 +1,31 @@
require 'fog/compute/models/ecloud/node'
module Fog
module Ecloud
class Compute
class Nodes < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::Node
attribute :href, :aliases => :Href
def all
check_href!( :messages => "the Nodes href of the Internet Service you want to enumerate" )
if data = connection.get_nodes(href).body[:NodeService]
load(data)
end
end
def get(uri)
if data = connection.get_node(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,22 @@
module Fog
module Ecloud
class Compute
class PublicIp < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
def internet_services
load_unless_loaded!
@internet_services ||= Fog::Ecloud::Compute::InternetServices.
new( :connection => connection,
:href => href.to_s + "/internetServices" )
end
end
end
end
end

View file

@ -0,0 +1,36 @@
require 'fog/compute/models/ecloud/public_ip'
module Fog
module Ecloud
class Compute
class PublicIps < Fog::Ecloud::Collection
undef_method :create
attribute :href, :aliases => :Href
model Fog::Ecloud::Compute::PublicIp
#get_request :get_public_ip
#vcloud_type "application/vnd.tmrk.ecloud.publicIp+xml"
#all_request lambda { |public_ips| public_ips.connection.get_public_ips(public_ips.href) }
def all
check_href!(:message => "the Public Ips href of the Vdc you want to enumerate")
if data = connection.get_public_ips(href).body[:PublicIPAddress]
load(data)
end
end
def get(uri)
if data = connection.get_public_ip(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,209 @@
module Fog
module Ecloud
class Compute
class Server < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type
attribute :name
attribute :status
attribute :network_connections, :aliases => :NetworkConnectionSection, :squash => :NetworkConnection
attribute :os, :aliases => :OperatingSystemSection
attribute :virtual_hardware, :aliases => :VirtualHardwareSection
attribute :storage_size, :aliases => :size
attribute :links, :aliases => :Link, :type => :array
def friendly_status
load_unless_loaded!
case status
when '0'
'creating'
when '2'
'off'
when '4'
'on'
else
'unkown'
end
end
def ready?
load_unless_loaded!
status == '2'
end
def on?
load_unless_loaded!
status == '4'
end
def off?
load_unless_loaded!
status == '2'
end
def power_on
power_operation( :power_on => :powerOn )
end
def power_off
power_operation( :power_off => :powerOff )
end
def shutdown
power_operation( :power_shutdown => :shutdown )
end
def power_reset
power_operation( :power_reset => :reset )
end
def graceful_restart
requires :href
shutdown
wait_for { off? }
power_on
end
def delete
requires :href
connection.delete_vapp( href)
end
def name=(new_name)
attributes[:name] = new_name
@changed = true
end
def cpus
if cpu_mess
{ :count => cpu_mess[:VirtualQuantity].to_i,
:units => cpu_mess[:AllocationUnits] }
end
end
def cpus=(qty)
@changed = true
cpu_mess[:VirtualQuantity] = qty.to_s
end
def memory
if memory_mess
{ :amount => memory_mess[:VirtualQuantity].to_i,
:units => memory_mess[:AllocationUnits] }
end
end
def memory=(amount)
@changed = true
memory_mess[:VirtualQuantity] = amount.to_s
end
def disks
disk_mess.map do |dm|
{ :number => dm[:AddressOnParent], :size => dm[:VirtualQuantity].to_i, :resource => dm[:HostResource] }
end
end
def add_disk(size)
if @disk_change == :deleted
raise RuntimeError, "Can't add a disk w/o saving changes or reloading"
else
@disk_change = :added
load_unless_loaded!
virtual_hardware[:Item] << { :ResourceType => '17',
:AddressOnParent => (disk_mess.map { |dm| dm[:AddressOnParent] }.sort.last.to_i + 1).to_s,
:VirtualQuantity => size.to_s }
end
true
end
def delete_disk(number)
if @disk_change == :added
raise RuntimeError, "Can't delete a disk w/o saving changes or reloading"
else
@disk_change = :deleted
load_unless_loaded!
unless number == 0
virtual_hardware[:Item].delete_if { |vh| vh[:ResourceType] == '17' && vh[:AddressOnParent].to_i == number }
end
end
true
end
def reload
reset_tracking
super
end
def save
if new_record?
#Lame ...
raise RuntimeError, "Should not be here"
else
if on?
if @changed
raise RuntimeError, "Can't save cpu, name or memory changes while the VM is on."
end
end
connection.configure_vapp( href, _compose_vapp_data )
end
reset_tracking
end
private
def reset_tracking
@disk_change = false
@changed = false
end
def _compose_vapp_data
{ :name => name,
:cpus => cpus[:count],
:memory => memory[:amount],
:disks => disks
}
end
def memory_mess
load_unless_loaded!
if virtual_hardware && virtual_hardware[:Item]
virtual_hardware[:Item].detect { |item| item[:ResourceType] == "4" }
end
end
def cpu_mess
load_unless_loaded!
if virtual_hardware && virtual_hardware[:Item]
virtual_hardware[:Item].detect { |item| item[:ResourceType] == "3" }
end
end
def disk_mess
load_unless_loaded!
if virtual_hardware && virtual_hardware[:Item]
virtual_hardware[:Item].select { |item| item[:ResourceType] == "17" }
else
[]
end
end
def power_operation(op)
requires :href
begin
connection.send(op.keys.first, href + "/power/action/#{op.values.first}" )
rescue Excon::Errors::InternalServerError => e
#Frankly we shouldn't get here ...
raise e unless e.to_s =~ /because it is already powered o(n|ff)/
end
true
end
end
end
end
end

View file

@ -0,0 +1,55 @@
require 'fog/compute/models/ecloud/server'
module Fog
module Ecloud
class Compute
class Servers < Fog::Ecloud::Collection
undef_method :create
model Fog::Ecloud::Compute::Server
attribute :href, :aliases => :Href
def all
check_href!(:parent => "Vdc")
load(_vapps)
end
def get(uri)
if data = connection.get_vapp(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
def create( catalog_item_uri, options )
options[:vdc_uri] = href
options[:cpus] ||= 1
options[:memory] ||= 512
data = connection.instantiate_vapp_template( catalog_item_uri, options ).body
object = new(data)
object
end
private
def _resource_entities
connection.get_vdc(href).body[:ResourceEntities][:ResourceEntity]
end
def _vapps
resource_entities = _resource_entities
if resource_entities.nil?
[]
else
resource_entities
end
end
end
end
end
end

View file

@ -0,0 +1,21 @@
module Fog
module Ecloud
class Compute
class Task < Fog::Ecloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :status
attribute :type
attribute :result, :aliases => :Result
attribute :owner, :aliases => :Owner
attribute :start_time, :aliases => :startTime, :type => :time
attribute :end_time, :aliases => :endTime, :type => :time
attribute :error, :aliases => :Error
end
end
end
end

View file

@ -0,0 +1,31 @@
require 'fog/compute/models/ecloud/task'
module Fog
module Ecloud
class Compute
class Tasks < Fog::Ecloud::Collection
model Fog::Ecloud::Compute::Task
attribute :href, :aliases => :Href
def all
check_href!
if data = connection.get_task_list(href).body[:Task]
load(data)
end
end
def get(uri)
if data = connection.get_task(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end

View file

@ -0,0 +1,81 @@
module Fog
module Ecloud
class Compute
class Vdc < Fog::Ecloud::Model
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd
attribute :name
attribute :type
attribute :description, :aliases => :Description
attribute :other_links, :aliases => :Link
attribute :compute_capacity, :aliases => :ComputeCapacity
attribute :storage_capacity, :aliases => :StorageCapacity
attribute :available_networks, :aliases => :AvailableNetworks, :squash => :Network
attribute :resource_entities, :aliases => :ResourceEntities, :squash => :ResourceEntity
attribute :deployed_vm_quota
attribute :instantiated_vm_quota
def public_ips
@public_ips ||= collection_based_on_type("application/vnd.tmrk.ecloud.publicIpsList+xml")
end
def internet_services
@internet_services ||= collection_based_on_type("application/vnd.tmrk.ecloud.internetServicesList+xml")
end
def backup_internet_services
@backup_internet_services ||= collection_based_on_type("application/vnd.tmrk.ecloud.internetServicesList+xml", BackupInternetServices)
end
def networks
@networks ||= Fog::Ecloud::Compute::Networks.
new( :connection => connection,
:href => href )
end
def servers
@servers ||= Fog::Ecloud::Compute::Servers.
new( :connection => connection,
:href => href )
end
def tasks
@tasks ||= Fog::Ecloud::Compute::Tasks.
new( :connection => connection,
:href => href + "/tasksList" )
end
def catalog
@catalog ||= collection_based_on_type("application/vnd.vmware.vcloud.catalog+xml")
end
def firewall_acls
@firewall_acls ||= collection_based_on_type("application/vnd.tmrk.ecloud.firewallAclsList+xml")
end
private
def collection_based_on_type(type, klass = nil)
load_unless_loaded!
if link = other_links.detect { |link| link[:type] == type }
case type
when "application/vnd.tmrk.ecloud.publicIpsList+xml"
Fog::Ecloud::Compute::PublicIps
when "application/vnd.tmrk.ecloud.internetServicesList+xml"
klass || Fog::Ecloud::Compute::InternetServices
when "application/vnd.vmware.vcloud.catalog+xml"
Fog::Ecloud::Compute::Catalog
when "application/vnd.tmrk.ecloud.firewallAclsList+xml"
Fog::Ecloud::Compute::FirewallAcls
end.new( :connection => connection, :href => link[:href] )
else
[ ]
end
end
end
end
end
end

View file

@ -0,0 +1,40 @@
require 'fog/compute/models/ecloud/vdc'
module Fog
module Ecloud
class Compute
class Vdcs < Collection
model Fog::Ecloud::Compute::Vdc
undef_method :create
def all
data = connection.get_organization(organization_uri).body[:Link].select { |link| link[:type] == "application/vnd.vmware.vcloud.vdc+xml" }
data.each { |link| link.delete_if { |key, value| [:rel].include?(key) } }
load(data)
end
def get(uri)
if data = connection.get_vdc(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
def organization_uri
@organizatio_uri ||= connection.default_organization_uri
end
private
def organization_uri=(new_organization_uri)
@organization_uri = new_organization_uri
end
end
end
end
end

View file

@ -0,0 +1,109 @@
module Fog
module Ecloud
class Compute
module Shared
def validate_backup_internet_service_data(service_data, configure=false)
required_opts = [:name, :protocol, :description, :enabled]
if configure
required_opts + [ :id, :href, :timeout ]
end
unless required_opts.all? { |opt| service_data.keys.include?(opt) }
raise ArgumentError.new("Required Backup Internet Service data missing: #{(required_opts - service_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def add_backup_internet_service(internet_services_uri, service_data)
validate_backup_internet_service_data(service_data)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
request(
:body => generate_backup_internet_service_request(service_data),
:expects => 200,
:headers => {'Content-Type' => 'application/xml'},
:method => 'POST',
:uri => internet_services_uri,
:parse => true
)
end
private
def generate_backup_internet_service_request(service_data)
builder = Builder::XmlMarkup.new
builder.CreateBackupInternetServiceRequest("xmlns" => "urn:tmrk:eCloudExtensions-2.5") {
builder.Name(service_data[:name])
builder.Protocol(service_data[:protocol])
builder.Enabled(service_data[:enabled])
builder.Description(service_data[:description])
builder.RedirectURL(service_data[:redirect_url])
if monitor = service_data[:monitor]
generate_monitor_section(builder,monitor)
end
}
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=729&Lang=1&SID=
# and many tears shed.
#
def add_backup_internet_service(internet_services_uri, service_data)
validate_backup_internet_service_data(service_data)
internet_services_uri = ensure_unparsed(internet_services_uri)
if vdc_internet_service_collection = mock_data.vdc_internet_service_collection_from_href(internet_services_uri)
new_backup_internet_service = MockBackupInternetService.new(service_data, vdc_internet_service_collection.backup_internet_services)
vdc_internet_service_collection.backup_internet_services << new_backup_internet_service
xml = generate_backup_internet_service_added_response(new_backup_internet_service)
mock_it 200, xml, {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
private
def generate_backup_internet_service_added_response(new_backup_internet_service)
builder = Builder::XmlMarkup.new
builder.InternetService("xmlns" => "urn:tmrk:eCloudExtensions-2.5", "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance") {
builder.Id new_backup_internet_service.object_id
builder.Href new_backup_internet_service.href
builder.Name new_backup_internet_service.name
# so broken
builder.PublicIpAddress do
builder.Id -2147483648
builder.Id "http://totally.invalid/1234"
builder.Name
end
builder.Port new_backup_internet_service.port
builder.Protocol new_backup_internet_service.protocol
builder.Enabled new_backup_internet_service.enabled
builder.Timeout new_backup_internet_service.timeout
builder.Description new_backup_internet_service.description
builder.RedirectURL new_backup_internet_service.redirect_url
builder.Monitor "i:nil" => true
# so broken
builder.IsBackupService false
builder.BackupService "i:nil" => true
builder.BackupOf "i:nil" => true
}
end
end
end
end
end

View file

@ -0,0 +1,149 @@
module Fog
module Ecloud
class Compute
module Shared
def validate_internet_service_monitor(monitor)
#FIXME: Refactor this type of function into something generic
unless ['Disabled','HTTP','ECV'].include?(monitor[:type])
raise ArgumentError.new("Supported monitor types are: ECV & HTTP")
end
required_opts = case monitor[:type]
when "Disabled"
[:type, :is_enabled]
else
[:type, :url_send_string, :http_headers, :receive_string, :is_enabled]
end
unless required_opts.all? { |opt| monitor.keys.include?(opt) && monitor[opt] }
raise ArgumentError.new("Required Monitor data missing: #{(required_opts - monitor.keys).map(&:inspect).join(", ")}")
end
case monitor[:type]
when "HTTP", "ECV"
unless monitor[:http_headers].is_a?(Array) || monitor[:http_headers].is_a?(String)
raise ArgumentError.new("Monitor :http_headers must be a String or Array")
end
end
unless [true, false, "true", "false"].include?(monitor[:is_enabled])
raise ArgumentError.new("Monitor :is_enabled must be true or false")
end
end
def validate_internet_service_data(service_data, configure=false)
required_opts = [:name, :protocol, :port, :description, :enabled]
if configure
required_opts + [ :id, :href, :timeout ]
end
unless required_opts.all? { |opt| service_data.keys.include?(opt) }
raise ArgumentError.new("Required Internet Service data missing: #{(required_opts - service_data.keys).map(&:inspect).join(", ")}")
end
end
def ensure_monitor_defaults!(monitor)
if monitor[:http_headers].is_a?(String)
monitor[:http_headers] = [ monitor[:http_headers] ]
end
unless monitor[:retries]
monitor[:retries] = 3
end
unless monitor[:response_timeout]
monitor[:response_timeout] = 2
end
unless monitor[:down_time]
monitor[:down_time] = 30
end
unless monitor[:interval]
monitor[:interval] = 5
end
end
end
class Real
include Shared
def add_internet_service(internet_services_uri, service_data)
validate_internet_service_data(service_data)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
request(
:body => generate_internet_service_request(service_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'},
:method => 'POST',
:uri => internet_services_uri,
:parse => true
)
end
private
def generate_internet_service_request(service_data)
builder = Builder::XmlMarkup.new
builder.CreateInternetServiceRequest(ecloud_xmlns) {
builder.Name(service_data[:name])
builder.Protocol(service_data[:protocol])
builder.Port(service_data[:port])
builder.Enabled(service_data[:enabled])
builder.Description(service_data[:description])
builder.RedirectURL(service_data[:redirect_url])
if monitor = service_data[:monitor]
generate_monitor_section(builder,monitor)
end
}
end
def generate_monitor_section(builder, monitor)
builder.Monitor {
builder.MonitorType(monitor[:type])
case monitor[:type]
when "ECV","HTTP"
builder.UrlSendString(monitor[:url_send_string])
builder.HttpHeader(monitor[:http_headers].join("\n"))
builder.ReceiveString(monitor[:receive_string])
builder.Interval(monitor[:interval])
builder.ResponseTimeOut(monitor[:response_timeout])
builder.DownTime(monitor[:downtime])
builder.Retries(monitor[:retries])
end
builder.IsEnabled(monitor[:is_enabled])
}
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=561&Lang=1&SID=
#
def add_internet_service(internet_services_uri, service_data)
validate_internet_service_data(service_data)
internet_services_uri = ensure_unparsed(internet_services_uri)
if public_ip_internet_service_collection = mock_data.public_ip_internet_service_collection_from_href(internet_services_uri)
new_public_ip_internet_service = MockPublicIpInternetService.new(service_data, public_ip_internet_service_collection)
public_ip_internet_service_collection.items << new_public_ip_internet_service
xml = generate_internet_service(Builder::XmlMarkup.new, new_public_ip_internet_service, true)
mock_it 200, xml, {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,62 @@
module Fog
module Ecloud
class Compute
module Shared
private
def generate_node_request(node_data)
builder = Builder::XmlMarkup.new
builder.CreateNodeServiceRequest(ecloud_xmlns) {
builder.IpAddress(node_data[:ip_address])
builder.Name(node_data[:name])
builder.Port(node_data[:port])
builder.Enabled(node_data[:enabled])
builder.Description(node_data[:description])
}
end
def validate_node_data(node_data, configure=false)
valid_opts = [:name, :port, :enabled, :description, :ip_address]
if configure
valid_opts.delete_if { |opt| ![:name, :enabled, :description].include?(opt) }
end
unless valid_opts.all? { |opt| node_data.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - node_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def add_node(nodes_uri, node_data)
validate_node_data(node_data)
request(
:body => generate_node_request(node_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml'},
:method => 'POST',
:uri => nodes_uri,
:parse => true
)
end
end
class Mock
include Shared
def add_node(nodes_uri, node_data)
validate_node_data(node_data)
if node_collection = mock_data.public_ip_internet_service_node_collection_from_href(ensure_unparsed(nodes_uri))
new_node = MockPublicIpInternetServiceNode.new(node_data, node_collection)
node_collection.items << new_node
mock_it 200, mock_node_service_response(new_node), { 'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,40 @@
module Fog
module Ecloud
class Compute
class Real
def validate_clone_vapp_options(options)
valid_opts = [:name, :poweron]
unless valid_opts.all? { |opt| options.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - options.keys).map(&:inspect).join(", ")}")
end
end
def generate_clone_vapp_request(uri, options)
xml = Builder::XmlMarkup.new
xml.CloneVAppParams(xmlns.merge!(:name => options[:name], :deploy => "true", :powerOn => options[:poweron])) {
xml.VApp( :href => uri, :type => "application/vnd.vmware.vcloud.vApp+xml",
:xmlns => "http://www.vmware.com/vcloud/v0.8")
}
end
def clone_vapp(vdc_uri, vapp_uri, options = {})
unless options.has_key?(:poweron)
options[:poweron] = "false"
end
validate_clone_vapp_options(options)
request(
:body => generate_clone_vapp_request(vapp_uri, options),
:expects => 202,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.cloneVAppParams+xml'},
:method => 'POST',
:uri => vdc_uri + '/action/clonevapp',
:parse => true
)
end
end
end
end
end

View file

@ -0,0 +1,112 @@
module Fog
module Ecloud
class Compute
module Shared
private
def validate_public_ip_address_data(ip_address_data)
valid_opts = [:name, :href, :id]
unless valid_opts.all? { |opt| ip_address_data.keys.include?(opt) }
raise ArgumentError.new("Required Internet Service data missing: #{(valid_opts - ip_address_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def configure_internet_service(internet_service_uri, service_data, ip_address_data)
validate_internet_service_data(service_data, true)
validate_public_ip_address_data(ip_address_data)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
request(
:body => generate_configure_internet_service_request(service_data, ip_address_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'},
:method => 'PUT',
:uri => internet_service_uri,
:parse => true
)
end
private
def generate_configure_internet_service_request(service_data, ip_address_data)
builder = Builder::XmlMarkup.new
builder.InternetService(ecloud_xmlns) {
builder.Id(service_data[:id])
builder.Href(service_data[:href])
builder.Name(service_data[:name])
builder.Protocol(service_data[:protocol])
builder.Port(service_data[:port])
builder.Enabled(service_data[:enabled])
builder.Description(service_data[:description])
builder.Timeout(service_data[:timeout])
builder.RedirectURL(service_data[:redirect_url])
builder.PublicIpAddress {
builder.Id(ip_address_data[:id])
builder.Href(ip_address_data[:href])
builder.Name(ip_address_data[:name])
}
if monitor = service_data[:monitor]
generate_monitor_section(builder, monitor)
end
if service_data[:backup_service_uri]
builder.BackupService do
builder.Href(service_data[:backup_service_uri])
end
end
}
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=583&Lang=1&SID=
#
def configure_internet_service(internet_service_uri, service_data, ip_address_data)
service_data = service_data.dup
validate_internet_service_data(service_data, true)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
validate_public_ip_address_data(ip_address_data)
internet_service_uri = ensure_unparsed(internet_service_uri)
backup_service_uri = service_data.delete(:backup_service_uri)
backup_service = backup_service_uri && mock_data.backup_internet_service_from_href(backup_service_uri)
xml = nil
if (public_ip_internet_service = mock_data.public_ip_internet_service_from_href(internet_service_uri)) &&
(backup_service_uri.nil? || backup_service)
public_ip_internet_service.update(service_data.reject {|k, v| [:id, :href].include?(k) })
public_ip_internet_service[:backup_service] = backup_service
xml = generate_internet_service(Builder::XmlMarkup.new, public_ip_internet_service, true)
end
if xml
mock_it 200, xml, {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,44 @@
module Fog
module Ecloud
class Compute
class Real
def validate_network_data(network_data, configure=false)
valid_opts = [:id, :href, :name, :rnat, :address, :broadcast, :gateway]
unless valid_opts.all? { |opt| network_data.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - network_data.keys).map(&:inspect).join(", ")}")
end
end
def configure_network(network_uri, network_data)
validate_network_data(network_data)
request(
:body => generate_configure_network_request(network_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.networkService+xml'},
:method => 'PUT',
:uri => network_uri,
:parse => true
)
end
private
def generate_configure_network_request(network_data)
builder = Builder::XmlMarkup.new
builder.Network(ecloud_xmlns) {
builder.Id(network_data[:id])
builder.Href(network_data[:href])
builder.Name(network_data[:name])
builder.RnatAddress(network_data[:rnat])
builder.Address(network_data[:address])
builder.BroadcastAddress(network_data[:broadcast])
builder.GatewayAddress(network_data[:gateway])
}
end
end
end
end
end

View file

@ -0,0 +1,66 @@
module Fog
module Ecloud
class Compute
module Shared
private
def validate_network_ip_data(network_ip_data)
valid_opts = [:id, :href, :name, :status, :server, :rnat]
unless valid_opts.all? { |opt| network_ip_data.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - network_ip_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def configure_network_ip(network_ip_uri, network_ip_data)
validate_network_ip_data(network_ip_data)
request(
:body => generate_configure_network_ip_request(network_ip_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.ip+xml' },
:method => 'PUT',
:uri => network_ip_uri,
:parse => true
)
end
private
def generate_configure_network_ip_request(network_ip_data)
builder = Builder::XmlMarkup.new
builder.IpAddress(ecloud_xmlns) {
builder.Id(network_ip_data[:id])
builder.Href(network_ip_data[:href])
builder.Name(network_ip_data[:name])
builder.Status(network_ip_data[:status])
builder.Server(network_ip_data[:server])
builder.RnatAddress(network_ip_data[:rnat])
}
end
end
class Mock
include Shared
def configure_network_ip(network_ip_uri, network_ip_data)
validate_network_ip_data(network_ip_data)
if network_ip = mock_data.network_ip_from_href(network_ip_uri)
network_ip[:rnat] = network_ip_data[:rnat]
builder = Builder::XmlMarkup.new
xml = network_ip_response(builder, network_ip, ecloud_xmlns)
mock_it 200, xml, { 'Content-Type' => 'application/vnd.tmrk.ecloud.ip+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,56 @@
module Fog
module Ecloud
class Compute
module Shared
private
def generate_configure_node_request(node_data)
builder = Builder::XmlMarkup.new
builder.NodeService(:"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance",
:xmlns => "urn:tmrk:eCloudExtensions-2.0") {
builder.Name(node_data[:name])
builder.Enabled(node_data[:enabled].to_s)
builder.Description(node_data[:description])
}
end
end
class Real
include Shared
def configure_node(node_uri, node_data)
validate_node_data(node_data, true)
request(
:body => generate_configure_node_request(node_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml'},
:method => 'PUT',
:uri => node_uri,
:parse => true
)
end
end
class Mock
include Shared
def configure_node(node_uri, node_data)
validate_node_data(node_data, true)
if node = mock_data.public_ip_internet_service_node_from_href(ensure_unparsed(node_uri))
node.update(node_data)
#if node_data[:enabled]
# node.enabled = (node_data[:enabled] == "true") ? true : false
#end
mock_it 200, mock_node_service_response(node), { 'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,144 @@
module Fog
module Ecloud
class Compute
module Shared
private
def validate_vapp_data(vapp_data)
valid_opts = [:name, :cpus, :memory, :disks]
unless valid_opts.all? { |opt| vapp_data.keys.include?(opt) }
raise ArgumentError.new("Required Vapp data missing: #{(valid_opts - vapp_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def generate_configure_vapp_request(vapp_uri, vapp_data)
rasd_xmlns = { "xmlns" => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" }
xml = Nokogiri::XML(request( :uri => vapp_uri).body)
xml.root['name'] = vapp_data[:name]
#cpu
xml.at("//xmlns:ResourceType[.='3']/..", rasd_xmlns).at('.//xmlns:VirtualQuantity', rasd_xmlns).content = vapp_data[:cpus]
#memory
xml.at("//xmlns:ResourceType[.='4']/..", rasd_xmlns).at('.//xmlns:VirtualQuantity', rasd_xmlns).content = vapp_data[:memory]
#disks
real_disks = xml.xpath("//xmlns:ResourceType[ .='17']/..", rasd_xmlns)
real_disk_numbers = real_disks.map { |disk| disk.at('.//xmlns:AddressOnParent', rasd_xmlns).content }
disk_numbers = vapp_data[:disks].map { |vdisk| vdisk[:number].to_s }
if vapp_data[:disks].length < real_disks.length
#Assume we're removing a disk
remove_disk_numbers = real_disk_numbers - disk_numbers
remove_disk_numbers.each do |number|
if result = xml.at("//xmlns:ResourceType[ .='17']/../xmlns:AddressOnParent[.='#{number}']/..", rasd_xmlns)
result.remove
end
end
elsif vapp_data[:disks].length > real_disks.length
add_disk_numbers = disk_numbers - real_disk_numbers
add_disk_numbers.each do |number|
new_disk = real_disks.first.dup
new_disk.at('.//xmlns:AddressOnParent', rasd_xmlns).content = -1
new_disk.at('.//xmlns:VirtualQuantity', rasd_xmlns).content = vapp_data[:disks].detect { |disk| disk[:number].to_s == number.to_s }[:size]
real_disks.first.parent << new_disk
end
end
#puts xml.root.to_s
xml.root.to_s
#builder = Builder::XmlMarkup.new
#builder.Vapp(:href => vapp_uri.to_s,
# :type => 'application/vnd.vmware.vcloud.vApp+xml',
# :name => vapp_data[:name],
# :status => 2,
# :size => 0,
# :xmlns => 'http://www.vmware.com/vcloud/v0.8',
# :"xmlns:xsi" => 'http://www.w3.org/2001/XMLSchema-instance',
# :"xmlns:xsd" => 'http://www.w3.org/2001/XMLSchema') {
# #builder.VirtualHardwareSection(:xmlns => 'http://schemas.dmtf.org/ovf/envelope/1') {
# builder.Section(:"xsi:type" => "q2:VirtualHardwareSection_Type", :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"xmlns:q2" => "http://www.vmware.com/vcloud/v0.8") {
# builder.Info('Virtual Hardware')
# builder.Item(:xmlns => 'http://schemas.dmtf.org/ovf/envelope/1') {
# #builder.Item {
# builder.InstanceID(1, :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.ResourceType(3, :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.VirtualQuantity(vapp_data[:cpus], :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# }
# builder.Item(:xmlns => 'http://schemas.dmtf.org/ovf/envelope/1') {
# #builder.Item {
# builder.InstanceID(2, :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.ResourceType(4, :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.VirtualQuantity(vapp_data[:memory], :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# }
# vapp_data[:disks].each do |disk_data|
# #builder.Item(:xmlns => 'http://schemas.dmtf.org/ovf/envelope/1') {
# builder.Item {
# builder.AddressOnParent(disk_data[:number], :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.HostResource(disk_data[:resource], :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.InstanceID(9, :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.ResourceType(17, :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# builder.VirtualQuantity(disk_data[:size], :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
# }
# end
#
# }
#}
end
def configure_vapp(vapp_uri, vapp_data)
validate_vapp_data(vapp_data)
request(
:body => generate_configure_vapp_request(vapp_uri, vapp_data),
:expects => 202,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.vApp+xml' },
:method => 'PUT',
:uri => vapp_uri,
:parse => true
)
end
end
class Mock
include Shared
def configure_vapp(vapp_uri, vapp_data)
validate_vapp_data(vapp_data)
if vapp = mock_data.virtual_machine_from_href(vapp_uri)
vapp_data.each do |key, value|
case key
when :cpus, :memory
vapp[key] = value
when :disks
addresses_to_delete = vapp.disks.map {|d| d.address } - value.map {|d| d[:number] }
addresses_to_delete.each do |address_to_delete|
vapp.disks.delete(vapp.disks.at_address(address_to_delete))
end
current_addresses = vapp.disks.map {|d| d.address }
disks_to_add = value.find_all {|d| !current_addresses.include?(d[:number]) }
disks_to_add.each do |disk_to_add|
vapp.disks << MockVirtualMachineDisk.new(:size => disk_to_add[:size] / 1024, :address => disk_to_add[:number])
end
end
end
mock_it 200, '', { "Location" => mock_data.base_url + "/some_tasks/1234" }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,22 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :delete_internet_service, 200, 'DELETE', {}, ""
end
class Mock
def delete_internet_service(service_uri)
if public_ip_internet_service = mock_data.public_ip_internet_service_from_href(service_uri)
public_ip_internet_service._parent.items.delete(public_ip_internet_service)
mock_it 200, '', { }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,22 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :delete_node, 200, 'DELETE', {}, ""
end
class Mock
def delete_node(node_uri)
if node = mock_data.public_ip_internet_service_node_from_href(ensure_unparsed(node_uri))
node._parent.items.delete(node)
mock_it 200, '', {}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,29 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :delete_vapp, 202, "DELETE"
end
class Mock
def delete_vapp(vapp_uri)
if virtual_machine = mock_data.virtual_machine_from_href(vapp_uri)
vdc = virtual_machine._parent
if vdc.internet_service_collection.items.detect {|is| is.node_collection.items.any? {|isn| isn.ip_address == virtual_machine.ip } } ||
virtual_machine.status != 2 ||
virtual_machine.network_ip.rnat_set?
mock_it 202, '', {}
else
vdc.virtual_machines.delete(virtual_machine)
mock_it 202, '', { "Location" => mock_data.base_url + "/some_tasks/1234" }
end
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,44 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_catalog
end
class Mock
def get_catalog(catalog_uri)
catalog_uri = ensure_unparsed(catalog_uri)
xml = nil
if catalog = mock_data.catalog_from_href(catalog_uri)
builder = Builder::XmlMarkup.new
xml = builder.Catalog(xmlns.merge(
:type => "application/vnd.vmware.vcloud.catalog+xml",
:href => catalog.href,
:name => catalog.name
)) do |xml|
xml.CatalogItems do |xml|
catalog.items.each do |catalog_item|
xml.CatalogItem(
:type => "application/vnd.vmware.vcloud.catalogItem+xml",
:href => catalog_item.href,
:name => catalog_item.name
)
end
end
end
end
if xml
mock_it 200,
xml, { 'Content-Type' => 'application/vnd.vmware.vcloud.catalog+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,47 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_catalog_item
end
class Mock
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=542&Lang=1&SID=
#
def get_catalog_item(catalog_item_uri)
if catalog_item = mock_data.catalog_item_from_href(catalog_item_uri)
builder = Builder::XmlMarkup.new
xml = builder.CatalogItem(xmlns.merge(:href => catalog_item.href, :name => catalog_item.name)) do
builder.Link(
:rel => "down",
:href => catalog_item.customization.href,
:type => "application/vnd.tmrk.ecloud.catalogItemCustomizationParameters+xml",
:name => catalog_item.customization.name
)
builder.Entity(
:href => catalog_item.vapp_template.href,
:type => "application/vnd.vmware.vcloud.vAppTemplate+xml",
:name => catalog_item.vapp_template.name
)
builder.Property(0, :key => "LicensingCost")
end
end
if xml
mock_it 200, xml, {'Content-Type' => 'application/vnd.vmware.vcloud.catalogItem+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,22 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_customization_options
end
class Mock
def get_customization_options(options_uri)
builder = Builder::XmlMarkup.new
xml = builder.CustomizationParameters(xmlns) do
builder.CustomizeNetwork "true"
builder.CustomizePassword "false"
end
mock_it 200, xml, "Content-Type" => "application/vnd.tmrk.ecloud.catalogItemCustomizationParameters+xml"
end
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_firewall_acl
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_firewall_acls
end
end
end
end

View file

@ -0,0 +1,82 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_internet_services
end
class Mock
#
#Based off of:
#http://support.theenterprisecloud.com/kb/default.asp?id=580&Lang=1&SID=
#http://support.theenterprisecloud.com/kb/default.asp?id=560&Lang=1&SID=
#
#
def get_internet_services(internet_services_uri)
internet_services_uri = ensure_unparsed(internet_services_uri)
xml = nil
if vdc_internet_service_collection = mock_data.vdc_internet_service_collection_from_href(internet_services_uri)
xml = generate_internet_services(vdc_internet_service_collection.items)
elsif public_ip_internet_service_collection = mock_data.public_ip_internet_service_collection_from_href(internet_services_uri)
xml = generate_internet_services(public_ip_internet_service_collection.items)
end
if xml
mock_it 200,
xml, { 'Content-Type' => 'application/vnd.tmrk.ecloud.internetServicesList+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
private
def generate_internet_services(services)
builder = Builder::XmlMarkup.new
builder.InternetServices("xmlns" => "urn:tmrk:eCloudExtensions-2.5", "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance") {|xml|
services.each do |service|
generate_internet_service(xml, service)
end
}
end
def generate_internet_service(xml, service, by_itself = false)
xml.InternetService(by_itself ? { "xmlns" => "urn:tmrk:eCloudExtensions-2.5", "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance" } : {}) {
xml.Id service.object_id
xml.Href service.href
xml.Name service.name
if MockDataClasses::MockBackupInternetService === service
xml.PublicIpAddress "i:nil" => true
else
xml.PublicIpAddress {
xml.Id service._parent._parent.object_id
xml.Href service._parent._parent.href
xml.Name service._parent._parent.name
}
end
xml.Port service.port
xml.Protocol service.protocol
xml.Enabled service.enabled
xml.Timeout service.timeout
xml.Description service.description
xml.RedirectURL service.redirect_url
xml.Monitor "i:nil" => true
xml.IsBackupService MockDataClasses::MockBackupInternetService === service
if MockDataClasses::MockPublicIpInternetService === service && service.backup_service
xml.BackupService do
xml.Href service.backup_service.href
end
else
xml.BackupService "i:nil" => true
end
xml.BackupOf
}
end
end
end
end
end

View file

@ -0,0 +1,44 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_network
end
class Mock
#
# Based off of:
# http://support.theenterprisecloud.com/kb/default.asp?id=546&Lang=1&SID=
#
def get_network(network_uri)
network_uri = ensure_unparsed(network_uri)
if network = mock_data.network_from_href(network_uri)
builder = Builder::XmlMarkup.new
xml = builder.Network(xmlns.merge(:href => network.href, :name => network.name, :type => "application/vnd.vmware.vcloud.network+xml")) {
builder.Link(:rel => "down", :href => network.ip_collection.href, :type => "application/xml", :name => network.ip_collection.name)
builder.Link(:rel => "down", :href => network.extensions.href, :type => "application/xml", :name => network.name)
builder.Configuration {
builder.Gateway(network.gateway)
builder.Netmask(network.netmask)
}
if network.features
builder.Features {
network.features.each do |feature|
builder.tag!(feature[:type], feature[:value])
end
}
end
}
mock_it 200, xml, { "Content-Type" => "application/vnd.vmware.vcloud.network+xml" }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,33 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_network_extensions
end
class Mock
def get_network_extensions(network_extension_uri)
if network_extension = mock_data.network_extension_from_href(ensure_unparsed(network_extension_uri))
xml = Builder::XmlMarkup.new
mock_it 200, xml.Network(ecloud_xmlns) {
xml.Address network_extension.address
xml.RnatAddress network_extension.rnat
xml.Href network_extension.href
xml.Id network_extension.object_id
xml.Name network_extension.name
xml.GatewayAddress network_extension.gateway
xml.BroadcastAddress network_extension.broadcast
xml.NetworkType network_extension.type
xml.Vlan network_extension.vlan
xml.FriendlyName network_extension.friendly_name
}, { 'Content-Type' => "application/vnd.tmrk.ecloud.network+xml" }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,43 @@
#
# AFAICT this is basically undocumented ATM - 6/18/2010 - freeformz
#
module Fog
module Ecloud
class Compute
class Real
basic_request :get_network_ip
end
class Mock
def get_network_ip(network_ip_uri)
if network_ip = mock_data.network_ip_from_href(network_ip_uri)
builder = Builder::XmlMarkup.new
xml = network_ip_response(builder, network_ip, ecloud_xmlns)
mock_it 200, xml, { 'Content-Type' => 'application/vnd.tmrk.ecloud.ip+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
def network_ip_response(builder, network_ip, xmlns = {})
builder.IpAddress(xmlns) do
builder.Id network_ip.object_id
builder.Href network_ip.href
builder.Name network_ip.name
builder.Status network_ip.status
if network_ip.used_by
builder.Server network_ip.used_by.name
end
builder.RnatAddress(network_ip.rnat)
end
end
end
end
end
end

View file

@ -0,0 +1,35 @@
#
# AFAICT - This is basically undocumented - 6/18/2010 - freeformz
#
module Fog
module Ecloud
class Compute
class Real
basic_request :get_network_ips
end
class Mock
def get_network_ips(network_ips_uri)
network_ips_uri = ensure_unparsed(network_ips_uri)
if network_ip_collection = mock_data.network_ip_collection_from_href(network_ips_uri)
builder = Builder::XmlMarkup.new
xml = builder.IpAddresses do
network_ip_collection.ordered_ips.each do |network_ip|
network_ip_response(builder, network_ip)
end
end
mock_it 200, xml, { 'Content-Type' => 'application/vnd.tmrk.ecloud.ipAddressesList+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,40 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_node
end
class Mock
#
# Based on http://support.theenterprisecloud.com/kb/default.asp?id=641&Lang=1&SID=
#
def mock_node_service_response(node)
xml = Builder::XmlMarkup.new
xml.NodeService(ecloud_xmlns) {
xml.Id(node.object_id)
xml.Href(node.href)
xml.Name(node.name)
xml.IpAddress(node.ip_address)
xml.Port(node.port)
xml.Enabled(node.enabled)
xml.Description(node.description)
}
end
def get_node(node_uri)
node_uri = ensure_unparsed(node_uri)
if public_ip_internet_service_node = mock_data.public_ip_internet_service_node_from_href(node_uri)
xml = Builder::XmlMarkup.new
mock_it 200, mock_node_service_response(public_ip_internet_service_node), { 'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,41 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_nodes
end
class Mock
#
# Based off of:
# http://support.theenterprisecloud.com/kb/default.asp?id=637&Lang=1&SID=
#
def get_nodes(nodes_uri)
nodes_uri = ensure_unparsed(nodes_uri)
if public_ip_internet_service_node_collection = mock_data.public_ip_internet_service_node_collection_from_href(nodes_uri)
xml = Builder::XmlMarkup.new
mock_it 200,
xml.NodeServices(ecloud_xmlns) {
public_ip_internet_service_node_collection.items.each do |node|
xml.NodeService {
xml.Id node.object_id
xml.Href node.href
xml.Name node.name
xml.IpAddress node.ip_address
xml.Port node.port
xml.Enabled node.enabled
xml.Description node.description
}
end
}, { 'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,49 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_organization
end
class Mock
def get_organization(organization_uri)
#
# Based off of:
# http://support.theenterprisecloud.com/kb/default.asp?id=540&Lang=1&SID=
#
# vCloud API Guide v0.9 - Page 26
#
organization_uri = ensure_unparsed(organization_uri)
if organization = mock_data.organization_from_href(organization_uri)
xml = Builder::XmlMarkup.new
mock_it 200,
xml.Org(xmlns.merge(:href => organization.href, :name => organization.name)) {
organization.vdcs.each do |vdc|
xml.Link(:rel => "down",
:href => vdc.href,
:type => "application/vnd.vmware.vcloud.vdc+xml",
:name => vdc.name)
xml.Link(:rel => "down",
:href => vdc.catalog.href,
:type => "application/vnd.vmware.vcloud.catalog+xml",
:name => vdc.catalog.name)
xml.Link(:rel => "down",
:href => vdc.task_list.href,
:type => "application/vnd.vmware.vcloud.tasksList+xml",
:name => vdc.task_list.name)
end
},
{'Content-Type' => "application/vnd.vmware.vcloud.org+xml" }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,34 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_public_ip
end
class Mock
#
#Based off of:
#http://support.theenterprisecloud.com/kb/default.asp?id=567&Lang=1&SID=
#
def get_public_ip(public_ip_uri)
public_ip_uri = ensure_unparsed(public_ip_uri)
if public_ip = mock_data.public_ip_from_href(public_ip_uri)
xml = Builder::XmlMarkup.new
mock_it 200,
xml.PublicIp(:xmlns => "urn:tmrk:eCloudExtensions-2.0", :"xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance") {
xml.Id public_ip.object_id
xml.Href public_ip.href
xml.Name public_ip.name
}, { 'Content-Type' => 'application/vnd.tmrk.ecloud.publicIp+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,38 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_public_ips
end
class Mock
#
# Based off of:
# http://support.theenterprisecloud.com/kb/default.asp?id=577&Lang=1&SID=
#
def get_public_ips(public_ips_uri)
public_ips_uri = ensure_unparsed(public_ips_uri)
if public_ip_collection = mock_data.public_ip_collection_from_href(public_ips_uri)
xml = Builder::XmlMarkup.new
mock_it 200,
xml.PublicIPAddresses {
public_ip_collection.items.each do |ip|
xml.PublicIPAddress {
xml.Id ip.object_id
xml.Href ip.href
xml.Name ip.name
}
end
}, { 'Content-Type' => 'application/vnd.tmrk.ecloud.publicIpsList+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_task
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_task_list
end
end
end
end

View file

@ -0,0 +1,99 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_vapp
end
class Mock
def return_vapp_as_creating!(name)
vapps_to_return_as_creating[name] = true
end
def vapps_to_return_as_creating
@vapps_to_return_as_creating ||= {}
end
def get_vapp(vapp_uri)
xml = nil
if vapp = mock_data.virtual_machine_from_href(vapp_uri)
if vapps_to_return_as_creating[vapp.name]
xml = generate_instantiate_vapp_template_response(vapp)
else
xml = generate_get_vapp_response(vapp)
end
end
if xml
mock_it 200, xml, "Content-Type" => "application/vnd.vmware.vcloud.vApp+xml"
else
mock_error 200, "401 Unauthorized"
end
end
private
def generate_get_vapp_response(vapp)
builder = Builder::XmlMarkup.new
builder.VApp(xmlns.merge(
:href => vapp.href,
:type => "application/vnd.vmware.vcloud.vApp+xml",
:name => vapp.name,
:status => vapp.status,
:size => vapp.size
)) do
builder.Link(:rel => "up", :href => vapp._parent.href, :type => "application/vnd.vmware.vcloud.vdc+xml")
builder.NetworkConnectionSection(:xmlns => "http://schemas.dmtf.org/ovf/envelope/1") do
builder.NetworkConnection(:Network => "Internal", :xmlns => "http://www.vmware.com/vcloud/v0.8") do
builder.IpAddress vapp.ip
end
end
builder.OperatingSystemSection(
"d2p1:id" => 4,
:xmlns => "http://schemas.dmtf.org/ovf/envelope/1",
"xmlns:d2p1" => "http://schemas.dmtf.org/ovf/envelope/1") do
builder.Info "The kind of installed guest operating system"
builder.Description "Red Hat Enterprise Linux 5 (64-bit)"
end
builder.VirtualHardwareSection(:xmlns => "http://schemas.dmtf.org/ovf/envelope/1") do
builder.Info
builder.System
builder.Item do
# CPUs
builder.VirtualQuantity vapp.cpus
builder.ResourceType 3
end
builder.Item do
# memory
builder.VirtualQuantity vapp.memory
builder.ResourceType 4
end
builder.Item do
# SCSI controller
builder.Address 0
builder.ResourceType 6
builder.InstanceId 3
end
# Hard Disks
vapp.disks.each do |disk|
builder.Item do
builder.Parent 3
builder.VirtualQuantity disk.vcloud_size
builder.HostResource disk.vcloud_size
builder.ResourceType 17
builder.AddressOnParent disk.address
end
end
end
end
end
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_vapp_template
end
end
end
end

View file

@ -0,0 +1,84 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :get_vdc
end
class Mock
#
#Based off of:
#http://support.theenterprisecloud.com/kb/default.asp?id=545&Lang=1&SID=
def get_vdc(vdc_uri)
vdc_uri = ensure_unparsed(vdc_uri)
if vdc = mock_data.vdc_from_href(vdc_uri)
xml = Builder::XmlMarkup.new
mock_it 200,
xml.Vdc(xmlns.merge(:href => vdc.href, :name => vdc.name)) {
xml.Link(:rel => "down",
:href => vdc.catalog.href,
:type => "application/vnd.vmware.vcloud.catalog+xml",
:name => vdc.catalog.name)
xml.Link(:rel => "down",
:href => vdc.public_ip_collection.href,
:type => "application/vnd.tmrk.ecloud.publicIpsList+xml",
:name => vdc.public_ip_collection.name)
xml.Link(:rel => "down",
:href => vdc.internet_service_collection.href,
:type => "application/vnd.tmrk.ecloud.internetServicesList+xml",
:name => vdc.internet_service_collection.name)
xml.Link(:rel => "down",
:href => vdc.firewall_acls.href,
:type => "application/vnd.tmrk.ecloud.firewallAclsList+xml",
:name => vdc.firewall_acls.name)
xml.Description("")
xml.StorageCapacity {
xml.Units("bytes * 10^9")
xml.Allocated(vdc.storage_allocated)
xml.Used(vdc.storage_used)
}
xml.ComputeCapacity {
xml.Cpu {
xml.Units("hz * 10^6")
xml.Allocated(vdc.cpu_allocated)
}
xml.Memory {
xml.Units("bytes * 2^20")
xml.Allocated(vdc.memory_allocated)
}
xml.DeployedVmsQuota {
xml.Limit("-1")
xml.Used("-1")
}
xml.InstantiatedVmsQuota {
xml.Limit("-1")
xml.Used("-1")
}
}
xml.ResourceEntities {
vdc.virtual_machines.each do |virtual_machine|
xml.ResourceEntity(:href => virtual_machine.href,
:type => "application/vnd.vmware.vcloud.vApp+xml",
:name => virtual_machine.name)
end
}
xml.AvailableNetworks {
vdc.networks.each do |network|
xml.Network(:href => network.href,
:type => "application/vnd.vmware.vcloud.network+xml",
:name => network.name)
end
}
}, { 'Content-Type' => 'application/vnd.vmware.vcloud.vdc+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,37 @@
module Fog
module Ecloud
class Compute
class Real
unauthenticated_basic_request :get_versions
end
class Mock
def get_versions(versions_uri)
#
# Based off of:
# http://support.theenterprisecloud.com/kb/default.asp?id=535&Lang=1&SID=
# https://community.vcloudexpress.terremark.com/en-us/product_docs/w/wiki/02-get-versions.aspx
# vCloud API Guide v0.9 - Page 89
#
xml = Builder::XmlMarkup.new
mock_it 200,
xml.SupportedVersions( xmlns.merge("xmlns" => "http://www.vmware.com/vcloud/versions")) {
mock_data.versions.select {|version| version.supported }.each do |version|
xml.VersionInfo {
xml.Version(version.version)
xml.LoginUrl(version.login_url)
}
end
}
end
end
end
end
end

View file

@ -0,0 +1,142 @@
module Fog
module Ecloud
class Compute
module Shared
private
def validate_instantiate_vapp_template_options(catalog_item_uri, options)
valid_opts = [:name, :vdc_uri, :network_uri, :cpus, :memory, :row, :group]
unless valid_opts.all? { |opt| options.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - options.keys).map(&:inspect).join(", ")}")
end
# Figure out the template_uri
catalog_item = get_catalog_item( catalog_item_uri ).body
catalog_item[:Entity] = [ catalog_item[:Entity] ] if catalog_item[:Entity].is_a?(Hash)
catalog_item[:Link] = [ catalog_item[:Link] ] if catalog_item[:Link].is_a?(Hash)
options[:template_uri] = begin
catalog_item[:Entity].detect { |entity| entity[:type] == "application/vnd.vmware.vcloud.vAppTemplate+xml" }[:href]
rescue
raise RuntimeError.new("Unable to locate template uri for #{catalog_item_uri}")
end
customization_options = begin
customization_href = catalog_item[:Link].detect { |link| link[:type] == "application/vnd.tmrk.ecloud.catalogItemCustomizationParameters+xml" }[:href]
get_customization_options( customization_href ).body
rescue
raise RuntimeError.new("Unable to get customization options for #{catalog_item_uri}")
end
# Check to see if we can set the password
if options[:password] and customization_options[:CustomizePassword] == "false"
raise ArgumentError.new("This catalog item (#{catalog_item_uri}) does not allow setting a password.")
end
# According to the docs if CustomizePassword is "true" then we NEED to set a password
if customization_options[:CustomizePassword] == "true" and ( options[:password].nil? or options[:password].empty? )
raise ArgumentError.new("This catalog item (#{catalog_item_uri}) requires a :password to instantiate.")
end
end
def generate_instantiate_vapp_template_request(options)
xml = Builder::XmlMarkup.new
xml.InstantiateVAppTemplateParams(xmlns.merge!(:name => options[:name], :"xml:lang" => "en")) {
xml.VAppTemplate(:href => options[:template_uri])
xml.InstantiationParams {
xml.ProductSection( :"xmlns:q1" => "http://www.vmware.com/vcloud/v0.8", :"xmlns:ovf" => "http://schemas.dmtf.org/ovf/envelope/1") {
if options[:password]
xml.Property( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"ovf:key" => "password", :"ovf:value" => options[:password] )
end
xml.Property( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"ovf:key" => "row", :"ovf:value" => options[:row] )
xml.Property( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1", :"ovf:key" => "group", :"ovf:value" => options[:group] )
}
xml.VirtualHardwareSection( :"xmlns:q1" => "http://www.vmware.com/vcloud/v0.8" ) {
# # of CPUS
xml.Item( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1" ) {
xml.InstanceID(1, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
xml.ResourceType(3, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
xml.VirtualQuantity(options[:cpus], :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
}
# Memory
xml.Item( :xmlns => "http://schemas.dmtf.org/ovf/envelope/1" ) {
xml.InstanceID(2, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
xml.ResourceType(4, :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
xml.VirtualQuantity(options[:memory], :xmlns => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
}
}
xml.NetworkConfigSection {
xml.NetworkConfig {
xml.NetworkAssociation( :href => options[:network_uri] )
}
}
}
}
end
end
class Real
include Shared
def instantiate_vapp_template(catalog_item_uri, options = {})
validate_instantiate_vapp_template_options(catalog_item_uri, options)
request(
:body => generate_instantiate_vapp_template_request(options),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'},
:method => 'POST',
:uri => options[:vdc_uri] + '/action/instantiatevAppTemplate',
:parse => true
)
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=554&Lang=1&SID=
#
def instantiate_vapp_template(catalog_item_uri, options = {})
validate_instantiate_vapp_template_options(catalog_item_uri, options)
catalog_item = mock_data.catalog_item_from_href(catalog_item_uri)
xml = nil
if vdc = mock_data.vdc_from_href(options[:vdc_uri])
if network = mock_data.network_from_href(options[:network_uri])
new_vm = MockVirtualMachine.new({ :name => options[:name], :ip => network.random_ip, :cpus => options[:cpus], :memory => options[:memory] }, vdc)
new_vm.disks.push(*catalog_item.disks.dup)
vdc.virtual_machines << new_vm
xml = generate_instantiate_vapp_template_response(new_vm)
end
end
if xml
mock_it 200, xml, {'Content-Type' => 'application/xml'}
else
mock_error 200, "401 Unauthorized"
end
end
private
def generate_instantiate_vapp_template_response(vapp)
builder = Builder::XmlMarkup.new
builder.VApp(xmlns.merge(
:href => vapp.href,
:type => "application/vnd.vmware.vcloud.vApp+xml",
:name => vapp.name,
:status => 0,
:size => 4
)) {
builder.Link(:rel => "up", :href => vapp._parent.href, :type => "application/vnd.vmware.vcloud.vdc+xml")
}
end
end
end
end
end

View file

@ -0,0 +1,48 @@
module Fog
module Ecloud
class Compute
class Real
def login
unauthenticated_request({
:expects => 200,
:headers => {
'Authorization' => authorization_header
},
:method => 'POST',
:parse => true,
:uri => login_uri
})
end
end
class Mock
def login
#
# Based off of:
# http://support.theenterprisecloud.com/kb/default.asp?id=536&Lang=1&SID=
# https://community.vcloudexpress.terremark.com/en-us/product_docs/w/wiki/01-get-login-token.aspx
# vCloud API Guide v0.9 - Page 17
#
xml = Builder::XmlMarkup.new
mock_it 200,
xml.OrgList(xmlns) {
mock_data.organizations.each do |organization|
xml.Org( :type => "application/vnd.vmware.vcloud.org+xml", :href => organization.href, :name => organization.name )
end
},
{ 'Set-Cookie' => 'vcloud-token=fc020a05-21d7-4f33-9b2a-25d8cd05a44e; path=/',
'Content-Type' => 'application/vnd.vmware.vcloud.orgslist+xml' }
end
end
end
end
end

View file

@ -0,0 +1,23 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :power_off, 202, 'POST'
end
class Mock
def power_off(vapp_uri)
if vapp = mock_data.virtual_machine_from_href(vapp_uri)
vapp.power_off!
builder = Builder::XmlMarkup.new
mock_it 200, builder.Task(xmlns)
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,23 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :power_on, 202, 'POST'
end
class Mock
def power_on(vapp_uri)
if vapp = mock_data.virtual_machine_from_href(vapp_uri)
vapp.power_on!
builder = Builder::XmlMarkup.new
mock_it 200, builder.Task(xmlns)
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :power_reset, 202, 'POST'
end
end
end
end

View file

@ -0,0 +1,11 @@
module Fog
module Ecloud
class Compute
class Real
basic_request :power_shutdown, 204, 'POST'
end
end
end
end

View file

@ -9,6 +9,7 @@ end
require 'fog/providers/aws'
require 'fog/providers/bluebox'
require 'fog/providers/brightbox'
require 'fog/providers/ecloud'
require 'fog/providers/go_grid'
require 'fog/providers/google'
require 'fog/providers/linode'

View file

@ -0,0 +1,11 @@
require 'fog/core'
module Fog
module Ecloud
extend Fog::Provider
service(:compute, 'compute/ecloud')
end
end

View file

@ -1 +0,0 @@
require 'fog/vcloud/terremark/ecloud'

View file

@ -1,60 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class BackupInternetService < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
attribute :protocol, :aliases => :Protocol
attribute :enabled, :aliases => :Enabled
attribute :description, :aliases => :Description
attribute :timeout, :aliases => :Timeout
attribute :redirect_url, :aliases => :RedirectURL
attribute :monitor, :aliases => :Monitor
def delete
requires :href
connection.delete_internet_service( href )
end
def monitor=(new_monitor = {})
if new_monitor.nil? || new_monitor.empty?
attributes[:monitor] = nil
end
end
def save
if new_record?
result = connection.add_backup_internet_service( collection.href, _compose_service_data )
merge_attributes(result.body)
else
connection.configure_backup_internet_service( href, _compose_service_data )
end
end
def nodes
@nodes ||= Fog::Vcloud::Terremark::Ecloud::Nodes.new( :connection => connection, :href => href + "/nodeServices" )
end
private
def _compose_service_data
#For some reason inject didn't work
service_data = {}
self.class.attributes.select{ |attribute| !send(attribute).nil? }.each { |attribute| service_data[attribute] = send(attribute) }
service_data
end
end
end
end
end
end

View file

@ -1,36 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/backup_internet_service'
module Fog
class Vcloud
module Terremark
class Ecloud
class BackupInternetServices < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::BackupInternetService
attribute :href, :aliases => :Href
def all
check_href! :message => "the Internet Services for the Vdc you want to enumerate"
if data = connection.get_internet_services(href).body[:InternetService].find_all {|i| i[:IsBackupService] == "true" }
load(data)
end
end
# Optimize later, no need to get_internet_services again?
def get(uri)
internet_services = connection.get_internet_services(href).body[:InternetService]
internet_services = [ internet_services ] if internet_services.is_a?(Hash)
if data = internet_services.detect { |service| service[:Href] == uri }
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,31 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Catalog < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::CatalogItem
attribute :href, :aliases => :Href
def all
check_href!
if data = connection.get_catalog(href).body[:CatalogItems][:CatalogItem]
load(data)
end
end
def get(uri)
if data = connection.get_catalog_item(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,31 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class CatalogItem < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type
attribute :name
attribute :entity, :aliases => :Entity
attribute :link, :aliases => :Link
attribute :property, :aliases => :Property
def customization_options
load_unless_loaded!
if data = connection.get_customization_options( link[:href] ).body
data.delete_if { |key, value| [:xmlns_i, :xmlns].include?(key) }
data
else
nil
end
end
end
end
end
end
end

View file

@ -1,28 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class FirewallAcl < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
attribute :protocol, :aliases => :Protocol
attribute :source, :aliases => :Source
attribute :destination, :aliases => :Destination
attribute :permission, :aliases => :Permission
attribute :port_start, :aliases => :PortStart
attribute :port_end, :aliases => :PortEnd
attribute :port_type, :aliases => :PortType
attribute :type, :aliases => :Type
end
end
end
end
end

View file

@ -1,34 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/firewall_acl'
module Fog
class Vcloud
module Terremark
class Ecloud
class FirewallAcls < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::FirewallAcl
attribute :href, :aliases => :Href
def all
check_href! :message => "the Firewall ACL href for the network you want to enumerate"
if data = connection.get_firewall_acls(href).body[:FirewallAcl]
data = [ data ] if data.is_a?(Hash)
load(data)
end
end
def get(uri)
if data = connection.get_firewall_acl(uri).body
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,121 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class InternetService < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
attribute :protocol, :aliases => :Protocol
attribute :port, :aliases => :Port
attribute :enabled, :aliases => :Enabled
attribute :description, :aliases => :Description
attribute :public_ip, :aliases => :PublicIpAddress
attribute :timeout, :aliases => :Timeout
attribute :redirect_url, :aliases => :RedirectURL
attribute :monitor, :aliases => :Monitor
attribute :backup_service_data, :aliases => :BackupService
def delete
requires :href
connection.delete_internet_service( href )
end
def save
if new_record?
result = connection.add_internet_service( collection.href, _compose_service_data )
merge_attributes(result.body)
else
connection.configure_internet_service( href, _compose_service_data, _compose_ip_data )
end
end
# disables monitoring for this service
def disable_monitor
if self.monitor and self.monitor[:type] == "Disabled"
raise RuntimeError.new("Monitoring already disabled")
else
self.monitor = {:type => "Disabled", :is_enabled => "true"}
self.save
end
end
# enable default ping monitoring, use monitor= for more exotic forms (ECV & HTTP)
def enable_ping_monitor
self.monitor = nil
self.save
end
def monitor=(new_monitor = {})
if new_monitor.nil? || new_monitor.empty?
attributes[:monitor] = nil
elsif new_monitor.is_a?(Hash)
attributes[:monitor] = {}
attributes[:monitor][:type] = new_monitor[:MonitorType] || new_monitor[:type]
attributes[:monitor][:url_send_string] = new_monitor[:UrlSendString] || new_monitor[:url_send_string]
attributes[:monitor][:http_headers] = new_monitor[:HttpHeader] || new_monitor[:http_headers]
if attributes[:monitor][:http_headers]
if attributes[:monitor][:http_headers].is_a?(String)
attributes[:monitor][:http_headers] = attributes[:monitor][:http_headers].split("\n")
else
attributes[:monitor][:http_headers] = attributes[:monitor][:http_headers]
end
end
attributes[:monitor][:receive_string] = new_monitor[:ReceiveString] || new_monitor[:receive_string]
attributes[:monitor][:interval] = new_monitor[:Interval] || new_monitor[:interval]
attributes[:monitor][:response_timeout] = new_monitor[:ResponseTimeOut] || new_monitor[:response_timeout]
attributes[:monitor][:downtime] = new_monitor[:DownTime] || new_monitor[:downtime]
attributes[:monitor][:retries] = new_monitor[:Retries] || new_monitor[:retries]
attributes[:monitor][:is_enabled] = new_monitor[:IsEnabled] || new_monitor[:is_enabled]
else
raise RuntimeError.new("monitor needs to either be nil or a Hash")
end
end
def nodes
@nodes ||= Fog::Vcloud::Terremark::Ecloud::Nodes.new( :connection => connection, :href => href + "/nodeServices" )
end
def backup_service_uri
if backup_service_data
backup_service_data[:Href]
end
end
def backup_service_uri=(new_value)
self.backup_service_data = {
:Href => new_value
}
end
private
def _compose_service_data
#For some reason inject didn't work
service_data = {}
self.class.attributes.select{ |attribute| attribute != :backup_service_data }.each { |attribute| service_data[attribute] = send(attribute) }
service_data[:backup_service_uri] = backup_service_uri
service_data.reject! {|k, v| v.nil? }
service_data
end
def _compose_ip_data
if public_ip.nil?
{}
else
{ :id => public_ip[:Id], :href => public_ip[:Href], :name => public_ip[:Name] }
end
end
end
end
end
end
end

View file

@ -1,36 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/internet_service'
module Fog
class Vcloud
module Terremark
class Ecloud
class InternetServices < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::InternetService
attribute :href, :aliases => :Href
def all
check_href! :message => "the Internet Services for the Vdc you want to enumerate"
if internet_service_data = connection.get_internet_services(href).body[:InternetService]
load(Array[internet_service_data].flatten.find_all {|i| i[:IsBackupService] == "false" })
end
end
# Optimize later, no need to get_internet_services again?
def get(uri)
internet_services = connection.get_internet_services(href).body[:InternetService]
internet_services = [ internet_services ] if internet_services.is_a?(Hash)
if data = internet_services.detect { |service| service[:Href] == uri }
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,51 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Ip < Fog::Vcloud::Model
ignore_attributes :xmlns_i, :xmlns
identity :href, :aliases => :Href
attribute :name, :aliases => :Name
attribute :status, :aliases => :Status
attribute :server, :aliases => :Server
attribute :rnat, :aliases => :RnatAddress
attribute :id, :aliases => :Id, :type => :integer
def rnat=(new_rnat)
attributes[:rnat] = new_rnat
@changed = true
end
def save
if @changed
connection.configure_network_ip( href, _compose_network_ip_data )
end
true
end
def reload
super
@changed = false
self
end
private
def _compose_network_ip_data
{
:id => id,
:href => href,
:name => name,
:status => status,
:server => server,
:rnat => rnat
}
end
end
end
end
end
end

View file

@ -1,35 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/ip'
module Fog
class Vcloud
module Terremark
class Ecloud
class Ips < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::Ip
undef_method :create
attribute :href
def all
check_href!( :messages => "Ips href of a Network you want to enumerate" )
if data = connection.get_network_ips(href).body[:IpAddress]
load(data)
end
end
def get(uri)
if data = connection.get_network_ip(uri).body
new(data)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,77 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Network < Fog::Vcloud::Model
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd, :xmlns_i, :Configuration, :Id
attribute :name, :aliases => :Name
#attribute :id, :aliases => :Id
attribute :features, :aliases => :Features, :type => :array
attribute :links, :aliases => :Link, :type => :array
attribute :type
attribute :gateway, :aliases => :GatewayAddress
attribute :broadcast, :aliases => :BroadcastAddress
attribute :address, :aliases => :Address
attribute :rnat, :aliases => :RnatAddress
attribute :extension_href, :aliases => :Href
attribute :network_type, :aliases => :NetworkType
attribute :vlan, :aliases => :Vlan
attribute :friendly_name, :aliases => :FriendlyName
def ips
load_unless_loaded!
@ips ||= Fog::Vcloud::Terremark::Ecloud::Ips.
new( :connection => connection,
:href => links.detect { |link| link[:name] == "IP Addresses" }[:href] )
end
def rnat=(new_rnat)
attributes[:rnat] = new_rnat
@changed = true
end
def save
if @changed
connection.configure_network( extension_href, _compose_network_data )
end
true
end
def reload
super
merge_attributes(extension_data.body)
self
end
private
def extension_data
connection.get_network_extensions( extensions_link[:href] )
end
def extensions_link
links.detect { |link| link[:name] == name }
end
def _compose_network_data
{
:id => id,
:href => extension_href,
:name => name,
:rnat => rnat,
:address => address,
:broadcast => broadcast,
:gateway => gateway
}
end
end
end
end
end
end

View file

@ -1,36 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/network'
module Fog
class Vcloud
module Terremark
class Ecloud
class Networks < Fog::Vcloud::Collection
undef_method :create
model Fog::Vcloud::Terremark::Ecloud::Network
attribute :href
def all
check_href!("Vdc")
if data = connection.get_vdc(href).body[:AvailableNetworks][:Network]
load(data)
end
end
def get(uri)
if data = connection.get_network(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,47 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Node < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :ip_address, :aliases => :IpAddress
attribute :description, :aliases => :Description
attribute :name, :aliases => :Name
attribute :port, :aliases => :Port
attribute :enabled, :aliases => :Enabled
attribute :id, :aliases => :Id
def delete
requires :href
connection.delete_node( href )
end
def save
if new_record?
result = connection.add_node( collection.href, _compose_node_data )
merge_attributes(result.body)
else
connection.configure_node( href, _compose_node_data )
end
end
private
def _compose_node_data
node_data = {}
self.class.attributes.select{ |attribute| !send(attribute).nil? }.each { |attribute| node_data[attribute] = send(attribute).to_s }
node_data
end
end
end
end
end
end

View file

@ -1,33 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/node'
module Fog
class Vcloud
module Terremark
class Ecloud
class Nodes < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::Node
attribute :href, :aliases => :Href
def all
check_href!( :messages => "the Nodes href of the Internet Service you want to enumerate" )
if data = connection.get_nodes(href).body[:NodeService]
load(data)
end
end
def get(uri)
if data = connection.get_node(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,25 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class PublicIp < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i
attribute :name, :aliases => :Name
attribute :id, :aliases => :Id
def internet_services
load_unless_loaded!
@internet_services ||= Fog::Vcloud::Terremark::Ecloud::InternetServices.
new( :connection => connection,
:href => href.to_s + "/internetServices" )
end
end
end
end
end
end

View file

@ -1,39 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/public_ip'
module Fog
class Vcloud
module Terremark
class Ecloud
class PublicIps < Fog::Vcloud::Collection
undef_method :create
attribute :href, :aliases => :Href
model Fog::Vcloud::Terremark::Ecloud::PublicIp
#get_request :get_public_ip
#vcloud_type "application/vnd.tmrk.ecloud.publicIp+xml"
#all_request lambda { |public_ips| public_ips.connection.get_public_ips(public_ips.href) }
def all
check_href!(:message => "the Public Ips href of the Vdc you want to enumerate")
if data = connection.get_public_ips(href).body[:PublicIPAddress]
load(data)
end
end
def get(uri)
if data = connection.get_public_ip(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,211 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Server < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type
attribute :name
attribute :status
attribute :network_connections, :aliases => :NetworkConnectionSection, :squash => :NetworkConnection
attribute :os, :aliases => :OperatingSystemSection
attribute :virtual_hardware, :aliases => :VirtualHardwareSection
attribute :storage_size, :aliases => :size
attribute :links, :aliases => :Link, :type => :array
def friendly_status
load_unless_loaded!
case status
when '0'
'creating'
when '2'
'off'
when '4'
'on'
else
'unkown'
end
end
def ready?
load_unless_loaded!
status == '2'
end
def on?
load_unless_loaded!
status == '4'
end
def off?
load_unless_loaded!
status == '2'
end
def power_on
power_operation( :power_on => :powerOn )
end
def power_off
power_operation( :power_off => :powerOff )
end
def shutdown
power_operation( :power_shutdown => :shutdown )
end
def power_reset
power_operation( :power_reset => :reset )
end
def graceful_restart
requires :href
shutdown
wait_for { off? }
power_on
end
def delete
requires :href
connection.delete_vapp( href)
end
def name=(new_name)
attributes[:name] = new_name
@changed = true
end
def cpus
if cpu_mess
{ :count => cpu_mess[:VirtualQuantity].to_i,
:units => cpu_mess[:AllocationUnits] }
end
end
def cpus=(qty)
@changed = true
cpu_mess[:VirtualQuantity] = qty.to_s
end
def memory
if memory_mess
{ :amount => memory_mess[:VirtualQuantity].to_i,
:units => memory_mess[:AllocationUnits] }
end
end
def memory=(amount)
@changed = true
memory_mess[:VirtualQuantity] = amount.to_s
end
def disks
disk_mess.map do |dm|
{ :number => dm[:AddressOnParent], :size => dm[:VirtualQuantity].to_i, :resource => dm[:HostResource] }
end
end
def add_disk(size)
if @disk_change == :deleted
raise RuntimeError, "Can't add a disk w/o saving changes or reloading"
else
@disk_change = :added
load_unless_loaded!
virtual_hardware[:Item] << { :ResourceType => '17',
:AddressOnParent => (disk_mess.map { |dm| dm[:AddressOnParent] }.sort.last.to_i + 1).to_s,
:VirtualQuantity => size.to_s }
end
true
end
def delete_disk(number)
if @disk_change == :added
raise RuntimeError, "Can't delete a disk w/o saving changes or reloading"
else
@disk_change = :deleted
load_unless_loaded!
unless number == 0
virtual_hardware[:Item].delete_if { |vh| vh[:ResourceType] == '17' && vh[:AddressOnParent].to_i == number }
end
end
true
end
def reload
reset_tracking
super
end
def save
if new_record?
#Lame ...
raise RuntimeError, "Should not be here"
else
if on?
if @changed
raise RuntimeError, "Can't save cpu, name or memory changes while the VM is on."
end
end
connection.configure_vapp( href, _compose_vapp_data )
end
reset_tracking
end
private
def reset_tracking
@disk_change = false
@changed = false
end
def _compose_vapp_data
{ :name => name,
:cpus => cpus[:count],
:memory => memory[:amount],
:disks => disks
}
end
def memory_mess
load_unless_loaded!
if virtual_hardware && virtual_hardware[:Item]
virtual_hardware[:Item].detect { |item| item[:ResourceType] == "4" }
end
end
def cpu_mess
load_unless_loaded!
if virtual_hardware && virtual_hardware[:Item]
virtual_hardware[:Item].detect { |item| item[:ResourceType] == "3" }
end
end
def disk_mess
load_unless_loaded!
if virtual_hardware && virtual_hardware[:Item]
virtual_hardware[:Item].select { |item| item[:ResourceType] == "17" }
else
[]
end
end
def power_operation(op)
requires :href
begin
connection.send(op.keys.first, href + "/power/action/#{op.values.first}" )
rescue Excon::Errors::InternalServerError => e
#Frankly we shouldn't get here ...
raise e unless e.to_s =~ /because it is already powered o(n|ff)/
end
true
end
end
end
end
end
end

View file

@ -1,57 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/server'
module Fog
class Vcloud
module Terremark
class Ecloud
class Servers < Fog::Vcloud::Collection
undef_method :create
model Fog::Vcloud::Terremark::Ecloud::Server
attribute :href, :aliases => :Href
def all
check_href!(:parent => "Vdc")
load(_vapps)
end
def get(uri)
if data = connection.get_vapp(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
def create( catalog_item_uri, options )
options[:vdc_uri] = href
options[:cpus] ||= 1
options[:memory] ||= 512
data = connection.instantiate_vapp_template( catalog_item_uri, options ).body
object = new(data)
object
end
private
def _resource_entities
connection.get_vdc(href).body[:ResourceEntities][:ResourceEntity]
end
def _vapps
resource_entities = _resource_entities
if resource_entities.nil?
[]
else
resource_entities
end
end
end
end
end
end
end

View file

@ -1,23 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Task < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :status
attribute :type
attribute :result, :aliases => :Result
attribute :owner, :aliases => :Owner
attribute :start_time, :aliases => :startTime, :type => :time
attribute :end_time, :aliases => :endTime, :type => :time
attribute :error, :aliases => :Error
end
end
end
end
end

View file

@ -1,33 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/task'
module Fog
class Vcloud
module Terremark
class Ecloud
class Tasks < Fog::Vcloud::Collection
model Fog::Vcloud::Terremark::Ecloud::Task
attribute :href, :aliases => :Href
def all
check_href!
if data = connection.get_task_list(href).body[:Task]
load(data)
end
end
def get(uri)
if data = connection.get_task(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
end
end
end
end
end

View file

@ -1,83 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Vdc < Fog::Vcloud::Model
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd
attribute :name
attribute :type
attribute :description, :aliases => :Description
attribute :other_links, :aliases => :Link
attribute :compute_capacity, :aliases => :ComputeCapacity
attribute :storage_capacity, :aliases => :StorageCapacity
attribute :available_networks, :aliases => :AvailableNetworks, :squash => :Network
attribute :resource_entities, :aliases => :ResourceEntities, :squash => :ResourceEntity
attribute :deployed_vm_quota
attribute :instantiated_vm_quota
def public_ips
@public_ips ||= collection_based_on_type("application/vnd.tmrk.ecloud.publicIpsList+xml")
end
def internet_services
@internet_services ||= collection_based_on_type("application/vnd.tmrk.ecloud.internetServicesList+xml")
end
def backup_internet_services
@backup_internet_services ||= collection_based_on_type("application/vnd.tmrk.ecloud.internetServicesList+xml", BackupInternetServices)
end
def networks
@networks ||= Fog::Vcloud::Terremark::Ecloud::Networks.
new( :connection => connection,
:href => href )
end
def servers
@servers ||= Fog::Vcloud::Terremark::Ecloud::Servers.
new( :connection => connection,
:href => href )
end
def tasks
@tasks ||= Fog::Vcloud::Terremark::Ecloud::Tasks.
new( :connection => connection,
:href => href + "/tasksList" )
end
def catalog
@catalog ||= collection_based_on_type("application/vnd.vmware.vcloud.catalog+xml")
end
def firewall_acls
@firewall_acls ||= collection_based_on_type("application/vnd.tmrk.ecloud.firewallAclsList+xml")
end
private
def collection_based_on_type(type, klass = nil)
load_unless_loaded!
if link = other_links.detect { |link| link[:type] == type }
case type
when "application/vnd.tmrk.ecloud.publicIpsList+xml"
Fog::Vcloud::Terremark::Ecloud::PublicIps
when "application/vnd.tmrk.ecloud.internetServicesList+xml"
klass || Fog::Vcloud::Terremark::Ecloud::InternetServices
when "application/vnd.vmware.vcloud.catalog+xml"
Fog::Vcloud::Terremark::Ecloud::Catalog
when "application/vnd.tmrk.ecloud.firewallAclsList+xml"
Fog::Vcloud::Terremark::Ecloud::FirewallAcls
end.new( :connection => connection, :href => link[:href] )
else
[ ]
end
end
end
end
end
end
end

View file

@ -1,42 +0,0 @@
require 'fog/vcloud/terremark/ecloud/models/vdc'
module Fog
class Vcloud
module Terremark
class Ecloud
class Vdcs < Collection
model Fog::Vcloud::Terremark::Ecloud::Vdc
undef_method :create
def all
data = connection.get_organization(organization_uri).body[:Link].select { |link| link[:type] == "application/vnd.vmware.vcloud.vdc+xml" }
data.each { |link| link.delete_if { |key, value| [:rel].include?(key) } }
load(data)
end
def get(uri)
if data = connection.get_vdc(uri)
new(data.body)
end
rescue Fog::Errors::NotFound
nil
end
def organization_uri
@organizatio_uri ||= connection.default_organization_uri
end
private
def organization_uri=(new_organization_uri)
@organization_uri = new_organization_uri
end
end
end
end
end
end

View file

@ -1,111 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
module Shared
def validate_backup_internet_service_data(service_data, configure=false)
required_opts = [:name, :protocol, :description, :enabled]
if configure
required_opts + [ :id, :href, :timeout ]
end
unless required_opts.all? { |opt| service_data.keys.include?(opt) }
raise ArgumentError.new("Required Backup Internet Service data missing: #{(required_opts - service_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def add_backup_internet_service(internet_services_uri, service_data)
validate_backup_internet_service_data(service_data)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
request(
:body => generate_backup_internet_service_request(service_data),
:expects => 200,
:headers => {'Content-Type' => 'application/xml'},
:method => 'POST',
:uri => internet_services_uri,
:parse => true
)
end
private
def generate_backup_internet_service_request(service_data)
builder = Builder::XmlMarkup.new
builder.CreateBackupInternetServiceRequest("xmlns" => "urn:tmrk:eCloudExtensions-2.5") {
builder.Name(service_data[:name])
builder.Protocol(service_data[:protocol])
builder.Enabled(service_data[:enabled])
builder.Description(service_data[:description])
builder.RedirectURL(service_data[:redirect_url])
if monitor = service_data[:monitor]
generate_monitor_section(builder,monitor)
end
}
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=729&Lang=1&SID=
# and many tears shed.
#
def add_backup_internet_service(internet_services_uri, service_data)
validate_backup_internet_service_data(service_data)
internet_services_uri = ensure_unparsed(internet_services_uri)
if vdc_internet_service_collection = mock_data.vdc_internet_service_collection_from_href(internet_services_uri)
new_backup_internet_service = MockBackupInternetService.new(service_data, vdc_internet_service_collection.backup_internet_services)
vdc_internet_service_collection.backup_internet_services << new_backup_internet_service
xml = generate_backup_internet_service_added_response(new_backup_internet_service)
mock_it 200, xml, {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
private
def generate_backup_internet_service_added_response(new_backup_internet_service)
builder = Builder::XmlMarkup.new
builder.InternetService("xmlns" => "urn:tmrk:eCloudExtensions-2.5", "xmlns:i" => "http://www.w3.org/2001/XMLSchema-instance") {
builder.Id new_backup_internet_service.object_id
builder.Href new_backup_internet_service.href
builder.Name new_backup_internet_service.name
# so broken
builder.PublicIpAddress do
builder.Id -2147483648
builder.Id "http://totally.invalid/1234"
builder.Name
end
builder.Port new_backup_internet_service.port
builder.Protocol new_backup_internet_service.protocol
builder.Enabled new_backup_internet_service.enabled
builder.Timeout new_backup_internet_service.timeout
builder.Description new_backup_internet_service.description
builder.RedirectURL new_backup_internet_service.redirect_url
builder.Monitor "i:nil" => true
# so broken
builder.IsBackupService false
builder.BackupService "i:nil" => true
builder.BackupOf "i:nil" => true
}
end
end
end
end
end
end

View file

@ -1,152 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
module Shared
def validate_internet_service_monitor(monitor)
#FIXME: Refactor this type of function into something generic
unless ['Disabled','HTTP','ECV'].include?(monitor[:type])
raise ArgumentError.new("Supported monitor types are: ECV & HTTP")
end
required_opts = case monitor[:type]
when "Disabled"
[:type, :is_enabled]
else
[:type, :url_send_string, :http_headers, :receive_string, :is_enabled]
end
unless required_opts.all? { |opt| monitor.keys.include?(opt) && monitor[opt] }
raise ArgumentError.new("Required Monitor data missing: #{(required_opts - monitor.keys).map(&:inspect).join(", ")}")
end
case monitor[:type]
when "HTTP", "ECV"
unless monitor[:http_headers].is_a?(Array) || monitor[:http_headers].is_a?(String)
raise ArgumentError.new("Monitor :http_headers must be a String or Array")
end
end
unless [true, false, "true", "false"].include?(monitor[:is_enabled])
raise ArgumentError.new("Monitor :is_enabled must be true or false")
end
end
def validate_internet_service_data(service_data, configure=false)
required_opts = [:name, :protocol, :port, :description, :enabled]
if configure
required_opts + [ :id, :href, :timeout ]
end
unless required_opts.all? { |opt| service_data.keys.include?(opt) }
raise ArgumentError.new("Required Internet Service data missing: #{(required_opts - service_data.keys).map(&:inspect).join(", ")}")
end
end
def ensure_monitor_defaults!(monitor)
if monitor[:http_headers].is_a?(String)
monitor[:http_headers] = [ monitor[:http_headers] ]
end
unless monitor[:retries]
monitor[:retries] = 3
end
unless monitor[:response_timeout]
monitor[:response_timeout] = 2
end
unless monitor[:down_time]
monitor[:down_time] = 30
end
unless monitor[:interval]
monitor[:interval] = 5
end
end
end
class Real
include Shared
def add_internet_service(internet_services_uri, service_data)
validate_internet_service_data(service_data)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
request(
:body => generate_internet_service_request(service_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'},
:method => 'POST',
:uri => internet_services_uri,
:parse => true
)
end
private
def generate_internet_service_request(service_data)
builder = Builder::XmlMarkup.new
builder.CreateInternetServiceRequest(ecloud_xmlns) {
builder.Name(service_data[:name])
builder.Protocol(service_data[:protocol])
builder.Port(service_data[:port])
builder.Enabled(service_data[:enabled])
builder.Description(service_data[:description])
builder.RedirectURL(service_data[:redirect_url])
if monitor = service_data[:monitor]
generate_monitor_section(builder,monitor)
end
}
end
def generate_monitor_section(builder, monitor)
builder.Monitor {
builder.MonitorType(monitor[:type])
case monitor[:type]
when "ECV","HTTP"
builder.UrlSendString(monitor[:url_send_string])
builder.HttpHeader(monitor[:http_headers].join("\n"))
builder.ReceiveString(monitor[:receive_string])
builder.Interval(monitor[:interval])
builder.ResponseTimeOut(monitor[:response_timeout])
builder.DownTime(monitor[:downtime])
builder.Retries(monitor[:retries])
end
builder.IsEnabled(monitor[:is_enabled])
}
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=561&Lang=1&SID=
#
def add_internet_service(internet_services_uri, service_data)
validate_internet_service_data(service_data)
internet_services_uri = ensure_unparsed(internet_services_uri)
if public_ip_internet_service_collection = mock_data.public_ip_internet_service_collection_from_href(internet_services_uri)
new_public_ip_internet_service = MockPublicIpInternetService.new(service_data, public_ip_internet_service_collection)
public_ip_internet_service_collection.items << new_public_ip_internet_service
xml = generate_internet_service(Builder::XmlMarkup.new, new_public_ip_internet_service, true)
mock_it 200, xml, {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end
end

View file

@ -1,64 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
module Shared
private
def generate_node_request(node_data)
builder = Builder::XmlMarkup.new
builder.CreateNodeServiceRequest(ecloud_xmlns) {
builder.IpAddress(node_data[:ip_address])
builder.Name(node_data[:name])
builder.Port(node_data[:port])
builder.Enabled(node_data[:enabled])
builder.Description(node_data[:description])
}
end
def validate_node_data(node_data, configure=false)
valid_opts = [:name, :port, :enabled, :description, :ip_address]
if configure
valid_opts.delete_if { |opt| ![:name, :enabled, :description].include?(opt) }
end
unless valid_opts.all? { |opt| node_data.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - node_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def add_node(nodes_uri, node_data)
validate_node_data(node_data)
request(
:body => generate_node_request(node_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml'},
:method => 'POST',
:uri => nodes_uri,
:parse => true
)
end
end
class Mock
include Shared
def add_node(nodes_uri, node_data)
validate_node_data(node_data)
if node_collection = mock_data.public_ip_internet_service_node_collection_from_href(ensure_unparsed(nodes_uri))
new_node = MockPublicIpInternetServiceNode.new(node_data, node_collection)
node_collection.items << new_node
mock_it 200, mock_node_service_response(new_node), { 'Content-Type' => 'application/vnd.tmrk.ecloud.nodeService+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end
end

View file

@ -1,42 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Real
def validate_clone_vapp_options(options)
valid_opts = [:name, :poweron]
unless valid_opts.all? { |opt| options.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - options.keys).map(&:inspect).join(", ")}")
end
end
def generate_clone_vapp_request(uri, options)
xml = Builder::XmlMarkup.new
xml.CloneVAppParams(xmlns.merge!(:name => options[:name], :deploy => "true", :powerOn => options[:poweron])) {
xml.VApp( :href => uri, :type => "application/vnd.vmware.vcloud.vApp+xml",
:xmlns => "http://www.vmware.com/vcloud/v0.8")
}
end
def clone_vapp(vdc_uri, vapp_uri, options = {})
unless options.has_key?(:poweron)
options[:poweron] = "false"
end
validate_clone_vapp_options(options)
request(
:body => generate_clone_vapp_request(vapp_uri, options),
:expects => 202,
:headers => {'Content-Type' => 'application/vnd.vmware.vcloud.cloneVAppParams+xml'},
:method => 'POST',
:uri => vdc_uri + '/action/clonevapp',
:parse => true
)
end
end
end
end
end
end

View file

@ -1,115 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
module Shared
private
def validate_public_ip_address_data(ip_address_data)
valid_opts = [:name, :href, :id]
unless valid_opts.all? { |opt| ip_address_data.keys.include?(opt) }
raise ArgumentError.new("Required Internet Service data missing: #{(valid_opts - ip_address_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def configure_internet_service(internet_service_uri, service_data, ip_address_data)
validate_internet_service_data(service_data, true)
validate_public_ip_address_data(ip_address_data)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
request(
:body => generate_configure_internet_service_request(service_data, ip_address_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'},
:method => 'PUT',
:uri => internet_service_uri,
:parse => true
)
end
private
def generate_configure_internet_service_request(service_data, ip_address_data)
builder = Builder::XmlMarkup.new
builder.InternetService(ecloud_xmlns) {
builder.Id(service_data[:id])
builder.Href(service_data[:href])
builder.Name(service_data[:name])
builder.Protocol(service_data[:protocol])
builder.Port(service_data[:port])
builder.Enabled(service_data[:enabled])
builder.Description(service_data[:description])
builder.Timeout(service_data[:timeout])
builder.RedirectURL(service_data[:redirect_url])
builder.PublicIpAddress {
builder.Id(ip_address_data[:id])
builder.Href(ip_address_data[:href])
builder.Name(ip_address_data[:name])
}
if monitor = service_data[:monitor]
generate_monitor_section(builder, monitor)
end
if service_data[:backup_service_uri]
builder.BackupService do
builder.Href(service_data[:backup_service_uri])
end
end
}
end
end
class Mock
include Shared
#
# Based on
# http://support.theenterprisecloud.com/kb/default.asp?id=583&Lang=1&SID=
#
def configure_internet_service(internet_service_uri, service_data, ip_address_data)
service_data = service_data.dup
validate_internet_service_data(service_data, true)
if monitor = service_data[:monitor]
validate_internet_service_monitor(monitor)
ensure_monitor_defaults!(monitor)
end
validate_public_ip_address_data(ip_address_data)
internet_service_uri = ensure_unparsed(internet_service_uri)
backup_service_uri = service_data.delete(:backup_service_uri)
backup_service = backup_service_uri && mock_data.backup_internet_service_from_href(backup_service_uri)
xml = nil
if (public_ip_internet_service = mock_data.public_ip_internet_service_from_href(internet_service_uri)) &&
(backup_service_uri.nil? || backup_service)
public_ip_internet_service.update(service_data.reject {|k, v| [:id, :href].include?(k) })
public_ip_internet_service[:backup_service] = backup_service
xml = generate_internet_service(Builder::XmlMarkup.new, public_ip_internet_service, true)
end
if xml
mock_it 200, xml, {'Content-Type' => 'application/vnd.tmrk.ecloud.internetService+xml'}
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end
end

View file

@ -1,46 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
class Real
def validate_network_data(network_data, configure=false)
valid_opts = [:id, :href, :name, :rnat, :address, :broadcast, :gateway]
unless valid_opts.all? { |opt| network_data.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - network_data.keys).map(&:inspect).join(", ")}")
end
end
def configure_network(network_uri, network_data)
validate_network_data(network_data)
request(
:body => generate_configure_network_request(network_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.networkService+xml'},
:method => 'PUT',
:uri => network_uri,
:parse => true
)
end
private
def generate_configure_network_request(network_data)
builder = Builder::XmlMarkup.new
builder.Network(ecloud_xmlns) {
builder.Id(network_data[:id])
builder.Href(network_data[:href])
builder.Name(network_data[:name])
builder.RnatAddress(network_data[:rnat])
builder.Address(network_data[:address])
builder.BroadcastAddress(network_data[:broadcast])
builder.GatewayAddress(network_data[:gateway])
}
end
end
end
end
end
end

View file

@ -1,68 +0,0 @@
module Fog
class Vcloud
module Terremark
class Ecloud
module Shared
private
def validate_network_ip_data(network_ip_data)
valid_opts = [:id, :href, :name, :status, :server, :rnat]
unless valid_opts.all? { |opt| network_ip_data.keys.include?(opt) }
raise ArgumentError.new("Required data missing: #{(valid_opts - network_ip_data.keys).map(&:inspect).join(", ")}")
end
end
end
class Real
include Shared
def configure_network_ip(network_ip_uri, network_ip_data)
validate_network_ip_data(network_ip_data)
request(
:body => generate_configure_network_ip_request(network_ip_data),
:expects => 200,
:headers => {'Content-Type' => 'application/vnd.tmrk.ecloud.ip+xml' },
:method => 'PUT',
:uri => network_ip_uri,
:parse => true
)
end
private
def generate_configure_network_ip_request(network_ip_data)
builder = Builder::XmlMarkup.new
builder.IpAddress(ecloud_xmlns) {
builder.Id(network_ip_data[:id])
builder.Href(network_ip_data[:href])
builder.Name(network_ip_data[:name])
builder.Status(network_ip_data[:status])
builder.Server(network_ip_data[:server])
builder.RnatAddress(network_ip_data[:rnat])
}
end
end
class Mock
include Shared
def configure_network_ip(network_ip_uri, network_ip_data)
validate_network_ip_data(network_ip_data)
if network_ip = mock_data.network_ip_from_href(network_ip_uri)
network_ip[:rnat] = network_ip_data[:rnat]
builder = Builder::XmlMarkup.new
xml = network_ip_response(builder, network_ip, ecloud_xmlns)
mock_it 200, xml, { 'Content-Type' => 'application/vnd.tmrk.ecloud.ip+xml' }
else
mock_error 200, "401 Unauthorized"
end
end
end
end
end
end
end

Some files were not shown because too many files have changed in this diff Show more