vagrant-vcloud 0.2.2 → 0.3.0
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 +4 -4
- data/README.md +14 -1
- data/lib/vagrant-vcloud/action/build_vapp.rb +6 -1
- data/lib/vagrant-vcloud/action/destroy_vapp.rb +54 -0
- data/lib/vagrant-vcloud/action/destroy_vm.rb +37 -0
- data/lib/vagrant-vcloud/action/forward_ports.rb +32 -7
- data/lib/vagrant-vcloud/action/handle_nat_port_collisions.rb +81 -45
- data/lib/vagrant-vcloud/action/is_last_vm.rb +31 -0
- data/lib/vagrant-vcloud/action/power_off.rb +4 -17
- data/lib/vagrant-vcloud/action/power_off_vapp.rb +40 -0
- data/lib/vagrant-vcloud/action/power_on.rb +1 -59
- data/lib/vagrant-vcloud/action/sync_folders.rb +1 -1
- data/lib/vagrant-vcloud/action.rb +31 -16
- data/lib/vagrant-vcloud/command.rb +38 -29
- data/lib/vagrant-vcloud/config.rb +6 -0
- data/lib/vagrant-vcloud/driver/base.rb +1 -1
- data/lib/vagrant-vcloud/driver/version_5_1.rb +143 -242
- data/lib/vagrant-vcloud/util/compile_forwarded_ports.rb +3 -0
- data/lib/vagrant-vcloud/version.rb +1 -1
- metadata +6 -3
- data/lib/vagrant-vcloud/action/destroy.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffdaef92decaf313b306add8bc6f4809fd96aa10
|
4
|
+
data.tar.gz: 7a92c5b464e12b4c1a00b0d61288eb1967f23e61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8823a60a23a6426b230abc79d99e2765f29a1bb173a135aa7a85a684288c4b91c844d2db340cfedb0c9913723972c86719610098af67985b631e8cf0f3771b4b
|
7
|
+
data.tar.gz: cf31bea829c6972bfcf5ef88b50333cec048bf9b50931f8576306b31fed4fd1ab320a2c482c54771332042e7856fdcca16c6d692fa90d5a3455b5316b97e7b4d
|
data/README.md
CHANGED
@@ -1,13 +1,24 @@
|
|
1
1
|
[Vagrant](http://www.vagrantup.com) provider for VMware vCloud Director®
|
2
2
|
=============
|
3
3
|
|
4
|
-
[Version 0.
|
4
|
+
[Version 0.3.0](https://github.com/frapposelli/vagrant-vcloud/releases/tag/v0.3.0) 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
|
+
Features of Version 0.3.0 are:
|
12
|
+
|
13
|
+
A substantial release, major kudos to Stefan Scherer who submitted some substantious PRs!
|
14
|
+
|
15
|
+
- Added support for port mapping at the Organization Edge Gateway.
|
16
|
+
- Added a new configuration options ```vapp_prefix``` to change vApp prefix (defaults to Vagrant).
|
17
|
+
- Improved vcloud-status command.
|
18
|
+
- Fixed cygdrive path for rsync on Windows.
|
19
|
+
- Fixed Issue #33 - Error removing/creating NAT rules on second vagrant up.
|
20
|
+
- Fixed Issue #43 - Destroy fails if VMs are halted.
|
21
|
+
|
11
22
|
Features of Version 0.2.2 are:
|
12
23
|
|
13
24
|
- Fixed Issue #32 - Port Forwarding rules are deleted when Halting a VM.
|
@@ -94,6 +105,8 @@ Vagrant.configure("2") do |config|
|
|
94
105
|
|
95
106
|
# vCloud Director provider settings
|
96
107
|
config.vm.provider :vcloud do |vcloud|
|
108
|
+
vcloud.vapp_prefix = "multibox-sample"
|
109
|
+
|
97
110
|
vcloud.hostname = "https://my.cloudprovider.com"
|
98
111
|
vcloud.username = "MyUserName"
|
99
112
|
vcloud.password = "MySup3rS3cr3tPassw0rd!"
|
@@ -111,9 +111,14 @@ module VagrantPlugins
|
|
111
111
|
if env[:machine].get_vapp_id.nil?
|
112
112
|
env[:ui].info('Building vApp...')
|
113
113
|
|
114
|
+
vapp_prefix = cfg.vapp_prefix
|
115
|
+
if vapp_prefix.nil?
|
116
|
+
vapp_prefix = "Vagrant"
|
117
|
+
end
|
118
|
+
|
114
119
|
compose = cnx.compose_vapp_from_vm(
|
115
120
|
cfg.vdc_id,
|
116
|
-
"
|
121
|
+
"#{vapp_prefix}-#{Etc.getlogin}-#{Socket.gethostname.downcase}-" +
|
117
122
|
"#{SecureRandom.hex(4)}",
|
118
123
|
"vApp created by #{Etc.getlogin} running on " +
|
119
124
|
"#{Socket.gethostname.downcase} using vagrant-vcloud on " +
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloud
|
3
|
+
module Action
|
4
|
+
class DestroyVApp
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_vcloud::action::destroy_vapp')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
cfg = env[:machine].provider_config
|
12
|
+
cnx = cfg.vcloud_cnx.driver
|
13
|
+
vapp_id = env[:machine].get_vapp_id
|
14
|
+
|
15
|
+
cfg.org = cnx.get_organization_by_name(cfg.org_name)
|
16
|
+
cfg.vdc_id = cnx.get_vdc_id_by_name(cfg.org, cfg.vdc_name)
|
17
|
+
|
18
|
+
test_vapp = cnx.get_vapp(vapp_id)
|
19
|
+
|
20
|
+
@logger.debug(
|
21
|
+
"Number of VMs in the vApp: #{test_vapp[:vms_hash].count}"
|
22
|
+
)
|
23
|
+
|
24
|
+
if cfg.vdc_edge_gateway_ip && cfg.vdc_edge_gateway
|
25
|
+
env[:ui].info(
|
26
|
+
"Removing NAT rules on [#{cfg.vdc_edge_gateway}] " +
|
27
|
+
"for IP [#{cfg.vdc_edge_gateway_ip}]."
|
28
|
+
)
|
29
|
+
@logger.debug(
|
30
|
+
"Deleting Edge Gateway rules - vdc id: #{cfg.vdc_id}"
|
31
|
+
)
|
32
|
+
edge_remove = cnx.remove_edge_gateway_rules(
|
33
|
+
cfg.vdc_edge_gateway,
|
34
|
+
cfg.vdc_id,
|
35
|
+
cfg.vdc_edge_gateway_ip,
|
36
|
+
vapp_id
|
37
|
+
)
|
38
|
+
cnx.wait_task_completion(edge_remove)
|
39
|
+
end
|
40
|
+
|
41
|
+
env[:ui].info('Destroying vApp...')
|
42
|
+
vapp_delete_task = cnx.delete_vapp(vapp_id)
|
43
|
+
@logger.debug("vApp Delete task id #{vapp_delete_task}")
|
44
|
+
cnx.wait_task_completion(vapp_delete_task)
|
45
|
+
|
46
|
+
env[:machine].id = nil
|
47
|
+
env[:machine].vappid = nil
|
48
|
+
|
49
|
+
@app.call env
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloud
|
3
|
+
module Action
|
4
|
+
class DestroyVM
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_vcloud::action::destroy_vm')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
cfg = env[:machine].provider_config
|
12
|
+
cnx = cfg.vcloud_cnx.driver
|
13
|
+
vapp_id = env[:machine].get_vapp_id
|
14
|
+
vm_id = env[:machine].id
|
15
|
+
|
16
|
+
cfg.org = cnx.get_organization_by_name(cfg.org_name)
|
17
|
+
cfg.vdc_id = cnx.get_vdc_id_by_name(cfg.org, cfg.vdc_name)
|
18
|
+
|
19
|
+
test_vapp = cnx.get_vapp(vapp_id)
|
20
|
+
|
21
|
+
@logger.debug(
|
22
|
+
"Number of VMs in the vApp: #{test_vapp[:vms_hash].count}"
|
23
|
+
)
|
24
|
+
|
25
|
+
env[:ui].info('Destroying VM...')
|
26
|
+
vm_delete_task = cnx.delete_vm(vm_id)
|
27
|
+
@logger.debug("VM Delete task id #{vm_delete_task}")
|
28
|
+
cnx.wait_task_completion(vm_delete_task)
|
29
|
+
|
30
|
+
env[:machine].id = nil
|
31
|
+
|
32
|
+
@app.call env
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -24,6 +24,7 @@ module VagrantPlugins
|
|
24
24
|
|
25
25
|
def forward_ports
|
26
26
|
ports = []
|
27
|
+
edge_ports = []
|
27
28
|
|
28
29
|
cfg = @env[:machine].provider_config
|
29
30
|
cnx = cfg.vcloud_cnx.driver
|
@@ -42,12 +43,6 @@ module VagrantPlugins
|
|
42
43
|
vm_info = vm[:vms_hash][vm_name.to_sym]
|
43
44
|
|
44
45
|
@env[:forwarded_ports].each do |fp|
|
45
|
-
# FIXME: Useless variable assignement 'message_attributes'
|
46
|
-
# (tsugliani)
|
47
|
-
message_attributes = {
|
48
|
-
:guest_port => fp.guest_port,
|
49
|
-
:host_port => fp.host_port
|
50
|
-
}
|
51
46
|
|
52
47
|
@env[:ui].info(
|
53
48
|
"Forwarding Ports: VM port #{fp.guest_port} -> " +
|
@@ -64,6 +59,8 @@ module VagrantPlugins
|
|
64
59
|
:nat_protocol => fp.protocol.upcase,
|
65
60
|
:vapp_scoped_local_id => vm_info[:vapp_scoped_local_id]
|
66
61
|
}
|
62
|
+
|
63
|
+
edge_ports << fp.host_port
|
67
64
|
end
|
68
65
|
|
69
66
|
if !ports.empty?
|
@@ -89,8 +86,36 @@ module VagrantPlugins
|
|
89
86
|
raise Errors::ComposeVAppError, :message => wait[:errormsg]
|
90
87
|
end
|
91
88
|
|
92
|
-
end
|
93
89
|
|
90
|
+
if cfg.vdc_edge_gateway_ip && \
|
91
|
+
cfg.vdc_edge_gateway && \
|
92
|
+
cfg.network_bridge.nil?
|
93
|
+
|
94
|
+
|
95
|
+
edge_ports.each do |port|
|
96
|
+
@env[:ui].info(
|
97
|
+
"Creating NAT rules on [#{cfg.vdc_edge_gateway}] " +
|
98
|
+
"for IP [#{cfg.vdc_edge_gateway_ip}] port #{port}."
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Add the vShield Edge Gateway rules
|
103
|
+
add_ports = cnx.add_edge_gateway_rules(
|
104
|
+
cfg.vdc_edge_gateway,
|
105
|
+
cfg.vdc_id,
|
106
|
+
cfg.vdc_edge_gateway_ip,
|
107
|
+
vapp_id,
|
108
|
+
edge_ports
|
109
|
+
)
|
110
|
+
|
111
|
+
wait = cnx.wait_task_completion(add_ports)
|
112
|
+
|
113
|
+
if !wait[:errormsg].nil?
|
114
|
+
raise Errors::ComposeVAppError, :message => wait[:errormsg]
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
94
119
|
end
|
95
120
|
end
|
96
121
|
end
|
@@ -42,67 +42,103 @@ module VagrantPlugins
|
|
42
42
|
cnx = cfg.vcloud_cnx.driver
|
43
43
|
vapp_id = env[:machine].get_vapp_id
|
44
44
|
|
45
|
+
@logger.debug('Getting VM info...')
|
46
|
+
vm_name = env[:machine].name
|
47
|
+
vm = cnx.get_vapp(vapp_id)
|
48
|
+
vm_info = vm[:vms_hash][vm_name.to_sym]
|
49
|
+
|
50
|
+
@logger.debug('Getting edge gateway port forwarding rules...')
|
51
|
+
edge_gateway_rules = cnx.get_edge_gateway_rules(cfg.vdc_edge_gateway,
|
52
|
+
cfg.vdc_id)
|
53
|
+
edge_dnat_rules = edge_gateway_rules.select {|r| (r[:rule_type] == 'DNAT')}
|
54
|
+
edge_ports_in_use = edge_dnat_rules.map{|r| r[:original_port].to_i}.to_set
|
55
|
+
|
45
56
|
@logger.debug('Getting port forwarding rules...')
|
46
|
-
|
57
|
+
vapp_nat_rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
|
58
|
+
ports_in_use = vapp_nat_rules.map{|r| r[:nat_external_port].to_i}.to_set
|
59
|
+
|
60
|
+
# merge the vapp ports and the edge gateway ports together, all are in use
|
61
|
+
ports_in_use = ports_in_use | edge_ports_in_use
|
47
62
|
|
48
63
|
# Pass two, detect/handle any collisions
|
49
64
|
with_forwarded_ports(env) do |options|
|
50
65
|
guest_port = options[:guest]
|
51
66
|
host_port = options[:host]
|
52
67
|
|
53
|
-
#
|
54
|
-
if
|
55
|
-
|
56
|
-
raise Errors::ForwardPortCollision,
|
57
|
-
:guest_port => guest_port.to_s,
|
58
|
-
:host_port => host_port.to_s
|
59
|
-
end
|
60
|
-
|
61
|
-
@logger.info("Attempting to repair FP collision: #{host_port}")
|
68
|
+
# Find if there already is a DNAT rule to this vApp
|
69
|
+
if r = edge_dnat_rules.find { |rule| (rule[:translated_ip] == vm_info[:ip] &&
|
70
|
+
rule[:translated_port] == guest_port.to_s) }
|
62
71
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
72
|
+
@logger.info(
|
73
|
+
"Found existing edge gateway port forwarding rule #r[:original_port] to #{guest_port}"
|
74
|
+
)
|
75
|
+
options[:already_exists_on_edge] = true
|
76
|
+
end
|
68
77
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
78
|
+
# Find if there already is a NAT rule to guest_port of this VM
|
79
|
+
if r = vapp_nat_rules.find { |rule| (rule[:vapp_scoped_local_id] == vm_info[:vapp_scoped_local_id] &&
|
80
|
+
rule[:nat_internal_port] == guest_port.to_s) }
|
81
|
+
host_port = r[:nat_external_port].to_i
|
82
|
+
@logger.info(
|
83
|
+
"Found existing port forwarding rule #{host_port} to #{guest_port}"
|
84
|
+
)
|
85
|
+
options[:host] = host_port
|
86
|
+
options[:already_exists] = true
|
87
|
+
else
|
88
|
+
# If the port is open (listening for TCP connections)
|
89
|
+
if ports_in_use.include?(host_port)
|
90
|
+
if !options[:auto_correct]
|
91
|
+
raise Errors::ForwardPortCollision,
|
92
|
+
:guest_port => guest_port.to_s,
|
93
|
+
:host_port => host_port.to_s
|
76
94
|
end
|
77
95
|
|
78
|
-
|
79
|
-
|
80
|
-
|
96
|
+
@logger.info("Attempting to repair FP collision: #{host_port}")
|
97
|
+
|
98
|
+
repaired_port = nil
|
99
|
+
while !usable_ports.empty?
|
100
|
+
# Attempt to repair the forwarded port
|
101
|
+
repaired_port = usable_ports.to_a.sort[0]
|
102
|
+
usable_ports.delete(repaired_port)
|
103
|
+
|
104
|
+
# If the port is in use, then we can't use this either...
|
105
|
+
if ports_in_use.include?(repaired_port)
|
106
|
+
@logger.info(
|
107
|
+
"Repaired port also in use: #{repaired_port}." +
|
108
|
+
'Trying another...'
|
109
|
+
)
|
110
|
+
next
|
111
|
+
end
|
112
|
+
|
113
|
+
# We have a port so break out
|
114
|
+
break
|
115
|
+
end
|
81
116
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
117
|
+
# If we have no usable ports then we can't repair
|
118
|
+
if !repaired_port && usable_ports.empty?
|
119
|
+
raise Errors::ForwardPortAutolistEmpty,
|
120
|
+
:vm_name => env[:machine].name,
|
121
|
+
:guest_port => guest_port.to_s,
|
122
|
+
:host_port => host_port.to_s
|
123
|
+
end
|
89
124
|
|
90
|
-
|
91
|
-
|
125
|
+
# Modify the args in place
|
126
|
+
options[:host] = repaired_port
|
92
127
|
|
93
|
-
|
94
|
-
|
95
|
-
|
128
|
+
@logger.info(
|
129
|
+
"Repaired FP collision: #{host_port} to #{repaired_port}"
|
130
|
+
)
|
96
131
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
132
|
+
# Notify the user
|
133
|
+
env[:ui].info(
|
134
|
+
I18n.t(
|
135
|
+
'vagrant.actions.vm.forward_ports.fixed_collision',
|
136
|
+
:host_port => host_port.to_s,
|
137
|
+
:guest_port => guest_port.to_s,
|
138
|
+
:new_port => repaired_port.to_s
|
139
|
+
)
|
104
140
|
)
|
105
|
-
|
141
|
+
end
|
106
142
|
end
|
107
143
|
end
|
108
144
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloud
|
3
|
+
module Action
|
4
|
+
class IsLastVM
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
cfg = env[:machine].provider_config
|
11
|
+
cnx = cfg.vcloud_cnx.driver
|
12
|
+
|
13
|
+
vapp_id = env[:machine].get_vapp_id
|
14
|
+
|
15
|
+
test_vapp = cnx.get_vapp(vapp_id)
|
16
|
+
|
17
|
+
if test_vapp[:vms_hash].count == 1
|
18
|
+
# Set the result to be true if the machine is running.
|
19
|
+
env[:result] = true
|
20
|
+
else
|
21
|
+
env[:result] = false
|
22
|
+
end
|
23
|
+
|
24
|
+
# Call the next if we have one (but we shouldn't, since this
|
25
|
+
# middleware is built to run with the Call-type middlewares)
|
26
|
+
@app.call(env)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -20,23 +20,10 @@ module VagrantPlugins
|
|
20
20
|
"Number of VMs in the vApp: #{test_vapp[:vms_hash].count}"
|
21
21
|
)
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
vapp_stop_task = cnx.poweroff_vapp(vapp_id)
|
28
|
-
vapp_stop_wait = cnx.wait_task_completion(vapp_stop_task)
|
29
|
-
|
30
|
-
unless vapp_stop_wait[:errormsg].nil?
|
31
|
-
fail Errors::StopVAppError, :message => vapp_stop_wait[:errormsg]
|
32
|
-
end
|
33
|
-
|
34
|
-
else
|
35
|
-
# Poweroff VM
|
36
|
-
env[:ui].info('Powering off VM...')
|
37
|
-
task_id = cnx.poweroff_vm(vm_id)
|
38
|
-
cnx.wait_task_completion(task_id)
|
39
|
-
end
|
23
|
+
# Poweroff VM
|
24
|
+
env[:ui].info('Powering off VM...')
|
25
|
+
task_id = cnx.poweroff_vm(vm_id)
|
26
|
+
cnx.wait_task_completion(task_id)
|
40
27
|
|
41
28
|
@app.call env
|
42
29
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloud
|
3
|
+
module Action
|
4
|
+
class PowerOffVApp
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_vcloud::action::poweroff_vapp')
|
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
|
+
|
16
|
+
test_vapp = cnx.get_vapp(vapp_id)
|
17
|
+
|
18
|
+
@logger.debug(
|
19
|
+
"Number of VMs in the vApp: #{test_vapp[:vms_hash].count}"
|
20
|
+
)
|
21
|
+
|
22
|
+
# this is a helper to get vapp_edge_ip into cache for later destroy
|
23
|
+
# of edge gateway rules
|
24
|
+
vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
|
25
|
+
|
26
|
+
# Poweroff vApp
|
27
|
+
env[:ui].info('Single VM left in the vApp, Powering off vApp...')
|
28
|
+
vapp_stop_task = cnx.poweroff_vapp(vapp_id)
|
29
|
+
vapp_stop_wait = cnx.wait_task_completion(vapp_stop_task)
|
30
|
+
|
31
|
+
unless vapp_stop_wait[:errormsg].nil?
|
32
|
+
fail Errors::StopVAppError, :message => vapp_stop_wait[:errormsg]
|
33
|
+
end
|
34
|
+
|
35
|
+
@app.call env
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -12,70 +12,12 @@ module VagrantPlugins
|
|
12
12
|
|
13
13
|
cfg = env[:machine].provider_config
|
14
14
|
cnx = cfg.vcloud_cnx.driver
|
15
|
-
vapp_id = env[:machine].get_vapp_id
|
16
15
|
|
17
|
-
env[:ui].info('
|
18
|
-
|
19
|
-
if cfg.network_bridge.nil?
|
20
|
-
test_ip = cnx.get_vapp_edge_public_ip(vapp_id)
|
21
|
-
end
|
16
|
+
env[:ui].info('Powering on VM...')
|
22
17
|
|
23
18
|
poweron_vm = cnx.poweron_vm(env[:machine].id)
|
24
19
|
cnx.wait_task_completion(poweron_vm)
|
25
20
|
|
26
|
-
if test_ip.nil? && \
|
27
|
-
cfg.vdc_edge_gateway_ip && \
|
28
|
-
cfg.vdc_edge_gateway && \
|
29
|
-
cfg.network_bridge.nil?
|
30
|
-
|
31
|
-
@logger.debug(
|
32
|
-
'This is our first boot, we should map ports on the ' \
|
33
|
-
'Organization vDC vShield Edge Gateway!'
|
34
|
-
)
|
35
|
-
|
36
|
-
### TMP FIX: tsugliani
|
37
|
-
### We need to verify the vShield Edge Gateway rules don't already
|
38
|
-
### exist.
|
39
|
-
### Removing any rule previously set for that same source IP
|
40
|
-
|
41
|
-
# ----
|
42
|
-
if cfg.vdc_edge_gateway_ip && cfg.vdc_edge_gateway
|
43
|
-
env[:ui].info(
|
44
|
-
"Removing NAT rules on [#{cfg.vdc_edge_gateway}] " +
|
45
|
-
"for IP [#{cfg.vdc_edge_gateway_ip}]."
|
46
|
-
)
|
47
|
-
@logger.debug(
|
48
|
-
'Cleaning possible conflicting Edge Gateway rules - ' +
|
49
|
-
"Organization vDC id: #{cfg.vdc_id}"
|
50
|
-
)
|
51
|
-
|
52
|
-
edge_remove = cnx.remove_edge_gateway_rules(
|
53
|
-
cfg.vdc_edge_gateway,
|
54
|
-
cfg.vdc_id,
|
55
|
-
cfg.vdc_edge_gateway_ip,
|
56
|
-
vapp_id
|
57
|
-
)
|
58
|
-
cnx.wait_task_completion(edge_remove)
|
59
|
-
end
|
60
|
-
# ----
|
61
|
-
|
62
|
-
env[:ui].info(
|
63
|
-
"Creating NAT rules on [#{cfg.vdc_edge_gateway}] " +
|
64
|
-
"for IP [#{cfg.vdc_edge_gateway_ip}]."
|
65
|
-
)
|
66
|
-
|
67
|
-
# Set the vShield Edge Gateway rules
|
68
|
-
edge_map = cnx.set_edge_gateway_rules(
|
69
|
-
cfg.vdc_edge_gateway,
|
70
|
-
cfg.vdc_id,
|
71
|
-
cfg.vdc_edge_gateway_ip,
|
72
|
-
vapp_id
|
73
|
-
)
|
74
|
-
|
75
|
-
# Wait for task to complete.
|
76
|
-
cnx.wait_task_completion(edge_map)
|
77
|
-
end
|
78
|
-
|
79
21
|
@app.call(env)
|
80
22
|
end
|
81
23
|
end
|
@@ -77,7 +77,7 @@ module VagrantPlugins
|
|
77
77
|
|
78
78
|
# on windows rsync.exe requires cygdrive-style paths
|
79
79
|
if Vagrant::Util::Platform.windows?
|
80
|
-
hostpath = hostpath.gsub(/^(\w):/) { "/cygdrive
|
80
|
+
hostpath = hostpath.gsub(/^(\w):/) { "/cygdrive/#{$1}" }
|
81
81
|
end
|
82
82
|
|
83
83
|
env[:ui].info(
|
@@ -53,14 +53,14 @@ module VagrantPlugins
|
|
53
53
|
b2.use MessageAlreadyRunning
|
54
54
|
next
|
55
55
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
b3.use action_boot
|
56
|
+
end
|
57
|
+
b.use Call, IsPaused do |env, b2|
|
58
|
+
if env[:result]
|
59
|
+
b3.use Resume
|
60
|
+
next
|
62
61
|
end
|
63
62
|
end
|
63
|
+
b.use PowerOn
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -105,12 +105,19 @@ module VagrantPlugins
|
|
105
105
|
b2.use Call, IsRunning do |env2, b3|
|
106
106
|
# If the VM is running, must power off
|
107
107
|
b3.use action_halt if env2[:result]
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
108
|
+
end
|
109
|
+
b2.use Call, IsLastVM do |env2, b3|
|
110
|
+
if env2[:result]
|
111
|
+
# Check if the network is bridged
|
112
|
+
b3.use Call, IsBridged do |env3, b4|
|
113
|
+
# if it's not, delete port forwardings.
|
114
|
+
b4.use UnmapPortForwardings unless env3[:bridged_network]
|
115
|
+
end
|
116
|
+
b3.use PowerOffVApp
|
117
|
+
b3.use DestroyVApp
|
118
|
+
else
|
119
|
+
b3.use DestroyVM
|
112
120
|
end
|
113
|
-
b3.use Destroy
|
114
121
|
end
|
115
122
|
else
|
116
123
|
b2.use MessageWillNotDestroy
|
@@ -191,13 +198,15 @@ module VagrantPlugins
|
|
191
198
|
b2.use HandleBox unless env[:result]
|
192
199
|
end
|
193
200
|
b.use ConnectVCloud
|
201
|
+
b.use InventoryCheck
|
194
202
|
b.use Call, IsCreated do |env, b2|
|
195
|
-
|
196
|
-
b2.use
|
203
|
+
if env[:result]
|
204
|
+
b2.use action_start
|
205
|
+
else
|
197
206
|
b2.use BuildVApp
|
207
|
+
b2.use action_boot
|
198
208
|
end
|
199
209
|
end
|
200
|
-
b.use action_start
|
201
210
|
b.use DisconnectVCloud
|
202
211
|
end
|
203
212
|
end
|
@@ -210,8 +219,10 @@ module VagrantPlugins
|
|
210
219
|
action_root.join('build_vapp')
|
211
220
|
autoload :ConnectVCloud,
|
212
221
|
action_root.join('connect_vcloud')
|
213
|
-
autoload :
|
214
|
-
action_root.join('
|
222
|
+
autoload :DestroyVM,
|
223
|
+
action_root.join('destroy_vm')
|
224
|
+
autoload :DestroyVApp,
|
225
|
+
action_root.join('destroy_vapp')
|
215
226
|
autoload :DisconnectVCloud,
|
216
227
|
action_root.join('disconnect_vcloud')
|
217
228
|
autoload :ForwardPorts,
|
@@ -228,6 +239,8 @@ module VagrantPlugins
|
|
228
239
|
action_root.join('is_paused')
|
229
240
|
autoload :IsRunning,
|
230
241
|
action_root.join('is_running')
|
242
|
+
autoload :IsLastVM,
|
243
|
+
action_root.join('is_last_vm')
|
231
244
|
autoload :MessageAlreadyRunning,
|
232
245
|
action_root.join('message_already_running')
|
233
246
|
autoload :MessageCannotSuspend,
|
@@ -238,6 +251,8 @@ module VagrantPlugins
|
|
238
251
|
action_root.join('message_will_not_destroy')
|
239
252
|
autoload :PowerOff,
|
240
253
|
action_root.join('power_off')
|
254
|
+
autoload :PowerOffVApp,
|
255
|
+
action_root.join('power_off_vapp')
|
241
256
|
autoload :PowerOn,
|
242
257
|
action_root.join('power_on')
|
243
258
|
autoload :ReadSSHInfo,
|
@@ -118,35 +118,44 @@ module VagrantPlugins
|
|
118
118
|
network_table << :separator
|
119
119
|
|
120
120
|
# Fetching Destination NAT Rules for each vApp/Edge/VM/Mapping
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
+
]
|
150
159
|
end
|
151
160
|
end
|
152
161
|
end
|
@@ -93,6 +93,12 @@ module VagrantPlugins
|
|
93
93
|
# @return [String]
|
94
94
|
attr_accessor :vdc_edge_gateway_ip
|
95
95
|
|
96
|
+
# Name of the vApp prefix [optional, defaults to 'Vagrant' ]
|
97
|
+
#
|
98
|
+
# @return [String]
|
99
|
+
attr_accessor :vapp_prefix
|
100
|
+
|
101
|
+
|
96
102
|
##
|
97
103
|
## vCloud Director config runtime values
|
98
104
|
##
|
@@ -309,7 +309,7 @@ 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 #{url}"
|
312
|
+
ap "SEND #{params['method'].upcase} #{url}"
|
313
313
|
if payload
|
314
314
|
payload_xml = Nokogiri.XML(payload)
|
315
315
|
ap payload_xml
|
@@ -39,6 +39,7 @@ module VagrantPlugins
|
|
39
39
|
@org_name = org_name
|
40
40
|
@api_version = '5.1'
|
41
41
|
@id = nil
|
42
|
+
@cached_vapp_edge_public_ips = {}
|
42
43
|
end
|
43
44
|
|
44
45
|
##
|
@@ -630,19 +631,6 @@ module VagrantPlugins
|
|
630
631
|
task_id
|
631
632
|
end
|
632
633
|
|
633
|
-
##
|
634
|
-
# Boot a given vm
|
635
|
-
def poweron_vm(vm_id)
|
636
|
-
params = {
|
637
|
-
'method' => :post,
|
638
|
-
'command' => "/vApp/vm-#{vm_id}/power/action/powerOn"
|
639
|
-
}
|
640
|
-
|
641
|
-
_response, headers = send_request(params)
|
642
|
-
task_id = headers['Location'].gsub("#{@api_url}/task/", '')
|
643
|
-
task_id
|
644
|
-
end
|
645
|
-
|
646
634
|
##
|
647
635
|
# Create a catalog in an organization
|
648
636
|
def create_catalog(org_id, catalog_name, catalog_description)
|
@@ -1091,46 +1079,6 @@ module VagrantPlugins
|
|
1091
1079
|
nat_rules
|
1092
1080
|
end
|
1093
1081
|
|
1094
|
-
##
|
1095
|
-
# Get vApp port forwarding rules external ports used and returns a set
|
1096
|
-
# instead of an HASH.
|
1097
|
-
#
|
1098
|
-
# - vapp_id: id of the vApp
|
1099
|
-
def get_vapp_port_forwarding_external_ports(vapp_id)
|
1100
|
-
params = {
|
1101
|
-
'method' => :get,
|
1102
|
-
'command' => "/vApp/vapp-#{vapp_id}/networkConfigSection"
|
1103
|
-
}
|
1104
|
-
|
1105
|
-
response, _headers = send_request(params)
|
1106
|
-
|
1107
|
-
# FIXME: this will return nil if the vApp uses multiple vApp Networks
|
1108
|
-
# with Edge devices in natRouted/portForwarding mode.
|
1109
|
-
config = response.css(
|
1110
|
-
'NetworkConfigSection/NetworkConfig/Configuration'
|
1111
|
-
)
|
1112
|
-
fence_mode = config.css('/FenceMode').text
|
1113
|
-
nat_type = config.css('/Features/NatService/NatType').text
|
1114
|
-
|
1115
|
-
unless fence_mode == 'natRouted'
|
1116
|
-
raise InvalidStateError,
|
1117
|
-
'Invalid request because FenceMode must be natRouted.'
|
1118
|
-
end
|
1119
|
-
|
1120
|
-
unless nat_type == 'portForwarding'
|
1121
|
-
raise InvalidStateError,
|
1122
|
-
'Invalid request because NatType must be portForwarding.'
|
1123
|
-
end
|
1124
|
-
|
1125
|
-
nat_rules = Set.new
|
1126
|
-
config.css('/Features/NatService/NatRule').each do |rule|
|
1127
|
-
# portforwarding rules information
|
1128
|
-
vm_rule = rule.css('VmRule')
|
1129
|
-
nat_rules.add(vm_rule.css('ExternalPort').text.to_i)
|
1130
|
-
end
|
1131
|
-
nat_rules
|
1132
|
-
end
|
1133
|
-
|
1134
1082
|
##
|
1135
1083
|
# Find an edge gateway id from the edge name and vdc_id
|
1136
1084
|
#
|
@@ -1217,195 +1165,6 @@ module VagrantPlugins
|
|
1217
1165
|
end
|
1218
1166
|
end
|
1219
1167
|
|
1220
|
-
##
|
1221
|
-
# Set Org Edge port forwarding and firewall rules
|
1222
|
-
#
|
1223
|
-
# - vapp_id: id of the vapp to be modified
|
1224
|
-
# - network_name: name of the vapp network to be modified
|
1225
|
-
# - config: hash with network configuration specifications,
|
1226
|
-
# must contain an array inside :nat_rules with the nat rules
|
1227
|
-
# to be applied.
|
1228
|
-
def set_edge_gateway_rules(edge_gateway_name, vdc_id, edge_gateway_ip, vapp_id)
|
1229
|
-
edge_vapp_ip = get_vapp_edge_public_ip(vapp_id)
|
1230
|
-
edge_network_id = find_edge_gateway_network(
|
1231
|
-
edge_gateway_name,
|
1232
|
-
vdc_id,
|
1233
|
-
edge_gateway_ip
|
1234
|
-
)
|
1235
|
-
edge_gateway_id = find_edge_gateway_id(edge_gateway_name, vdc_id)
|
1236
|
-
|
1237
|
-
### FIXME: tsugliani
|
1238
|
-
# We need to check the previous variables, especially (edge_*)
|
1239
|
-
# which can fail in some *weird* situations.
|
1240
|
-
params = {
|
1241
|
-
'method' => :get,
|
1242
|
-
'command' => "/admin/edgeGateway/#{edge_gateway_id}"
|
1243
|
-
}
|
1244
|
-
|
1245
|
-
response, _headers = send_request(params)
|
1246
|
-
|
1247
|
-
interesting = response.css(
|
1248
|
-
'EdgeGateway Configuration EdgeGatewayServiceConfiguration'
|
1249
|
-
)
|
1250
|
-
|
1251
|
-
nat_rule_1 = Nokogiri::XML::Node.new 'NatRule', response
|
1252
|
-
rule_type = Nokogiri::XML::Node.new 'RuleType', response
|
1253
|
-
rule_type.content = 'DNAT'
|
1254
|
-
nat_rule_1.add_child rule_type
|
1255
|
-
|
1256
|
-
is_enabled = Nokogiri::XML::Node.new 'IsEnabled', response
|
1257
|
-
is_enabled.content = 'true'
|
1258
|
-
nat_rule_1.add_child is_enabled
|
1259
|
-
|
1260
|
-
gateway_nat_rule = Nokogiri::XML::Node.new 'GatewayNatRule',
|
1261
|
-
response
|
1262
|
-
nat_rule_1.add_child gateway_nat_rule
|
1263
|
-
|
1264
|
-
interface = Nokogiri::XML::Node.new 'Interface', response
|
1265
|
-
interface['href'] = edge_network_id
|
1266
|
-
|
1267
|
-
gateway_nat_rule.add_child interface
|
1268
|
-
|
1269
|
-
original_ip = Nokogiri::XML::Node.new 'OriginalIp', response
|
1270
|
-
original_ip.content = edge_gateway_ip
|
1271
|
-
gateway_nat_rule.add_child original_ip
|
1272
|
-
|
1273
|
-
original_port = Nokogiri::XML::Node.new 'OriginalPort', response
|
1274
|
-
original_port.content = 'any'
|
1275
|
-
gateway_nat_rule.add_child original_port
|
1276
|
-
|
1277
|
-
translated_ip = Nokogiri::XML::Node.new 'TranslatedIp', response
|
1278
|
-
translated_ip.content = edge_vapp_ip
|
1279
|
-
gateway_nat_rule.add_child translated_ip
|
1280
|
-
|
1281
|
-
translated_port = Nokogiri::XML::Node.new 'TranslatedPort',
|
1282
|
-
response
|
1283
|
-
translated_port.content = 'any'
|
1284
|
-
gateway_nat_rule.add_child translated_port
|
1285
|
-
|
1286
|
-
protocol = Nokogiri::XML::Node.new 'Protocol', response
|
1287
|
-
protocol.content = 'any'
|
1288
|
-
gateway_nat_rule.add_child protocol
|
1289
|
-
|
1290
|
-
# FIXME: frapposelli/tsugliani we should be able to remove this
|
1291
|
-
# FIXME: test this against a vCloud Director 5.1.x installation
|
1292
|
-
# icmpSubType = Nokogiri::XML::Node.new 'IcmpSubType', response
|
1293
|
-
# icmpSubType.content = "any"
|
1294
|
-
# gatewayNatRule.add_child icmpSubType
|
1295
|
-
|
1296
|
-
nat_rule_2 = Nokogiri::XML::Node.new 'NatRule', response
|
1297
|
-
|
1298
|
-
rule_type = Nokogiri::XML::Node.new 'RuleType', response
|
1299
|
-
rule_type.content = 'SNAT'
|
1300
|
-
nat_rule_2.add_child rule_type
|
1301
|
-
|
1302
|
-
is_enabled = Nokogiri::XML::Node.new 'IsEnabled', response
|
1303
|
-
is_enabled.content = 'true'
|
1304
|
-
nat_rule_2.add_child is_enabled
|
1305
|
-
|
1306
|
-
gateway_nat_rule = Nokogiri::XML::Node.new 'GatewayNatRule',
|
1307
|
-
response
|
1308
|
-
nat_rule_2.add_child gateway_nat_rule
|
1309
|
-
|
1310
|
-
interface = Nokogiri::XML::Node.new 'Interface', response
|
1311
|
-
interface['href'] = edge_network_id
|
1312
|
-
|
1313
|
-
gateway_nat_rule.add_child interface
|
1314
|
-
|
1315
|
-
original_ip = Nokogiri::XML::Node.new 'OriginalIp', response
|
1316
|
-
original_ip.content = edge_vapp_ip
|
1317
|
-
gateway_nat_rule.add_child original_ip
|
1318
|
-
|
1319
|
-
translated_ip = Nokogiri::XML::Node.new 'TranslatedIp', response
|
1320
|
-
translated_ip.content = edge_gateway_ip
|
1321
|
-
gateway_nat_rule.add_child translated_ip
|
1322
|
-
|
1323
|
-
protocol = Nokogiri::XML::Node.new 'Protocol', response
|
1324
|
-
protocol.content = 'any'
|
1325
|
-
gateway_nat_rule.add_child protocol
|
1326
|
-
|
1327
|
-
firewall_rule_1 = Nokogiri::XML::Node.new 'FirewallRule', response
|
1328
|
-
|
1329
|
-
is_enabled = Nokogiri::XML::Node.new 'IsEnabled', response
|
1330
|
-
is_enabled.content = 'true'
|
1331
|
-
firewall_rule_1.add_child is_enabled
|
1332
|
-
|
1333
|
-
description = Nokogiri::XML::Node.new 'Description', response
|
1334
|
-
description.content = 'Allow Vagrant Communications'
|
1335
|
-
firewall_rule_1.add_child description
|
1336
|
-
|
1337
|
-
policy = Nokogiri::XML::Node.new 'Policy', response
|
1338
|
-
policy.content = 'allow'
|
1339
|
-
firewall_rule_1.add_child policy
|
1340
|
-
|
1341
|
-
protocols = Nokogiri::XML::Node.new 'Protocols', response
|
1342
|
-
firewall_rule_1.add_child protocols
|
1343
|
-
|
1344
|
-
any = Nokogiri::XML::Node.new 'Any', response
|
1345
|
-
any.content = 'true'
|
1346
|
-
protocols.add_child any
|
1347
|
-
|
1348
|
-
destination_port_range =
|
1349
|
-
Nokogiri::XML::Node.new 'DestinationPortRange', response
|
1350
|
-
destination_port_range.content = 'Any'
|
1351
|
-
firewall_rule_1.add_child destination_port_range
|
1352
|
-
|
1353
|
-
destination_ip = Nokogiri::XML::Node.new 'DestinationIp', response
|
1354
|
-
destination_ip.content = edge_gateway_ip
|
1355
|
-
firewall_rule_1.add_child destination_ip
|
1356
|
-
source_port_range = Nokogiri::XML::Node.new 'SourcePortRange',
|
1357
|
-
|
1358
|
-
response
|
1359
|
-
source_port_range.content = 'Any'
|
1360
|
-
firewall_rule_1.add_child source_port_range
|
1361
|
-
|
1362
|
-
source_ip = Nokogiri::XML::Node.new 'SourceIp', response
|
1363
|
-
source_ip.content = 'Any'
|
1364
|
-
firewall_rule_1.add_child source_ip
|
1365
|
-
|
1366
|
-
enable_logging = Nokogiri::XML::Node.new 'EnableLogging', response
|
1367
|
-
enable_logging.content = 'false'
|
1368
|
-
firewall_rule_1.add_child enable_logging
|
1369
|
-
|
1370
|
-
# FIXME: Think about adding an outgoing rule
|
1371
|
-
# (which could not be available)
|
1372
|
-
# by default in all cases vapp_edge_ip -> any
|
1373
|
-
# Especially for provisionners using apt-get, internet, etc...
|
1374
|
-
# (tsugliani)
|
1375
|
-
|
1376
|
-
builder = Nokogiri::XML::Builder.new
|
1377
|
-
builder << interesting
|
1378
|
-
|
1379
|
-
set_edge_rules = Nokogiri::XML(builder.to_xml) do |config|
|
1380
|
-
config.default_xml.noblanks
|
1381
|
-
end
|
1382
|
-
|
1383
|
-
nat_rules = set_edge_rules.at_css('NatService')
|
1384
|
-
nat_rules << nat_rule_1
|
1385
|
-
nat_rules << nat_rule_2
|
1386
|
-
|
1387
|
-
fw_rules = set_edge_rules.at_css('FirewallService')
|
1388
|
-
fw_rules << firewall_rule_1
|
1389
|
-
|
1390
|
-
xml = set_edge_rules.at_css 'EdgeGatewayServiceConfiguration'
|
1391
|
-
xml['xmlns'] = 'http://www.vmware.com/vcloud/v1.5'
|
1392
|
-
|
1393
|
-
params = {
|
1394
|
-
'method' => :post,
|
1395
|
-
'command' => "/admin/edgeGateway/#{edge_gateway_id}/action/" +
|
1396
|
-
'configureServices'
|
1397
|
-
}
|
1398
|
-
|
1399
|
-
_response, headers = send_request(
|
1400
|
-
params,
|
1401
|
-
set_edge_rules.to_xml,
|
1402
|
-
'application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml'
|
1403
|
-
)
|
1404
|
-
|
1405
|
-
task_id = headers['Location'].gsub("#{@api_url}/task/", '')
|
1406
|
-
task_id
|
1407
|
-
end
|
1408
|
-
|
1409
1168
|
##
|
1410
1169
|
# Get Org Edge port forwarding and firewall rules
|
1411
1170
|
#
|
@@ -1541,6 +1300,145 @@ module VagrantPlugins
|
|
1541
1300
|
task_id
|
1542
1301
|
end
|
1543
1302
|
|
1303
|
+
#
|
1304
|
+
# Add Org Edge port forwarding and firewall rules
|
1305
|
+
#
|
1306
|
+
# - vapp_id: id of the vapp to be modified
|
1307
|
+
# - network_name: name of the vapp network to be modified
|
1308
|
+
# - ports: array with port numbers to forward 1:1 to vApp.
|
1309
|
+
def add_edge_gateway_rules(edge_gateway_name, vdc_id, edge_gateway_ip, vapp_id, ports)
|
1310
|
+
edge_vapp_ip = get_vapp_edge_public_ip(vapp_id)
|
1311
|
+
edge_network_id = find_edge_gateway_network(
|
1312
|
+
edge_gateway_name,
|
1313
|
+
vdc_id,
|
1314
|
+
edge_gateway_ip
|
1315
|
+
)
|
1316
|
+
edge_gateway_id = find_edge_gateway_id(edge_gateway_name, vdc_id)
|
1317
|
+
|
1318
|
+
### FIXME: tsugliani
|
1319
|
+
# We need to check the previous variables, especially (edge_*)
|
1320
|
+
# which can fail in some *weird* situations.
|
1321
|
+
params = {
|
1322
|
+
'method' => :get,
|
1323
|
+
'command' => "/admin/edgeGateway/#{edge_gateway_id}"
|
1324
|
+
}
|
1325
|
+
|
1326
|
+
response, _headers = send_request(params)
|
1327
|
+
|
1328
|
+
interesting = response.css(
|
1329
|
+
'EdgeGateway Configuration EdgeGatewayServiceConfiguration'
|
1330
|
+
)
|
1331
|
+
|
1332
|
+
add_snat_rule = true
|
1333
|
+
interesting.css('NatService NatRule').each do |node|
|
1334
|
+
if node.css('RuleType').text == 'DNAT' &&
|
1335
|
+
node.css('GatewayNatRule/OriginalIp').text == edge_gateway_ip &&
|
1336
|
+
node.css('GatewayNatRule/TranslatedIp').text == edge_vapp_ip &&
|
1337
|
+
node.css('GatewayNatRule/OriginalPort').text == 'any'
|
1338
|
+
# remove old DNAT rule any -> any from older vagrant-vcloud versions
|
1339
|
+
node.remove
|
1340
|
+
end
|
1341
|
+
if node.css('RuleType').text == 'SNAT' &&
|
1342
|
+
node.css('GatewayNatRule/OriginalIp').text == edge_vapp_ip &&
|
1343
|
+
node.css('GatewayNatRule/TranslatedIp').text == edge_gateway_ip
|
1344
|
+
add_snat_rule = false
|
1345
|
+
end
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
add_firewall_rule = true
|
1349
|
+
interesting.css('FirewallService FirewallRule').each do |node|
|
1350
|
+
if node.css('Port').text == '-1' &&
|
1351
|
+
node.css('DestinationIp').text == edge_gateway_ip &&
|
1352
|
+
node.css('DestinationPortRange').text == 'Any'
|
1353
|
+
add_firewall_rule = false
|
1354
|
+
end
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
builder = Nokogiri::XML::Builder.new
|
1358
|
+
builder << interesting
|
1359
|
+
|
1360
|
+
set_edge_rules = Nokogiri::XML(builder.to_xml) do |config|
|
1361
|
+
config.default_xml.noblanks
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
nat_rules = set_edge_rules.at_css('NatService')
|
1365
|
+
|
1366
|
+
# Add all DNAT port rules edge -> vApp for the given list
|
1367
|
+
ports.each do |port|
|
1368
|
+
nat_rule = Nokogiri::XML::Builder.new do |xml|
|
1369
|
+
xml.NatRule {
|
1370
|
+
xml.RuleType 'DNAT'
|
1371
|
+
xml.IsEnabled 'true'
|
1372
|
+
xml.GatewayNatRule {
|
1373
|
+
xml.Interface('href' => edge_network_id )
|
1374
|
+
xml.OriginalIp edge_gateway_ip
|
1375
|
+
xml.OriginalPort port
|
1376
|
+
xml.TranslatedIp edge_vapp_ip
|
1377
|
+
xml.TranslatedPort port
|
1378
|
+
xml.Protocol 'tcpudp'
|
1379
|
+
}
|
1380
|
+
}
|
1381
|
+
end
|
1382
|
+
nat_rules << nat_rule.doc.root.to_xml
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
if (add_snat_rule)
|
1386
|
+
snat_rule = Nokogiri::XML::Builder.new do |xml|
|
1387
|
+
xml.NatRule {
|
1388
|
+
xml.RuleType 'SNAT'
|
1389
|
+
xml.IsEnabled 'true'
|
1390
|
+
xml.GatewayNatRule {
|
1391
|
+
xml.Interface('href' => edge_network_id )
|
1392
|
+
xml.OriginalIp edge_vapp_ip
|
1393
|
+
xml.TranslatedIp edge_gateway_ip
|
1394
|
+
xml.Protocol 'any'
|
1395
|
+
}
|
1396
|
+
}
|
1397
|
+
end
|
1398
|
+
nat_rules << snat_rule.doc.root.to_xml
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
|
1402
|
+
if (add_firewall_rule)
|
1403
|
+
firewall_rule_1 = Nokogiri::XML::Builder.new do |xml|
|
1404
|
+
xml.FirewallRule {
|
1405
|
+
xml.IsEnabled 'true'
|
1406
|
+
xml.Description 'Allow Vagrant Communications'
|
1407
|
+
xml.Policy 'allow'
|
1408
|
+
xml.Protocols {
|
1409
|
+
xml.Any 'true'
|
1410
|
+
}
|
1411
|
+
xml.DestinationPortRange 'Any'
|
1412
|
+
xml.DestinationIp edge_gateway_ip
|
1413
|
+
xml.SourcePortRange 'Any'
|
1414
|
+
xml.SourceIp 'Any'
|
1415
|
+
xml.EnableLogging 'false'
|
1416
|
+
}
|
1417
|
+
end
|
1418
|
+
fw_rules = set_edge_rules.at_css('FirewallService')
|
1419
|
+
fw_rules << firewall_rule_1.doc.root.to_xml
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
xml = set_edge_rules.at_css 'EdgeGatewayServiceConfiguration'
|
1423
|
+
xml['xmlns'] = 'http://www.vmware.com/vcloud/v1.5'
|
1424
|
+
|
1425
|
+
params = {
|
1426
|
+
'method' => :post,
|
1427
|
+
'command' => "/admin/edgeGateway/#{edge_gateway_id}/action/" +
|
1428
|
+
'configureServices'
|
1429
|
+
}
|
1430
|
+
|
1431
|
+
_response, headers = send_request(
|
1432
|
+
params,
|
1433
|
+
set_edge_rules.to_xml,
|
1434
|
+
'application/vnd.vmware.admin.edgeGatewayServiceConfiguration+xml'
|
1435
|
+
)
|
1436
|
+
|
1437
|
+
task_id = headers['Location'].gsub("#{@api_url}/task/", '')
|
1438
|
+
task_id
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
|
1544
1442
|
##
|
1545
1443
|
# get vApp edge public IP from the vApp ID
|
1546
1444
|
# Only works when:
|
@@ -1550,6 +1448,8 @@ module VagrantPlugins
|
|
1550
1448
|
# This will be required to know how to connect to VMs behind the Edge
|
1551
1449
|
# device.
|
1552
1450
|
def get_vapp_edge_public_ip(vapp_id)
|
1451
|
+
return @cached_vapp_edge_public_ips[vapp_id] unless @cached_vapp_edge_public_ips[vapp_id].nil?
|
1452
|
+
|
1553
1453
|
# Check the network configuration section
|
1554
1454
|
params = {
|
1555
1455
|
'method' => :get,
|
@@ -1583,6 +1483,7 @@ module VagrantPlugins
|
|
1583
1483
|
if edge_ip == ''
|
1584
1484
|
return nil
|
1585
1485
|
else
|
1486
|
+
@cached_vapp_edge_public_ips[vapp_id] = edge_ip
|
1586
1487
|
return edge_ip
|
1587
1488
|
end
|
1588
1489
|
end
|
@@ -18,6 +18,9 @@ module VagrantPlugins
|
|
18
18
|
options = scoped_hash_override(options, :vcloud)
|
19
19
|
id = options[:id]
|
20
20
|
|
21
|
+
# skip forwarded rules already found in handle_nat_port_collisions
|
22
|
+
next if options[:already_exists]
|
23
|
+
|
21
24
|
mappings[host_port] =
|
22
25
|
Model::ForwardedPort.new(id, host_port, guest_port, options)
|
23
26
|
end
|
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.
|
4
|
+
version: 0.3.0
|
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-04-
|
12
|
+
date: 2014-04-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: i18n
|
@@ -201,13 +201,15 @@ files:
|
|
201
201
|
- lib/vagrant-vcloud/action/announce_ssh_exec.rb
|
202
202
|
- lib/vagrant-vcloud/action/build_vapp.rb
|
203
203
|
- lib/vagrant-vcloud/action/connect_vcloud.rb
|
204
|
-
- lib/vagrant-vcloud/action/
|
204
|
+
- lib/vagrant-vcloud/action/destroy_vapp.rb
|
205
|
+
- lib/vagrant-vcloud/action/destroy_vm.rb
|
205
206
|
- lib/vagrant-vcloud/action/disconnect_vcloud.rb
|
206
207
|
- lib/vagrant-vcloud/action/forward_ports.rb
|
207
208
|
- lib/vagrant-vcloud/action/handle_nat_port_collisions.rb
|
208
209
|
- lib/vagrant-vcloud/action/inventory_check.rb
|
209
210
|
- lib/vagrant-vcloud/action/is_bridged.rb
|
210
211
|
- lib/vagrant-vcloud/action/is_created.rb
|
212
|
+
- lib/vagrant-vcloud/action/is_last_vm.rb
|
211
213
|
- lib/vagrant-vcloud/action/is_paused.rb
|
212
214
|
- lib/vagrant-vcloud/action/is_running.rb
|
213
215
|
- lib/vagrant-vcloud/action/message_already_running.rb
|
@@ -215,6 +217,7 @@ files:
|
|
215
217
|
- lib/vagrant-vcloud/action/message_not_created.rb
|
216
218
|
- lib/vagrant-vcloud/action/message_will_not_destroy.rb
|
217
219
|
- lib/vagrant-vcloud/action/power_off.rb
|
220
|
+
- lib/vagrant-vcloud/action/power_off_vapp.rb
|
218
221
|
- lib/vagrant-vcloud/action/power_on.rb
|
219
222
|
- lib/vagrant-vcloud/action/read_ssh_info.rb
|
220
223
|
- lib/vagrant-vcloud/action/read_state.rb
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module VagrantPlugins
|
2
|
-
module VCloud
|
3
|
-
module Action
|
4
|
-
class Destroy
|
5
|
-
def initialize(app, env)
|
6
|
-
@app = app
|
7
|
-
@logger = Log4r::Logger.new('vagrant_vcloud::action::destroy')
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(env)
|
11
|
-
cfg = env[:machine].provider_config
|
12
|
-
cnx = cfg.vcloud_cnx.driver
|
13
|
-
vapp_id = env[:machine].get_vapp_id
|
14
|
-
vm_id = env[:machine].id
|
15
|
-
|
16
|
-
cfg.org = cnx.get_organization_by_name(cfg.org_name)
|
17
|
-
cfg.vdc_id = cnx.get_vdc_id_by_name(cfg.org, cfg.vdc_name)
|
18
|
-
|
19
|
-
test_vapp = cnx.get_vapp(vapp_id)
|
20
|
-
|
21
|
-
@logger.debug(
|
22
|
-
"Number of VMs in the vApp: #{test_vapp[:vms_hash].count}"
|
23
|
-
)
|
24
|
-
|
25
|
-
if test_vapp[:vms_hash].count == 1
|
26
|
-
env[:ui].info('Single VM left in the vApp, destroying the vApp...')
|
27
|
-
|
28
|
-
if cfg.vdc_edge_gateway_ip && cfg.vdc_edge_gateway
|
29
|
-
env[:ui].info(
|
30
|
-
"Removing NAT rules on [#{cfg.vdc_edge_gateway}] " +
|
31
|
-
"for IP [#{cfg.vdc_edge_gateway_ip}]."
|
32
|
-
)
|
33
|
-
@logger.debug(
|
34
|
-
"Deleting Edge Gateway rules - vdc id: #{cfg.vdc_id}"
|
35
|
-
)
|
36
|
-
edge_remove = cnx.remove_edge_gateway_rules(
|
37
|
-
cfg.vdc_edge_gateway,
|
38
|
-
cfg.vdc_id,
|
39
|
-
cfg.vdc_edge_gateway_ip,
|
40
|
-
vapp_id
|
41
|
-
)
|
42
|
-
cnx.wait_task_completion(edge_remove)
|
43
|
-
end
|
44
|
-
|
45
|
-
env[:ui].info('Destroying vApp...')
|
46
|
-
vapp_delete_task = cnx.delete_vapp(vapp_id)
|
47
|
-
@logger.debug("vApp Delete task id #{vapp_delete_task}")
|
48
|
-
cnx.wait_task_completion(vapp_delete_task)
|
49
|
-
|
50
|
-
env[:machine].id = nil
|
51
|
-
env[:machine].vappid = nil
|
52
|
-
else
|
53
|
-
env[:ui].info('Destroying VM...')
|
54
|
-
vm_delete_task = cnx.delete_vm(vm_id)
|
55
|
-
@logger.debug("VM Delete task id #{vm_delete_task}")
|
56
|
-
cnx.wait_task_completion(vm_delete_task)
|
57
|
-
|
58
|
-
env[:machine].id = nil
|
59
|
-
end
|
60
|
-
|
61
|
-
@app.call env
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|