vagrant-vcloud 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ module VagrantPlugins
14
14
 
15
15
  # Get the ports we are forwarding
16
16
  env[:forwarded_ports] ||= compile_forwarded_ports(
17
- env[:machine].config
17
+ env[:machine]
18
18
  )
19
19
 
20
20
  forward_ports
@@ -23,7 +23,7 @@ module VagrantPlugins
23
23
  end
24
24
 
25
25
  def forward_ports
26
- ports = []
26
+ ports = {}
27
27
  edge_ports = []
28
28
 
29
29
  cfg = @env[:machine].provider_config
@@ -41,6 +41,7 @@ module VagrantPlugins
41
41
  @logger.debug('Getting VM info...')
42
42
  vm = cnx.get_vapp(vapp_id)
43
43
  vm_info = vm[:vms_hash][vm_name.to_sym]
44
+ network_name = ''
44
45
 
45
46
  @env[:forwarded_ports].each do |fp|
46
47
 
@@ -50,12 +51,17 @@ module VagrantPlugins
50
51
  )
51
52
 
52
53
  # Add the options to the ports array to send to the driver later
53
- ports << {
54
+ ports["#{fp.network_name}#{fp.edge_network_name}"] = { rules: [] } if !ports["#{fp.network_name}#{fp.edge_network_name}"]
55
+ ports["#{fp.network_name}#{fp.edge_network_name}"][:network_name] = fp.network_name
56
+ ports["#{fp.network_name}#{fp.edge_network_name}"][:parent_network] = fp.edge_network_id
57
+ ports["#{fp.network_name}#{fp.edge_network_name}"][:edge_network_name] = fp.edge_network_name
58
+ ports["#{fp.network_name}#{fp.edge_network_name}"][:rules] << {
54
59
  :guestip => fp.guest_ip,
55
60
  :nat_internal_port => fp.guest_port,
56
61
  :hostip => fp.host_ip,
57
62
  :nat_external_port => fp.host_port,
58
63
  :name => fp.id,
64
+ :nat_vmnic_id => fp.vmnic_id,
59
65
  :nat_protocol => fp.protocol.upcase,
60
66
  :vapp_scoped_local_id => vm_info[:vapp_scoped_local_id]
61
67
  }
@@ -64,24 +70,26 @@ module VagrantPlugins
64
70
  if !ports.empty?
65
71
  # We only need to forward ports if there are any to forward
66
72
  @logger.debug("Port object to be passed: #{ports.inspect}")
67
- @logger.debug("Current network id #{cfg.vdc_network_id}")
68
73
 
69
74
  ### Here we apply the nat_rules to the vApp we just built
70
- add_ports = cnx.add_vapp_port_forwarding_rules(
71
- vapp_id,
72
- 'Vagrant-vApp-Net',
73
- {
74
- :fence_mode => 'natRouted',
75
- :parent_network => cfg.vdc_network_id,
76
- :nat_policy_type => 'allowTraffic',
77
- :nat_rules => ports
78
- }
79
- )
80
-
81
- wait = cnx.wait_task_completion(add_ports)
82
-
83
- if !wait[:errormsg].nil?
84
- raise Errors::ComposeVAppError, :message => wait[:errormsg]
75
+ ports.values.each do |port|
76
+ add_ports = cnx.add_vapp_port_forwarding_rules(
77
+ vapp_id,
78
+ port[:network_name],
79
+ port[:edge_network_name],
80
+ {
81
+ :fence_mode => 'natRouted',
82
+ :parent_network => port[:parent_network],
83
+ :nat_policy_type => 'allowTraffic',
84
+ :nat_rules => port[:rules]
85
+ }
86
+ )
87
+
88
+ wait = cnx.wait_task_completion(add_ports)
89
+
90
+ if !wait[:errormsg].nil?
91
+ raise Errors::ComposeVAppError, :message => wait[:errormsg]
92
+ end
85
93
  end
86
94
 
87
95
 
@@ -97,15 +105,17 @@ module VagrantPlugins
97
105
  r[:translated_ip] == vapp_edge_ip)}
