[vcloud|compute] improve models + additional tests

vCloud has also the concept of links in the responses. So we should
make use of them to navigate through the tree of resources in the
vCloud.
Furthermore, we can make various calls a bit easier by directly
returning the specific resource object than the plain xml response.

Adjust tests to work with the new changes, and also test the added
parts.
This commit is contained in:
Peter Meier 2012-01-30 15:24:14 +01:00
parent f3d97623d4
commit 3e240474ac
25 changed files with 125 additions and 106 deletions

View File

@ -52,6 +52,20 @@ module Fog
end
end
def link_up
load_unless_loaded!
self.links.find{|l| l[:rel] == 'up' }
end
def self.has_up(item)
class_eval <<-EOS, __FILE__,__LINE__
def #{item}
load_unless_loaded!
connection.get_#{item}(link_up[:href])
end
EOS
end
end
end
end
@ -99,22 +113,15 @@ module Fog
request :configure_vm_name_description
request :configure_vm_disks
request :delete_vapp
request :get_catalog
request :get_catalog_item
request :get_customization_options
request :get_network
request :get_network_ip
request :get_network_ips
request :get_network_extensions
request :get_organization
request :get_server
request :get_task
request :get_task_list
request :get_vapp
request :get_vapp_template
request :get_vm_disks
request :get_vm_memory
request :get_vdc
request :instantiate_vapp_template
request :login
request :power_off
@ -138,13 +145,16 @@ module Fog
def basic_request(*args)
self.class_eval <<-EOS, __FILE__,__LINE__
def #{args[0]}(uri)
request({
request(
{
:expects => #{args[1] || 200},
:method => '#{args[2] || 'GET'}',
:headers => #{args[3] ? args[3].inspect : '{}'},
:body => '#{args[4] ? args[4] : ''}',
:parse => true,
:uri => uri })
:uri => uri
}
)
end
EOS
end
@ -161,7 +171,6 @@ module Fog
end
EOS
end
end
def initialize(options = {})
@ -244,6 +253,17 @@ module Fog
private
def basic_request_params(uri,*args)
{
:expects => args[0] || 200,
:method => args[1] || 'GET',
:headers => args[2] ? args[2].inspect : {},
:body => args[3] ? args[3] : '',
:parse => true,
:uri => uri
}
end
def ensure_parsed(uri)
if uri.is_a?(String)
URI.parse(uri)
@ -311,7 +331,25 @@ module Fog
end
end
def self.item_requests(*types)
types.each{|t| item_request(t) }
end
def self.item_request(type)
Fog::Vcloud::Compute::Real.class_eval <<-EOS, __FILE__,__LINE__
def get_#{type}(uri)
Fog::Vcloud::Compute::#{type.to_s.capitalize}.new(
self.request(basic_request_params(uri)).body.merge(
:connection => self,
:collection => Fog::Vcloud::Compute::#{type.to_s.capitalize}s.new(
:connection => self
)
)
)
end
EOS
end
item_requests :organization, :vdc, :network, :vapp, :server, :catalog, :task
end
end
end

View File

@ -4,7 +4,7 @@ module Fog
class Catalog < Fog::Vcloud::Model
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type

View File

@ -4,7 +4,7 @@ module Fog
class CatalogItem < Fog::Vcloud::Model
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type

View File

