Skip to content

Commit 9d8264b

Browse files
author
Ryan Larson
committed
Add the capability to configure the VLAN that the new clone will use.
This is very similar to the -cvlan capability that knife-vsphere gives you. == DETAILS -Added a new configuration option 'vlan' that lets you specify the vlan string -If vlan is set, the clone spec is modified with an edit action to connect the first NIC on the VM to the configured VLAN.
1 parent 60a14a1 commit 9d8264b

File tree

6 files changed

+60
-3
lines changed

6 files changed

+60
-3
lines changed

lib/vSphere/action/clone.rb

+18-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def call(env)
3131
customization_info = get_customization_spec_info_by_name connection, machine
3232

3333
spec[:customization] = get_customization_spec(machine, customization_info) unless customization_info.nil?
34+
add_custom_vlan(template, dc, spec, config.vlan) unless config.vlan.nil?
3435

3536
env[:ui].info I18n.t('vsphere.creating_cloned_vm')
3637
env[:ui].info " -- #{config.clone_from_vm ? "Source" : "Template"} VM: #{template.pretty_path}"
@@ -131,9 +132,25 @@ def get_vm_base_folder(dc, template, config)
131132
if config.vm_base_path.nil?
132133
template.parent
133134
else
134-
dc.vmFolder.traverse(config.vm_base_path, RbVmomi::VIM::Folder, create=true)
135+
dc.vmFolder.traverse(config.vm_base_path, RbVmomi::VIM::Folder, create = true)
135136
end
136137
end
138+
139+
def add_custom_vlan(template, dc, spec, vlan)
140+
spec[:config] = RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => Array.new)
141+
network = get_network_by_name(dc, vlan)
142+
config = template.config
143+
card = config.hardware.device.grep(RbVmomi::VIM::VirtualEthernetCard).first or fail Errors::VSphereError, :missing_network_card
144+
begin
145+
switch_port = RbVmomi::VIM.DistributedVirtualSwitchPortConnection(:switchUuid => network.config.distributedVirtualSwitch.uuid, :portgroupKey => network.key)
146+
card.backing.port = switch_port
147+
rescue
148+
# not connected to a distibuted switch?
149+
card.backing.deviceName = network.name
150+
end
151+
dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(:device => card, :operation => "edit")
152+
spec[:config][:deviceChange].push dev_spec
153+
end
137154
end
138155
end
139156
end

lib/vSphere/config.rb

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Config < Vagrant.plugin('2', :config)
1919
attr_accessor :linked_clone
2020
attr_accessor :proxy_host
2121
attr_accessor :proxy_port
22+
attr_accessor :vlan
2223

2324
def validate(machine)
2425
errors = _detected_errors

lib/vSphere/util/vim_helpers.rb

+4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def get_datastore(connection, machine)
3535

3636
get_datacenter(connection, machine).find_datastore name or fail Errors::VSphereError, :missing_datastore
3737
end
38+
39+
def get_network_by_name(dc, name)
40+
dc.network.find { |f| f.name == name } or fail Errors::VSphereError, :missing_vlan
41+
end
3842
end
3943
end
4044
end

locales/en.yml

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ en:
4040
Configured data store not found
4141
too_many_private_networks: |-
4242
There a more private networks configured than can be assigned to the customization spec
43+
missing_vlan: |-
44+
Configured vlan not found
45+
missing_network_card: |-
46+
Cannot find network card to customize
4347
config:
4448
host: |-
4549
Configuration must specify a vSphere host

spec/clone_spec.rb

+21
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,27 @@
3939
expect(@app).to have_received :call
4040
end
4141

42+
it 'should create a CloneVM spec with configured vlan' do
43+
@machine.provider_config.stub(:vlan).and_return('vlan')
44+
network = double('network', :name => 'vlan')
45+
network.stub(:config).and_raise(StandardError)
46+
@data_center.stub(:network).and_return([network])
47+
call
48+
49+
expected_config = RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => Array.new)
50+
expected_dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(:device => @device, :operation => "edit")
51+
expected_config[:deviceChange].push expected_dev_spec
52+
53+
expect(@template).to have_received(:CloneVM_Task).with({
54+
:folder => @data_center,
55+
:name => NAME,
56+
:spec => {:location =>
57+
{:pool => @child_resource_pool},
58+
:config => expected_config
59+
}
60+
})
61+
end
62+
4263
it 'should set static IP when given config spec' do
4364
@machine.provider_config.stub(:customization_spec_name).and_return('spec')
4465
call

spec/spec_helper.rb

+12-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ def call
5252
:clone_from_vm => nil,
5353
:linked_clone => nil,
5454
:proxy_host => nil,
55-
:proxy_port => nil)
55+
:proxy_port => nil,
56+
:vlan => nil)
5657
vm_config = double(
5758
:vm => double('config_vm',
5859
:box => nil,
@@ -101,11 +102,20 @@ def call
101102
:pretty_path => "data_center/#{vm_folder}",
102103
:find_compute_resource => double('compute resource', :resourcePool => @root_resource_pool))
103104

105+
@device = RbVmomi::VIM::VirtualEthernetCard.new
106+
@device.stub(:backing).and_return(RbVmomi::VIM::VirtualEthernetCardNetworkBackingInfo.new)
107+
108+
@virtual_hardware = double('virtual_hardware',
109+
:device => [@device])
110+
@template_config = double('template_config',
111+
:hardware => @virtual_hardware)
112+
104113
@template = double('template_vm',
105114
:parent => @data_center,
106115
:pretty_path => "#{@data_center.pretty_path}/template_vm",
107116
:CloneVM_Task => double('result',
108-
:wait_for_completion => double('new_vm', :config => double('config', :uuid => NEW_UUID))))
117+
:wait_for_completion => double('new_vm', :config => double('config', :uuid => NEW_UUID))),
118+
:config => @template_config)
109119

110120
@data_center.stub(:find_vm).with(TEMPLATE).and_return(@template)
111121

0 commit comments

Comments
 (0)