98
106
  vapp_edge_ports_in_use = vapp_edge_dnat_rules.map{|r| r[:original_port].to_i}.to_set
99
107
 
100
- ports.each do |port|
101
- if port[:vapp_scoped_local_id] == vm_info[:vapp_scoped_local_id] &&
102
- !vapp_edge_ports_in_use.include?(port[:nat_external_port])
103
- @env[:ui].info(
104
- "Creating NAT rules on [#{cfg.vdc_edge_gateway}] " +
105
- "for IP [#{vapp_edge_ip}] port #{port[:nat_external_port]}."
106
- )
107
-
108
- edge_ports << port[:nat_external_port]
108
+ ports.values.each do |port|
109
+ port[:rules].each do |rule|
110
+ if rule[:vapp_scoped_local_id] == vm_info[:vapp_scoped_local_id] &&
111
+ !vapp_edge_ports_in_use.include?(rule[:nat_external_port])
112
+ @env[:ui].info(
113
+ "Creating NAT rules on [#{cfg.vdc_edge_gateway}] " +
114
+ "for IP [#{vapp_edge_ip}] port #{rule[:nat_external_port]}."
115
+ )
116
+
117
+ edge_ports << rule[:nat_external_port]
118
+ end
109
119
  end
110
120
  end
111
121
 
@@ -47,7 +47,9 @@ module VagrantPlugins
47
47
  vm = cnx.get_vapp(vapp_id)
48
48
  vm_info = vm[:vms_hash][vm_name.to_sym]
49
49
 
50
- vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
50
+ network_name = get_edge_network_name(env)
51
+
52
+ vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id, network_name)
51
53
 
52
54
  @logger.debug('Getting edge gateway port forwarding rules...')
53
55
  edge_gateway_rules = cnx.get_edge_gateway_rules(cfg.vdc_edge_gateway,
@@ -56,7 +58,7 @@ module VagrantPlugins
56
58
  edge_ports_in_use = edge_dnat_rules.map{|r| r[:original_port].to_i}.to_set
57
59
 
58
60
  @logger.debug('Getting port forwarding rules...')
59
- vapp_nat_rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
61
+ vapp_nat_rules = cnx.get_vapp_port_forwarding_rules(vapp_id, network_name)
60
62
  ports_in_use = vapp_nat_rules.map{|r| r[:nat_external_port].to_i}.to_set
61
63
 
62
64
  # merge the vapp ports and the edge gateway ports together, all are in use
@@ -143,9 +145,33 @@ module VagrantPlugins
143
145
  env[:machine].config.vm.networks.each do |type, options|
144
146
  # Ignore anything but forwarded ports
145
147
  next if type != :forwarded_port
148
+ next if !options[:disabled].nil? && options[:disabled] == true
146
149
 
147
150
  yield options
148
151
  end
152
+ # advanced networking check
153
+ if !env[:machine].provider_config.nics.nil?
154
+ env[:machine].provider_config.nics.each do |nic|
155
+ next if nic[:forwarded_port].nil?
156
+ nic[:forwarded_port].each do |fp|
157
+ next if !fp[:disabled].nil? && fp[:disabled] == true
158
+ yield fp
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ def get_edge_network_name(env)
165
+ # advanced networking check
166
+ if !env[:machine].provider_config.networks.nil?
167
+ env[:machine].provider_config.networks[:vapp].each do |net|
168
+ # Ignore anything but forwarded ports
169
+ next if net[:vdc_network_name].nil?
170
+
171
+ return net[:vdc_network_name]
172
+ end
173
+ end
174
+ return env[:machine].provider_config.vdc_network_name
149
175
  end
150
176
  end
151
177
  end
@@ -138,14 +138,16 @@ module VagrantPlugins
138
138
  @logger.debug("Catalog item is now #{cfg.catalog_item}")
139
139
 
140
140
  # This only works with Org Admin role or higher
141
- cfg.vdc_network_id = cfg.org[:networks][cfg.vdc_network_name]
142
- if !cfg.vdc_network_id
143
- # TEMP FIX: permissions issues at the Org Level for vApp authors
144
- # to "view" Org vDC Networks but they can see them at the
145
- # Organization vDC level (tsugliani)
146
- cfg.vdc_network_id = cfg.vdc[:networks][cfg.vdc_network_name]
141
+ if cfg.vdc_network_name
142
+ cfg.vdc_network_id = cfg.org[:networks][cfg.vdc_network_name]
147
143
  if !cfg.vdc_network_id
148
- raise 'vCloud User credentials has insufficient privileges'
144
+ # TEMP FIX: permissions issues at the Org Level for vApp authors
145
+ # to "view" Org vDC Networks but they can see them at the
146
+ # Organization vDC level (tsugliani)
147
+ cfg.vdc_network_id = cfg.vdc[:networks][cfg.vdc_network_name]
148
+ if !cfg.vdc_network_id
149
+ raise 'vCloud User credentials has insufficient privileges'
150
+ end
149
151
  end
150
152
  end
151
153
 
@@ -167,13 +169,17 @@ module VagrantPlugins
167
169
  "in Catalog [#{cfg.catalog_name}] does not exist!"
168
170
  )