@ -11,14 +11,12 @@ module Fog
def all
org_uri = self.organization_uri || connection.default_organization_uri
data = connection.get_organization(org_uri).body[:Link].select { |link| link[:type] == "application/vnd.vmware.vcloud.catalog+xml" }
data = connection.get_organization(org_uri).links.select { |link| link[:type] == "application/vnd.vmware.vcloud.catalog+xml" }
load(data)
end
def get(uri)
if data = connection.get_catalog(uri)
new(data.body)
end
connection.get_catalog(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -3,9 +3,9 @@ module Fog
class Compute
class Ip < Fog::Vcloud::Model
ignore_attributes :xmlns_i, :xmlns
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :name, :aliases => :Name
attribute :status, :aliases => :Status

View File

@ -4,8 +4,8 @@ module Fog
class Network < Fog::Vcloud::Model
identity :href, :aliases => :Href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd, :xmlns_i, :Id
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :name, :aliases => :Name
@ -13,15 +13,9 @@ module Fog
attribute :configuration, :aliases => :Configuration
attribute :provider_info, :aliases => :ProviderInfo
attribute :links, :aliases => :Link, :type => :array
def parent_network
return nil if configuration[:ParentNetwork].nil?
@parent_network ||= Fog::Vcloud::Compute::Network.new(
:connection => connection,
:collection => Fog::Vcloud::Compute::Networks.new(:connection => connection),
:href => configuration[:ParentNetwork][:href]
)
@parent_network ||= connection.get_network(configuration[:ParentNetwork][:href])
end
end
end

View File

@ -17,22 +17,19 @@ module Fog
data = nil
if self.href =~ /\/vdc\//
check_href!("Vdc")
data = [connection.get_vdc(self.href).body[:AvailableNetworks][:Network]].flatten.compact
data = [connection.get_vdc(self.href).available_networks].flatten.compact.reject{|n| n == '' }
elsif self.href =~ /\/org\//
check_href!("Org")
links = (l=connection.get_organization(self.href).body[:Link]).is_a?(Array) ? l : [l].compact
data = links.select{|l| l[:type] == 'application/vnd.vmware.vcloud.network+xml' }
data = connection.get_organization(self.href).links.select{|l| l[:type] == 'application/vnd.vmware.vcloud.network+xml' }
elsif self.href =~ /\/vApp\//
check_href!("Vapp")
data = [(connection.get_vapp(self.href).body[:NetworkConfigSection]||{})[:NetworkConfig]].flatten.compact.collect{|n| n[:Configuration][:ParentNetwork] unless n[:Configuration].nil? }.compact
data = [(connection.get_vapp(self.href).network_configs||{})[:NetworkConfig]].flatten.compact.collect{|n| n[:Configuration][:ParentNetwork] unless n[:Configuration].nil? }.compact
end
load([*data]) unless data.nil?
end
def get(uri)
if data = connection.get_network(uri)
new(data.body)
end
connection.get_network(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -3,15 +3,14 @@ module Fog
class Compute
class Organization < Fog::Vcloud::Model
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :name
attribute :description, :aliases => :Description
attribute :type
attribute :full_name, :aliases => :FullName
attribute :other_links, :aliases => :Link
def networks
@networks ||= Fog::Vcloud::Compute::Networks.

View File

@ -17,9 +17,7 @@ module Fog
end
def get(uri)
if data = connection.get_organization(uri)
new(data.body)
end
connection.get_organization(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -7,7 +7,7 @@ module Fog
include Fog::Vcloud::Compute::Helpers::Status
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :type
@ -24,9 +24,10 @@ module Fog
attribute :guest_customization, :aliases => :GuestCustomizationSection
attribute :operating_system, :aliases => :'ovf:OperatingSystemSection'
attribute :links, :aliases => :Link, :type => :array
attribute :tasks, :aliases => :Tasks, :type => :array
has_up :vapp
def computer_name
load_unless_loaded!
self.guest_customization[:ComputerName]
@ -44,7 +45,7 @@ module Fog
def ip_addresses
load_unless_loaded!
self.network_connections.collect{|n| n[:IpAddress] }
[self.network_connections].flatten.collect{|n| n[:IpAddress] }
end
def ready?
@ -262,7 +263,7 @@ module Fog
end
def reload_status
self.status = connection.get_vapp(href).body[:status]
self.status = connection.get_vapp(href).status
end
end
end

View File

@ -19,11 +19,7 @@ module Fog
end
def get(uri)
if data = connection.get_vapp(uri)
# If no tasks returned, set a mock entry to flush on reload
data.body[:Tasks] = {} unless data.body[:Tasks]
new(data.body)
end
connection.get_vapp(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -4,7 +4,7 @@ module Fog
class Task < Fog::Vcloud::Model
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :status

View File

@ -19,9 +19,7 @@ module Fog
end
def get(uri)
if data = connection.get_task(uri)
new(data.body)
end
connection.get_task(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -6,9 +6,9 @@ module Fog
include Fog::Vcloud::Compute::Helpers::Status
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :name
attribute :type
@ -19,7 +19,9 @@ module Fog
attribute :children, :aliases => :Children, :squash => :Vm
attribute :lease_settings, :aliases => :LeaseSettingsSection
attribute :other_links, :aliases => :Link
attribute :network_configs, :aliases => :NetworkConfigSection
has_up :vdc
def servers
@servers ||= Fog::Vcloud::Compute::Servers.

View File

@ -13,15 +13,11 @@ module Fog
attribute :href
def all
resource_entities = (re=connection.get_vdc(self.href).body[:ResourceEntities][:ResourceEntity]).is_a?(Array) ? re : [re].compact
data = resource_entities.select { |re| re[:type] == "application/vnd.vmware.vcloud.vApp+xml" }
load(data)
load([connection.get_vdc(self.href).resource_entities].flatten.select { |re| re[:type] == "application/vnd.vmware.vcloud.vApp+xml" })
end
def get(uri)
if data = connection.get_vapp(uri)
new(data.body)
end
connection.get_vapp(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -3,9 +3,9 @@ module Fog
class Compute
class Vdc < Fog::Vcloud::Model
identity :href
ignore_attributes :xmlns, :xmlns_xsi, :xmlns_xsd
identity :href, :aliases => :Href
attribute :links, :aliases => :Link, :type => :array
ignore_attributes :xmlns, :xmlns_i, :xmlns_xsi, :xmlns_xsd
attribute :name
attribute :type
@ -18,10 +18,10 @@ module Fog
attribute :storage_capacity, :aliases => :StorageCapacity
attribute :available_networks, :aliases => :AvailableNetworks, :squash => :Network
attribute :other_links, :aliases => :Link
attribute :resource_entities, :aliases => :ResourceEntities, :squash => :ResourceEntity
has_up :organization
def networks
@networks ||= Fog::Vcloud::Compute::Networks.
new( :connection => connection,

View File

@ -13,16 +13,13 @@ module Fog
attribute :href
def all
links = (l=connection.get_organization(org_uri).body[:Link]).is_a?(Array) ? l : [l].compact
data = links.select { |link| link[:type] == "application/vnd.vmware.vcloud.vdc+xml" }
data = connection.get_organization(org_uri).links.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
connection.get_vdc(uri)
rescue Fog::Errors::NotFound
nil
end

View File

@ -6,7 +6,7 @@
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1/action/undeploy"/>
<Link rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1/controlAccess/"/>
<Link rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1/action/controlAccess"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vdc+xml" href="https://vcloud.example.com/api/v1.0/vdc/652994200"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vdc+xml" href="https://vcloud.example.com/api/v1.0/vdc/1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1"/>
<Description>Some Description of a vApp</Description>
<LeaseSettingsSection type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1/leaseSettingsSection/" ovf:required="false">

View File

@ -10,7 +10,7 @@
<Link rel="power:powerOn" href="https://vcloud.example.com/api/v1.0/vApp/vm-1/power/action/powerOn"/>
<Link rel="power:powerOff" href="https://vcloud.example.com/api/v1.0/vApp/vm-1/power/action/powerOff"/>
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://vcloud.example.com/api/v1.0/vApp/vm-1/action/undeploy"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1006933678"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vm+xml" href="https://vcloud.example.com/api/v1.0/vApp/vm-1"/>
<Link rel="screen:thumbnail" href="https://vcloud.example.com/api/v1.0/vApp/vm-1/screen"/>
<Link rel="media:insertMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://vcloud.example.com/api/v1.0/vApp/vm-1/media/action/insertMedia"/>

View File

@ -10,7 +10,7 @@
<Link rel="power:powerOn" href="https://vcloud.example.com/api/v1.0/vApp/vm-2/power/action/powerOn"/>
<Link rel="power:powerOff" href="https://vcloud.example.com/api/v1.0/vApp/vm-2/power/action/powerOff"/>
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://vcloud.example.com/api/v1.0/vApp/vm-2/action/undeploy"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1006933678"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vcloud.example.com/api/v1.0/vApp/vapp-1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vm+xml" href="https://vcloud.example.com/api/v1.0/vApp/vm-2"/>
<Link rel="screen:thumbnail" href="https://vcloud.example.com/api/v1.0/vApp/vm-2/screen"/>
<Link rel="media:insertMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://vcloud.example.com/api/v1.0/vApp/vm-2/media/action/insertMedia"/>

View File

@ -6,10 +6,7 @@ Shindo.tests("Vcloud::Compute | network", ['vcloud']) do
connection = Fog::Vcloud::Compute.new(:vcloud_host => 'vcloud.example.com', :vcloud_username => 'username', :vcloud_password => 'password')
tests("an org network") do
instance = Fog::Vcloud::Compute::Networks.new(
:connection => connection,
:href => "https://vcloud.example.com/api/v1.0/vApp/vapp-1"
).first
instance = connection.get_network('https://vcloud.example.com/api/v1.0/network/1')
instance.reload
tests("#href").returns("https://vcloud.example.com/api/v1.0/network/1") { instance.href }
@ -39,16 +36,12 @@ Shindo.tests("Vcloud::Compute | network", ['vcloud']) do
end
tests("#parent_network") do
tests("returned network name").returns("ParentNetwork1"){ p = instance.parent_network; p.reload; p.name }
tests("returned network name").returns("ParentNetwork1"){ p = instance.parent_network; p.name }
end
end
tests("an external network") do
instance = Fog::Vcloud::Compute::Network.new(
:connection => connection,
:collection => Fog::Vcloud::Compute::Networks.new(:connection => connection),
:href => "https://vcloud.example.com/api/v1.0/admin/network/2"
)
instance = connection.get_network('https://vcloud.example.com/api/v1.0/admin/network/2')
instance.reload
tests("#href").returns("https://vcloud.example.com/api/v1.0/admin/network/2") { instance.href }
tests("#name").returns("ParentNetwork1") { instance.name }

View File

@ -2,7 +2,11 @@ Shindo.tests("Vcloud::Compute | organization", ['vcloud']) do
pending if Fog.mocking?
instance = Fog::Vcloud::Compute.new(:vcloud_host => 'vcloud.example.com', :vcloud_username => 'username', :vcloud_password => 'password').organizations.first
instance = Fog::Vcloud::Compute.new(
:vcloud_host => 'vcloud.example.com',
:vcloud_username => 'username',
:vcloud_password => 'password'
).get_organization('https://vcloud.example.com/api/v1.0/org/1')
instance.reload
tests("#href").returns('https://vcloud.example.com/api/v1.0/org/1'){ instance.href }

View File

@ -4,14 +4,17 @@ Shindo.tests("Vcloud::Compute | server", ['vcloud']) do
pending if Fog.mocking?
instance = Fog::Vcloud::Compute::Servers.new(
:connection => Fog::Vcloud::Compute.new(:vcloud_host => 'vcloud.example.com', :vcloud_username => 'username', :vcloud_password => 'password'),
:href => "https://vcloud.example.com/api/v1.0/vApp/vapp-1"
).first
instance = Fog::Vcloud::Compute.new(
:vcloud_host => 'vcloud.example.com',
:vcloud_username => 'username',
:vcloud_password => 'password'
).get_server('https://vcloud.example.com/api/v1.0/vApp/vm-2')
instance.reload
tests("#href").returns("https://vcloud.example.com/api/v1.0/vApp/vm-2") { instance.href }
tests("#name").returns("vm2") { instance.name }
tests("#vapp").returns("vApp1") { instance.vapp.name }
tests("#description").returns("Some VM Description") { instance.description }
tests("#status").returns('8') { instance.status }
tests("#deployed").returns(true) { instance.deployed }

View File

@ -5,14 +5,16 @@ Shindo.tests("Vcloud::Compute | vapp", ['vcloud']) do
pending if Fog.mocking?
instance = Fog::Vcloud::Compute::Vapps.new(
:connection => Fog::Vcloud::Compute.new(:vcloud_host => 'vcloud.example.com', :vcloud_username => 'username', :vcloud_password => 'password'),
:href => "https://vcloud.example.com/api/v1.0/vdc/1"
).first
instance = Fog::Vcloud::Compute.new(
:vcloud_host => 'vcloud.example.com',
:vcloud_username => 'username',
:vcloud_password => 'password'
).get_vapp('https://vcloud.example.com/api/v1.0/vApp/vapp-1')
instance.reload
tests("#href").returns("https://vcloud.example.com/api/v1.0/vApp/vapp-1") { instance.href }
tests("#name").returns("vApp1") { instance.name }
tests("#vdc").returns("vDC1"){ instance.vdc.name }
tests("#description").returns("Some Description of a vApp") { instance.description }
tests("#status").returns('8') { instance.status }
tests("#deployed").returns(true) { instance.deployed }

View File

@ -5,14 +5,17 @@ Shindo.tests("Vcloud::Compute | vdc", ['vcloud']) do
pending if Fog.mocking?
instance = Fog::Vcloud::Compute::Vdcs.new(
:connection => Fog::Vcloud::Compute.new(:vcloud_host => 'vcloud.example.com', :vcloud_username => 'username', :vcloud_password => 'password'),
:href => "https://vcloud.example.com/api/v1.0/org/1"
).first
instance = Fog::Vcloud::Compute.new(
:vcloud_host => 'vcloud.example.com',
:vcloud_username => 'username',
:vcloud_password => 'password'
).get_vdc('https://vcloud.example.com/api/v1.0/vdc/1')
instance.reload
tests("#href").returns("https://vcloud.example.com/api/v1.0/vdc/1") { instance.href }
tests("#name").returns("vDC1") { instance.name }
tests('#organization').returns("Org1") { instance.organization.name }
tests("#description").returns("Some Description") { instance.description }
tests("#network_quota").returns(10) { instance.network_quota }
tests("#nic_quota").returns(10) { instance.nic_quota }