vagrant-vcloud 0.3.1 → 0.3.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 377aff5a6fcd7aa53aeb8a1c07c6ea0814a768ee
4
- data.tar.gz: 663ad5f16d5dc1bd1a66bc91b9779c406e604b07
3
+ metadata.gz: 4bbc6566a5568f44799cac8c73a73bb5c127e8c5
4
+ data.tar.gz: 05d23945c5e91ed947cf69ae5c92a7b9a7aca1bd
5
5
  SHA512:
6
- metadata.gz: 41d434f6cd5704e662edd1ac2f68d75d883fb7486559018e0a55b2a1e64ddd7dfc1fcbaf9fc921e78dfb7186eb082859eb17a1112b6170968c56b438733925fc
7
- data.tar.gz: 142935eac15c311473c27eb829358afe4340551e2c4e8cd4a7ca4ea2d47bf82590716c0fa43dbb1e447fba6ef9058b3f969046a0ab0a6a905f4c348255743517
6
+ metadata.gz: 14299a5e78c4b71505aa785e90e570c50478c68777ed45115280403db365f819d3bdf1dea2656ef1f572624b68ad8b123b81eec84dd2d8f88294e9439fae7e75
7
+ data.tar.gz: 1c305fb8f6ca86e0acc976ae4cce5c9d025570c79ef62d047d1f8c50bf905951b42fb675376e761348a1c55674d0ccab49af9e62b4c6d645273db3d3d58afacc
data/README.md CHANGED
@@ -1,16 +1,25 @@
1
1
  [Vagrant](http://www.vagrantup.com) provider for VMware vCloud Director®
2
2
  =============
3
3
 
4
- [Version 0.3.1](https://github.com/frapposelli/vagrant-vcloud/releases/tag/v0.3.1) has been released!
4
+ [Version 0.3.2](../../releases/tag/v0.3.2) has been released!
5
5
  -------------
6
6
 
7
7
  Please note that this software is still Alpha/Beta quality and is not recommended for production usage.
8
8
 
9
9
  Right now a [Precise32](http://vagrant.tsugliani.fr/precise32.box) is available for use, or you can roll your own as you please, make sure to install VMware tools in it.
10
10
 
11
+ If you're unsure about what are the correct network settings for your Vagrantfile make sure to check out the [Network Deployment Options](https://github.com/frapposelli/vagrant-vcloud/wiki/Network-Deployment-Options) wiki page.
12
+
13
+ Features of Version 0.3.2 are:
14
+
15
+ - Added support for ```vagrant share``` command [[#31](https://github.com/frapposelli/vagrant-vcloud/issues/31)] Support vagrant share
16
+ - Restructured the ```vagrant vcloud-status``` to ```vagrant vcloud status``` for future-proofing [[#53](https://github.com/frapposelli/vagrant-vcloud/issues/53)]
17
+ - Added ```vagrant vcloud --redeploy-edge-gw``` to redeploy Edge Gateway [[#54](https://github.com/frapposelli/vagrant-vcloud/issues/54)]
18
+ - Several Bug Fixes [[#45](https://github.com/frapposelli/vagrant-vcloud/issues/45)], [[#46](https://github.com/frapposelli/vagrant-vcloud/issues/46)], [[#47](https://github.com/frapposelli/vagrant-vcloud/issues/47)], [[#48](https://github.com/frapposelli/vagrant-vcloud/issues/48)], [[#50](https://github.com/frapposelli/vagrant-vcloud/issues/50)], [[#51](https://github.com/frapposelli/vagrant-vcloud/issues/51)], [[#52](https://github.com/frapposelli/vagrant-vcloud/issues/52)], [[#56](https://github.com/frapposelli/vagrant-vcloud/issues/56)], [[#57](https://github.com/frapposelli/vagrant-vcloud/issues/57)], [[#61](https://github.com/frapposelli/vagrant-vcloud/issues/61)]
19
+
11
20
  Features of Version 0.3.1 are:
12
21
 
13
- - Small hotfix to include "preRunning" condition when using vCloud Director 5.5 [Issue #44]
22
+ - Small hotfix to include "preRunning" condition when using vCloud Director 5.5 [[#44](https://github.com/frapposelli/vagrant-vcloud/issues/44)]. - [Andrew Poland](https://github.com/apoland)
14
23
 
15
24
  Features of Version 0.3.0 are:
16
25
 
@@ -20,12 +29,12 @@ A substantial release, major kudos to [Stefan Scherer](https://github.com/Stefan
20
29
  - Added a new configuration options ```vapp_prefix``` to change vApp prefix (defaults to Vagrant).
21
30
  - Improved vcloud-status command.
22
31
  - Fixed cygdrive path for rsync on Windows.
23
- - Fixed Issue #33 - Error removing/creating NAT rules on second vagrant up.
24
- - Fixed Issue #43 - Destroy fails if VMs are halted.
32
+ - Fixed Issue [[#33](../../issues/33)] - Error removing/creating NAT rules on second vagrant up.
33
+ - Fixed Issue [[#43](../../issues/43)] - Destroy fails if VMs are halted.
25
34
 
26
35
  Features of Version 0.2.2 are:
27
36
 
28
- - Fixed Issue #32 - Port Forwarding rules are deleted when Halting a VM.
37
+ - Fixed Issue [[#32](../../issues/32)] - Port Forwarding rules are deleted when Halting a VM.
29
38
 
30
39
  Features of Version 0.2.1 are:
31
40
 
@@ -33,8 +42,8 @@ Features of Version 0.2.1 are:
33
42
 
34
43
  Features of Version 0.2.0 are:
35
44
 
36
- - It's now possible to connect to an existing VDC network without creating a vShield Edge using ```network_bridge = true``` in the Vagrantfile [ISSUE #23]. *experimental*
37
- - Added a ```upload_chunksize``` parameter to specify the chunk dimension during box uploads [ISSUE #21].
45
+ - It's now possible to connect to an existing VDC network without creating a vShield Edge using ```network_bridge = true``` in the Vagrantfile [[#23](../../issues/23)]. *experimental*
46
+ - Added a ```upload_chunksize``` parameter to specify the chunk dimension during box uploads [[#21](../../issues/21)].
38
47
  - Added support for [vCloud® Hybrid Service™](http://www.vmware.com/products/vcloud-hybrid-service) API version 5.7.
39
48
  - Added a new command to vagrant called ```vcloud-status``` that shows the current status of the vCloud instance relative to the Vagrant deployment. *experimental*
40
49
  - General code cleanup, code should be more readable and there's a rubocop file for our code conventions.
@@ -44,47 +53,13 @@ Features of Version 0.2.0 are:
44
53
  - Fixed the Edge Gateway NAT rules creation / deletion.
45
54
  - Added debug capabilities down to XML traffic exchanged during the REST calls.
46
55
 
47
- Features of Version 0.1.2 are:
48
-
49
- - Fix ssh_key array for the sync_folder [ISSUE #30 thanks [@JMG-OICR](https://github.com/JMG-OICR)]
50
-
51
- Features of Version 0.1.1 are:
52
-
53
- - bugfix multiple sub allocation pools ranges [ISSUE #24]
54
- - Putting back Google DNS as default if not specified
55
- - binding vCloud 5.5 API on 5.1 driver
56
- - Debug cut and general cosmetic cleanup
57
- - added DNS choice using the "ip_dns" Array config property.
58
- - Updated sync_folders.rb with code from vagrant-aws, Will focus on a better sync engine later in the future.
59
- - Removed dependency on rest-client gem, moved everything to httpclient.
60
- - Fixed destroy vApp bug.
61
-
62
- Features of Version 0.1.0 are:
63
-
64
- - Basic Create/Provision/Destroy lifecycle.
65
- - Rsync-based provisioning (working on alternatives for that).
66
- - Use a single vApp as a container for Multi-VM Vagrantfiles.
67
- - Use a vApp vShield Edge to perform DNAT/SNAT on a single IP for Multi-VM Vagrantfiles.
68
- - Automatically create NAT rules on a fronting Organization Edge.
69
- - Automatic upload of the Vagrant box to the specified catalog.
70
- - Works on [vCloud® Hybrid Service™](http://www.vmware.com/products/vcloud-hybrid-service)!
71
-
72
- What is still missing:
73
-
74
- - TEST SUITES! (working on that).
75
- - Speed, the code is definitely not optimized.
76
- - Permission checks, make sure you have at least Catalog Admin privileges if you want to upload boxes to vCloud.
77
- - Thorough testing.
78
- - Error checking is absymal.
79
- - Some spaghetti code here and there.
80
- - Bugs, bugs and BUGS!.
81
56
 
82
- If you're a developer and want to lend us a hand, head over to our ```develop``` branch and get busy!
57
+ Check the full releases changelog [here](../../releases)
83
58
 
84
59
  Install
85
60
  -------------
86
61
 
87
- Version 0.1.0 can be easily installed by running:
62
+ Latest version can be easily installed by running the following command:
88
63
 
89
64
  ```vagrant plugin install vagrant-vcloud```
90
65
 
@@ -92,6 +67,9 @@ Vagrant will download all the required gems during the installation process.
92
67
 
93
68
  After the install has completed a ```vagrant up --provider=vcloud``` will trigger the newly installed provider.
94
69
 
70
+ Configuration
71
+ -------------
72
+
95
73
  Here's a sample Multi-VM Vagrantfile, please note that ```vcloud.vdc_edge_gateway``` and ```vcloud.vdc_edge_gateway_ip``` are required only when you cannot access ```vcloud.vdc_network_name``` directly and there's an Organization Edge between your workstation and the vCloud Network.
96
74
 
97
75
  ```ruby
@@ -143,4 +121,22 @@ Vagrant.configure("2") do |config|
143
121
  end
144
122
  ```
145
123
 
124
+ For additional documentation on different network setups with vCloud Director, check the [Network Deployment Options](../../wiki/Network-Deployment-Options) Wiki page
125
+
126
+ Contribute
127
+ -------------
128
+
129
+ What is still missing:
130
+
131
+ - TEST SUITES! (working on that).
132
+ - Speed, the code is definitely not optimized.
133
+ - Permission checks, make sure you have at least Catalog Admin privileges if you want to upload boxes to vCloud.
134
+ - Thorough testing.
135
+ - Error checking is absymal.
136
+ - Some spaghetti code here and there.
137
+ - Bugs, bugs and BUGS!.
138
+
139
+ If you're a developer and want to lend us a hand, head over to our ```develop``` branch and send us PRs!
140
+
141
+
146
142
  [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/frapposelli/vagrant-vcloud/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
@@ -51,16 +51,10 @@ module VagrantPlugins
51
51
  # If the VM is running, then our work here is done, exit
52
52
  if env[:result]
53
53
  b2.use MessageAlreadyRunning
54
- next
55
- end
56
- end
57
- b.use Call, IsPaused do |env, b2|
58
- if env[:result]
59
- b3.use Resume
60
- next
54
+ else
55
+ b2.use PowerOn
61
56
  end
62
57
  end
63
- b.use PowerOn
64
58
  end
65
59
  end
66
60
 
@@ -145,7 +139,6 @@ module VagrantPlugins
145
139
  # key.
146
140
  def self.action_read_ssh_info
147
141
  Vagrant::Action::Builder.new.tap do |b|
148
- b.use ConfigValidate
149
142
  b.use ConnectVCloud
150
143
  b.use ReadSSHInfo
151
144
  end
@@ -164,15 +157,22 @@ module VagrantPlugins
164
157
 
165
158
  def self.action_ssh
166
159
  Vagrant::Action::Builder.new.tap do |b|
167
- b.use ConfigValidate
160
+ # b.use ConfigValidate
168
161
  b.use Call, IsCreated do |env, b2|
169
162
  unless env[:result]
170
163
  b2.use MessageNotCreated
171
164
  next
172
165
  end
173
- # This calls our helper that announces the IP used to connect
174
- # to the VM, either directly to the vApp vShield or to the Org Edge
175
- b2.use AnnounceSSHExec
166
+
167
+ b2.use Call, IsRunning do |env2, b3|
168
+ unless env2[:result]
169
+ b3.use MessageNotRunning
170
+ next
171
+ end
172
+ # This calls our helper that announces the IP used to connect
173
+ # to the VM, either directly to the vApp vShield or to the Org Edge
174
+ b3.use AnnounceSSHExec
175
+ end
176
176
  end
177
177
  end
178
178
  end
@@ -243,6 +243,8 @@ module VagrantPlugins
243
243
  action_root.join('is_last_vm')
244
244
  autoload :MessageAlreadyRunning,
245
245
  action_root.join('message_already_running')
246
+ autoload :MessageNotRunning,
247
+ action_root.join('message_not_running')
246
248
  autoload :MessageCannotSuspend,
247
249
  action_root.join('message_cannot_suspend')
248
250
  autoload :MessageNotCreated,
@@ -10,7 +10,7 @@ module VagrantPlugins
10
10
  def call(env)
11
11
  config = env[:machine].provider_config
12
12
 
13
- if !config.vcloud_cnx
13
+ if !config.vcloud_cnx or !config.vcloud_cnx.driver.auth_key
14
14
  @logger.info('Connecting to vCloud Director...')
15
15
 
16
16
  @logger.debug("config.hostname : #{config.hostname}")
@@ -4,21 +4,20 @@ module VagrantPlugins
4
4
  class IsBridged
5
5
  def initialize(app, env)
6
6
  @app = app
7
- @logger = Log4r::Logger.new("vagrant_vcloud::action::is_bridged")
7
+ @logger = Log4r::Logger.new('vagrant_vcloud::action::is_bridged')
8
8
  end
9
9
 
10
10
  def call(env)
11
-
12
- vAppId = env[:machine].get_vapp_id
11
+ vapp_id = env[:machine].get_vapp_id
13
12
 
14
13
  cfg = env[:machine].provider_config
15
14
  cnx = cfg.vcloud_cnx.driver
16
15
 
17
16
  begin
18
- @logger.debug("Trying to get the vApp port forwarding rules")
19
- cnx.get_vapp_port_forwarding_rules(vAppId)
17
+ @logger.debug('Trying to get the vApp port forwarding rules')
18
+ cnx.get_vapp_port_forwarding_rules(vapp_id)
20
19
  rescue
21
- @logger.debug("Setting the bridged_network environment var to true")
20
+ @logger.debug('Setting the bridged_network environment var to true')
22
21
  env[:bridged_network] = true
23
22
  end
24
23
 
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module VCloud
3
+ module Action
4
+ class MessageNotRunning
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t('vagrant_vcloud.vm_not_running'))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,7 +2,6 @@ module VagrantPlugins
2
2
  module VCloud
3
3
  module Action
4
4
  class ReadSSHInfo
5
- # FIXME: More work needed here for vCloud logic (vApp, VM IPs, etc.)
6
5
  def initialize(app, env)
7
6
  @app = app
8
7
  @logger = Log4r::Logger.new('vagrant_vcloud::action::read_ssh_info')
@@ -14,6 +13,28 @@ module VagrantPlugins
14
13
  @app.call env
15
14
  end
16
15
 
16
+ # Small method to check the tcp connection to an ip:port works.
17
+ # Return false if anything fails, and true if it succeeded.
18
+ def check_for_ssh(ip, port)
19
+ begin
20
+ Timeout::timeout(1) do
21
+ begin
22
+ s = TCPSocket.new(ip, port)
23
+ s.close
24
+ @logger.debug("SSH Connection successful !")
25
+ return true
26
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
27
+ @logger.debug("SSH Connection Refused/Host Unreachable...")
28
+ return false
29
+ end
30
+ end
31
+ rescue Timeout::Error
32
+ @logger.debug("SSH Connection Timeout...")
33
+ end
34
+
35
+ return false
36
+ end
37
+
17
38
  def read_ssh_info(env)
18
39
  return nil if env[:machine].id.nil?
19
40
 
@@ -36,11 +57,16 @@ module VagrantPlugins
36
57
  end
37
58
 
38
59
  if !cfg.network_bridge.nil?
39
- @logger.debug("We're running in bridged mode,
40
- fetching the IP directly from the VM")
60
+ @logger.debug(
61
+ 'We\'re running in bridged mode, ' \
62
+ 'fetching the IP directly from the VM'
63
+ )
41
64
  vm_info = cnx.get_vm(env[:machine].id)
42
- @logger.debug("IP address for #{vm_name}:
43
- #{vm_info[:networks]['Vagrant-vApp-Net'][:ip]}")
65
+ @logger.debug(
66
+ "IP address for #{vm_name}: " \
67
+ "#{vm_info[:networks]['Vagrant-vApp-Net'][:ip]}"
68
+ )
69
+
44
70
  @external_ip = vm_info[:networks]['Vagrant-vApp-Net'][:ip]
45
71
  @external_port = '22'
46
72
  else
@@ -58,21 +84,43 @@ module VagrantPlugins
58
84
  end
59
85
 
60
86
  if cfg.vdc_edge_gateway_ip && cfg.vdc_edge_gateway
61
- @logger.debug("We're running vagrant behind an Organization vDC
62
- edge")
87
+ @logger.debug(
88
+ "We're running vagrant behind an Organization vDC Edge"
89
+ )
63
90
  @external_ip = cfg.vdc_edge_gateway_ip
64
91
  end
65
92
  end
66
93
 
67
- # FIXME: fix the selfs and create a meaningful info message
68
- # @logger.debug(
69
- # "Our variables: IP #{@external_ip} and Port #{@external_port}"
70
- # )
94
+ @logger.debug(
95
+ "SSH INFO: IP #{@external_ip} and Port #{@external_port}"
96
+ )
97
+
98
+ # tsugliani: Temporary Fix for Issue #56
99
+ # SSH unavailable makes the deployment fails.
100
+ # Wait infinitely right now for SSH...
101
+ # sleep_counter incremented by 1s each loop.
102
+ #
103
+ # This should be fixed with implementing Vagrant::Util::Retryable
104
+ # and something like:
105
+ #
106
+ # retryable(:on => Vagrant::Errors::SSHSomething, :tries => 10, :sleep => 5) do
107
+ # check_for_ssh(ip, port, :error_class => Vagrant::Errors::SSHSomething)
108
+ # end
109
+ #
110
+ sleep_counter = 5
111
+
112
+ while check_for_ssh(@external_ip, @external_port) == false
113
+ env[:ui].info(
114
+ "Waiting for SSH Access on #{@external_ip}:#{@external_port} ... "
115
+ )
116
+ sleep sleep_counter
117
+ sleep_counter += 1
118
+ end
71
119
 
120
+ # If we are here, then SSH is ready, continue
72
121
  {
73
- # FIXME: these shouldn't be self
74
- :host => @external_ip,
75
- :port => @external_port
122
+ :host => @external_ip,
123
+ :port => @external_port
76
124
  }
77
125
  end
78
126
  end
@@ -0,0 +1,43 @@
1
+ module VagrantPlugins
2
+ module VCloud
3
+ module Cap
4
+ module ForwardedPorts
5
+
6
+ # Reads the forwarded ports that currently exist on the machine
7
+ # itself. This raises an exception if the machine isn't running.
8
+ #
9
+ # This also may not match up with configured forwarded ports, because
10
+ # Vagrant auto port collision fixing may have taken place.
11
+ #
12
+ # @return [Hash<Integer, Integer>] Host => Guest port mappings.
13
+ def self.forwarded_ports(machine)
14
+ result = {}
15
+
16
+ cfg = machine.provider_config
17
+ cnx = cfg.vcloud_cnx.driver
18
+ vapp_id = machine.get_vapp_id
19
+ vm_name = machine.name
20
+ vm = cnx.get_vapp(vapp_id)
21
+ myhash = vm[:vms_hash][vm_name.to_sym]
22
+
23
+ if vm.nil?
24
+ return
25
+ end
26
+
27
+ if cfg.network_bridge.nil?
28
+ rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
29
+
30
+ rules.each do |rule|
31
+ if rule[:vapp_scoped_local_id] == myhash[:vapp_scoped_local_id]
32
+ result[rule[:nat_external_port].to_i] = rule[:nat_internal_port].to_i
33
+ end
34
+ end
35
+ end
36
+ result
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+ end
43
+
@@ -0,0 +1,20 @@
1
+ module VagrantPlugins
2
+ module VCloud
3
+ module Cap
4
+ module PublicAddress
5
+
6
+ def self.public_address(machine)
7
+
8
+ # Initial try for vagrant share feature.
9
+ # It seems ssh_info[:port] is given automatically.
10
+ # I think this feature was built planning that the port forwarding
11
+ # and networking was done on the vagrant machine, which isn't the
12
+ # case in vagrant-vcloud
13
+
14
+ ssh_info = machine.ssh_info
15
+ ssh_info[:host]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -5,51 +5,13 @@ module VagrantPlugins
5
5
  module VCloud
6
6
  class Command < Vagrant.plugin('2', :command)
7
7
  def self.synopsis
8
- 'outputs status of the vCloud Director setup [vcloud provider only]'
8
+ 'namespace to interact with vCloud Director specifics [vcloud provider only]'
9
9
  end
10
10
 
11
- def execute
12
- options = {}
13
- opts = OptionParser.new do |o|
14
- o.banner = 'Usage: vagrant vcloud-status [--all]'
15
-
16
- # We can probably extend this if needed for specific information
17
- o.on('-a', '--all', 'Displays all available information') do |f|
18
- options[:all] = true
19
- end
20
- end
21
-
22
- @argv = parse_options(opts)
23
- return unless @argv
24
-
25
- # initialize some variables
26
- vapp_id = nil
27
- cfg = nil
28
-
29
- # Go through the vagrant machines
30
- with_target_vms(@argv) do |machine|
31
-
32
- # FIXME/Bug: why does the provider switch to virtualbox when
33
- # destroying VMs within the the vApp:
34
- # .vagrant/machines/<machine>/virtualbox Cannot trace why this
35
- # happens :-( (tsugliani)
36
- if machine.provider_name != :vcloud
37
- # Not a vCloud Director provider, exit with explicit error message
38
- puts "#{machine.provider_name} provider is incompatible with " +
39
- 'this command'
40
- exit 1
41
- end
42
-
43
- # Force reloads on objects by fetching the ssh_info
44
- machine.provider.ssh_info
45
-
46
- # populate cfg & vApp Id for later use.
47
- cfg = machine.provider_config
48
- vapp_id = machine.get_vapp_id
49
- break
50
- end
51
-
11
+ def command_vcloud_status(cfg, vapp_id)
52
12
  # Set our handlers to the driver and objects
13
+
14
+ puts "Fetching vCloud Director status..."
53
15
  cnx = cfg.vcloud_cnx.driver
54
16
  vapp = cnx.get_vapp(vapp_id)
55
17
 
@@ -80,130 +42,223 @@ module VagrantPlugins
80
42
 
81
43
  # Print the General Information Table
82
44
  puts table
45
+ end
83
46
 
84
- # Display Network information only if --all is passed to the cmd
85
- if options[:all] == true
86
-
87
- # FIXME: this needs to be fixed to accomodate the bridged scenario
88
- # potentially showing only the assigned IPs in the VMs
47
+ def command_vcloud_network(cfg, vapp_id)
48
+ # FIXME: this needs to be fixed to accomodate the bridged scenario
49
+ # potentially showing only the assigned IPs in the VMs
89
50
 
90
- if !cfg.network_bridge.nil?
51
+ puts 'Fetching vCloud Director network settings ...'
52
+ cnx = cfg.vcloud_cnx.driver
53
+ vapp = cnx.get_vapp(vapp_id)
91
54
 
92
- # Create a new table for the network information
93
- network_table = Terminal::Table.new
94
- network_table.title = 'Network Map'
55
+ organization = cnx.get_organization_by_name(cfg.org_name)
56
+ cfg.vdc_id = cnx.get_vdc_id_by_name(organization, cfg.vdc_name)
95
57
 
96
- network_table << ['VM Name', 'IP Address', 'Connection']
97
- network_table << :separator
58
+ if !cfg.network_bridge.nil?
59
+ # Create a new table for the network information
60
+ network_table = Terminal::Table.new
61
+ network_table.title = 'Network Map'
98
62
 
99
- # ap vapp[:vms_hash]
63
+ network_table << ['VM Name', 'IP Address', 'Connection']
64
+ network_table << :separator
100
65
 
66
+ vapp[:vms_hash].each do |vm|
67
+ network_table << [vm[0], vm[1][:addresses][0], 'Direct']
68
+ end
69
+ else
70
+ vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
71
+ vapp_edge_rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
72
+ edge_gateway_rules = cnx.get_edge_gateway_rules(cfg.vdc_edge_gateway,
73
+ cfg.vdc_id)
74
+
75
+ # Create a new table for the network information
76
+ network_table = Terminal::Table.new
77
+ network_table.title = 'Vagrant vCloud Director Network Map'
78
+
79
+ network_table << ['VM Name', 'Destination NAT Mapping', 'Enabled']
80
+ network_table << :separator
81
+
82
+ # Fetching Destination NAT Rules for each vApp/Edge/VM/Mapping
83
+ vapp_edge_rules.each do |vapp_edge_rule|
84
+ edge_gateway_rule = edge_gateway_rules.find {|r|
85
+ (r[:rule_type] == 'DNAT' &&
86
+ r[:original_ip] == cfg.vdc_edge_gateway_ip &&
87
+ r[:translated_ip] == vapp_edge_ip)}
88
+
89
+ # Loop on every VM in the vApp
101
90
  vapp[:vms_hash].each do |vm|
102
- # ap vm
103
-
104
- network_table << [vm[0], vm[1][:addresses][0], 'Direct']
105
- end
106
- else
107
-
108
- vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
109
- vapp_edge_rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
110
- edge_gateway_rules = cnx.get_edge_gateway_rules(cfg.vdc_edge_gateway,
111
- cfg.vdc_id)
112
-
113
- # Create a new table for the network information
114
- network_table = Terminal::Table.new
115
- network_table.title = 'Vagrant vCloud Director Network Map'
116
-
117
- network_table << ['VM Name', 'Destination NAT Mapping', 'Enabled']
118
- network_table << :separator
119
-
120
- # Fetching Destination NAT Rules for each vApp/Edge/VM/Mapping
121
- vapp_edge_rules.each do |vapp_edge_rule|
122
- edge_gateway_rule = edge_gateway_rules.find {|r|
123
- (r[:rule_type] == 'DNAT' &&
124
- r[:original_ip] == cfg.vdc_edge_gateway_ip &&
125
- r[:translated_ip] == vapp_edge_ip)}
126
-
127
- # Loop on every VM in the vApp
128
- vapp[:vms_hash].each do |vm|
129
- # Only Map valid vAppEdge scope to VM scope
130
- vm_scope = vm[1][:vapp_scoped_local_id]
131
- vapp_edge_scope = vapp_edge_rule[:vapp_scoped_local_id]
132
-
133
- if vm_scope == vapp_edge_scope
134
-
135
- # Generate DNAT Mappings for the valid machines
136
- # If rules don't match, you will not see them !
137
- if edge_gateway_rule
138
- # DNAT rule from edge to vapp to vm
139
- network_table << [
140
- "#{vm[0]}",
141
- "#{cfg.vdc_edge_gateway_ip}:" +
142
- "#{vapp_edge_rule[:nat_external_port]}" +
143
- " -> #{vapp_edge_ip}:" +
144
- "#{vapp_edge_rule[:nat_external_port]}" +
145
- " -> #{vm[1][:addresses][0]}:" +
146
- "#{vapp_edge_rule[:nat_internal_port]}",
147
- edge_gateway_rule[:is_enabled]
148
- ]
149
- else
150
- # DNAT rule only from vapp to vm
151
- network_table << [
152
- "#{vm[0]}",
153
- "#{vapp_edge_ip}:" +
154
- "#{vapp_edge_rule[:nat_external_port]}" +
155
- " -> #{vm[1][:addresses][0]}:" +
156
- "#{vapp_edge_rule[:nat_internal_port]}",
157
- true
158
- ]
159
- end
91
+ # Only Map valid vAppEdge scope to VM scope
92
+ vm_scope = vm[1][:vapp_scoped_local_id]
93
+ vapp_edge_scope = vapp_edge_rule[:vapp_scoped_local_id]
94
+
95
+ if vm_scope == vapp_edge_scope
96
+ # Generate DNAT Mappings for the valid machines
97
+ # If rules don't match, you will not see them !
98
+ if edge_gateway_rule
99
+ # DNAT rule from edge to vapp to vm
100
+ network_table << [
101
+ "#{vm[0]}",
102
+ "#{cfg.vdc_edge_gateway_ip}:" +
103
+ "#{vapp_edge_rule[:nat_external_port]}" +
104
+ " -> #{vapp_edge_ip}:" +
105
+ "#{vapp_edge_rule[:nat_external_port]}" +
106
+ " -> #{vm[1][:addresses][0]}:" +
107
+ "#{vapp_edge_rule[:nat_internal_port]}",
108
+ edge_gateway_rule[:is_enabled]
109
+ ]
110
+ else
111
+ # DNAT rule only from vapp to vm
112
+ network_table << [
113
+ "#{vm[0]}",
114
+ "#{vapp_edge_ip}:" +
115
+ "#{vapp_edge_rule[:nat_external_port]}" +
116
+ " -> #{vm[1][:addresses][0]}:" +
117
+ "#{vapp_edge_rule[:nat_internal_port]}",
118
+ true
119
+ ]
160
120
  end
161
121
  end
162
122
  end
123
+ end
163
124
 
164
- # Fetching Source NAT Rules for the vApp
165
- network_table << :separator
166
- network_table << ['Network Name', 'Source NAT Mapping', 'Enabled']
167
- network_table << :separator
168
-
169
- edge_gateway_rules.each do |edge_gateway_rule|
170
- # Only check SNAT and src/dst
171
- if edge_gateway_rule[:rule_type] == 'SNAT' &&
172
- edge_gateway_rule[:original_ip] == vapp_edge_ip &&
173
- edge_gateway_rule[:translated_ip] == cfg.vdc_edge_gateway_ip
174
-
175
- network_table << [
176
- edge_gateway_rule[:interface_name],
177
- "#{vapp_edge_ip} -> #{cfg.vdc_edge_gateway_ip}",
178
- edge_gateway_rule[:is_enabled]
179
- ]
180
- end
125
+ # Fetching Source NAT Rules for the vApp
126
+ network_table << :separator
127
+ network_table << ['Network Name', 'Source NAT Mapping', 'Enabled']
128
+ network_table << :separator
129
+
130
+ edge_gateway_rules.each do |edge_gateway_rule|
131
+ # Only check SNAT and src/dst
132
+ if edge_gateway_rule[:rule_type] == 'SNAT' &&
133
+ edge_gateway_rule[:original_ip] == vapp_edge_ip &&
134
+ edge_gateway_rule[:translated_ip] == cfg.vdc_edge_gateway_ip
135
+
136
+ network_table << [
137
+ edge_gateway_rule[:interface_name],
138
+ "#{vapp_edge_ip} -> #{cfg.vdc_edge_gateway_ip}",
139
+ edge_gateway_rule[:is_enabled]
140
+ ]
181
141
  end
142
+ end
182
143
 
183
- # Fetching Edge Gateway Firewall Rules
184
- network_table << :separator
185
- network_table << ['Rule# - Description', 'Firewall Rules', 'Enabled']
186
- network_table << :separator
187
- edge_gateway_rules.each do |edge_gateway_rule|
188
- # Only add firewall rules
189
- if edge_gateway_rule[:rule_type] == 'Firewall'
190
- network_table << [
191
- "#{edge_gateway_rule[:id]} - " +
192
- "(#{edge_gateway_rule[:description]})",
193
- "#{edge_gateway_rule[:policy]} " +
194
- "SRC:#{edge_gateway_rule[:source_ip]}:" +
195
- "#{edge_gateway_rule[:source_portrange]} to " +
196
- "DST:#{edge_gateway_rule[:destination_ip]}:" +
197
- "#{edge_gateway_rule[:destination_portrange]}",
198
- "#{edge_gateway_rule[:is_enabled]}"
199
- ]
200
- end
144
+ # Fetching Edge Gateway Firewall Rules
145
+ network_table << :separator
146
+ network_table << ['Rule# - Description', 'Firewall Rules', 'Enabled']
147
+ network_table << :separator
148
+ edge_gateway_rules.each do |edge_gateway_rule|
149
+ # Only add firewall rules
150
+ if edge_gateway_rule[:rule_type] == 'Firewall'
151
+ network_table << [
152
+ "#{edge_gateway_rule[:id]} - " +
153
+ "(#{edge_gateway_rule[:description]})",
154
+ "#{edge_gateway_rule[:policy]} " +
155
+ "SRC:#{edge_gateway_rule[:source_ip]}:" +
156
+ "#{edge_gateway_rule[:source_portrange]} to " +
157
+ "DST:#{edge_gateway_rule[:destination_ip]}:" +
158
+ "#{edge_gateway_rule[:destination_portrange]}",
159
+ "#{edge_gateway_rule[:is_enabled]}"
160
+ ]
201
161
  end
202
162
  end
203
- # Print the Network Table
204
- puts
205
- puts network_table
163
+ end
164
+ # Print the Network Table
165
+ puts network_table
166
+ end
167
+
168
+ def command_vcloud_redeploy_edge_gw(cfg)
169
+ cnx = cfg.vcloud_cnx.driver
170
+
171
+ organization = cnx.get_organization_by_name(cfg.org_name)
172
+ cfg.vdc_id = cnx.get_vdc_id_by_name(organization, cfg.vdc_name)
173
+
174
+ edge_gw_id = cnx.find_edge_gateway_id(cfg.vdc_edge_gateway, cfg.vdc_id)
175
+ task_id = cnx.redeploy_edge_gateway(edge_gw_id)
176
+
177
+ puts "Redeploying #{cfg.vdc_edge_gateway} vShield Edge Gateway... " +
178
+ '(This task can take a few minutes)'
179
+ cnx.wait_task_completion(task_id)
180
+ puts 'Done'
181
+ end
182
+
183
+ def execute
184
+ options = {}
185
+ opts = OptionParser.new do |o|
186
+ o.banner = 'Usage: vagrant vcloud [options]'
187
+
188
+ # We can probably extend this if needed for specific information
189
+ o.on(
190
+ '-n',
191
+ '--network',
192
+ 'Display the vCloud Director network mapping information'
193
+ ) do |f|
194
+ options[:network] = true
195
+ end
196
+
197
+ o.on(
198
+ '-s',
199
+ '--status',
200
+ 'Display the vCloud Director objects IDs'
201
+ ) do |f|
202
+ options[:status] = true
203
+ end
204
+
205
+ o.on(
206
+ '-r',
207
+ '--redeploy-edge-gw',
208
+ 'Redeploy the vCloud Director Edge Gateway'
209
+ ) do |f|
210
+ options[:redeploy_edge_gw] = true
211
+ end
212
+
213
+ end
214
+
215
+ @argv = parse_options(opts)
216
+ return unless @argv
217
+
218
+ # If no arguments, print help
219
+ if options.keys.count() == 0
220
+ puts opts
221
+ exit 1
222
+ end
223
+
224
+ puts 'Initializing vCloud Director provider...'
225
+ # initialize some variables
226
+ vapp_id = nil
227
+ cfg = nil
228
+
229
+ # Go through the vagrant machines
230
+ with_target_vms(@argv) do |machine|
231
+
232
+ # FIXME/Bug: why does the provider switch to virtualbox when
233
+ # destroying VMs within the the vApp:
234
+ # .vagrant/machines/<machine>/virtualbox Cannot trace why this
235
+ # happens :-( (tsugliani)
236
+ if machine.provider_name != :vcloud
237
+ # Not a vCloud Director provider, exit with explicit error message
238
+ puts "#{machine.provider_name} provider is incompatible with " +
239
+ 'this command'
240
+ exit 1
241
+ end
206
242
 
243
+ # Force reloads on objects by fetching the ssh_info
244
+ machine.provider.ssh_info
245
+
246
+ # populate cfg & vApp Id for later use.
247
+ cfg = machine.provider_config
248
+ vapp_id = machine.get_vapp_id
249
+ break
250
+ end
251
+
252
+ # iterate through each option and call the according command.
253
+ options.keys.each do |key|
254
+ case key
255
+ when :status
256
+ command_vcloud_status(cfg, vapp_id)
257
+ when :network
258
+ command_vcloud_network(cfg, vapp_id)
259
+ when :redeploy_edge_gw
260
+ command_vcloud_redeploy_edge_gw(cfg)
261
+ end
207
262
  end
208
263
 
209
264
  0
@@ -309,9 +309,12 @@ module VagrantPlugins
309
309
  # Massive debug when LOG=DEBUG
310
310
  # Using awesome_print to get nice XML output for better readability
311
311
  if @logger.level == 1
312
- ap "SEND #{params['method'].upcase} #{url}"
312
+ ap "[#{Time.now.ctime}] -> SEND #{params['method'].upcase} #{url}"
313
313
  if payload
314
314
  payload_xml = Nokogiri.XML(payload)
315
+ ap 'SEND HEADERS'
316
+ ap extheader
317
+ ap 'SEND BODY'
315
318
  ap payload_xml
316
319
  end
317
320
  end
@@ -335,9 +338,12 @@ module VagrantPlugins
335
338
  # Massive debug when LOG=DEBUG
336
339
  # Using awesome_print to get nice XML output for readability
337
340
  if @logger.level == 1
338
- ap "RECV #{response.status}"
341
+ ap "[#{Time.now.ctime}] <- RECV #{response.status}"
339
342
  # Just avoid the task spam.
340
343
  if !url.index('/task/')
344
+ ap 'RECV HEADERS'
345
+ ap response.headers
346
+ ap 'RECV BODY'
341
347
  ap nicexml
342
348
  end
343
349
  end
@@ -47,9 +47,10 @@ module VagrantPlugins
47
47
  # Instantiate the proper version driver for vCloud
48
48
  @logger.debug("Finding driver for vCloud version: #{@version}")
49
49
  driver_map = {
50
- "5.1" => Version_5_1,
51
- "5.5" => Version_5_1, # Binding vCloud 5.5 API on our current 5.1 implementation
52
- "5.7" => Version_5_1 # Binding vCHS API on our current 5.1 implementation
50
+ '5.1' => Version_5_1,
51
+ '5.5' => Version_5_1, # Binding vCloud 5.5 API on our current 5.1 implementation
52
+ '5.6' => Version_5_1, # Binding vCHS API on our current 5.1 implementation
53
+ '5.7' => Version_5_1 # Binding vCHS API on our current 5.1 implementation
53
54
  }
54
55
 
55
56
  if @version.start_with?('0.9') ||
@@ -138,11 +139,20 @@ module VagrantPlugins
138
139
  end
139
140
 
140
141
  version_info = Nokogiri.parse(response.body)
141
- # FIXME: Find a smarter way to check for vCloud API version
142
- # Changed from .first to .last because that's the way it's defined
143
- # in the request answer.
142
+
144
143
  api_version = version_info.css('VersionInfo Version')
145
- api_version.last.text
144
+
145
+ api_version_supported = 0.0
146
+
147
+ # Go through each available Version and return the latest supported
148
+ # version
149
+ api_version.each do |api_available_version|
150
+ if api_version_supported.to_f < api_available_version.text.to_f
151
+ api_version_supported = api_available_version.text
152
+ end
153
+ end
154
+
155
+ api_version_supported
146
156
 
147
157
  rescue SocketError
148
158
  raise Errors::HostNotFound, :message => host_url
@@ -1107,6 +1107,22 @@ module VagrantPlugins
1107
1107
  end
1108
1108
  end
1109
1109
 
1110
+ ##
1111
+ # Redeploy the vShield Edge Gateway VM, due to some knowns issues
1112
+ # where the current rules are not "applied" and the EdgeGW is in an
1113
+ # unmanageable state.
1114
+ #
1115
+ def redeploy_edge_gateway(edge_gateway_id)
1116
+ params = {
1117
+ 'method' => :post,
1118
+ 'command' => "/admin/edgeGateway/#{edge_gateway_id}/action/redeploy"
1119
+ }
1120
+
1121
+ _response, headers = send_request(params)
1122
+ task_id = headers['Location'].gsub("#{@api_url}/task/", '')
1123
+ task_id
1124
+ end
1125
+
1110
1126
  ##
1111
1127
  # Find an edge gateway network from the edge name and vdc_id, and ip
1112
1128
  #
@@ -1364,7 +1380,7 @@ module VagrantPlugins
1364
1380
  nat_rules = set_edge_rules.at_css('NatService')
1365
1381
 
1366
1382
  # Add all DNAT port rules edge -> vApp for the given list
1367
- ports.each do |port|
1383
+ ports.each do |port|
1368
1384
  nat_rule = Nokogiri::XML::Builder.new do |xml|
1369
1385
  xml.NatRule {
1370
1386
  xml.RuleType 'DNAT'
@@ -1394,7 +1410,7 @@ module VagrantPlugins
1394
1410
  xml.Protocol 'any'
1395
1411
  }
1396
1412
  }
1397
- end
1413
+ end
1398
1414
  nat_rules << snat_rule.doc.root.to_xml
1399
1415
  end
1400
1416
 
@@ -1414,7 +1430,7 @@ module VagrantPlugins
1414
1430
  xml.SourceIp 'Any'
1415
1431
  xml.EnableLogging 'false'
1416
1432
  }
1417
- end
1433
+ end
1418
1434
  fw_rules = set_edge_rules.at_css('FirewallService')
1419
1435
  fw_rules << firewall_rule_1.doc.root.to_xml
1420
1436
  end
@@ -1438,7 +1454,7 @@ module VagrantPlugins
1438
1454
  task_id
1439
1455
  end
1440
1456
 
1441
-
1457
+
1442
1458
  ##
1443
1459
  # get vApp edge public IP from the vApp ID
1444
1460
  # Only works when:
@@ -1697,9 +1713,9 @@ module VagrantPlugins
1697
1713
  task, errormsg = nil
1698
1714
  loop do
1699
1715
  task = get_task(task_id)
1700
- @logger.debug(
1701
- "Evaluating taskid: #{task_id}, current status #{task[:status]}"
1702
- )
1716
+ # @logger.debug(
1717
+ # "Evaluating taskid: #{task_id}, current status #{task[:status]}"
1718
+ # )
1703
1719
  break if !['queued','preRunning','running'].include?(task[:status])
1704
1720
  sleep 5
1705
1721
  end
@@ -30,9 +30,20 @@ module VagrantPlugins
30
30
  Provider
31
31
  end
32
32
 
33
+ # Add vagrant share support
34
+ provider_capability('vcloud', 'public_address') do
35
+ require_relative 'cap/public_address'
36
+ Cap::PublicAddress
37
+ end
38
+
39
+ provider_capability(:vcloud, :forwarded_ports) do
40
+ require_relative "cap/forwarded_ports"
41
+ Cap::ForwardedPorts
42
+ end
43
+
33
44
  # Added a vagrant vcloud-status command to enhance troubleshooting and
34
45
  # visibility.
35
- command('vcloud-status') do
46
+ command('vcloud') do
36
47
  require_relative 'command'
37
48
  Command
38
49
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module VCloud
3
- VERSION = '0.3.1'
3
+ VERSION = '0.3.2'
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -1,8 +1,9 @@
1
- en:
2
- vagrant_vcloud:
1
+ en:
2
+ vagrant_vcloud:
3
3
  vm_not_created: "The VM has not been created"
4
4
  will_not_destroy: "VM will not be destroyed"
5
5
  vm_already_running: "VM is already running"
6
+ vm_not_running: "VM is not running"
6
7
  vm_halted_cannot_suspend: "VM is not running or already suspended, cannot suspend it."
7
8
  sync:
8
9
  rsync_not_found_warning: |-
@@ -10,7 +11,7 @@ en:
10
11
  Make sure rsync is installed and the binary can be found in the PATH.
11
12
  rsync_folder: |-
12
13
  Rsyncing folder: %{hostpath} => %{guestpath}
13
- config:
14
+ config:
14
15
  api_version: "Configuration must specify a vCloud API version (default=5.1)"
15
16
  catalog_name: "Configuration must specify a vCloud Director Catalog (for the VM templates images)"
16
17
  ip_dns: "DNS configuration must be specified as an Array type"
@@ -23,7 +24,7 @@ en:
23
24
  template: "Configuration must specify a template name"
24
25
  username: "Configuration must specify a vCloud Director username"
25
26
  vdc_name: "Configuration must specify a vCloud Director Virtual Datacenter (Target Organization VDC)"
26
- errors:
27
+ errors:
27
28
  missing_compute_resource: "Configured compute resource not found"
28
29
  missing_datacenter: "Configured data center not found"
29
30
  missing_resource_pool: "Configured resource pool not found"
@@ -37,7 +38,7 @@ en:
37
38
  stop_vapp_error: "Impossible to stop vApp, could be a transient error, please try again, error: %{message}"
38
39
  compose_vapp_error: "Impossible to compose a vApp, error: %{message}"
39
40
  forward_port_collision: "Port collision detected, change it in the Vagrantfile or add auto_correct: true. %{guest_port} => %{host_port}"
40
- rest_errors:
41
+ rest_errors:
41
42
  object_not_found: "Object not found in vCloud Director"
42
43
  invalid_config_error: "Invalid Guest Customization Specified"
43
44
  invalid_state_error: "Invalid vApp State %{message}"
@@ -58,7 +59,7 @@ en:
58
59
  Host path: %{hostpath}
59
60
  Error: %{err}
60
61
 
61
- states:
62
+ states:
62
63
  not_created: |-
63
64
  The environment has not yet been created. Run `vagrant up` to
64
65
  create the environment. If a machine is not created, only the
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-vcloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fabio Rapposelli
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-06 00:00:00.000000000 Z
12
+ date: 2014-05-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n
@@ -215,6 +215,7 @@ files:
215
215
  - lib/vagrant-vcloud/action/message_already_running.rb
216
216
  - lib/vagrant-vcloud/action/message_cannot_suspend.rb
217
217
  - lib/vagrant-vcloud/action/message_not_created.rb
218
+ - lib/vagrant-vcloud/action/message_not_running.rb
218
219
  - lib/vagrant-vcloud/action/message_will_not_destroy.rb
219
220
  - lib/vagrant-vcloud/action/power_off.rb
220
221
  - lib/vagrant-vcloud/action/power_off_vapp.rb
@@ -225,6 +226,8 @@ files:
225
226
  - lib/vagrant-vcloud/action/suspend.rb
226
227
  - lib/vagrant-vcloud/action/sync_folders.rb
227
228
  - lib/vagrant-vcloud/action/unmap_port_forwardings.rb
229
+ - lib/vagrant-vcloud/cap/forwarded_ports.rb
230
+ - lib/vagrant-vcloud/cap/public_address.rb
228
231
  - lib/vagrant-vcloud/command.rb
229
232
  - lib/vagrant-vcloud/config.rb
230
233
  - lib/vagrant-vcloud/driver/base.rb