169
171
 
170
- user_input = env[:ui].ask(
171
- "Would you like to upload the [#{box_name}] " +
172
- "box to [#{cfg.catalog_name}] Catalog?\n" +
173
- 'Choice (yes/no): '
174
- )
175
-
176
- if user_input.downcase == 'yes' || user_input.downcase == 'y'
172
+ if cfg.auto_yes_for_upload.nil? || cfg.auto_yes_for_upload == false
173
+ user_input = env[:ui].ask(
174
+ "Would you like to upload the [#{box_name}] " +
175
+ "box to [#{cfg.catalog_name}] Catalog?\n" +
176
+ 'Choice (yes/no): '
177
+ )
178
+ else
179
+ auto_upload = cfg.auto_yes_for_upload
180
+ end
181
+
182
+ if !auto_upload.nil? || user_input.downcase == 'yes' || user_input.downcase == 'y'
177
183
  env[:ui].info("Uploading [#{box_name}]...")
178
184
  vcloud_upload_box(env)
179
185
  else
@@ -21,7 +21,9 @@ module VagrantPlugins
21
21
 
22
22
  # this is a helper to get vapp_edge_ip into cache for later destroy
23
23
  # of edge gateway rules
24
- vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id) if cfg.network_bridge.nil?
24
+ if cfg.network_bridge.nil? && cfg.networks.nil?
25
+ vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
26
+ end
25
27
 
26
28
  # Poweroff vApp
27
29
  env[:ui].info('Single VM left in the vApp, Powering off vApp...')
@@ -13,24 +13,51 @@ module VagrantPlugins
13
13
  cfg = env[:machine].provider_config
14
14
  cnx = cfg.vcloud_cnx.driver
15
15
 
16
- env[:ui].info('Setting VM hardware...')
16
+ # add vm metadata
17
+ if !cfg.metadata_vm.nil?
18
+ env[:ui].info('Setting VM metadata...')
19
+ set_metadata_vm = cnx.set_vm_metadata env[:machine].id, cfg.metadata_vm
20
+ cnx.wait_task_completion(set_metadata_vm)
21
+ end
17
22
 
23
+ # add/update hardware
24
+ env[:ui].info('Setting VM hardware...')
18
25
  set_vm_hardware = cnx.set_vm_hardware(env[:machine].id, cfg)
19
26
  if set_vm_hardware
20
- cnx.wait_task_completion(set_vm_hardware)
27
+ wait = cnx.wait_task_completion(set_vm_hardware)
28
+ unless wait[:errormsg].nil?
29
+ fail Errors::ModifyVAppError, :message => wait[:errormsg]
30
+ end
31
+ end
32
+ set_vm_network_connected = cnx.set_vm_network_connected(env[:machine].id)
33
+ if set_vm_network_connected
34
+ env[:ui].info('Connecting all NICs...')
35
+ wait = cnx.wait_task_completion(set_vm_network_connected)
36
+ unless wait[:errormsg].nil?
37
+ fail Errors::ModifyVAppError, :message => wait[:errormsg]
38
+ end
21
39
  end
