rvc 1.6.0 → 1.7.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.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/rvc +46 -70
- data/devel/test-dependencies.sh +4 -0
- data/lib/rvc.rb +5 -6
- data/lib/rvc/command.rb +65 -0
- data/lib/rvc/command_slate.rb +112 -0
- data/lib/rvc/completion.rb +89 -58
- data/lib/rvc/connection.rb +48 -0
- data/lib/rvc/extensions/DistributedVirtualPortgroup.rb +1 -1
- data/lib/rvc/extensions/DistributedVirtualSwitch.rb +3 -3
- data/lib/rvc/extensions/HostSystem.rb +90 -0
- data/lib/rvc/extensions/VirtualMachine.rb +37 -7
- data/lib/rvc/field.rb +59 -12
- data/lib/rvc/fs.rb +34 -4
- data/lib/rvc/inventory.rb +5 -1
- data/lib/rvc/modules/alarm.rb +2 -0
- data/lib/rvc/modules/basic.rb +66 -61
- data/lib/rvc/modules/cluster.rb +117 -22
- data/lib/rvc/modules/connection.rb +40 -0
- data/lib/rvc/modules/core.rb +4 -16
- data/lib/rvc/modules/datacenter.rb +2 -0
- data/lib/rvc/modules/datastore.rb +11 -78
- data/lib/rvc/modules/device.rb +40 -5
- data/lib/rvc/modules/diagnostics.rb +169 -0
- data/lib/rvc/modules/esxcli.rb +9 -5
- data/lib/rvc/modules/find.rb +5 -3
- data/lib/rvc/modules/host.rb +46 -3
- data/lib/rvc/modules/issue.rb +2 -0
- data/lib/rvc/modules/mark.rb +5 -3
- data/lib/rvc/modules/perf.rb +99 -33
- data/lib/rvc/modules/permissions.rb +2 -0
- data/lib/rvc/modules/resource_pool.rb +2 -0
- data/lib/rvc/modules/role.rb +3 -1
- data/lib/rvc/modules/snapshot.rb +12 -4
- data/lib/rvc/modules/statsinterval.rb +13 -11
- data/lib/rvc/modules/vds.rb +67 -10
- data/lib/rvc/modules/vim.rb +19 -53
- data/lib/rvc/modules/vm.rb +27 -6
- data/lib/rvc/modules/vm_guest.rb +490 -0
- data/lib/rvc/modules/vmrc.rb +60 -32
- data/lib/rvc/modules/vnc.rb +2 -0
- data/lib/rvc/namespace.rb +114 -0
- data/lib/rvc/option_parser.rb +12 -15
- data/lib/rvc/readline-ffi.rb +4 -1
- data/lib/rvc/ruby_evaluator.rb +84 -0
- data/lib/rvc/shell.rb +68 -83
- data/lib/rvc/uri_parser.rb +59 -0
- data/lib/rvc/util.rb +134 -29
- data/lib/rvc/{extensions/PerfCounterInfo.rb → version.rb} +2 -4
- data/lib/rvc/{memory_session.rb → vim.rb} +10 -32
- data/test/modules/foo.rb +9 -0
- data/test/modules/foo/bar.rb +9 -0
- data/test/test_completion.rb +17 -0
- data/test/test_fs.rb +9 -11
- data/test/test_help.rb +46 -0
- data/test/test_helper.rb +12 -0
- data/test/test_metric.rb +1 -2
- data/test/test_modules.rb +38 -0
- data/test/test_parse_path.rb +1 -2
- data/test/test_shell.rb +138 -0
- data/test/test_uri.rb +34 -0
- metadata +115 -81
- data/lib/rvc/extensions/PerformanceManager.rb +0 -83
- data/lib/rvc/filesystem_session.rb +0 -101
- data/lib/rvc/modules.rb +0 -138
data/lib/rvc/modules/issue.rb
CHANGED
data/lib/rvc/modules/mark.rb
CHANGED
@@ -18,6 +18,8 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
+
require 'rvc/vim'
|
22
|
+
|
21
23
|
opts :mark do
|
22
24
|
summary "Save an object for later use"
|
23
25
|
arg :key, "Name for this mark"
|
@@ -29,7 +31,7 @@ rvc_alias :mark, :m
|
|
29
31
|
|
30
32
|
def mark key, objs
|
31
33
|
err "invalid mark name" unless key =~ /^\w+$/
|
32
|
-
|
34
|
+
shell.fs.marks[key] = objs
|
33
35
|
end
|
34
36
|
|
35
37
|
|
@@ -42,7 +44,7 @@ rvc_alias :edit, :me
|
|
42
44
|
|
43
45
|
def edit key
|
44
46
|
editor = ENV['VISUAL'] || ENV['EDITOR'] || 'vi'
|
45
|
-
objs =
|
47
|
+
objs = shell.fs.marks[key] or err "no such mark #{key.inspect}"
|
46
48
|
filename = File.join(Dir.tmpdir, "rvc.#{Time.now.to_i}.#{rand(65536)}")
|
47
49
|
File.open(filename, 'w') { |io| objs.each { |obj| io.puts(obj.rvc_path_str) } }
|
48
50
|
begin
|
@@ -61,5 +63,5 @@ opts :list do
|
|
61
63
|
end
|
62
64
|
|
63
65
|
def list
|
64
|
-
|
66
|
+
shell.fs.marks.each { |k,v| puts k }
|
65
67
|
end
|
data/lib/rvc/modules/perf.rb
CHANGED
@@ -1,9 +1,24 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'rvc/vim'
|
7
22
|
|
8
23
|
TIMEFMT = '%Y-%m-%dT%H:%M:%SZ'
|
9
24
|
|
@@ -15,6 +30,39 @@ DISPLAY_TIMEFMT = {
|
|
15
30
|
4 => '%Y/%m/%d',
|
16
31
|
}
|
17
32
|
|
33
|
+
def require_gnuplot
|
34
|
+
begin
|
35
|
+
require 'gnuplot'
|
36
|
+
rescue LoadError
|
37
|
+
Gem::Specification.reset
|
38
|
+
begin
|
39
|
+
require 'gnuplot'
|
40
|
+
rescue LoadError
|
41
|
+
err "The gnuplot gem is not installed"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_interval pm, start
|
47
|
+
now = Time.now
|
48
|
+
ago = now - start
|
49
|
+
|
50
|
+
if ago < 3600
|
51
|
+
#puts "Using realtime interval, period = 20 seconds."
|
52
|
+
interval_id = 20
|
53
|
+
display_timefmt = DISPLAY_TIMEFMT[:realtime]
|
54
|
+
else
|
55
|
+
intervals = pm.historicalInterval
|
56
|
+
interval = intervals.find { |x| now - x.length < start }
|
57
|
+
err "start time is too long ago" unless interval
|
58
|
+
#puts "Using historical interval #{interval.name.inspect}, period = #{interval.samplingPeriod} seconds."
|
59
|
+
interval_id = interval.samplingPeriod
|
60
|
+
display_timefmt = DISPLAY_TIMEFMT[interval.key]
|
61
|
+
end
|
62
|
+
|
63
|
+
return interval_id, display_timefmt
|
64
|
+
end
|
65
|
+
|
18
66
|
opts :plot do
|
19
67
|
summary "Plot a graph of the given performance counters"
|
20
68
|
arg :counter, "Counter name"
|
@@ -22,10 +70,17 @@ opts :plot do
|
|
22
70
|
opt :terminal, "Display plot on terminal", :default => ENV['DISPLAY'].nil?
|
23
71
|
opt :start, "Start time", :type => :date, :short => 's'
|
24
72
|
opt :end, "End time", :type => :date, :short => 'e'
|
73
|
+
summary <<-EOS
|
74
|
+
|
75
|
+
Example:
|
76
|
+
perf.plot cpu.usagemhz myvm myvm2 --start '20 minutes ago'
|
77
|
+
|
78
|
+
See perf.counters to determine which performance counters are available.
|
79
|
+
EOS
|
25
80
|
end
|
26
81
|
|
27
82
|
def plot counter_name, objs, opts
|
28
|
-
|
83
|
+
require_gnuplot
|
29
84
|
vim = single_connection objs
|
30
85
|
pm = vim.serviceContent.perfManager
|
31
86
|
group_key, counter_key, rollup_type = counter_name.split('.', 3)
|
@@ -35,20 +90,8 @@ def plot counter_name, objs, opts
|
|
35
90
|
opts[:start] ||= opts[:end] - 1800
|
36
91
|
|
37
92
|
err "end time is in the future" unless opts[:end] <= Time.now
|
38
|
-
ago = now - opts[:start]
|
39
93
|
|
40
|
-
|
41
|
-
#puts "Using realtime interval, period = 20 seconds."
|
42
|
-
interval_id = 20
|
43
|
-
display_timefmt = DISPLAY_TIMEFMT[:realtime]
|
44
|
-
else
|
45
|
-
intervals = pm.historicalInterval
|
46
|
-
interval = intervals.find { |x| now - x.length < opts[:start] }
|
47
|
-
err "start time is too long ago" unless interval
|
48
|
-
#puts "Using historical interval #{interval.name.inspect}, period = #{interval.samplingPeriod} seconds."
|
49
|
-
interval_id = interval.samplingPeriod
|
50
|
-
display_timefmt = DISPLAY_TIMEFMT[interval.key]
|
51
|
-
end
|
94
|
+
interval_id, display_timefmt = find_interval pm, opts[:start]
|
52
95
|
|
53
96
|
all_counters = Hash[pm.perfCounter.map { |x| [x.key, x] }]
|
54
97
|
|
@@ -59,9 +102,8 @@ def plot counter_name, objs, opts
|
|
59
102
|
metric = metrics.find do |metric|
|
60
103
|
counter = all_counters[metric.counterId]
|
61
104
|
counter.groupInfo.key == group_key &&
|
62
|
-
counter.nameInfo.key == counter_key
|
63
|
-
|
64
|
-
end or err "no such metric"
|
105
|
+
counter.nameInfo.key == counter_key
|
106
|
+
end or err "counter #{group_key}.#{counter_key} was not found in the #{interval_id}s interval"
|
65
107
|
counter = all_counters[metric.counterId]
|
66
108
|
|
67
109
|
specs = objs.map do |obj|
|
@@ -105,6 +147,10 @@ def retrieve_datasets pm, counter, specs
|
|
105
147
|
results = pm.QueryPerf(:querySpec => specs)
|
106
148
|
datasets = results.map do |result|
|
107
149
|
times = result.sampleInfoCSV.split(',').select { |x| x['T'] }
|
150
|
+
if result.value.empty?
|
151
|
+
puts "No data for #{result.entity.name} #{counter.name}"
|
152
|
+
next
|
153
|
+
end
|
108
154
|
data = result.value[0].value.split(',').map(&:to_i)
|
109
155
|
|
110
156
|
if counter.unitInfo.key == 'percent'
|
@@ -123,7 +169,7 @@ def retrieve_datasets pm, counter, specs
|
|
123
169
|
ds.using = '1:2'
|
124
170
|
ds.title = result.entity.name
|
125
171
|
end
|
126
|
-
end
|
172
|
+
end.compact
|
127
173
|
end
|
128
174
|
|
129
175
|
def with_gnuplot persist
|
@@ -152,7 +198,7 @@ opts :watch do
|
|
152
198
|
end
|
153
199
|
|
154
200
|
def watch counter_name, objs, opts
|
155
|
-
|
201
|
+
require_gnuplot
|
156
202
|
with_gnuplot false do |gp|
|
157
203
|
puts "Press Ctrl-C to stop."
|
158
204
|
while true
|
@@ -181,6 +227,14 @@ def counters obj
|
|
181
227
|
interval = nil
|
182
228
|
end
|
183
229
|
|
230
|
+
active_intervals = pm.active_intervals
|
231
|
+
active_intervals_text = lambda do |level|
|
232
|
+
return '' unless level
|
233
|
+
xs = active_intervals[level]
|
234
|
+
return 'none' if xs.empty?
|
235
|
+
xs.map { |x| x.name.match(/Past (\w+)/)[1] } * ','
|
236
|
+
end
|
237
|
+
|
184
238
|
metrics = pm.QueryAvailablePerfMetric(
|
185
239
|
:entity => obj,
|
186
240
|
:intervalId => interval)
|
@@ -188,12 +242,19 @@ def counters obj
|
|
188
242
|
map { |id| pm.perfcounter_idhash[id] }
|
189
243
|
|
190
244
|
groups = available_counters.group_by { |counter| counter.groupInfo }
|
245
|
+
|
246
|
+
table = Terminal::Table.new
|
247
|
+
table.add_row ["Name", "Description", "Unit", "Level", "Active Intervals"]
|
191
248
|
groups.sort_by { |group,counters| group.key }.each do |group,counters|
|
192
|
-
|
193
|
-
|
194
|
-
|
249
|
+
table.add_separator
|
250
|
+
table.add_row [{ :value => group.label, :colspan => 5}]
|
251
|
+
table.add_separator
|
252
|
+
counters.sort_by(&:name).each do |counter|
|
253
|
+
table.add_row [counter.name, counter.nameInfo.label, counter.unitInfo.label,
|
254
|
+
counter.level, active_intervals_text[counter.level]]
|
195
255
|
end
|
196
256
|
end
|
257
|
+
puts(table)
|
197
258
|
end
|
198
259
|
|
199
260
|
|
@@ -208,8 +269,7 @@ def counter counter_name, obj
|
|
208
269
|
pm = vim.serviceContent.perfManager
|
209
270
|
counter = pm.perfcounter_hash[counter_name] or err "no such counter #{counter_name.inspect}"
|
210
271
|
|
211
|
-
|
212
|
-
active_intervals = lambda { |level| intervals.select { |x| x.level >= level } }
|
272
|
+
active_intervals = pm.active_intervals
|
213
273
|
active_intervals_text = lambda do |level|
|
214
274
|
xs = active_intervals[level]
|
215
275
|
xs.empty? ? 'none' : xs.map(&:name).map(&:inspect) * ', '
|
@@ -254,9 +314,15 @@ end
|
|
254
314
|
|
255
315
|
def stats metrics, objs, opts
|
256
316
|
metrics = metrics.split(",")
|
257
|
-
|
258
|
-
|
259
|
-
|
317
|
+
|
318
|
+
vim = single_connection objs
|
319
|
+
pm = vim.serviceContent.perfManager
|
320
|
+
|
321
|
+
metrics.each do |x|
|
322
|
+
err "no such metric #{x}" unless pm.perfcounter_hash.member? x
|
323
|
+
end
|
324
|
+
|
325
|
+
interval = pm.provider_summary(objs.first).refreshRate
|
260
326
|
start_time = nil
|
261
327
|
if interval == -1
|
262
328
|
# Object does not support real time stats
|
@@ -18,6 +18,8 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
+
require 'rvc/vim'
|
22
|
+
|
21
23
|
opts :get do
|
22
24
|
summary "Display the permissions of a managed entity"
|
23
25
|
arg :obj, nil, :lookup => VIM::ManagedEntity, :multi => true
|
data/lib/rvc/modules/role.rb
CHANGED
@@ -18,8 +18,10 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
+
require 'rvc/vim'
|
22
|
+
|
21
23
|
def cur_auth_mgr
|
22
|
-
conn =
|
24
|
+
conn = shell.fs.cur._connection
|
23
25
|
conn.serviceContent.authorizationManager
|
24
26
|
end
|
25
27
|
|
data/lib/rvc/modules/snapshot.rb
CHANGED
@@ -18,6 +18,9 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
+
require 'rvc/vim'
|
22
|
+
VIM::VirtualMachine
|
23
|
+
|
21
24
|
opts :create do
|
22
25
|
summary "Snapshot a VM"
|
23
26
|
arg :vm, nil, :lookup => VIM::VirtualMachine
|
@@ -71,11 +74,16 @@ end
|
|
71
74
|
|
72
75
|
|
73
76
|
opts :remove do
|
74
|
-
summary "Remove
|
75
|
-
arg :
|
77
|
+
summary "Remove snapshots"
|
78
|
+
arg :snapshots, nil, :multi => true, :lookup => RVC::SnapshotFolder
|
76
79
|
opt :remove_children, "Whether to remove the snapshot's children too"
|
77
80
|
end
|
78
81
|
|
79
|
-
def remove
|
80
|
-
|
82
|
+
def remove snapshots, opts
|
83
|
+
# Sort by path and use reverse_each to remove child snapshots first
|
84
|
+
snapshots.sort_by! {|s| s.rvc_path_str }
|
85
|
+
|
86
|
+
snapshots.reverse_each do |snapshot|
|
87
|
+
tasks [snapshot.find_tree.snapshot], :RemoveSnapshot, :removeChildren => opts[:remove_children]
|
88
|
+
end
|
81
89
|
end
|
@@ -18,6 +18,8 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
+
require 'rvc/vim'
|
22
|
+
|
21
23
|
#see vSphere Client: Administration -> vCenter Server Settings -> Statistics -> Statistics Intervals
|
22
24
|
|
23
25
|
def stats_time secs
|
@@ -39,19 +41,19 @@ opts :list do
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def list
|
42
|
-
conn =
|
43
|
-
|
44
|
+
conn = lookup_single('~@')
|
45
|
+
pm = conn.serviceContent.perfManager
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
puts columns.map {|s| "-" * s.size }.join("-+-")
|
47
|
+
table = Terminal::Table.new
|
48
|
+
table.add_row ["Name", "Enabled", "Interval Duration", "Save For", "Statistics Level"]
|
49
|
+
table.add_separator
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
stats_time(interval.length), interval.level.to_s
|
51
|
+
pm.historicalInterval.each do |interval|
|
52
|
+
table.add_row [interval.name, interval.enabled, stats_time(interval.samplingPeriod),
|
53
|
+
stats_time(interval.length), interval.level]
|
54
54
|
end
|
55
|
+
|
56
|
+
puts table
|
55
57
|
end
|
56
58
|
|
57
59
|
|
@@ -65,7 +67,7 @@ opts :update do
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def update name, opts
|
68
|
-
conn = single_connection [
|
70
|
+
conn = single_connection [shell.fs.cur]
|
69
71
|
perfman = conn.serviceContent.perfManager
|
70
72
|
|
71
73
|
interval = perfman.historicalInterval.select {|i| i.name == name or i.name == "Past #{name}" }.first
|
data/lib/rvc/modules/vds.rb
CHANGED
@@ -18,7 +18,9 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
require
|
21
|
+
require 'rvc/vim'
|
22
|
+
|
23
|
+
require "terminal-table"
|
22
24
|
|
23
25
|
opts :summarize do
|
24
26
|
summary ""
|
@@ -440,13 +442,13 @@ opts :show_running_config do
|
|
440
442
|
end
|
441
443
|
|
442
444
|
def show_running_config vds
|
443
|
-
|
445
|
+
shell.cmds.basic.info vds
|
444
446
|
portgroups = vds.children['portgroups']
|
445
447
|
portgroups.rvc_link vds, 'portgroups'
|
446
448
|
vds.children['portgroups'].children.each do |name, pg|
|
447
449
|
pg.rvc_link portgroups, name
|
448
450
|
puts '---'
|
449
|
-
|
451
|
+
shell.cmds.basic.info pg
|
450
452
|
end
|
451
453
|
end
|
452
454
|
|
@@ -461,13 +463,13 @@ def show_all_portgroups path
|
|
461
463
|
paths = nil
|
462
464
|
end
|
463
465
|
|
464
|
-
vds =
|
466
|
+
vds = shell.cmds.find.find_items nil, paths, ['vds']
|
465
467
|
pgs = []
|
466
468
|
vds.each do |v|
|
467
469
|
v.portgroup.each { |pg| pgs << pg}
|
468
470
|
end
|
469
|
-
|
470
|
-
|
471
|
+
shell.cmds.basic.table pgs, { :field => ["vds_name", "name", "vlan"],
|
472
|
+
:field_given => true }
|
471
473
|
end
|
472
474
|
|
473
475
|
opts :show_all_vds do
|
@@ -481,9 +483,9 @@ def show_all_vds path
|
|
481
483
|
paths = nil
|
482
484
|
end
|
483
485
|
|
484
|
-
vds =
|
485
|
-
|
486
|
-
|
486
|
+
vds = shell.cmds.find.find_items nil, paths, ['vds']
|
487
|
+
shell.cmds.basic.table vds, { :field => ['name', 'vlans', 'hosts'],
|
488
|
+
:field_given => true }
|
487
489
|
end
|
488
490
|
|
489
491
|
opts :show_all_ports do
|
@@ -571,7 +573,7 @@ def show_all_ports path
|
|
571
573
|
rows.each { |r| r.delete_at(2) }
|
572
574
|
end
|
573
575
|
|
574
|
-
t =
|
576
|
+
t = Terminal::Table.new(columns)
|
575
577
|
rows.sort_by { |o| o[0] }.each { |o| t << o }
|
576
578
|
puts t
|
577
579
|
end
|
@@ -603,3 +605,58 @@ def abbrev_hostnames names
|
|
603
605
|
}
|
604
606
|
end
|
605
607
|
end
|
608
|
+
|
609
|
+
opts :add_hosts do
|
610
|
+
summary "Add hosts to a vDS"
|
611
|
+
arg :vds, nil, :lookup => VIM::DistributedVirtualSwitch
|
612
|
+
arg :hosts, nil, :lookup => VIM::HostSystem, :multi => true
|
613
|
+
opt :vmnic, "Name of vmnic (multiple allowed)", :multi => true, :type => :string
|
614
|
+
end
|
615
|
+
|
616
|
+
def add_hosts vds, hosts, opts
|
617
|
+
pnicSpec = opts[:vmnic].map do |x|
|
618
|
+
VIM::DistributedVirtualSwitchHostMemberPnicSpec({:pnicDevice => x})
|
619
|
+
end
|
620
|
+
dvsConfig = VIM::DVSConfigSpec({
|
621
|
+
:configVersion => vds.config.configVersion,
|
622
|
+
:host => hosts.map do |host|
|
623
|
+
{
|
624
|
+
:operation => :add,
|
625
|
+
:host => host,
|
626
|
+
:backing => VIM::DistributedVirtualSwitchHostMemberPnicBacking({
|
627
|
+
:pnicSpec => pnicSpec
|
628
|
+
})
|
629
|
+
}
|
630
|
+
end
|
631
|
+
})
|
632
|
+
task = vds.ReconfigureDvs_Task(:spec => dvsConfig)
|
633
|
+
progress([task])
|
634
|
+
end
|
635
|
+
|
636
|
+
opts :create_vmknic do
|
637
|
+
summary "Create a vmknic on vDS on one or more hosts. Always uses DHCP"
|
638
|
+
arg :portgroup, nil, :lookup => VIM::Network
|
639
|
+
arg :host, nil, :lookup => VIM::HostSystem, :multi => true
|
640
|
+
end
|
641
|
+
|
642
|
+
def create_vmknic portgroup, hosts, opts
|
643
|
+
if !portgroup.is_a?(VIM::DistributedVirtualPortgroup)
|
644
|
+
err "Legacy switches not supported yet"
|
645
|
+
end
|
646
|
+
hosts.each do |host|
|
647
|
+
ns = host.configManager.networkSystem
|
648
|
+
vmknic_name = ns.AddVirtualNic(
|
649
|
+
:portgroup => "",
|
650
|
+
:nic => {
|
651
|
+
:ip => {
|
652
|
+
:dhcp => true
|
653
|
+
},
|
654
|
+
:distributedVirtualPort => VIM::DistributedVirtualSwitchPortConnection(
|
655
|
+
:portgroupKey => portgroup.key,
|
656
|
+
:switchUuid => portgroup.config.distributedVirtualSwitch.uuid,
|
657
|
+
)
|
658
|
+
}
|
659
|
+
)
|
660
|
+
puts "Host #{host.name}: Added vmknic #{vmknic_name}"
|
661
|
+
end
|
662
|
+
end
|