vagrant-vcloud 0.4.4 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -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