22
40
 
23
- env[:ui].info('Powering on VM...')
24
-
25
- if ! cfg.nested_hypervisor.nil?
26
- set_vm_nested_hypervisor = cnx.set_vm_nested_hypervisor(env[:machine].id, cfg.nested_hypervisor)
41
+ # enable nested hypervisor
42
+ if !cfg.nested_hypervisor.nil? && cfg.nested_hypervisor == true
43
+ env[:ui].info('Enabling nested hypervisor...')
44
+ set_vm_nested_hypervisor = cnx.set_vm_nested_hypervisor(env[:machine].id, true)
27
45
  if set_vm_nested_hypervisor
28
- cnx.wait_task_completion(set_vm_nested_hypervisor)
46
+ wait = cnx.wait_task_completion(set_vm_nested_hypervisor)
47
+ unless wait[:errormsg].nil?
48
+ fail Errors::ModifyVAppError, :message => wait[:errormsg]
49
+ end
29
50
  end
30
51
  end
31
52
 
32
- poweron_vm = cnx.poweron_vm(env[:machine].id)
33
- cnx.wait_task_completion(poweron_vm)
53
+ if cfg.power_on.nil? || cfg.power_on == true
54
+ env[:ui].info('Powering on VM...')
55
+ poweron_vm = cnx.poweron_vm(env[:machine].id)
56
+ wait = cnx.wait_task_completion(poweron_vm)
57
+ unless wait[:errormsg].nil?
58
+ fail Errors::PoweronVAppError, :message => wait[:errormsg]
59
+ end
60
+ end
34
61
 
35
62
  @app.call(env)
36
63
  end
@@ -17,6 +17,7 @@ module VagrantPlugins
17
17
  # Small method to check the tcp connection to an ip:port works.
18
18
  # Return false if anything fails, and true if it succeeded.
19
19
  def check_for_port(ip, port, port_name)
20
+ @logger.debug("Checking #{port_name} (#{ip}:#{port})...")
20
21
  begin
21
22
  Timeout::timeout(1) do
22
23
  begin
@@ -71,9 +72,22 @@ module VagrantPlugins
71
72
  @external_ip = vm_info[:networks]['Vagrant-vApp-Net'][:ip]
72
73
  @external_port = "#{@port}"
73
74
  else
75
+ network_name = nil
76
+ if cfg.nics
77
+ cfg.nics.each do |nic|
78
+ next if nic[:forwarded_port].nil?
79
+ if !cfg.networks.nil? && !cfg.networks[:vapp].nil?
80
+ cfg.networks[:vapp].each do |net|
81
+ next if net[:name] != nic[:network]
82
+ network_name = net[:vdc_network_name]
83
+ break
84
+ end
85
+ end
86
+ end
87
+ end
74
88
 
75
89
  @logger.debug('Getting port forwarding rules...')
76
- rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
90
+ rules = cnx.get_vapp_port_forwarding_rules(vapp_id, network_name)
77
91
 
78
92
  rules.each do |rule|
79
93
  if rule[:vapp_scoped_local_id] == myhash[:vapp_scoped_local_id] && rule[:nat_internal_port] == "#{@port}"
@@ -0,0 +1,33 @@
1
+ module VagrantPlugins
2
+ module VCloud
3
+ module Action
4
+ class ShutDown
5
+ def initialize(app, env)
6
+ @app = app
7
+ @logger = Log4r::Logger.new('vagrant_vcloud::action::shutdown')
8
+ end
9
+
10
+ def call(env)
11
+ cfg = env[:machine].provider_config
12
+ cnx = cfg.vcloud_cnx.driver
13
+
14
+ vapp_id = env[:machine].get_vapp_id
15
+ vm_id = env[:machine].id
16
+
17
+ test_vapp = cnx.get_vapp(vapp_id)
18
+
19
+ @logger.debug(
20
+ "Number of VMs in the vApp: #{test_vapp[:vms_hash].count}"
21
+ )
22
+
23
+ # Shutdown VM
24
+ env[:ui].info('Shutting down VM...')
25
+ task_id = cnx.shutdown_vm(vm_id)
26
+ cnx.wait_task_completion(task_id)
27
+
28
+ @app.call env
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -146,6 +146,122 @@ module VagrantPlugins
146
146
  # NestedHypervisor (Bool)
