rvc 1.5.0 → 1.6.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/README.rdoc +1 -1
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/bin/rvc +53 -9
- data/lib/rvc/completion.rb +57 -19
- data/lib/rvc/extensions/ComputeResource.rb +2 -2
- data/lib/rvc/extensions/DVPortSetting.rb +108 -0
- data/lib/rvc/extensions/Datacenter.rb +19 -4
- data/lib/rvc/extensions/Datastore.rb +6 -1
- data/lib/rvc/extensions/DistributedVirtualPort.rb +146 -0
- data/lib/rvc/extensions/DistributedVirtualPortgroup.rb +274 -10
- data/lib/rvc/extensions/DistributedVirtualSwitch.rb +124 -3
- data/lib/rvc/extensions/Folder.rb +9 -2
- data/lib/rvc/extensions/HostSystem.rb +60 -0
- data/lib/rvc/extensions/ManagedEntity.rb +19 -0
- data/lib/rvc/extensions/ParaVirtualSCSIController.rb +25 -0
- data/lib/rvc/extensions/PerfCounterInfo.rb +26 -0
- data/lib/rvc/extensions/PerformanceManager.rb +83 -0
- data/lib/rvc/extensions/ResourcePool.rb +21 -0
- data/lib/rvc/extensions/VirtualDevice.rb +59 -0
- data/lib/rvc/extensions/VirtualDisk.rb +25 -0
- data/lib/rvc/extensions/VirtualEthernetCard.rb +32 -0
- data/lib/rvc/extensions/VirtualMachine.rb +112 -1
- data/lib/rvc/field.rb +122 -0
- data/lib/rvc/filesystem_session.rb +20 -0
- data/lib/rvc/inventory.rb +35 -12
- data/lib/rvc/known_hosts.rb +20 -0
- data/lib/rvc/memory_session.rb +20 -0
- data/lib/rvc/modules.rb +67 -7
- data/lib/rvc/modules/alarm.rb +37 -0
- data/lib/rvc/modules/basic.rb +172 -41
- data/lib/rvc/modules/cluster.rb +18 -2
- data/lib/rvc/modules/core.rb +63 -0
- data/lib/rvc/modules/datastore.rb +158 -0
- data/lib/rvc/modules/device.rb +275 -0
- data/lib/rvc/modules/esxcli.rb +193 -0
- data/lib/rvc/modules/find.rb +125 -0
- data/lib/rvc/modules/issue.rb +33 -0
- data/lib/rvc/modules/perf.rb +284 -0
- data/lib/rvc/modules/permissions.rb +20 -0
- data/lib/rvc/modules/resource_pool.rb +69 -0
- data/lib/rvc/modules/role.rb +23 -3
- data/lib/rvc/modules/snapshot.rb +20 -0
- data/lib/rvc/modules/vds.rb +605 -0
- data/lib/rvc/modules/vim.rb +103 -26
- data/lib/rvc/modules/vm.rb +93 -220
- data/lib/rvc/modules/vnc.rb +50 -13
- data/lib/rvc/option_parser.rb +50 -2
- data/lib/rvc/readline-ffi.rb +2 -1
- data/lib/rvc/shell.rb +34 -33
- data/lib/rvc/util.rb +120 -2
- data/test/test_fs.rb +9 -5
- data/test/test_metric.rb +79 -0
- metadata +33 -3
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -7,11 +7,12 @@ begin
|
|
7
7
|
gem.email = "rlane@vmware.com"
|
8
8
|
#gem.homepage = ""
|
9
9
|
gem.authors = ["Rich Lane"]
|
10
|
-
gem.add_dependency 'rbvmomi', '>= 1.
|
10
|
+
gem.add_dependency 'rbvmomi', '>= 1.5.0'
|
11
11
|
gem.add_dependency 'trollop', '>= 1.16.2'
|
12
12
|
gem.add_dependency 'backports', '>= 1.18.2'
|
13
13
|
gem.add_dependency 'highline', '>= 1.6.1'
|
14
14
|
gem.add_dependency 'zip', '>= 2.0.2'
|
15
|
+
gem.add_dependency 'terminal-table', '>= 1.4.2'
|
15
16
|
#gem.add_dependency 'ffi', '>= 1.0.7'
|
16
17
|
end
|
17
18
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.6.0
|
data/bin/rvc
CHANGED
@@ -28,6 +28,7 @@ require 'shellwords'
|
|
28
28
|
require 'yaml'
|
29
29
|
require 'backports'
|
30
30
|
require 'rvc'
|
31
|
+
require 'tempfile'
|
31
32
|
|
32
33
|
VIM = RbVmomi::VIM
|
33
34
|
|
@@ -54,6 +55,7 @@ EOS
|
|
54
55
|
opt :create_directory, "Create the initial directory if it doesn't exist", :short => :none
|
55
56
|
opt :cmd, "command to evaluate", :short => 'c', :multi => true, :type => :string
|
56
57
|
opt :script, "file to execute", :short => 's', :type => :string
|
58
|
+
opt :cookie, "authentication cookie file", :short => 'k', :type => :string
|
57
59
|
end
|
58
60
|
|
59
61
|
$interactive = $opts[:script].nil? and $stdin.tty?
|
@@ -77,20 +79,38 @@ $shell.session.connections.each do |key|
|
|
77
79
|
conn = $shell.session.get_connection(key) or fail "no such connection #{key.inspect}"
|
78
80
|
uri = "#{conn['username']}@#{conn['host']}"
|
79
81
|
begin
|
80
|
-
puts "Connecting to #{
|
82
|
+
puts "Connecting to #{conn['host']}..."
|
81
83
|
CMD.vim.connect uri, {}
|
82
84
|
rescue RVC::Util::UserError
|
83
|
-
puts "Failed to connect to #{
|
85
|
+
puts "Failed to connect to #{conn['host']}: #{$!.message}"
|
84
86
|
exit 1
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
90
|
+
cookies = {}
|
91
|
+
certdigests = {}
|
92
|
+
if $opts[:cookie]
|
93
|
+
File.readlines($opts[:cookie]).each do |info|
|
94
|
+
host, cookie, certdigest = info.chomp.split('|')
|
95
|
+
cookies[host] = cookie
|
96
|
+
certdigests[host] = certdigest
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
88
100
|
ARGV.each do |uri|
|
101
|
+
# get hostname from uri to display in "connecting to..." message
|
102
|
+
hostinfo = uri.split("@")
|
103
|
+
host = if hostinfo.length > 1
|
104
|
+
hostinfo[1].split(":")[0]
|
105
|
+
else
|
106
|
+
hostinfo[0].split(":")[0]
|
107
|
+
end
|
89
108
|
begin
|
90
|
-
puts "Connecting to #{
|
91
|
-
CMD.vim.connect uri, {
|
109
|
+
puts "Connecting to #{host}..." if (ARGV+$shell.session.connections).size > 1
|
110
|
+
CMD.vim.connect uri, {:cookie => cookies[host],
|
111
|
+
:certdigest => certdigests[host]}
|
92
112
|
rescue RVC::Util::UserError
|
93
|
-
puts "Failed to connect to #{
|
113
|
+
puts "Failed to connect to #{host}: #{$!.message}"
|
94
114
|
exit 1
|
95
115
|
end
|
96
116
|
end
|
@@ -99,7 +119,11 @@ if $interactive
|
|
99
119
|
RVC::Completion.install
|
100
120
|
history_fn = "#{ENV['HOME']}/.rvc-history"
|
101
121
|
IO.foreach(history_fn) { |l| Readline::HISTORY << l.chomp } rescue puts "Welcome to RVC. Try the 'help' command."
|
102
|
-
|
122
|
+
begin
|
123
|
+
history = File.open(history_fn, 'a')
|
124
|
+
rescue Errno::EACCES
|
125
|
+
history = nil
|
126
|
+
end
|
103
127
|
end
|
104
128
|
|
105
129
|
if $opts[:path]
|
@@ -127,23 +151,43 @@ if defined? Ocra
|
|
127
151
|
end
|
128
152
|
|
129
153
|
if $interactive
|
130
|
-
|
154
|
+
if ENV['DISPLAY']
|
155
|
+
$stderr.puts "VMRC is not installed. You will be unable to view virtual machine consoles. Use the vmrc.install command to install it." unless CMD.vmrc.find_vmrc
|
156
|
+
end
|
131
157
|
$stderr.puts "Use the 'connect' command to connect to an ESX or VC server." if $shell.connections.empty?
|
132
158
|
CMD.basic.ls RVC::Util.lookup_single('.')
|
133
159
|
end
|
134
160
|
|
161
|
+
trap "SIGCHLD" do |sig|
|
162
|
+
begin
|
163
|
+
while pid = Process.wait(-1, Process::WNOHANG)
|
164
|
+
end
|
165
|
+
rescue Errno::ECHILD
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
135
169
|
if $opts[:script]
|
136
170
|
$shell.eval_ruby File.read($opts[:script]), $opts[:script]
|
137
171
|
else
|
138
172
|
while true
|
139
173
|
begin
|
140
|
-
|
174
|
+
begin
|
175
|
+
input = $opts[:cmd].shift || Readline.readline($shell.prompt, false) or break
|
176
|
+
rescue
|
177
|
+
puts "\n#{$!.class} during readline: #{$!.message}"
|
178
|
+
$!.backtrace.each { |x| puts x } if $shell.debug
|
179
|
+
next
|
180
|
+
end
|
141
181
|
input = input.strip
|
142
182
|
next if input.empty?
|
143
|
-
(history.puts
|
183
|
+
(history && history.puts(input); Readline::HISTORY << input) unless input == Readline::HISTORY.to_a[-1]
|
144
184
|
$shell.eval_input input
|
145
185
|
rescue Interrupt
|
146
186
|
puts
|
147
187
|
end
|
148
188
|
end
|
149
189
|
end
|
190
|
+
|
191
|
+
$shell.connections.each do |name, conn|
|
192
|
+
conn.close if conn.respond_to? :close rescue puts("failed to close connection #{name.inspect}: #{$!.class}: #{$!.message}")
|
193
|
+
end
|
data/lib/rvc/completion.rb
CHANGED
@@ -40,10 +40,16 @@ module Completion
|
|
40
40
|
|
41
41
|
Completor = lambda do |word|
|
42
42
|
return unless word
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
begin
|
44
|
+
line = Readline.line_buffer if Readline.respond_to? :line_buffer
|
45
|
+
append_char, candidates = RVC::Completion.complete word, line
|
46
|
+
Readline.completion_append_character = append_char
|
47
|
+
candidates
|
48
|
+
rescue RVC::Util::UserError
|
49
|
+
puts
|
50
|
+
puts $!.message
|
51
|
+
Readline.refresh_line
|
52
|
+
end
|
47
53
|
end
|
48
54
|
|
49
55
|
def self.install
|
@@ -58,25 +64,44 @@ module Completion
|
|
58
64
|
end
|
59
65
|
|
60
66
|
def self.complete word, line
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
+
line ||= ''
|
68
|
+
first_whitespace_index = line.index(' ')
|
69
|
+
|
70
|
+
if Readline.respond_to? :point
|
71
|
+
do_complete_cmd = !first_whitespace_index || first_whitespace_index >= Readline.point
|
72
|
+
do_complete_args = !do_complete_cmd
|
67
73
|
else
|
68
|
-
|
74
|
+
do_complete_cmd = true
|
75
|
+
do_complete_args = true
|
76
|
+
end
|
77
|
+
|
78
|
+
candidates = []
|
79
|
+
|
80
|
+
if do_complete_cmd
|
81
|
+
candidates.concat cmd_candidates(word)
|
69
82
|
end
|
70
83
|
|
71
|
-
|
84
|
+
if do_complete_args
|
85
|
+
mod, cmd, args = Shell.parse_input line
|
86
|
+
if mod and mod.completor_for cmd
|
87
|
+
candidates.concat RVC::complete_for_cmd(line, word)
|
88
|
+
else
|
89
|
+
candidates.concat(fs_candidates(word) +
|
90
|
+
long_option_candidates(mod, cmd, word))
|
91
|
+
end
|
92
|
+
end
|
72
93
|
|
73
|
-
if candidates.size == 1
|
74
|
-
append_char =
|
94
|
+
if candidates.size == 1
|
95
|
+
append_char = candidates[0][1]
|
75
96
|
else
|
76
|
-
append_char = '
|
97
|
+
append_char = '?' # should never be displayed
|
77
98
|
end
|
78
99
|
|
79
|
-
return append_char, candidates
|
100
|
+
return append_char, candidates.map(&:first)
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.fs_candidates word
|
104
|
+
child_candidates(word) + mark_candidates(word)
|
80
105
|
end
|
81
106
|
|
82
107
|
def self.cmd_candidates word
|
@@ -86,7 +111,18 @@ module Completion
|
|
86
111
|
m.commands.each { |s| ret << "#{name}.#{s}" }
|
87
112
|
end
|
88
113
|
ret.concat ALIASES.keys
|
89
|
-
ret.
|
114
|
+
ret.grep(prefix_regex).sort.
|
115
|
+
map { |x| [x, ' '] }
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.long_option_candidates mod, cmd, word
|
119
|
+
return [] unless mod and cmd
|
120
|
+
parser = mod.opts_for cmd
|
121
|
+
return [] unless parser.is_a? RVC::OptionParser
|
122
|
+
prefix_regex = /^#{Regexp.escape(word)}/
|
123
|
+
parser.specs.map { |k,v| "--#{v[:long]}" }.
|
124
|
+
grep(prefix_regex).sort.
|
125
|
+
map { |x| [x, ' '] }
|
90
126
|
end
|
91
127
|
|
92
128
|
# TODO convert to globbing
|
@@ -101,13 +137,15 @@ module Completion
|
|
101
137
|
children.
|
102
138
|
select { |k,v| k.gsub(' ', '\\ ') =~ /^#{Regexp.escape(last)}/ }.
|
103
139
|
map { |k,v| (arcs+[k])*'/' }.
|
104
|
-
map { |x| x.gsub ' ', '\\ ' }
|
140
|
+
map { |x| x.gsub ' ', '\\ ' }.
|
141
|
+
map { |x| [x, '/'] }
|
105
142
|
end
|
106
143
|
|
107
144
|
def self.mark_candidates word
|
108
145
|
return [] unless word.empty? || word[0..0] == '~'
|
109
146
|
prefix_regex = /^#{Regexp.escape(word[1..-1] || '')}/
|
110
|
-
$shell.session.marks.
|
147
|
+
$shell.session.marks.grep(prefix_regex).sort.
|
148
|
+
map { |x| ["~#{x}", '/'] }
|
111
149
|
end
|
112
150
|
end
|
113
151
|
end
|
@@ -25,8 +25,8 @@ class RbVmomi::VIM::ComputeResource
|
|
25
25
|
pct_cpu_used = 100.0*stats[:usedCPU]/stats[:totalCPU]
|
26
26
|
pct_mem_used = 100.0*stats[:usedMem]/stats[:totalMem]
|
27
27
|
puts "name: #{name}"
|
28
|
-
puts "cpu #{stats[:totalCPU]} GHz (#{pct_cpu_used.to_i}% used)"
|
29
|
-
puts "memory #{stats[:totalMem]} GB (#{pct_mem_used.to_i}% used)"
|
28
|
+
puts "cpu: #{stats[:totalCPU]/1e3} GHz (#{pct_cpu_used.to_i}% used)"
|
29
|
+
puts "memory: #{stats[:totalMem]/1e3} GB (#{pct_mem_used.to_i}% used)"
|
30
30
|
puts "hosts:"
|
31
31
|
host.each do |h|
|
32
32
|
puts " #{h.name}"
|
@@ -0,0 +1,108 @@
|
|
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
|
+
include RVC::Util
|
22
|
+
|
23
|
+
class RbVmomi::VIM::DVPortSetting
|
24
|
+
def dump_config vds, prefix, show_inheritance = true, show_uplinkinfo = true
|
25
|
+
@show_inheritance = show_inheritance
|
26
|
+
|
27
|
+
# map network respool to human-readable name
|
28
|
+
if self.networkResourcePoolKey
|
29
|
+
poolName = translate_respool vds, self.networkResourcePoolKey, show_inheritance
|
30
|
+
end
|
31
|
+
puts_policy "#{prefix}blocked:", self.blocked
|
32
|
+
puts_policy("#{prefix}vlan:", self.vlan, "", nil) { |v| translate_vlan v }
|
33
|
+
if self.networkResourcePoolKey
|
34
|
+
puts "#{prefix}network resource pool: #{poolName}"
|
35
|
+
end
|
36
|
+
p = self.inShapingPolicy
|
37
|
+
if p
|
38
|
+
puts "#{prefix}Rx Shaper: "
|
39
|
+
puts_policy "#{prefix} enabled:", p.enabled
|
40
|
+
avg_bw = p.averageBandwidth
|
41
|
+
puts_policy("#{prefix} average bw:", avg_bw, "b/sec"){|v|metric(v)}
|
42
|
+
puts_policy("#{prefix} peak bw:", p.peakBandwidth, "b/sec"){|v|metric(v)}
|
43
|
+
puts_policy("#{prefix} burst size:", p.burstSize, "B"){|v|metric(v)}
|
44
|
+
end
|
45
|
+
p = self.outShapingPolicy
|
46
|
+
if p
|
47
|
+
puts "#{prefix}Tx Shaper:"
|
48
|
+
puts_policy "#{prefix} enabled:", p.enabled
|
49
|
+
avg_bw = p.averageBandwidth
|
50
|
+
puts_policy("#{prefix} average bw:", avg_bw, "b/sec") { |v| metric(v) }
|
51
|
+
puts_policy("#{prefix} peak bw:", p.peakBandwidth, "b/sec") {|v| metric(v)}
|
52
|
+
puts_policy("#{prefix} burst size:", p.burstSize, "B") {|v| metric(v)}
|
53
|
+
end
|
54
|
+
if show_uplinkinfo
|
55
|
+
p = self.uplinkTeamingPolicy
|
56
|
+
if p
|
57
|
+
puts "#{prefix}Uplink Teaming Policy:"
|
58
|
+
puts_policy "#{prefix} policy:", p.policy #XXX map the strings values
|
59
|
+
puts_policy "#{prefix} reverse policy:", p.reversePolicy
|
60
|
+
puts_policy "#{prefix} notify switches:", p.notifySwitches
|
61
|
+
puts_policy "#{prefix} rolling order:", p.rollingOrder
|
62
|
+
c = p.failureCriteria
|
63
|
+
if c
|
64
|
+
puts "#{prefix} Failure Criteria: "
|
65
|
+
puts_policy "#{prefix} check speed:", c.checkSpeed
|
66
|
+
puts_policy("#{prefix} speed:", c.speed, "Mb/sec")# { |v| metric(v) }
|
67
|
+
puts_policy "#{prefix} check duplex:", c.checkDuplex
|
68
|
+
puts_policy "#{prefix} full duplex:", c.fullDuplex
|
69
|
+
puts_policy "#{prefix} check error percentage:", c.checkErrorPercent
|
70
|
+
puts_policy "#{prefix} max error percentage:", c.percentage, "%"
|
71
|
+
puts_policy "#{prefix} check beacon:", c.checkBeacon
|
72
|
+
end
|
73
|
+
o = p.uplinkPortOrder
|
74
|
+
if o
|
75
|
+
puts "#{prefix} Uplink Port Order:"
|
76
|
+
puts_policy("#{prefix} active:", o,"", :activeUplinkPort){|v|v.join(',')}
|
77
|
+
puts_policy("#{prefix} standby:",o,"",:standbyUplinkPort){|v|v.join(',')}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
p = self.securityPolicy
|
82
|
+
if p
|
83
|
+
puts "#{prefix}Security:"
|
84
|
+
puts_policy "#{prefix} allow promiscuous mode:", p.allowPromiscuous
|
85
|
+
puts_policy "#{prefix} allow mac changes:", p.macChanges
|
86
|
+
puts_policy "#{prefix} allow forged transmits:", p.forgedTransmits
|
87
|
+
puts_policy "#{prefix}enable ipfix monitoring:", self.ipfixEnabled
|
88
|
+
puts_policy "#{prefix}forward all tx to uplink:", self.txUplink
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def puts_policy prefix, policy, suffix = "", prop = :value, &b
|
93
|
+
b ||= lambda { |v| v }
|
94
|
+
if policy
|
95
|
+
if prop != nil
|
96
|
+
v = policy.send(prop)
|
97
|
+
else
|
98
|
+
v = policy
|
99
|
+
end
|
100
|
+
print "#{prefix} #{b.call(v)}#{suffix}"
|
101
|
+
if @show_inheritance and policy.inherited == false
|
102
|
+
puts "*"
|
103
|
+
else
|
104
|
+
puts ""
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -27,10 +27,25 @@ class RbVmomi::VIM::Datacenter
|
|
27
27
|
vmFolder, datastoreFolder, networkFolder, hostFolder =
|
28
28
|
collect *%w(vmFolder datastoreFolder networkFolder hostFolder)
|
29
29
|
{
|
30
|
-
'
|
31
|
-
'
|
32
|
-
'
|
33
|
-
'
|
30
|
+
'vms' => vmFolder,
|
31
|
+
'datastores' => datastoreFolder,
|
32
|
+
'networks' => networkFolder,
|
33
|
+
'computers' => hostFolder,
|
34
34
|
}
|
35
35
|
end
|
36
|
+
|
37
|
+
# For compatibility with previous RVC versions
|
38
|
+
def traverse_one arc
|
39
|
+
children = self.children
|
40
|
+
return children[arc] if children.member? arc
|
41
|
+
if arc == 'vm' then return vmFolder
|
42
|
+
elsif arc == 'datastore' then return datastoreFolder
|
43
|
+
elsif arc == 'network' then return networkFolder
|
44
|
+
elsif arc == 'host' then return hostFolder
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.folder?
|
49
|
+
true
|
50
|
+
end
|
36
51
|
end
|
@@ -23,10 +23,15 @@ class RbVmomi::VIM::Datastore
|
|
23
23
|
s, info, = collect :summary, :info
|
24
24
|
puts "type: #{s.type}"
|
25
25
|
puts "url: #{s.accessible ? s.url : '<inaccessible>'}"
|
26
|
-
puts "uuid: #{info.vmfs.uuid}"
|
27
26
|
puts "multipleHostAccess: #{s.multipleHostAccess}"
|
28
27
|
puts "capacity: %0.2fGB" % (s.capacity.to_f/10**9)
|
29
28
|
puts "free space: %0.2fGB" % (s.freeSpace.to_f/10**9)
|
29
|
+
case info
|
30
|
+
when VIM::VmfsDatastoreInfo
|
31
|
+
puts "uuid: #{info.vmfs.uuid}"
|
32
|
+
when VIM::NasDatastoreInfo
|
33
|
+
puts "location: #{info.nas.remoteHost}:#{info.nas.remotePath}"
|
34
|
+
end
|
30
35
|
end
|
31
36
|
|
32
37
|
def self.ls_properties
|
@@ -0,0 +1,146 @@
|
|
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
|
+
class RbVmomi::VIM::DistributedVirtualPort
|
22
|
+
include RVC::InventoryObject
|
23
|
+
|
24
|
+
field 'ip' do
|
25
|
+
summary "The guest tools reported IP address."
|
26
|
+
property 'connectee'
|
27
|
+
block do |c|
|
28
|
+
ip = nil
|
29
|
+
vm = c.connectedEntity
|
30
|
+
if vm.is_a? VIM::VirtualMachine
|
31
|
+
info = vm.guest.net.reject { |info|
|
32
|
+
info.deviceConfigId.to_s != c.nicKey
|
33
|
+
}.first
|
34
|
+
if info != nil
|
35
|
+
#XXX deal with multiple ips?
|
36
|
+
ip = info.ipAddress[0]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
ip
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
field 'mac' do
|
44
|
+
summary "The guest tools reported IP address."
|
45
|
+
property 'connectee'
|
46
|
+
block do |c|
|
47
|
+
mac = nil
|
48
|
+
vm = c.connectedEntity
|
49
|
+
if vm.is_a? VIM::VirtualMachine
|
50
|
+
info = vm.config.hardware.device.reject { |device|
|
51
|
+
!(device.class < VIM::VirtualEthernetCard &&
|
52
|
+
device.key.to_s == c.nicKey)
|
53
|
+
}.first
|
54
|
+
if info != nil
|
55
|
+
mac = info.macAddress
|
56
|
+
end
|
57
|
+
end
|
58
|
+
mac
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def display_info
|
63
|
+
# if possible, get info about the connected VM
|
64
|
+
vm_name = ""
|
65
|
+
mac = ""
|
66
|
+
ip = ""
|
67
|
+
if self.connectee
|
68
|
+
vm = self.connectee.connectedEntity
|
69
|
+
if vm.class == VIM::VirtualMachine
|
70
|
+
vm_name = vm.name
|
71
|
+
mac = vm.config.hardware.device.reject { |device|
|
72
|
+
!(device.class < VIM::VirtualEthernetCard &&
|
73
|
+
device.key.to_s == self.connectee.nicKey)
|
74
|
+
}.first.macAddress
|
75
|
+
nicinfo = vm.guest.net.reject { |info|
|
76
|
+
info.deviceConfigId.to_s != self.connectee.nicKey.to_s
|
77
|
+
}.first
|
78
|
+
|
79
|
+
if nicinfo != nil
|
80
|
+
ip = nicinfo.ipAddress
|
81
|
+
if nicinfo.macAddress != nil and nicinfo.macAddress != ""
|
82
|
+
mac = nicinfo.macAddress
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# if possible, get info about the port configuration
|
89
|
+
poolName = "-"
|
90
|
+
vlan = "-"
|
91
|
+
link_up = false
|
92
|
+
if self.state.runtimeInfo
|
93
|
+
vds = self.rvc_parent.config.distributedVirtualSwitch
|
94
|
+
poolName = translate_respool vds, self.config.setting.networkResourcePoolKey
|
95
|
+
vlan = translate_vlan self.state.runtimeInfo.vlanIds
|
96
|
+
link_up = self.state.runtimeInfo.linkUp
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
#puts "name: #{self.config.name}"
|
101
|
+
puts "link up: #{link_up}"
|
102
|
+
#puts "vds: #{vds.name}"
|
103
|
+
#puts "portgroup: #{self.rvc_parent.name}"
|
104
|
+
#puts "vlan: #{vlan}"
|
105
|
+
#puts "network resource pool: #{poolName}"
|
106
|
+
puts "name: #{self.config.name}"
|
107
|
+
puts "description: #{self.config.description}"
|
108
|
+
puts "host: #{if self.proxyHost then self.proxyHost.name end}"
|
109
|
+
puts "vm: #{vm_name}"
|
110
|
+
puts "mac: #{mac}"
|
111
|
+
puts "ip: #{ip}"
|
112
|
+
puts "Port Settings:"
|
113
|
+
#XXX scope?
|
114
|
+
self.config.setting.dump_config vds, " ", true, false
|
115
|
+
if self.state
|
116
|
+
if self.state.stats
|
117
|
+
puts "Statistics:"
|
118
|
+
stats = self.state.stats
|
119
|
+
# normally, i would explicitly write this out, but in this case
|
120
|
+
# the stats are pretty self explanatory, and require pretty much
|
121
|
+
# no formatting, so we just procedurally generate them
|
122
|
+
stats.class.full_props_desc.map { |stat|
|
123
|
+
stat = stat['name']
|
124
|
+
num = stats.send(stat)
|
125
|
+
# skip uninteresting properties
|
126
|
+
if !num.is_a?(Integer) then next end
|
127
|
+
# un-camelcase the name of the stat
|
128
|
+
stat = stat.gsub(/[A-Z]/) { |p| ' ' + p.downcase}
|
129
|
+
puts " #{stat}: #{num}"
|
130
|
+
}
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def children
|
136
|
+
{
|
137
|
+
'vm' => self.connectee.connectedEntity,
|
138
|
+
'host' => self.proxyHost
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
142
|
+
def invalidate vds
|
143
|
+
port = vds.FetchDVPorts(:criteria => { :portKey => [self.key] }).first
|
144
|
+
@props = port.props
|
145
|
+
end
|
146
|
+
end
|