diff --git a/Rakefile b/Rakefile index 6142868eb..cc3325cc3 100644 --- a/Rakefile +++ b/Rakefile @@ -92,6 +92,12 @@ namespace :test do task :vcloud_director do sh("export FOG_MOCK=#{mock} && bundle exec shindont tests/vcloud_director") end + task :vcloud_director_specs do + puts "Running vCloud Minitest Suite" + Rake::TestTask.new do |t| + Dir.glob('./spec/vcloud_director/**/*_spec.rb').each { |file| require file} + end + end end desc 'Run mocked tests for a specific provider' diff --git a/fog.gemspec b/fog.gemspec index 11fe7399b..6fe5f17c7 100644 --- a/fog.gemspec +++ b/fog.gemspec @@ -95,7 +95,6 @@ Gem::Specification.new do |s| s.add_development_dependency("rspec-expectations") s.add_development_dependency("vcr") s.add_development_dependency("webmock","~>1.22.2") - s.add_development_dependency("builder", ">=3.2.2") s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {spec,tests}/*`.split("\n") diff --git a/lib/fog/vcloud_director/generators/compute/compose_common.rb b/lib/fog/vcloud_director/generators/compute/compose_common.rb index 9c874637f..e1f74a3c0 100644 --- a/lib/fog/vcloud_director/generators/compute/compose_common.rb +++ b/lib/fog/vcloud_director/generators/compute/compose_common.rb @@ -50,12 +50,21 @@ module Fog } } end + + def build_source_template(xml) + xml.Source(:href => @configuration[:Source]) + end def build_source_items(xml) vms = @configuration[:source_vms] vms.each do |vm| xml.SourcedItem { xml.Source(:name =>vm[:name], :href => vm[:href]) + xml.VmGeneralParams { + xml.Name vm[:name] + xml.Description vm[:Description] if vm[:Description] + xml.NeedsCustomization if vm[:NeedsCustomization] + } if vm[:name] xml.InstantiationParams { if vm[:networks] xml.NetworkConnectionSection(:href => "#{vm[:href]}/networkConnectionSection/", :type => "application/vnd.vmware.vcloud.networkConnectionSection+xml", 'xmlns:ovf' => "http://schemas.dmtf.org/ovf/envelope/1", "ovf:required" => "false") { diff --git a/lib/fog/vcloud_director/generators/compute/instantiate_vapp_template_params.rb b/lib/fog/vcloud_director/generators/compute/instantiate_vapp_template_params.rb new file mode 100644 index 000000000..347a47a4f --- /dev/null +++ b/lib/fog/vcloud_director/generators/compute/instantiate_vapp_template_params.rb @@ -0,0 +1,30 @@ +require 'fog/vcloud_director/generators/compute/compose_common' + +module Fog + module Generators + module Compute + module VcloudDirector + # @see http://pubs.vmware.com/vcd-51/topic/com.vmware.vcloud.api.reference.doc_51/doc/types/VAppType.html + class InstantiateVappTemplateParams + attr_reader :options + + include ComposeCommon + + def generate_xml + Nokogiri::XML::Builder.new do |xml| + + + xml.InstantiateVAppTemplateParams((vapp_attrs)) { + build_vapp_instantiation_params(xml) + build_source_template(xml) + build_source_items(xml) + } + end.to_xml + + end + + end + end + end + end +end diff --git a/lib/fog/vcloud_director/requests/compute/instantiate_vapp_template.rb b/lib/fog/vcloud_director/requests/compute/instantiate_vapp_template.rb index 14243cfa1..c5b21e88b 100644 --- a/lib/fog/vcloud_director/requests/compute/instantiate_vapp_template.rb +++ b/lib/fog/vcloud_director/requests/compute/instantiate_vapp_template.rb @@ -4,6 +4,7 @@ module Fog module Compute class VcloudDirector class Real + require 'fog/vcloud_director/generators/compute/instantiate_vapp_template_params' # Create a vApp from a vApp template. # # The response includes a Task element. You can monitor the task to to @@ -43,43 +44,33 @@ module Fog options end - def generate_instantiate_vapp_template_request(options ={}) - xml = Builder::XmlMarkup.new - xml.InstantiateVAppTemplateParams(xmlns.merge!(:name => options[:vapp_name], :"xml:lang" => "en")) { - xml.Description(options[:description]) - xml.InstantiationParams { - # This options are fully ignored - if options[:network_uri] - xml.NetworkConfigSection { - xml.tag!("ovf:Info"){ "Configuration parameters for logical networks" } - xml.NetworkConfig("networkName" => options[:network_name]) { - xml.Configuration { - xml.ParentNetwork(:href => options[:network_uri]) - xml.FenceMode("bridged") - } - } - } - end - } - # The template - xml.Source(:href => options[:template_uri]) - # Use of sourceItems for configuring VM's during instantiation. - # NOTE: Name and storage profile configuration supported so far. - # http://pubs.vmware.com/vca/index.jsp?topic=%2Fcom.vmware.vcloud.api.doc_56%2FGUID-BF9B790D-512E-4EA1-99E8-6826D4B8E6DC.html - (options[:vms_config] || []).each do |vm_config| - next unless vm_config[:href] - xml.SourcedItem { - xml.Source(:href => vm_config[:href]) - xml.VmGeneralParams{ - xml.Name(vm_config[:name]) if vm_config[:name] - } - if storage_href = vm_config[:storage_profile_href] - xml.StorageProfile(:href => storage_href) - end - } - end - xml.AllEULAsAccepted("true") - } + def generate_instantiate_vapp_template_request(options ={}) + + #overriding some params so they work with new standardised generator + options[:InstantiationParams] = + { + :NetworkConfig => + [{ + :networkName => options[:network_name], + :networkHref => options[:network_uri], + :fenceMode => 'bridged' + }] + } unless options[:InstantiationParams] + options[:name] = options.delete(:vapp_name) if options[:vapp_name] + options[:Description] = options.delete(:description) unless options[:Description] + if options[:vms_config] then + options[:source_vms] = options.delete(:vms_config) + options[:source_vms].each_with_index {|vm, i|options[:source_vms][i][:StorageProfileHref] = options[:source_vms][i].delete(:storage_profile_href) } + end + options[:Source] = options.delete(:template_uri) if options[:template_uri] + + + + + Fog::Generators::Compute::VcloudDirector::InstantiateVappTemplateParams.new(options).generate_xml + + + end def xmlns diff --git a/spec/vcloud_director/fixtures/instantiate_vapp_template_params_full.xml b/spec/vcloud_director/fixtures/instantiate_vapp_template_params_full.xml new file mode 100644 index 000000000..5397080ec --- /dev/null +++ b/spec/vcloud_director/fixtures/instantiate_vapp_template_params_full.xml @@ -0,0 +1,30 @@ + + MY VAPP + + + + + + + bridged + + + + + + + + + VM1 + + + + + + + VM2 + + + + true + \ No newline at end of file diff --git a/spec/vcloud_director/generators/compute/instantiate_vapp_template_params_spec.rb b/spec/vcloud_director/generators/compute/instantiate_vapp_template_params_spec.rb new file mode 100644 index 000000000..4df4199b9 --- /dev/null +++ b/spec/vcloud_director/generators/compute/instantiate_vapp_template_params_spec.rb @@ -0,0 +1,69 @@ +require 'minitest/autorun' +require 'nokogiri' +require './lib/fog/vcloud_director/generators/compute/instantiate_vapp_template_params.rb' + +describe Fog::Generators::Compute::VcloudDirector::InstantiateVappTemplateParams do + + let(:xml) do + params = { + :name => 'VAPP_NAME', + :Description => 'MY VAPP', + :InstantiationParams => { + :NetworkConfig => [ + { + :networkName => 'NETWORK', + :networkHref => 'http://vcloud/api/network/123456789', + :fenceMode => 'bridged' + } + ] + }, + :Source => 'http://vcloud/vapp_template/1234', + :source_vms => [ + { + :name => 'VM1', + :href => 'http://vcloud/api/vm/12345', + :StorageProfileHref => 'http://vcloud/storage/123456789' + }, + { + :name => 'VM2', + :href => 'http://vcloud/api/vm/12345', + :StorageProfileHref => 'http://vcloud/storage/123456789' + } + ] + + } + + output = Fog::Generators::Compute::VcloudDirector::InstantiateVappTemplateParams.new(params).generate_xml + Nokogiri::XML(output) + end + + it "Generates InstantiateVAppTemplateParams" do + xml.xpath('//InstantiateVAppTemplateParams').must_be_instance_of Nokogiri::XML::NodeSet + end + + it "Has a valid Network" do + node = xml.xpath('//xmlns:NetworkConfigSection') + + xml.xpath("//xmlns:NetworkConfig")[0].attr('networkName').must_equal "NETWORK" + xml.xpath('//xmlns:ParentNetwork')[0].attr('href').must_equal 'http://vcloud/api/network/123456789' + + end + + it "Has valid source VAPP info" do + node = xml.xpath('//xmlns:Source[@href="http://vcloud/vapp_template/1234"]') + node.length.must_equal 1 + end + + it "Has valid source VM info" do + + xml.xpath('//xmlns:StorageProfile[@href="http://vcloud/storage/123456789"]').length.must_equal 2 + end + + it "Allows New VM Parameters" do + nodes = xml.xpath('//xmlns:VmGeneralParams') + nodes.length.must_equal 2 + puts nodes + + end + +end \ No newline at end of file diff --git a/spec/vcloud_director/requests/compute/instantiate_vapp_template_spec.rb b/spec/vcloud_director/requests/compute/instantiate_vapp_template_spec.rb new file mode 100644 index 000000000..363ec9a8f --- /dev/null +++ b/spec/vcloud_director/requests/compute/instantiate_vapp_template_spec.rb @@ -0,0 +1,63 @@ +require 'minitest/autorun' +require './lib/fog/vcloud_director/requests/compute/instantiate_vapp_template.rb' + +describe Fog::Compute::VcloudDirector::Real do + + let(:xml) do + service = Fog::Compute::VcloudDirector.new() + + params = { + :description => 'MY VAPP', + :vdc_uri => 'http://vcloud/api/vdc/123456789', + :network_uri => 'http://vcloud/api/network/123456789', + :template_uri => 'http://vcloud/api/vapptemplate/123456789', + :vapp_name => 'http://vcloud/api/vapp/123456789', + :network_name => 'NETWORK', + :vms_config => [ + { + :name => 'VM1', + :href => 'http://vcloud/api/vm/12345', + :storage_profile_href => 'http://vcloud/storage/123456789' + }, + { + :name => 'VM2', + :href => 'http://vcloud/api/vm/12345', + :storage_profile_href => 'http://vcloud/storage/123456789' + } + ] + } + + + Nokogiri::XML(service.send(:generate_instantiate_vapp_template_request,params)) + end + + + + it "Generates InstantiateVAppTemplateParams" do + + xml.xpath('//InstantiateVAppTemplateParams').must_be_instance_of Nokogiri::XML::NodeSet + end + + it "Has a valid Network" do + node = xml.xpath('//xmlns:NetworkConfigSection') + + xml.xpath("//xmlns:NetworkConfig")[0].attr('networkName').must_equal "NETWORK" + xml.xpath('//xmlns:ParentNetwork')[0].attr('href').must_equal 'http://vcloud/api/network/123456789' + + end + + it "Has valid source VAPP info" do + node = xml.xpath('//xmlns:Source[@href="http://vcloud/api/vapptemplate/123456789"]') + node.length.must_equal 1 + end + + it "Has valid source VM info" do + xml.xpath('//xmlns:Source[@name="VM1"]').length.must_equal 1 + xml.xpath('//xmlns:StorageProfile[@href="http://vcloud/storage/123456789"]').length.must_equal 2 + end + + + + + +end \ No newline at end of file