147
147
  attr_accessor :nested_hypervisor
148
148
 
149
+ # Specify a vApp name (String)
150
+ attr_accessor :vapp_name
151
+
152
+ # Use advanced networking settings (Bool = false)
153
+ attr_accessor :advanced_network
154
+
155
+ # Specify networks to add to the vApp (Hash)
156
+ # networks: {
157
+ # org: [ 'Organization VDC network' ],
158
+ # vapp: [ {
159
+ # name: 'vApp network',
160
+ # ip_subnet: '172.16.4.0/255.255.255.0'
161
+ # } ]
162
+ # }
163
+ #
164
+ attr_accessor :networks
165
+
166
+ # Add hard disks to the VM (Array)
167
+ # add_hdds: [ 20480 ]
168
+ #
169
+ attr_accessor :add_hdds
170
+
171
+ # Update / add network cards to the VM (Array)
172
+ # type is not updated for existing network cards
173
+ # nics: [ {
174
+ # type: :vmxnet3,
175
+ # connected: true,
176
+ # network: "vApp network",
177
+ # primary: true,
178
+ # ip_mode: "static",
179
+ # ip: "10.10.10.1",
180
+ # mac: "00:50:56:00:00:01"
181
+ # } ]
182
+ #
183
+ attr_accessor :nics
184
+
185
+ # Power on the VM once created (Bool = true)
186
+ attr_accessor :power_on
187
+
188
+ # Attempt to connect via SSH to the VM (Bool = true)
189
+ attr_accessor :ssh_enabled
190
+
191
+ # Attempt to sync files to the VM (Bool = true)
192
+ attr_accessor :sync_enabled
193
+
194
+ # Turn DHCP on for this network (Bool = false)
195
+ attr_accessor :dhcp_enabled
196
+
197
+ # POOL ip range if dhcp is enabled (Array)
198
+ attr_accessor :pool_range
199
+
200
+ # DHCP ip range if enabled (Array)
201
+ attr_accessor :dhcp_range
202
+
203
+ # Add metadata to the vApp (Array)
204
+ # metadata_vapp: [
205
+ # [ 'key', 'value' ]
206
+ # ]
207
+ #
208
+ attr_accessor :metadata_vapp
209
+
210
+ # Add metadata to the VM (Array)
211
+ # metadata_vapp: [
212
+ # [ 'key', 'value' ]
213
+ # ]
214
+ #
215
+ attr_accessor :metadata_vm
216
+
217
+ # Auto answer "Yes" to upload the box to vCloud (Bool = false)
218
+ attr_accessor :auto_yes_for_upload
219
+
220
+ # ability to disable gc for vms without tools installed
221
+ attr_accessor :enable_guest_customization
222
+
223
+ # scripts to run on machine boot
224
+ attr_accessor :guest_customization_script
225
+
226
+ # guest customization change sid setting (Windows only) (Bool = false)
227
+ attr_accessor :guest_customization_change_sid
228
+
229
+ # guest customization join domain (Windows only) (Bool = false)
230
+ attr_accessor :guest_customization_join_domain
231
+
232
+ # guest customization domain name (Windows only) (String)
233
+ attr_accessor :guest_customization_domain_name
234
+
235
+ # guest customization domain user name (Windows only) (String)
236
+ attr_accessor :guest_customization_domain_user_name
237
+
238
+ # guest customization domain user password (Windows only) (String)
239
+ attr_accessor :guest_customization_domain_user_password
240
+
241
+ # guest customization domain machine ou (Windows only) (String)
242
+ attr_accessor :guest_customization_domain_ou
243
+
244
+ # guest customization local admin (Bool = false)
245
+ attr_accessor :guest_customization_admin_password_enabled
246
+
247
+ # guest customization auto generate admin password (Bool = false)
248
+ attr_accessor :guest_customization_admin_password_auto
249
+
250
+ # guest customization specify admin password (String)
251
+ attr_accessor :guest_customization_admin_password
252
+
253
+ # guest customization admin auto login (Windows only) (Bool = false)
254
+ attr_accessor :guest_customization_admin_auto_login
255
+
256
+ # guest customization admin auto login count (Windows only) (Integer)
257
+ attr_reader :guest_customization_admin_auto_login_count
258
+ def guest_customization_admin_auto_login_count=(count)
259
+ @guest_customization_admin_auto_login_count = count.to_i
260
+ end
261
+
262
+ # guest customization admin require password reset (Bool = false)
263
+ attr_accessor :guest_customization_admin_password_reset
264
+
149
265
  def validate(machine)
