vagrant-vcloud 0.3.1 → 0.3.2

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