diff --git a/lib/ruby_vcloud_sdk/catalog.rb b/lib/ruby_vcloud_sdk/catalog.rb
index 5ec0e24..06b9753 100644
--- a/lib/ruby_vcloud_sdk/catalog.rb
+++ b/lib/ruby_vcloud_sdk/catalog.rb
@@ -230,7 +230,7 @@ def ovf_directory(directory)
end
def admin_xml
- admin_catalog_link = "/api/admin/catalog/#{id}"
+ admin_catalog_link = "/api/compute/api/catalog/#{id}"
admin_catalog = connection.get(admin_catalog_link)
unless admin_catalog
diff --git a/lib/ruby_vcloud_sdk/connection/connection.rb b/lib/ruby_vcloud_sdk/connection/connection.rb
index 917b7b8..a362f2d 100644
--- a/lib/ruby_vcloud_sdk/connection/connection.rb
+++ b/lib/ruby_vcloud_sdk/connection/connection.rb
@@ -31,9 +31,9 @@ def initialize(url, request_timeout = nil,
def connect(username, password)
login_password = "#{username}:#{password}"
- auth_header_value = "Basic #{Base64.encode64(login_password)}"
- response = @site[login_url].post(
- Authorization: auth_header_value, Accept: ACCEPT)
+ auth_header_value = "Basic #{Base64.strict_encode64(login_password)}"
+ response = @site[login_url].post(nil,
+ {Authorization: auth_header_value, Accept: ACCEPT})
Config.logger.debug(response)
@cookies = response.cookies
unless @cookies["vcloud-token"].gsub!("+", "%2B").nil?
@@ -63,11 +63,13 @@ def post(destination, data, content_type = "*/*")
"Warning: content type not specified. Default to '*/*'")
end
@rest_logger.info("#{__method__.to_s.upcase} data:#{data.to_s}")
+
response = @site[get_nested_resource(destination)].post(data.to_s, {
Accept: ACCEPT,
cookies: @cookies,
content_type: content_type
})
+
fail ApiRequestError if http_error?(response)
@rest_logger.debug(response)
wrap_response(response)
diff --git a/lib/ruby_vcloud_sdk/vdc.rb b/lib/ruby_vcloud_sdk/vdc.rb
index 4837f12..0d84a3d 100644
--- a/lib/ruby_vcloud_sdk/vdc.rb
+++ b/lib/ruby_vcloud_sdk/vdc.rb
@@ -17,6 +17,7 @@ class VDC
extend Forwardable
def_delegators :entity_xml,
:name, :upload_link, :upload_media_link,
+ :instantiate_ovf_link,
:instantiate_vapp_template_link
public :find_network_by_name, :network_exists?
@@ -209,6 +210,101 @@ def storage_profile_xml_node(name)
storage_profile
end
+
+ def instantiate_ovf_params(vapp_name, vdc)
+ instantiate_ovf_params = VCloudSdk::Xml::WrapperFactory.create_instance("InstantiateOvfParams").tap do |params|
+ params.name = vapp_name
+ end
+
+ connection.post(entity_xml.instantiate_ovf_link,
+ instantiate_ovf_params,
+ Xml::MEDIA_TYPE[:INSTANTIATE_OVF_PARAMS])
+ end
+
+
+ def instantiate_ovf(vapp_name,directory)
+ if vapp_exists?(vapp_name)
+ fail CloudError,
+ "vApp '#{vapp_name}' already exists in vdc #{entity_xml.name}"
+ end
+
+ Config.logger.info "Uploading vApp #{vapp_name} to #{entity_xml.name}"
+ vapp = instantiate_ovf_params(vapp_name, entity_xml)
+ vapp = upload_vapp_files(vapp, ovf_directory(directory))
+
+ end
+
+
+ def ovf_directory(directory)
+ # if directory behaves like an OVFDirectory, then use it
+ is_ovf_directory = [:ovf_file, :ovf_file_path, :vmdk_file, :vmdk_file_path]
+ .reduce(true) do |present, name|
+ present && directory.respond_to?(name)
+ end
+
+ if is_ovf_directory
+ directory
+ else
+ OVFDirectory.new(directory)
+ end
+ end
+
+ def upload_vapp_files(
+ vapp_template,
+ ovf_directory,
+ tries = @session.retries[:upload_vapp_files])
+ tries.times do |try|
+ current_vapp_template = connection.get(vapp_template)
+ if !current_vapp_template.files || current_vapp_template.files.empty?
+ Config.logger.info %Q{
+ #{current_vapp_template.name} has tasks in progress...
+ Waiting until done...
+ }
+ current_vapp_template.running_tasks.each do |task|
+ monitor_task(task,
+ @session.time_limit[:process_descriptor_vapp_template])
+ end
+
+ return current_vapp_template
+ end
+
+ Config.logger.debug "vapp files left to upload #{current_vapp_template.files}."
+ Config.logger.debug %Q{
+ vapp incomplete files left to upload:
+ #{current_vapp_template.incomplete_files}
+ }
+
+ current_vapp_template.incomplete_files.each do |f|
+ # switch on extension
+ case f.name.split(".")[-1].downcase
+ when "ovf"
+ Config.logger.info %Q{
+ Uploading OVF file:
+ #{ovf_directory.ovf_file_path} for #{vapp_template.name}
+ }
+ connection.put(f.upload_link, ovf_directory.ovf_file.read,
+ Xml::MEDIA_TYPE[:OVF])
+ when "vmdk"
+ Config.logger.info %Q{
+ Uploading VMDK file:
+ #{ovf_directory.vmdk_file_path(f.name)} for #{vapp_template.name}
+ }
+ connection.put_file(f.upload_link,
+ ovf_directory.vmdk_file(f.name))
+ end
+ end
+ # Repeat
+ sleep 2**try
+ end
+
+ fail ApiTimeoutError,
+ %Q{
+ Unable to finish uploading vApp after #{tries} tries.
+ current_vapp_template.files:
+ #{current_vapp_template.files}
+ }
+ end
+
private
def storage_profile_records
@@ -238,5 +334,6 @@ def delete_single_disk(disk)
Config.logger.info "Disk deleted successfully"
end
+
end
end
diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb
index f5bf51a..83fc173 100644
--- a/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb
+++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes.rb
@@ -3,6 +3,7 @@
require "ruby_vcloud_sdk/xml/wrapper_classes/admin_catalog"
require "ruby_vcloud_sdk/xml/wrapper_classes/admin_org"
require "ruby_vcloud_sdk/xml/wrapper_classes/allocated_ip_addresses"
+require "ruby_vcloud_sdk/xml/wrapper_classes/catalog"
require "ruby_vcloud_sdk/xml/wrapper_classes/catalog_item"
require "ruby_vcloud_sdk/xml/wrapper_classes/disk"
require "ruby_vcloud_sdk/xml/wrapper_classes/disk_attach_or_detach_params"
@@ -12,6 +13,7 @@
require "ruby_vcloud_sdk/xml/wrapper_classes/file"
require "ruby_vcloud_sdk/xml/wrapper_classes/gateway_interface"
require "ruby_vcloud_sdk/xml/wrapper_classes/hard_disk_item_wrapper"
+require "ruby_vcloud_sdk/xml/wrapper_classes/instantiate_ovf_params"
require "ruby_vcloud_sdk/xml/wrapper_classes/instantiate_vapp_template_params"
require "ruby_vcloud_sdk/xml/wrapper_classes/ip_address"
require "ruby_vcloud_sdk/xml/wrapper_classes/ip_scope"
diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog.rb
new file mode 100644
index 0000000..c0fc78d
--- /dev/null
+++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/catalog.rb
@@ -0,0 +1,29 @@
+module VCloudSdk
+ module Xml
+
+ class Catalog < Wrapper
+ def description
+ get_nodes("Description").first
+ end
+
+ def description=(desc)
+ description.content = desc
+ end
+
+ def add_item_link
+ get_nodes(XML_TYPE[:LINK],
+ { type: ADMIN_MEDIA_TYPE[:CATALOG_ITEM],
+ rel: XML_TYPE[:ADD] }).first
+ end
+
+ def catalog_items(name = nil)
+ if name
+ get_nodes(XML_TYPE[:CATALOGITEM], { name: name })
+ else
+ get_nodes(XML_TYPE[:CATALOGITEM])
+ end
+ end
+ end
+
+ end
+end
diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_ovf_params.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_ovf_params.rb
new file mode 100644
index 0000000..9099933
--- /dev/null
+++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/instantiate_ovf_params.rb
@@ -0,0 +1,9 @@
+module VCloudSdk
+ module Xml
+ class UploadVAppTemplateParams < Wrapper
+ def storage_profile=(storage_profile)
+ add_child(storage_profile) unless storage_profile.nil?
+ end
+ end
+ end
+end
diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb
index a71e5b6..7bc2d33 100644
--- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb
+++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vapp.rb
@@ -40,6 +40,15 @@ def vms
def vm(name)
get_nodes("Vm", name: name).first
end
+
+ def files
+ get_nodes("File")
+ end
+
+ def incomplete_files
+ files.find_all {|f| f["size"].to_i < 0 ||
+ (f["size"].to_i > f["bytesTransferred"].to_i)}
+ end
end
end
diff --git a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb
index def4a0e..a3c54bf 100644
--- a/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb
+++ b/lib/ruby_vcloud_sdk/xml/wrapper_classes/vdc.rb
@@ -30,6 +30,12 @@ def upload_link
.first
end
+ def instantiate_ovf_link
+ get_nodes(XML_TYPE[:LINK],
+ type: MEDIA_TYPE[:INSTANTIATE_OVF_PARAMS])
+ .first
+ end
+
def upload_media_link
get_nodes(XML_TYPE[:LINK],
type: MEDIA_TYPE[:MEDIA])
diff --git a/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateOvfParams.xml b/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateOvfParams.xml
index bbfb41c..be1e517 100644
--- a/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateOvfParams.xml
+++ b/lib/ruby_vcloud_sdk/xml/xml_templates/InstantiateOvfParams.xml
@@ -1 +1 @@
-false
\ No newline at end of file
+false