150
266
  errors = _detected_errors
151
267
 
@@ -169,10 +285,66 @@ module VagrantPlugins
169
285
  errors << I18n.t('vagrant_vcloud.config.vdc_name')
170
286
  end
171
287
 
172
- if vdc_network_name.nil?
288
+ if networks.nil? && vdc_network_name.nil?
173
289
  errors << I18n.t('vagrant_vcloud.config.vdc_network_name')
174
290
  end
175
291
 
292
+ # guest customization
293
+ if enable_guest_customization.nil? ||
294
+ enable_guest_customization == false
295
+ if guest_customization_change_sid == true
296
+ errors << I18n.t('vagrant_vcloud.gc.change_sid')
297
+ end
298
+ if !guest_customization_admin_password_enabled.nil?
299
+ errors << I18n.t('vagrant_vcloud.gc.admin_password')
300
+ end
301
+ if !guest_customization_admin_password_reset.nil?
302
+ errors << I18n.t('vagrant_vcloud.gc.admin_password_reset')
303
+ end
304
+ if !guest_customization_script.nil?
305
+ errors << I18n.t('vagrant_vcloud.gc.script')
306
+ end
307
+ else
308
+ if guest_customization_change_sid.nil? ||
309
+ guest_customization_change_sid == false
310
+ if guest_customization_join_domain == true
311
+ errors << I18n.t('vagrant_vcloud.gc.domain')
312
+ end
313
+ else
314
+ if guest_customization_join_domain == true
315
+ if guest_customization_domain_name.nil? ||
316
+ guest_customization_domain_user_name.nil? ||
317
+ guest_customization_domain_user_password.nil?
318
+ errors << I18n.t('vagrant_vcloud.gc.domain_join')
319
+ end
320
+ end
321
+ end
322
+ if guest_customization_admin_password_enabled.nil? ||
323
+ guest_customization_admin_password_enabled == false
324
+ if guest_customization_admin_auto_login == true
325
+ errors << I18n.t('vagrant_vcloud.gc.auto_login')
326
+ end
327
+ else
328
+ if guest_customization_admin_auto_login == true
329
+ if guest_customization_admin_password_auto.nil? ||
330
+ guest_customization_admin_password_auto == false
331
+ if guest_customization_admin_password.nil? ||
332
+ guest_customization_admin_password.empty?
333
+ errors << I18n.t('vagrant_vcloud.gc.admin_password_gs')
334
+ end
335
+ end
336
+ if guest_customization_admin_auto_login_count.nil?
337
+ errors << I18n.t('vagrant_vcloud.gc.auto_login_count_req')
338
+ else
339
+ if !( guest_customization_admin_auto_login_count >= 1 &&
340
+ guest_customization_admin_auto_login_count <= 100 )
341
+ errors << I18n.t('vagrant_vcloud.gc.auto_login_count')
342
+ end
343
+ end
344
+ end
345
+ end
346
+ end
347
+
176
348
  { 'vCloud Provider' => errors }
177
349
  end
178
350
  end