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