Class: VagrantPlugins::VCloud::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant-vcloud/command.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.synopsisObject


7
8
9
# File 'lib/vagrant-vcloud/command.rb', line 7

def self.synopsis
  'namespace to interact with vCloud Director specifics [vcloud provider only]'
end

Instance Method Details

#command_vcloud_network(cfg, vapp_id, ssh_host) ⇒ Object


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/vagrant-vcloud/command.rb', line 47

def command_vcloud_network(cfg, vapp_id, ssh_host)
  # FIXME: this needs to be fixed to accomodate the bridged scenario
  # potentially showing only the assigned IPs in the VMs

  puts 'Fetching vCloud Director network settings ...'
  cnx = cfg.vcloud_cnx.driver
  vapp = cnx.get_vapp(vapp_id)

  organization = cnx.get_organization_by_name(cfg.org_name)
  cfg.vdc_id = cnx.get_vdc_id_by_name(organization, cfg.vdc_name)

  if !cfg.network_bridge.nil?
    # Create a new table for the network information
    network_table = Terminal::Table.new
    network_table.title = 'Network Map'

    network_table << ['VM Name', 'IP Address', 'Connection']
    network_table << :separator

    vapp[:vms_hash].each do |vm|
      network_table << [vm[0], vm[1][:addresses][0], 'Direct']
    end
  else
    vapp_edge_ip = cnx.get_vapp_edge_public_ip(vapp_id)
    vapp_edge_rules = cnx.get_vapp_port_forwarding_rules(vapp_id)
    edge_gateway_rules = cnx.get_edge_gateway_rules(cfg.vdc_edge_gateway,
                                                    cfg.vdc_id)

    # Create a new table for the network information
    network_table = Terminal::Table.new
    network_table.title = 'Vagrant vCloud Director Network Map'

    network_table << ['VM Name', 'Destination NAT Mapping', 'Enabled']
    network_table << :separator

    # Fetching Destination NAT Rules for each vApp/Edge/VM/Mapping
    vapp_edge_rules.each do |vapp_edge_rule|
      edge_gateway_rule = edge_gateway_rules.find {|r|
              (r[:rule_type] == 'DNAT' &&
               r[:original_ip] == cfg.vdc_edge_gateway_ip &&
               r[:translated_ip] == vapp_edge_ip)}

      # Loop on every VM in the vApp
      vapp[:vms_hash].each do |vm|
        # Only Map valid vAppEdge scope to VM scope
        vm_scope = vm[1][:vapp_scoped_local_id]
        vapp_edge_scope = vapp_edge_rule[:vapp_scoped_local_id]

        if vm_scope == vapp_edge_scope
          # Generate DNAT Mappings for the valid machines
          # If rules don't match, you will not see them !
          if edge_gateway_rule
            # DNAT rule from edge to vapp to vm
            connect_host = nil

            # Add support for config.ssh.host
            if ssh_host
              connect_host = "#{ssh_host}:" +
                             "#{vapp_edge_rule[:nat_external_port]}" +
                             ' -> ' +
                             "#{cfg.vdc_edge_gateway_ip}:" +
                             "#{vapp_edge_rule[:nat_external_port]}"
            else
              connect_host = "#{cfg.vdc_edge_gateway_ip}:" +
                             "#{vapp_edge_rule[:nat_external_port]}"
            end

            network_table << [
              "#{vm[0]}",
              "#{connect_host}" +
              " -> #{vapp_edge_ip}:" +
              "#{vapp_edge_rule[:nat_external_port]}" +
              " -> #{vm[1][:addresses][0]}:" +
              "#{vapp_edge_rule[:nat_internal_port]}",
              edge_gateway_rule[:is_enabled]
            ]
          else
            # DNAT rule only from vapp to vm
            network_table << [
              "#{vm[0]}",
              "#{vapp_edge_ip}:" +
              "#{vapp_edge_rule[:nat_external_port]}" +
              " -> #{vm[1][:addresses][0]}:" +
              "#{vapp_edge_rule[:nat_internal_port]}",
              true
            ]
          end
        end
      end
    end

    # Fetching Source NAT Rules for the vApp
    network_table << :separator
    network_table << ['Network Name', 'Source NAT Mapping', 'Enabled']
    network_table << :separator

    edge_gateway_rules.each do |edge_gateway_rule|
      # Only check SNAT and src/dst
      if edge_gateway_rule[:rule_type] == 'SNAT' &&
         edge_gateway_rule[:original_ip] == vapp_edge_ip &&
         edge_gateway_rule[:translated_ip] == cfg.vdc_edge_gateway_ip

        network_table << [
          edge_gateway_rule[:interface_name],
          "#{vapp_edge_ip} -> #{cfg.vdc_edge_gateway_ip}",
          edge_gateway_rule[:is_enabled]
        ]
      end
    end

    # Fetching Edge Gateway Firewall Rules
    network_table << :separator
    network_table << ['Rule# - Description', 'Firewall Rules', 'Enabled']
    network_table << :separator
    edge_gateway_rules.each do |edge_gateway_rule|
      # Only add firewall rules
      if edge_gateway_rule[:rule_type] == 'Firewall'
        network_table << [
          "#{edge_gateway_rule[:id]} - " +
          "(#{edge_gateway_rule[:description]})",
          "#{edge_gateway_rule[:policy]} " +
          "SRC:#{edge_gateway_rule[:source_ip]}:" +
          "#{edge_gateway_rule[:source_portrange]} to " +
          "DST:#{edge_gateway_rule[:destination_ip]}:" +
          "#{edge_gateway_rule[:destination_portrange]}",
          "#{edge_gateway_rule[:is_enabled]}"
        ]
      end
    end
  end
  # Print the Network Table
  puts network_table
