diff --git a/lib/fog/compute/models/vcloud/server.rb b/lib/fog/compute/models/vcloud/server.rb
index 9d879708f..95cbdec9a 100644
--- a/lib/fog/compute/models/vcloud/server.rb
+++ b/lib/fog/compute/models/vcloud/server.rb
@@ -128,11 +128,14 @@ module Fog
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 }
+ @disk_change = :added
+
+ @add_disk = {
+ :'rasd:HostResource' => {:vcloud_capacity => size},
+ :'rasd:AddressOnParent' => (disk_mess.map { |dm| dm[:'rasd:AddressOnParent'] }.sort.last.to_i + 1).to_s,
+ :'rasd:ResourceType' => '17'
+ }
end
true
end
@@ -141,10 +144,10 @@ module Fog
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 }
+ @disk_change = :deleted
+ @remove_disk = number
end
end
true
@@ -169,6 +172,18 @@ module Fog
memory_mess[:"rasd:VirtualQuantity"] = @update_memory_value.to_s
connection.configure_vm_memory(memory_mess)
end
+ if @disk_change == :deleted
+ data = disk_mess.delete_if do |vh|
+ vh[:'rasd:ResourceType'] == '17' &&
+ vh[:'rasd:AddressOnParent'].to_s == @remove_disk.to_s
+ end
+ connection.configure_vm_disks(vm_href, data)
+ end
+ if @disk_change == :added
+ data = disk_mess
+ data << @add_disk
+ connection.configure_vm_disks(vm_href, data)
+ end
#connection.configure_vapp( href, _compose_vapp_data )
end
reset_tracking
@@ -187,6 +202,14 @@ module Fog
end
alias :delete :destroy
+ def vm_href
+ load_unless_loaded!
+ #require 'pp'
+ #pp vm_data
+ #vm_data[0][:Link].select {|v| v[:rel] == 'edit'}[0][:href]
+ vm_data.kind_of?(Array)? vm_data[0][:href] : vm_data[:href]
+ end
+
private
def reset_tracking
diff --git a/lib/fog/compute/requests/vcloud/configure_vm.rb b/lib/fog/compute/requests/vcloud/configure_vm.rb
new file mode 100644
index 000000000..9c1328a27
--- /dev/null
+++ b/lib/fog/compute/requests/vcloud/configure_vm.rb
@@ -0,0 +1,247 @@
+# -*- coding: utf-8 -*-
+hardware_hash = {:xmlns_vcloud=>"http://www.vmware.com/vcloud/v1",
+ :vcloud_href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/",
+ :vcloud_type=>"application/vnd.vmware.vcloud.virtualHardwareSection+xml",
+ :"ovf:Info"=>"Virtual hardware requirements",
+ :"ovf:System"=>
+ {:"vssd:ElementName"=>"Virtual Hardware Family",
+ :"vssd:InstanceID"=>"0",
+ :"vssd:VirtualSystemIdentifier"=>"centos",
+ :"vssd:VirtualSystemType"=>"vmx-07"},
+ :"ovf:Item"=>
+ [{:"rasd:Address"=>"00:50:56:01:00:db",
+ :"rasd:AddressOnParent"=>"0",
+ :"rasd:AutomaticAllocation"=>"true",
+ :"rasd:Connection"=>"Gandalf_Dev_OrgNW_to_ExtNW_DirectConnect",
+ :"rasd:Description"=>"PCNet32 ethernet adapter",
+ :"rasd:ElementName"=>"Network adapter 0",
+ :"rasd:InstanceID"=>"1",
+ :"rasd:ResourceSubType"=>"PCNet32",
+ :"rasd:ResourceType"=>"10"},
+ {:"rasd:Address"=>"0",
+ :"rasd:Description"=>"SCSI Controller",
+ :"rasd:ElementName"=>"SCSI Controller 0",
+ :"rasd:InstanceID"=>"2",
+ :"rasd:ResourceSubType"=>"lsilogic",
+ :"rasd:ResourceType"=>"6"},
+ {:"rasd:AddressOnParent"=>"0",
+ :"rasd:Description"=>"Hard disk",
+ :"rasd:ElementName"=>"Hard disk 1",
+ :"rasd:HostResource"=>
+ {:vcloud_capacity=>"8192",
+ :vcloud_busType=>"6",
+ :vcloud_busSubType=>"lsilogic"},
+ :"rasd:InstanceID"=>"2000",
+ :"rasd:Parent"=>"2",
+ :"rasd:ResourceType"=>"17"},
+ {:"rasd:Address"=>"0",
+ :"rasd:Description"=>"IDE Controller",
+ :"rasd:ElementName"=>"IDE Controller 0",
+ :"rasd:InstanceID"=>"3",
+ :"rasd:ResourceType"=>"5"},
+ {:"rasd:AddressOnParent"=>"0",
+ :"rasd:AutomaticAllocation"=>"false",
+ :"rasd:Description"=>"CD/DVD Drive",
+ :"rasd:ElementName"=>"CD/DVD Drive 1",
+ :"rasd:HostResource"=>"",
+ :"rasd:InstanceID"=>"3000",
+ :"rasd:Parent"=>"3",
+ :"rasd:ResourceType"=>"15"},
+ {:"rasd:AddressOnParent"=>"0",
+ :"rasd:AutomaticAllocation"=>"false",
+ :"rasd:Description"=>"Floppy Drive",
+ :"rasd:ElementName"=>"Floppy Drive 1",
+ :"rasd:HostResource"=>"",
+ :"rasd:InstanceID"=>"8000",
+ :"rasd:ResourceType"=>"14"},
+ {:vcloud_href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/cpu",
+ :vcloud_type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :"rasd:AllocationUnits"=>"hertz * 10^6",
+ :"rasd:Description"=>"Number of Virtual CPUs",
+ :"rasd:ElementName"=>"1 virtual CPU(s)",
+ :"rasd:InstanceID"=>"4",
+ :"rasd:Reservation"=>"0",
+ :"rasd:ResourceType"=>"3",
+ :"rasd:VirtualQuantity"=>"1",
+ :"rasd:Weight"=>"0",
+ :Link=>
+ {:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/cpu"}},
+ {:vcloud_href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/memory",
+ :vcloud_type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :"rasd:AllocationUnits"=>"byte * 2^20",
+ :"rasd:Description"=>"Memory Size",
+ :"rasd:ElementName"=>"512 MB of memory",
+ :"rasd:InstanceID"=>"5",
+ :"rasd:Reservation"=>"0",
+ :"rasd:ResourceType"=>"4",
+ :"rasd:VirtualQuantity"=>"768",
+ :"rasd:Weight"=>"0",
+ :Link=>
+ {:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/memory"}}],
+ :Link=>
+ [{:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.virtualHardwareSection+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/"},
+ {:rel=>"down",
+ :type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/cpu"},
+ {:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/cpu"},
+ {:rel=>"down",
+ :type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/memory"},
+ {:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.rasdItem+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/memory"},
+ {:rel=>"down",
+ :type=>"application/vnd.vmware.vcloud.rasdItemsList+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/disks"},
+ {:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.rasdItemsList+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/disks"},
+ {:rel=>"down",
+ :type=>"application/vnd.vmware.vcloud.rasdItemsList+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/media"},
+ {:rel=>"down",
+ :type=>"application/vnd.vmware.vcloud.rasdItemsList+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/networkCards"},
+ {:rel=>"edit",
+ :type=>"application/vnd.vmware.vcloud.rasdItemsList+xml",
+ :href=>
+ "https://vcd01.esx.dev.int.realestate.com.au/api/v1.0/vApp/vm-624535987/virtualHardwareSection/networkCards"}]}
+
+
+module Fog
+ module Vcloud
+ class Compute
+ module Shared
+ private
+
+ def validate_vm_data(vm_data)
+ valid_opts = [:name, :cpus, :memory, :disks]
+ unless valid_opts.all? { |opt| vm_data.keys.include?(opt) }
+ raise ArgumentError.new("Required vm data missing: #{(valid_opts - vm_data.keys).map(&:inspect).join(", ")}")
+ end
+ end
+ end
+
+ class Real
+ include Shared
+
+ def generate_configure_vm_request(vm_data)
+ xmlns = 'http://schemas.dmtf.org/ovf/envelope/1'
+ xmlns_vcloud = 'http://www.vmware.com/vcloud/v1'
+ xmlns_rasd = 'http://schemas.dmtf.org/wbem/wscim/1/cim‐schema/2/CIM_ResourceAllocationSettingData'
+ xmlns_vssd = 'http://schemas.dmtf.org/wbem/wscim/1/cim‐schema/2/CIM_VirtualSystemSettingData'
+
+ builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2) # TODO - remove params
+ builder.VirtualHardwareSection(
+ :"vcloud:href" => vm_data[:"vcloud_href"],
+ :"vcloud:type" => vm_data[:"vcloud_type"],
+ :name => vm_data[:name],
+ :status => 2,
+ :size => 0,
+ :xmlns => xmlns,
+ :"xmlns:vcloud" => xmlns_vcloud,
+ :"xmlns:rasd" => xmlns_rasd,
+ :"xmlns:vssd" => xmlns_vssd) {
+ #builder.VirtualHardwareSection(:xmlns => 'http://schemas.dmtf.org/ovf/envelope/1') {
+
+ builder.Info(vm_data[:"ovf:Info"])
+ if system = vm_data[:"ovf:System"]
+ builder.System {
+ builder.ElementName(system[:"vssd:ElementName"], :xmlns => xmlns_vssd) if system[:"vssd:ElementName"]
+ builder.InstanceID(system[:"vssd:InstanceID"], :xmlns => xmlns_vssd) if system[:"vssd:InstanceID"]
+ builder.VirtualSystemIdentifier(system[:"vssd:VirtualSystemIdentifier"], :xmlns => xmlns_vssd) if system[:"vssd:VirtualSystemIdentifier"]
+ builder.VirtualSystemType(system[:"vssd:VirtualSystemType"], :xmlns => xmlns_vssd) if system[:"vssd:VirtualSystemType"]
+ }
+ end
+
+ vm_data[:'ovf:Item'].each do |oi|
+ builder.Item {
+ builder.Address(oi[:'rasd:Address'], :xmlns => xmlns_rasd) if oi[:'rasd:Address']
+ builder.AddressOnParent(oi[:'rasd:AddressOnParent'], :xmlns => xmlns_rasd) if oi[:'rasd:AddressOnParent']
+ builder.AutomaticAllocation(oi[:'rasd:AutomaticAllocation'], :xmlns => xmlns_rasd) if oi[:'rasd:AutomaticAllocation']
+ builder.Connection(oi[:'rasd:Connection'], :xmlns => xmlns_rasd) if oi[:'rasd:Connection']
+ builder.Description(oi[:'rasd:Description'], :xmlns => xmlns_rasd) if oi[:'rasd:Description']
+ builder.ElementName(oi[:'rasd:ElementName'], :xmlns => xmlns_rasd) if oi[:'rasd:ElementName']
+ builder.InstanceID(oi[:'rasd:InstanceID'], :xmlns => xmlns_rasd) if oi[:'rasd:InstanceID']
+ builder.ResourceSubType(oi[:'rasd:ResourceSubType'], :xmlns => xmlns_rasd) if oi[:'rasd:ResourceSubType']
+ builder.ResourceType(oi[:'rasd:ResourceType'], :xmlns => xmlns_rasd) if oi[:'rasd:ResourceType']
+ if hr = oi[:'rasd:HostResource']
+ attrs = {}
+ attrs[]
+ end
+ }
+ end
+
+
+
+ # 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(vm_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(vm_data[:memory], :xmlns => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData')
+ # }
+ # vm_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_vm(vm_uri, vm_data)
+ validate_vm_data(vm_data)
+
+ request(
+ :body => generate_configure_vm_request(vm_uri, vm_data),
+ :expects => 202,
+ :headers => {'Content-Type' => 'application/vnd.vmware.vcloud.vm+xml' },
+ :method => 'PUT',
+ :uri => vm_uri,
+ :parse => true
+ )
+ end
+
+ end
+ end
+ end
+end
+
+if $0 == __FILE__
+ require 'builder'
+ i = Fog::Vcloud::Compute::Real.new
+ puts i.generate_configure_vm_request(hardware_hash)
+end
diff --git a/lib/fog/compute/requests/vcloud/configure_vm_disks.rb b/lib/fog/compute/requests/vcloud/configure_vm_disks.rb
new file mode 100644
index 000000000..b61713bc0
--- /dev/null
+++ b/lib/fog/compute/requests/vcloud/configure_vm_disks.rb
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+#
+#
+# -
+# 0
+# SCSI Controller
+# SCSI Controller 0
+# 2
+# lsilogic
+# 6
+#
+# -
+# 0
+# Hard disk
+# Hard disk 1
+#
+# 2000
+# 2
+# 17
+#
+# -
+# 0
+# IDE Controller
+# IDE Controller 0
+# 3
+# 5
+#
+#
+
+
+
+
+
+module Fog
+ module Vcloud
+ class Compute
+ class Real
+
+ def generate_configure_vm_disks_request(href, disk_data)
+ xmlns = {
+ "xmlns:rasd" => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
+ "xmlns" => "http://www.vmware.com/vcloud/v1"
+ }
+ # Get the XML from the API, parse it.
+ xml = Nokogiri::XML(request( :uri => href).body)
+
+ #xml.root['name'] = vapp_data[:name]
+
+ #disks
+ real_disks = xml.xpath("//rasd:ResourceType[ .='17']/..", xmlns)
+ real_disk_numbers = real_disks.map { |disk| disk.at('.//rasd:AddressOnParent', xmlns).content }
+ disk_numbers = disk_data.map { |vdisk| vdisk[:"rasd:AddressOnParent"].to_s }
+
+ if disk_data.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("//rasd:ResourceType[ .='17']/../rasd:AddressOnParent[.='#{number}']/..", xmlns)
+ result.remove
+ end
+ end
+ elsif disk_data.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('.//rasd:AddressOnParent', xmlns).content = number.to_i #-1
+ new_disk.at('.//rasd:HostResource', xmlns)["vcloud:capacity"] = disk_data.detect { |disk| disk[:'rasd:AddressOnParent'].to_s == number.to_s }[:'rasd:HostResource'][:vcloud_capacity].to_s
+ # nokogiri bug? shouldn't need to add this explicitly.
+ new_disk.at('.//rasd:HostResource', xmlns)["xmlns:vcloud"] = xmlns['xmlns']
+ new_disk.at('.//rasd:InstanceID', xmlns).content = (2000 + number.to_i).to_s
+ new_disk.at('.//rasd:ElementName', xmlns).content = "Hard disk #{number.to_i + 1}"
+ real_disks.first.parent << new_disk
+ end
+
+ end
+ xml.to_s
+ end
+
+ def configure_vm_disks(vm_href, disk_data)
+ disk_href = vm_href + '/virtualHardwareSection/disks'
+
+ body = generate_configure_vm_disks_request(disk_href, disk_data)
+
+ request(
+ :body => body,
+ :expects => 202,
+ :headers => {'Content-Type' => 'application/vnd.vmware.vcloud.rasdItem+xml' },
+ :method => 'PUT',
+ :uri => disk_href,
+ :parse => true
+ )
+ end
+
+ end
+
+ end
+ end
+end
diff --git a/lib/fog/compute/requests/vcloud/get_vm_disks.rb b/lib/fog/compute/requests/vcloud/get_vm_disks.rb
new file mode 100644
index 000000000..9b56f186f
--- /dev/null
+++ b/lib/fog/compute/requests/vcloud/get_vm_disks.rb
@@ -0,0 +1,16 @@
+module Fog
+ module Vcloud
+ class Compute
+
+ class Real
+ def get_vm_disks(href)
+ request(
+ :expects => 200,
+ :uri => href,
+ :parse => true#false#true
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/fog/compute/vcloud.rb b/lib/fog/compute/vcloud.rb
index 150f6cac8..286f3d967 100644
--- a/lib/fog/compute/vcloud.rb
+++ b/lib/fog/compute/vcloud.rb
@@ -90,6 +90,7 @@ module Fog
request :configure_network_ip
request :configure_vapp
request :configure_vm_memory
+ request :configure_vm_disks
request :delete_vapp
request :get_catalog
request :get_catalog_item
@@ -103,6 +104,7 @@ module Fog
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
diff --git a/tests/compute/models/vcloud/servers_tests.rb b/tests/compute/models/vcloud/servers_tests.rb
index 2d28d5c22..be9e922ae 100644
--- a/tests/compute/models/vcloud/servers_tests.rb
+++ b/tests/compute/models/vcloud/servers_tests.rb
@@ -41,6 +41,40 @@ Shindo.tests("Vcloud::Compute | servers", ['vcloud']) do
@svr.reload.memory[:amount]
end
+ tests("#svr.add_disk(4096)").returns([2, "4096"]) do
+ pending if Fog.mocking?
+ raise 'Server template already has two disks' if @svr.disks.size == 2
+ @svr.wait_for { ready? }
+ @svr.add_disk(4096)
+ @svr.save
+ @svr.wait_for { ready? }
+ # Can take a little while for the VM to know it has different ram, and not tied to a task..
+ (1..20).each do |i|
+ break if @svr.reload.disks.size == 2
+ sleep 1
+ end
+ [
+ @svr.disks.size,
+ @svr.disks[1][:resource][:vcloud_capacity]
+ ]
+ end
+
+ tests("#svr.delete_disk(1)").returns(1) do
+ pending if Fog.mocking?
+ raise "Server doesn't have two disks - did previous step fail? " if @svr.disks.size != 2
+ @svr.wait_for { ready? }
+ sleep 5 # otherwise complains about being busy
+ @svr.delete_disk 1
+ @svr.save
+ @svr.wait_for { ready? }
+ # Can take a little while for the VM to know it has different ram, and not tied to a task..
+ (1..20).each do |i|
+ break if @svr.reload.disks.size == 1
+ sleep 1
+ end
+ @svr.disks.size
+ end
+
tests("#svr.destroy").raises(Excon::Errors::Forbidden) do
pending if Fog.mocking?
@svr.destroy
diff --git a/tests/compute/requests/vcloud/disk_configure_tests.rb b/tests/compute/requests/vcloud/disk_configure_tests.rb
new file mode 100644
index 000000000..6c17251e5
--- /dev/null
+++ b/tests/compute/requests/vcloud/disk_configure_tests.rb
@@ -0,0 +1,107 @@
+require 'spec'
+require 'spec/mocks'
+
+Shindo.tests("Vcloud::Compute | disk_requests", ['vcloud']) do
+
+ @xmlns = {
+ "xmlns" => "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
+ "xmlns:vcloud" => "http://www.vmware.com/vcloud/v1"
+ }
+
+ def disk_hash
+ [{:"rasd:AddressOnParent"=>"0",
+ :"rasd:Description"=>"Hard disk",
+ :"rasd:ElementName"=>"Hard disk 1",
+ :"rasd:HostResource"=>
+ {:vcloud_capacity=>"8192",
+ :vcloud_busType=>"6",
+ :vcloud_busSubType=>"lsilogic"},
+ :"rasd:InstanceID"=>"2000",
+ :"rasd:Parent"=>"2",
+ :"rasd:ResourceType"=>"17"}]
+ end
+
+ def nokogiri_load
+ Nokogiri::XML(MockDiskResponse.new.body)
+ end
+
+ class MockDiskResponse
+ def body
+ <
+
+ -
+ 0
+ SCSI Controller
+ SCSI Controller 0
+ 2
+ lsilogic
+ 6
+
+ -
+ 0
+ Hard disk
+ Hard disk 1
+
+ 2000
+ 2
+ 17
+
+ -
+ 0
+ IDE Controller
+ IDE Controller 0
+ 3
+ 5
+
+
+EOF
+ end
+ end
+
+ Vcloud[:compute].stub!(:request).and_return(MockDiskResponse.new)
+
+ tests("Call to generate config returns string").returns(true) do
+ Vcloud[:compute].generate_configure_vm_disks_request('http://blah', disk_hash).kind_of? String
+ end
+
+ tests("Call to generate config with no changes returns input data").returns(true) do
+ Nokogiri::XML(Vcloud[:compute].generate_configure_vm_disks_request('http://blah', disk_hash)).to_s ==
+ Nokogiri::XML(MockDiskResponse.new.body).to_s
+ end
+
+ tests("Call to generate config with no disks removes disk").returns(true) do
+ xml = Vcloud[:compute].generate_configure_vm_disks_request('http://blah', [])
+ ng = Nokogiri::XML(xml)
+ # Should have 2 controllers, but no disks.
+ ng.xpath("//xmlns:ResourceType", @xmlns).size == 2 &&
+ ng.xpath("//xmlns:ResourceType[ .='17']", @xmlns).size == 0
+ end
+
+ tests("Call to generate config adding a disk").returns(['4096', true, true]) do
+ disks = disk_hash
+ disks << {
+ :"rasd:AddressOnParent"=>"1",
+ :"rasd:Description"=>"Hard disk",
+ :"rasd:ElementName"=>"Hard disk 2",
+ :"rasd:HostResource"=>
+ {:vcloud_capacity=>"4096",
+ :vcloud_busType=>"6",
+ :vcloud_busSubType=>"lsilogic"},
+ :"rasd:InstanceID"=>"2000",
+ :"rasd:Parent"=>"2",
+ :"rasd:ResourceType"=>"17"}
+ xml = Vcloud[:compute].generate_configure_vm_disks_request('http://blah', disks)
+ ng = Nokogiri::XML(xml)
+ [
+ # should be 4096mb
+ ng.at("//xmlns:ResourceType[ .='17']/../xmlns:AddressOnParent[.='-1']/../xmlns:HostResource", @xmlns)["capacity"],
+ # Should have 2 controllers, and 2 disks
+ ng.xpath("//xmlns:ResourceType", @xmlns).size == 4,
+ ng.xpath("//xmlns:ResourceType[ .='17']", @xmlns).size == 2
+ ]
+ end
+
+
+ Vcloud[:compute].unstub!(:request)
+end