vagrant-vcloudair 0.5.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 +7 -0
- data/.gitignore +34 -0
- data/.rubocop.yml +34 -0
- data/Gemfile +7 -0
- data/LICENSE +21 -0
- data/README.md +109 -0
- data/lib/vagrant-vcloudair.rb +63 -0
- data/lib/vagrant-vcloudair/action.rb +298 -0
- data/lib/vagrant-vcloudair/action/announce_ssh_exec.rb +22 -0
- data/lib/vagrant-vcloudair/action/build_vapp.rb +235 -0
- data/lib/vagrant-vcloudair/action/connect_vcloud.rb +54 -0
- data/lib/vagrant-vcloudair/action/destroy_vapp.rb +54 -0
- data/lib/vagrant-vcloudair/action/destroy_vm.rb +37 -0
- data/lib/vagrant-vcloudair/action/disconnect_vcloud.rb +31 -0
- data/lib/vagrant-vcloudair/action/forward_ports.rb +132 -0
- data/lib/vagrant-vcloudair/action/handle_nat_port_collisions.rb +153 -0
- data/lib/vagrant-vcloudair/action/inventory_check.rb +210 -0
- data/lib/vagrant-vcloudair/action/is_bridged.rb +29 -0
- data/lib/vagrant-vcloudair/action/is_created.rb +35 -0
- data/lib/vagrant-vcloudair/action/is_last_vm.rb +31 -0
- data/lib/vagrant-vcloudair/action/is_paused.rb +20 -0
- data/lib/vagrant-vcloudair/action/is_running.rb +20 -0
- data/lib/vagrant-vcloudair/action/message_already_running.rb +16 -0
- data/lib/vagrant-vcloudair/action/message_cannot_suspend.rb +16 -0
- data/lib/vagrant-vcloudair/action/message_not_created.rb +16 -0
- data/lib/vagrant-vcloudair/action/message_not_running.rb +16 -0
- data/lib/vagrant-vcloudair/action/message_will_not_destroy.rb +21 -0
- data/lib/vagrant-vcloudair/action/power_off.rb +33 -0
- data/lib/vagrant-vcloudair/action/power_off_vapp.rb +40 -0
- data/lib/vagrant-vcloudair/action/power_on.rb +39 -0
- data/lib/vagrant-vcloudair/action/read_ssh_info.rb +153 -0
- data/lib/vagrant-vcloudair/action/read_state.rb +51 -0
- data/lib/vagrant-vcloudair/action/resume.rb +25 -0
- data/lib/vagrant-vcloudair/action/suspend.rb +25 -0
- data/lib/vagrant-vcloudair/action/unmap_port_forwardings.rb +74 -0
- data/lib/vagrant-vcloudair/cap/forwarded_ports.rb +38 -0
- data/lib/vagrant-vcloudair/cap/public_address.rb +18 -0
- data/lib/vagrant-vcloudair/cap/rdp_info.rb +18 -0
- data/lib/vagrant-vcloudair/cap/winrm_info.rb +15 -0
- data/lib/vagrant-vcloudair/command.rb +285 -0
- data/lib/vagrant-vcloudair/config.rb +205 -0
- data/lib/vagrant-vcloudair/driver/base.rb +643 -0
- data/lib/vagrant-vcloudair/driver/meta.rb +202 -0
- data/lib/vagrant-vcloudair/driver/version_5_1.rb +2019 -0
- data/lib/vagrant-vcloudair/errors.rb +77 -0
- data/lib/vagrant-vcloudair/model/forwarded_port.rb +66 -0
- data/lib/vagrant-vcloudair/plugin.rb +111 -0
- data/lib/vagrant-vcloudair/provider.rb +41 -0
- data/lib/vagrant-vcloudair/util/compile_forwarded_ports.rb +34 -0
- data/lib/vagrant-vcloudair/version.rb +5 -0
- data/locales/en.yml +169 -0
- data/vagrant-vcloudair.gemspec +33 -0
- metadata +266 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloudAir
|
3
|
+
module Action
|
4
|
+
# Override the builtin SSHExec action to show the IP used to connect
|
5
|
+
class AnnounceSSHExec < Vagrant::Action::Builtin::SSHExec
|
6
|
+
def initialize(app, env)
|
7
|
+
@app = app
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
ssh_info = env[:machine].ssh_info
|
12
|
+
env[:ui].success(
|
13
|
+
I18n.t('vagrant_vcloudair.vm.ssh_announce',
|
14
|
+
machine_name: env[:machine].name,
|
15
|
+
ip: ssh_info[:host])
|
16
|
+
)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'etc'
|
3
|
+
require 'netaddr'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module VCloudAir
|
7
|
+
module Action
|
8
|
+
class BuildVApp
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new('vagrant_vcloudair::action::build_vapp')
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
# FIXME: we need to find a way to clean things up when a SIGINT get
|
16
|
+
# called... see env[:interrupted] in the vagrant code
|
17
|
+
|
18
|
+
cfg = env[:machine].provider_config
|
19
|
+
cnx = cfg.vcloudair_cnx.driver
|
20
|
+
vm_name = env[:machine].name
|
21
|
+
|
22
|
+
if cfg.ip_dns.nil?
|
23
|
+
dns_address1 = '8.8.8.8'
|
24
|
+
dns_address2 = '8.8.4.4'
|
25
|
+
else
|
26
|
+
dns_address1 = NetAddr::CIDR.create(cfg.ip_dns.shift).base
|
27
|
+
dns_address2 = NetAddr::CIDR.create(cfg.ip_dns.shift).base
|
28
|
+
end
|
29
|
+
|
30
|
+
if !cfg.ip_subnet.nil?
|
31
|
+
@logger.debug("Input address: #{cfg.ip_subnet}")
|
32
|
+
|
33
|
+
range_addresses = cidr.range(0)
|
34
|
+
|
35
|
+
@logger.debug("Range: #{range_addresses}")
|
36
|
+
|
37
|
+
# Delete the "network" address from the range.
|
38
|
+
range_addresses.shift
|
39
|
+
# Retrieve the first usable IP, to be used as a gateway.
|
40
|
+
gateway_ip = range_addresses.shift
|
41
|
+
# Reverse the array in place.
|
42
|
+
range_addresses.reverse!
|
43
|
+
# Delete the "broadcast" address from the range.
|
44
|
+
range_addresses.shift
|
45
|
+
# Reverse back the array.
|
46
|
+
range_addresses.reverse!
|
47
|
+
|
48
|
+
@logger.debug("Gateway IP: #{gateway_ip.to_s}")
|
49
|
+
@logger.debug("Netmask: #{cidr.wildcard_mask}")
|
50
|
+
@logger.debug(
|
51
|
+
"IP Pool: #{range_addresses.first}-#{range_addresses.last}"
|
52
|
+
)
|
53
|
+
@logger.debug("DNS1: #{dns_address1} DNS2: #{dns_address2}")
|
54
|
+
|
55
|
+
network_options = {
|
56
|
+
:name => 'Vagrant-vApp-Net',
|
57
|
+
:gateway => gateway_ip.to_s,
|
58
|
+
:netmask => cidr.wildcard_mask,
|
59
|
+
:start_address => range_addresses.first,
|
60
|
+
:end_address => range_addresses.last,
|
61
|
+
:fence_mode => 'natRouted',
|
62
|
+
:ip_allocation_mode => 'POOL',
|
63
|
+
:parent_network => cfg.vdc_network_id,
|
64
|
+
:enable_firewall => 'false',
|
65
|
+
:dns1 => dns_address1,
|
66
|
+
:dns2 => dns_address2
|
67
|
+
}
|
68
|
+
|
69
|
+
elsif !cfg.network_bridge.nil?
|
70
|
+
# Bridged mode, avoid deploying a vShield Edge altogether.
|
71
|
+
network_options = {
|
72
|
+
:name => 'Vagrant-vApp-Net',
|
73
|
+
:fence_mode => 'bridged',
|
74
|
+
:ip_allocation_mode => 'POOL',
|
75
|
+
:parent_network => cfg.vdc_network_id
|
76
|
+
}
|
77
|
+
|
78
|
+
env[:bridged_network] = true
|
79
|
+
|
80
|
+
else
|
81
|
+
|
82
|
+
@logger.debug("DNS1: #{dns_address1} DNS2: #{dns_address2}")
|
83
|
+
# No IP subnet specified, reverting to defaults
|
84
|
+
network_options = {
|
85
|
+
:name => 'Vagrant-vApp-Net',
|
86
|
+
:gateway => '10.1.1.1',
|
87
|
+
:netmask => '255.255.255.0',
|
88
|
+
:start_address => '10.1.1.2',
|
89
|
+
:end_address => '10.1.1.254',
|
90
|
+
:fence_mode => 'natRouted',
|
91
|
+
:ip_allocation_mode => 'POOL',
|
92
|
+
:parent_network => cfg.vdc_network_id,
|
93
|
+
:enable_firewall => 'false',
|
94
|
+
:dns1 => dns_address1,
|
95
|
+
:dns2 => dns_address2
|
96
|
+
}
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
if env[:machine].get_vapp_id.nil?
|
101
|
+
env[:ui].info(I18n.t('vagrant_vcloudair.vapp.build_vapp'))
|
102
|
+
|
103
|
+
vapp_prefix = cfg.vapp_prefix
|
104
|
+
vapp_prefix = 'Vagrant' if vapp_prefix.nil?
|
105
|
+
|
106
|
+
compose = cnx.compose_vapp_from_vm(
|
107
|
+
cfg.vdc_id,
|
108
|
+
"#{vapp_prefix}-#{Etc.getlogin}-#{Socket.gethostname.downcase}-" +
|
109
|
+
"#{SecureRandom.hex(4)}",
|
110
|
+
"vApp created by #{Etc.getlogin} running on " +
|
111
|
+
"#{Socket.gethostname.downcase} using vagrant-vcloudair on " +
|
112
|
+
"#{Time.now.strftime("%B %d, %Y")}",
|
113
|
+
{
|
114
|
+
vm_name => cfg.catalog_item[:vms_hash].first.last[:id]
|
115
|
+
},
|
116
|
+
network_options
|
117
|
+
)
|
118
|
+
@logger.debug('Launch Compose vApp...')
|
119
|
+
|
120
|
+
# Fetch thenewly created vApp ID
|
121
|
+
vapp_id = compose[:vapp_id]
|
122
|
+
|
123
|
+
# putting the vApp Id in a globally reachable var and file.
|
124
|
+
env[:machine].vappid = vapp_id
|
125
|
+
|
126
|
+
# Wait for the task to finish.
|
127
|
+
wait = cnx.wait_task_completion(compose[:task_id])
|
128
|
+
|
129
|
+
unless wait[:errormsg].nil?
|
130
|
+
fail Errors::ComposeVAppError, :message => wait[:errormsg]
|
131
|
+
end
|
132
|
+
|
133
|
+
# Fetching new vApp object to check stuff.
|
134
|
+
new_vapp = cnx.get_vapp(vapp_id)
|
135
|
+
|
136
|
+
if new_vapp
|
137
|
+
env[:ui].success(I18n.t('vagrant_vcloudair.vapp.vapp_created',
|
138
|
+
vapp_name: new_vapp[:name]))
|
139
|
+
|
140
|
+
# Add the vm id as machine.id
|
141
|
+
new_vm_properties = new_vapp[:vms_hash].fetch(vm_name)
|
142
|
+
env[:machine].id = new_vm_properties[:id]
|
143
|
+
|
144
|
+
### SET GUEST CONFIG
|
145
|
+
@logger.info(
|
146
|
+
"Setting Guest Customization on ID: [#{vm_name}] " +
|
147
|
+
"of vApp [#{new_vapp[:name]}]"
|
148
|
+
)
|
149
|
+
|
150
|
+
set_custom = cnx.set_vm_guest_customization(
|
151
|
+
new_vm_properties[:id],
|
152
|
+
vm_name,
|
153
|
+
{
|
154
|
+
:enabled => true,
|
155
|
+
:admin_passwd_enabled => false
|
156
|
+
}
|
157
|
+
)
|
158
|
+
wait = cnx.wait_task_completion(set_custom)
|
159
|
+
|
160
|
+
unless wait[:errormsg].nil?
|
161
|
+
fail Errors::ComposeVAppError, :message => wait[:errormsg]
|
162
|
+
end
|
163
|
+
|
164
|
+
else
|
165
|
+
env[:ui].error(I18n.t(
|
166
|
+
'vagrant_vcloudair.vapp.vapp_creation_failed'),
|
167
|
+
vapp_name: new_vapp[:name])
|
168
|
+
fail Errors::ComposeVAppError,
|
169
|
+
:message => 'vApp created but cannot get a working id, \
|
170
|
+
please report this error'
|
171
|
+
end
|
172
|
+
|
173
|
+
else
|
174
|
+
env[:ui].info(I18n.t('vagrant_vcloudair.vapp.adding_vm'))
|
175
|
+
|
176
|
+
recompose = cnx.recompose_vapp_from_vm(
|
177
|
+
env[:machine].get_vapp_id,
|
178
|
+
{
|
179
|
+
vm_name => cfg.catalog_item[:vms_hash].first.last[:id]
|
180
|
+
},
|
181
|
+
network_options
|
182
|
+
)
|
183
|
+
|
184
|
+
@logger.info('Waiting for the recompose task to complete ...')
|
185
|
+
|
186
|
+
# Wait for the task to finish.
|
187
|
+
wait = cnx.wait_task_completion(recompose[:task_id])
|
188
|
+
|
189
|
+
unless wait[:errormsg].nil?
|
190
|
+
fail Errors::ComposeVAppError, :message => wait[:errormsg]
|
191
|
+
end
|
192
|
+
|
193
|
+
new_vapp = cnx.get_vapp(env[:machine].get_vapp_id)
|
194
|
+
|
195
|
+
if new_vapp
|
196
|
+
new_vm_properties = new_vapp[:vms_hash].fetch(vm_name)
|
197
|
+
env[:machine].id = new_vm_properties[:id]
|
198
|
+
|
199
|
+
### SET GUEST CONFIG
|
200
|
+
@logger.info(
|
201
|
+
'Setting Guest Customization on ID: ' +
|
202
|
+
"[#{new_vm_properties[:id]}] of vApp [#{new_vapp[:name]}]"
|
203
|
+
)
|
204
|
+
|
205
|
+
set_custom = cnx.set_vm_guest_customization(
|
206
|
+
new_vm_properties[:id],
|
207
|
+
vm_name,
|
208
|
+
{
|
209
|
+
:enabled => true,
|
210
|
+
:admin_passwd_enabled => false
|
211
|
+
}
|
212
|
+
)
|
213
|
+
wait = cnx.wait_task_completion(set_custom)
|
214
|
+
|
215
|
+
unless wait[:errormsg].nil?
|
216
|
+
fail Errors::ComposeVAppError, :message => wait[:errormsg]
|
217
|
+
end
|
218
|
+
|
219
|
+
else
|
220
|
+
# env[:ui].error("VM #{vm_name} add to #{new_vapp[:name]} failed!")
|
221
|
+
env[:ui].error(I18n.t('vagrant_vcloudair.vapp.vm_add_failed',
|
222
|
+
vm_name: vm_name,
|
223
|
+
vapp_name: new_vapp[:name]))
|
224
|
+
fail Errors::ComposeVAppError,
|
225
|
+
:message => 'VM added to vApp but cannot get a working id, \
|
226
|
+
please report this error'
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
@app.call env
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloudAir
|
3
|
+
module Action
|
4
|
+
class ConnectVCloudAir
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_vcloudair::action::connect_vcloud')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
config = env[:machine].provider_config
|
12
|
+
|
13
|
+
if !config.vcloudair_cnx || !config.vcloudair_cnx.driver.auth_key
|
14
|
+
@logger.info('Connecting to vCloud Air...')
|
15
|
+
|
16
|
+
@logger.debug("config.cloud_id: #{config.cloud_id}") unless config.cloud_id.nil?
|
17
|
+
@logger.debug("config.username: #{config.username}")
|
18
|
+
@logger.debug('config.password: <hidden>')
|
19
|
+
@logger.debug("config.vdc_name: #{config.vdc_name}")
|
20
|
+
|
21
|
+
# Create the vcloud-rest connection object with the configuration
|
22
|
+
# information.
|
23
|
+
config.vcloudair_cnx = Driver::Meta.new(
|
24
|
+
config.cloud_id,
|
25
|
+
config.username,
|
26
|
+
config.password,
|
27
|
+
config.vdc_name
|
28
|
+
)
|
29
|
+
|
30
|
+
@logger.info('Logging into vCloud Air...')
|
31
|
+
# config.vcloudair_cnx.login
|
32
|
+
|
33
|
+
# Check for the vCloud Air authentication token
|
34
|
+
if config.vcloudair_cnx.driver.auth_key
|
35
|
+
@logger.info('Logged in successfully!')
|
36
|
+
@logger.debug(
|
37
|
+
"x-vcloud-authorization=#{config.vcloudair_cnx.driver.auth_key}"
|
38
|
+
)
|
39
|
+
else
|
40
|
+
@logger.info("Login failed in to #{config.hostname}.")
|
41
|
+
fail Errors::UnauthorizedAccess
|
42
|
+
end
|
43
|
+
else
|
44
|
+
@logger.info('Already logged in, using current session')
|
45
|
+
@logger.debug(
|
46
|
+
"x-vcloud-authorization=#{config.vcloudair_cnx.driver.auth_key}"
|
47
|
+
)
|
48
|
+
end
|
49
|
+
@app.call env
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloudAir
|
3
|
+
module Action
|
4
|
+
class DestroyVApp
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_vcloudair::action::destroy_vapp')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
cfg = env[:machine].provider_config
|
12
|
+
cnx = cfg.vcloudair_cnx.driver
|
13
|
+
vapp_id = env[:machine].get_vapp_id
|
14
|
+
|
15
|
+
cfg.org = cnx.get_organization_by_name(cfg.vdc_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(I18n.t('vagrant_vcloudair.edge.removing_nat_rules',
|
26
|
+
vdc_edge_gateway: cfg.vdc_edge_gateway,
|
27
|
+
vdc_edge_gateway_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(I18n.t('vagrant_vcloudair.vapp.destroy_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 VCloudAir
|
3
|
+
module Action
|
4
|
+
class DestroyVM
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new('vagrant_vcloudair::action::destroy_vm')
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
cfg = env[:machine].provider_config
|
12
|
+
cnx = cfg.vcloudair_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.vdc_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(I18n.t('vagrant_vcloudair.vm.destroy_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
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloudAir
|
3
|
+
module Action
|
4
|
+
class DisconnectVCloudAir
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@logger = Log4r::Logger.new(
|
8
|
+
'vagrant_vcloudair::action::disconnect_vcloud'
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
@logger.info('Disconnecting from vCloud Air...')
|
14
|
+
|
15
|
+
# Fetch the global vCloud Air connection handle
|
16
|
+
cnx = env[:machine].provider_config.vcloudair_cnx.driver
|
17
|
+
|
18
|
+
# Delete the current vCloud Air Session
|
19
|
+
cnx.logout
|
20
|
+
|
21
|
+
# If session key doesn't exist, we are disconnected
|
22
|
+
if !cnx.auth_key
|
23
|
+
@logger.info('Disconnected from vCloud Air successfully!')
|
24
|
+
else
|
25
|
+
fail Errors::VCloudAirGenericError, :message => e.message
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module VCloudAir
|
3
|
+
module Action
|
4
|
+
class ForwardPorts
|
5
|
+
include Util::CompileForwardedPorts
|
6
|
+
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new('vagrant_vcloudair::action::forward_ports')
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
@env = env
|
14
|
+
|
15
|
+
# Get the ports we are forwarding
|
16
|
+
env[:forwarded_ports] ||= compile_forwarded_ports(
|
17
|
+
env[:machine].config
|
18
|
+
)
|
19
|
+
|
20
|
+
forward_ports
|
21
|
+
|
22
|
+
@app.call(env)
|
23
|
+
end
|
24
|
+
|
25
|
+
def forward_ports
|
26
|
+
ports = []
|
27
|
+
edge_ports = []
|
28
|
+
|
29
|
+
cfg = @env[:machine].provider_config
|
30
|
+
cnx = cfg.vcloudair_cnx.driver
|
31
|
+
vapp_id = @env[:machine].get_vapp_id
|
32
|
+
vm_name = @env[:machine].name
|
33
|
+
|
34
|
+
# FIXME: why are we overriding this here ?
|
35
|
+
# It's already been taken care during the initial
|
36
|
+
# InventoryCheck. (tsugliani)
|
37
|
+
#
|
38
|
+
# cfg.org = cnx.get_organization_by_name(cfg.vdc_name)
|
39
|
+
# cfg.vdc_network_id = cfg.org[:networks][cfg.vdc_network_name]
|
40
|
+
|
41
|
+
@logger.debug('Getting VM info...')
|
42
|
+
vm = cnx.get_vapp(vapp_id)
|
43
|
+
vm_info = vm[:vms_hash][vm_name.to_sym]
|
44
|
+
|
45
|
+
@env[:forwarded_ports].each do |fp|
|
46
|
+
|
47
|
+
@env[:ui].info(I18n.t('vagrant_vcloudair.edge.port_forwarding',
|
48
|
+
guest_port: fp.guest_port,
|
49
|
+
host_port: fp.host_port))
|
50
|
+
|
51
|
+
# Add the options to the ports array to send to the driver later
|
52
|
+
ports << {
|
53
|
+
:guestip => fp.guest_ip,
|
54
|
+
:nat_internal_port => fp.guest_port,
|
55
|
+
:hostip => fp.host_ip,
|
56
|
+
:nat_external_port => fp.host_port,
|
57
|
+
:name => fp.id,
|
58
|
+
:nat_protocol => fp.protocol.upcase,
|
59
|
+
:vapp_scoped_local_id => vm_info[:vapp_scoped_local_id]
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
unless ports.empty?
|
64
|
+
# We only need to forward ports if there are any to forward
|
65
|
+
@logger.debug("Port object to be passed: #{ports.inspect}")
|
66
|
+
@logger.debug("Current network id #{cfg.vdc_network_id}")
|
67
|
+
|
68
|
+
### Here we apply the nat_rules to the vApp we just built
|
69
|
+
add_ports = cnx.add_vapp_port_forwarding_rules(
|
70
|
+
vapp_id,
|
71
|
+
'Vagrant-vApp-Net',
|
72
|
+
{
|
73
|
+
:fence_mode => 'natRouted',
|
74
|
+
:parent_network => cfg.vdc_network_id,
|
75
|
+
:nat_policy_type => 'allowTraffic',
|
76
|
+
:nat_rules => ports
|
77
|
+
}
|
78
|
+
)
|
79
|
+
|
80
|
+
wait = cnx.wait_task_completion(add_ports)
|
81
|
+
|
82
|
+
unless wait[:errormsg].nil?
|
83
|
+
fail Errors::ComposeVAppError, :message => wait[:errormsg]
|
84
|
+
end
|
85
|
+
|
86
|
+
if cfg.vdc_edge_gateway_ip && \
|
87
|
+
cfg.vdc_edge_gateway && \
|
88
|
+
cfg.network_bridge.nil?
|
89
|
+
|
90
|
+
vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
|
91
|
+
@logger.debug('Getting edge gateway port forwarding rules...')
|
92
|
+
edge_gateway_rules = cnx.get_edge_gateway_rules(cfg.vdc_edge_gateway,
|
93
|
+
cfg.vdc_id)
|
94
|
+
vapp_edge_dnat_rules = edge_gateway_rules.select {|r| (r[:rule_type] == 'DNAT' &&
|
95
|
+
r[:translated_ip] == vapp_edge_ip)}
|
96
|
+
vapp_edge_ports_in_use = vapp_edge_dnat_rules.map{|r| r[:original_port].to_i}.to_set
|
97
|
+
|
98
|
+
ports.each do |port|
|
99
|
+
if port[:vapp_scoped_local_id] == vm_info[:vapp_scoped_local_id] &&
|
100
|
+
!vapp_edge_ports_in_use.include?(port[:nat_external_port])
|
101
|
+
|
102
|
+
@env[:ui].info(I18n.t(
|
103
|
+
'vagrant_vcloudair.edge.nat_rules_creation',
|
104
|
+
vdc_edge_gateway: cfg.vdc_edge_gateway,
|
105
|
+
vapp_edge_ip: vapp_edge_ip,
|
106
|
+
port: port[:nat_external_port]))
|
107
|
+
|
108
|
+
edge_ports << port[:nat_external_port]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
unless edge_ports.empty?
|
113
|
+
# Add the vShield Edge Gateway rules
|
114
|
+
add_ports = cnx.add_edge_gateway_rules(
|
115
|
+
cfg.vdc_edge_gateway,
|
116
|
+
cfg.vdc_id,
|
117
|
+
cfg.vdc_edge_gateway_ip,
|
118
|
+
vapp_id,
|
119
|
+
edge_ports
|
120
|
+
)
|
121
|
+
|
122
|
+
wait = cnx.wait_task_completion(add_ports)
|
123
|
+
|
124
|
+
fail Errors::ComposeVAppError, :message => wait[:errormsg] unless wait[:errormsg].nil?
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|