end

#command_vcloud_redeploy_edge_gw(cfg) ⇒ Object


181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/vagrant-vcloud/command.rb', line 181

def command_vcloud_redeploy_edge_gw(cfg)
  cnx = cfg.vcloud_cnx.driver

  organization = cnx.get_organization_by_name(cfg.org_name)
  cfg.vdc_id = cnx.get_vdc_id_by_name(organization, cfg.vdc_name)

  edge_gw_id = cnx.find_edge_gateway_id(cfg.vdc_edge_gateway, cfg.vdc_id)
  task_id = cnx.redeploy_edge_gateway(edge_gw_id)

  puts "Redeploying #{cfg.vdc_edge_gateway} vShield Edge Gateway... " +
       '(This task can take a few minutes)'
  cnx.wait_task_completion(task_id)
  puts 'Done'
end

#command_vcloud_status(cfg, vapp_id) ⇒ Object


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/vagrant-vcloud/command.rb', line 11

def command_vcloud_status(cfg, vapp_id)
  # Set our handlers to the driver and objects

  puts "Fetching vCloud Director status..."
  cnx = cfg.vcloud_cnx.driver
  vapp = cnx.get_vapp(vapp_id)

  organization = cnx.get_organization_by_name(cfg.org_name)
  cfg.vdc_id = cnx.get_vdc_id_by_name(organization, cfg.vdc_name)

  # Create a new table for the general information
  table = Terminal::Table.new
  table.title = "Vagrant vCloud Director Status : #{cfg.hostname}"

  table << ['Organization Name', cfg.org_name]
  table << ['Organization vDC Name', cfg.vdc_name]
  table << ['Organization vDC ID', cfg.vdc_id]
  table << ['Organization vDC Network Name', cfg.vdc_network_name]
  table << ['Organization vDC Edge Gateway Name',
            cfg.vdc_edge_gateway] unless cfg.vdc_edge_gateway.nil?
  table << ['Organization vDC Edge IP',
            cfg.vdc_edge_gateway_ip] unless cfg.vdc_edge_gateway_ip.nil?
  table << :separator
  table << ['vApp Name', vapp[:name]]
  table << ['vAppID', vapp_id]

  vapp[:vms_hash].each do |vm|
    # This should be checked indivudually
    # When 1 VM is destroyed, ID is still populated, should be cleaned.
    table << ["-> #{vm[0]}", vm[1][:id]]
  end

  # Print the General Information Table
  puts table
end

#executeObject


196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# File 'lib/vagrant-vcloud/command.rb', line 196

def execute
  options = {}
  opts = OptionParser.new do |o|
    o.banner = 'Usage: vagrant vcloud [options]'

    # We can probably extend this if needed for specific information
    o.on(
      '-n',
      '--network',
      'Display the vCloud Director network mapping information'
    ) do |f|
      options[:network] = true
    end

    o.on(
      '-s',
      '--status',
      'Display the vCloud Director objects IDs'
    ) do |f|
      options[:status] = true
    end

    o.on(
      '-r',
      '--redeploy-edge-gw',
      'Redeploy the vCloud Director Edge Gateway'
    ) do |f|
      options[:redeploy_edge_gw] = true
    end

  end

  @argv = parse_options(opts)
  return unless @argv

  # If no arguments, print help
  if options.keys.count() == 0
    puts opts
    exit 1
  end

  puts 'Initializing vCloud Director provider...'
  # initialize some variables
  ssh_host = nil
  vapp_id = nil
  cfg = nil

  # Go through the vagrant machines
  with_target_vms(@argv) do |machine|

    # FIXME/Bug: why does the provider switch to virtualbox when
    # destroying VMs within the the vApp:
    # .vagrant/machines/<machine>/virtualbox Cannot trace why this
    # happens :-( (tsugliani)
    if machine.provider_name != :vcloud
      # Not a vCloud Director provider, exit with explicit error message
      puts "#{machine.provider_name} provider is incompatible with " +
            'this command'
      exit 1
    end

    # Force reloads on objects by fetching the ssh_info
    machine.provider.ssh_info

    # populate cfg & vApp Id for later use.
    cfg = machine.provider_config
    vapp_id = machine.get_vapp_id
    ssh_host = machine.config.ssh.host
    break
  end

  # iterate through each option and call the according command.
  options.keys.each do |key|
    case key
    when :status
      command_vcloud_status(cfg, vapp_id)
    when :network
      command_vcloud_network(cfg, vapp_id, ssh_host)
    when :redeploy_edge_gw
      command_vcloud_redeploy_edge_gw(cfg)
    end
  end

  0
end