require 'spec_helper' describe Vcloud::Launcher::VmOrchestrator do before(:each) do @vm_id = "vm-12345678-1234-1234-1234-123456712312" end let(:vcloud_vm) { { :href => "/#{@vm_id}" } } let(:vapp) { double(:vapp, :name => 'web-app1') } let(:mock_disk_orchestrator) { double(:mock_disk_orchestrator) } subject { Vcloud::Launcher::VmOrchestrator.new(vcloud_vm, vapp) } it "orchestrates customization" do vm_config = { :hardware_config => { :memory => 4096, :cpu => 2 }, :metadata => { :shutdown => true }, :extra_disks => [ {:name => 'Hard disk 2', :size => '1024'}, {:name => 'Hard disk 3', :size => '2048'}, ], :independent_disks => [ {:name => 'test-independent-disk-1' }, {:name => 'test-independent-disk-2' }, ], :network_connections => [ {:name => "network1", :ip_address => "198.12.1.21"}, ], :storage_profile => { :name => 'basic-storage', :href => 'https://vcloud.example.net/api/vdcStorageProfile/000aea1e-a5e9-4dd1-a028-40db8c98d237' } } vm = double(:vm, :id => @vm_id, :vapp_name => 'web-app1', :vapp => vapp, :name => 'test-vm-1') expect(Vcloud::Core::Vm).to receive(:new).with(@vm_id, vapp).and_return(vm) expect(vm).to receive(:update_name).with('web-app1') expect(vm).to receive(:configure_network_interfaces).with(vm_config[:network_connections]) expect(vm).to receive(:update_storage_profile).with(vm_config[:storage_profile]) expect(vm).to receive(:update_cpu_count).with(2) expect(vm).to receive(:update_memory_size_in_mb).with(4096) expect(vm).to receive(:add_extra_disks).with(vm_config[:extra_disks]) expect(vm).to receive(:update_metadata).with(vm_config[:metadata]) expect(Vcloud::Launcher::IndependentDiskOrchestrator). to receive(:new).with(vm).and_return(mock_disk_orchestrator) expect(mock_disk_orchestrator).to receive(:attach).with(vm_config[:independent_disks]) allow(vm).to receive(:configure_guest_customization_section).with('') subject.customize(vm_config) end it "if a storage_profile is not specified, customize continues with other customizations" do vm = double(:vm, :id => @vm_id, :vapp_name => 'web-app1', :vapp => vapp, :name => 'test-vm-1') vm_config = { :metadata => {:shutdown => true}, :network_connections => [{:name => "network1", :ip_address => "198.12.1.21"}], :extra_disks => [ {:size => '1024', :name => 'Hard disk 2', :fs_file => 'mysql', :fs_mntops => 'mysql-something'}, {:size => '2048', :name => 'Hard disk 3', :fs_file => 'solr', :fs_mntops => 'solr-something'} ] } expect(Vcloud::Core::Vm).to receive(:new).with(@vm_id, vapp).and_return(vm) expect(vm).to receive(:update_metadata).with(:shutdown => true) expect(vm).to receive(:update_name).with('web-app1') expect(vm).to receive(:add_extra_disks).with(vm_config[:extra_disks]) expect(vm).to receive(:configure_network_interfaces).with(vm_config[:network_connections]) allow(vm).to receive(:configure_guest_customization_section) subject.customize(vm_config) end context "when customizing a VM" do let(:vm_config_with_bootstrap) do { hardware_config: { memory: 4096, cpu: 2 }, network_connections: [ { name: "network1", ip_address: "198.12.1.21" } ], bootstrap: { script_path: '/tmp/bootstrap.erb', vars: { message: 'hello world' } } } end let(:vm_config_without_bootstrap) do { hardware_config: { memory: 4096, cpu: 2 }, network_connections: [ { name: "network1", ip_address: "198.12.1.21" } ] } end let(:vm) { double(:vm, id: @vm_id, vapp_name: 'web-app1', vapp: vapp, name: 'test-vm-1') } before(:each) do Vcloud::Core::Vm.stub(:new).and_return(vm) allow(vm).to receive(:update_name) allow(vm).to receive(:configure_network_interfaces) allow(vm).to receive(:update_cpu_count) allow(vm).to receive(:update_memory_size_in_mb) allow(vm).to receive(:add_extra_disks) allow(vm).to receive(:update_metadata) end context "when bootstrap configuration is omitted" do before { allow(vm).to receive(:configure_guest_customization_section) } it "skips preamble processing" do expect(Vcloud::Launcher::Preamble).not_to receive(:new) expect(Vcloud::Launcher::Preamble).not_to receive(:generate) subject.customize(vm_config_without_bootstrap) end it "skips customization if nothing to customize" do expect(vm).not_to receive(:configure_guest_customization_section) subject.customize(vm_config_without_bootstrap) end end context "when bootstrap configuration is supplied" do context "Vcloud::Launcher::Preamble used to generate a preamble" do it "instantiates Vcloud::Launcher::Preamble" do preamble = double allow(preamble).to receive(:generate) allow(vm).to receive(:configure_guest_customization_section) expect(Vcloud::Launcher::Preamble).to receive(:new).with(vm.vapp_name, vm_config_with_bootstrap).and_return(preamble) subject.customize(vm_config_with_bootstrap) end it "uses Vcloud::Launcher::Preamble.generate to template a preamble" do preamble = double allow(Vcloud::Launcher::Preamble).to receive(:new).with(vm.vapp_name, vm_config_with_bootstrap).and_return(preamble) allow(vm).to receive(:configure_guest_customization_section) expect(preamble).to receive(:generate) subject.customize(vm_config_with_bootstrap) end it "passes the generated preamble to configure_guest_customization_section" do preamble = double allow(Vcloud::Launcher::Preamble).to receive(:new).with(vm.vapp_name, vm_config_with_bootstrap).and_return(preamble) allow(preamble).to receive(:generate).and_return('FAKE_PREAMBLE') expect(vm).to receive(:configure_guest_customization_section).with('FAKE_PREAMBLE') subject.customize(vm_config_with_bootstrap) end end end end end