rvc 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/LICENSE +19 -0
  2. data/README.rdoc +120 -0
  3. data/Rakefile +39 -0
  4. data/TODO +4 -0
  5. data/VERSION +1 -0
  6. data/bin/rvc +104 -0
  7. data/lib/rvc.rb +31 -0
  8. data/lib/rvc/completion.rb +110 -0
  9. data/lib/rvc/extensions/ClusterComputeResource.rb +42 -0
  10. data/lib/rvc/extensions/ComputeResource.rb +47 -0
  11. data/lib/rvc/extensions/Datacenter.rb +36 -0
  12. data/lib/rvc/extensions/Datastore.rb +188 -0
  13. data/lib/rvc/extensions/DistributedVirtualPortgroup.rb +38 -0
  14. data/lib/rvc/extensions/DistributedVirtualSwitch.rb +40 -0
  15. data/lib/rvc/extensions/Folder.rb +33 -0
  16. data/lib/rvc/extensions/HostSystem.rb +48 -0
  17. data/lib/rvc/extensions/ManagedEntity.rb +28 -0
  18. data/lib/rvc/extensions/Network.rb +28 -0
  19. data/lib/rvc/extensions/ResourcePool.rb +52 -0
  20. data/lib/rvc/extensions/VirtualMachine.rb +72 -0
  21. data/lib/rvc/fs.rb +123 -0
  22. data/lib/rvc/inventory.rb +125 -0
  23. data/lib/rvc/modules.rb +74 -0
  24. data/lib/rvc/modules/basic.rb +276 -0
  25. data/lib/rvc/modules/datastore.rb +63 -0
  26. data/lib/rvc/modules/host.rb +29 -0
  27. data/lib/rvc/modules/resource_pool.rb +95 -0
  28. data/lib/rvc/modules/vim.rb +128 -0
  29. data/lib/rvc/modules/vm.rb +607 -0
  30. data/lib/rvc/modules/vmrc.rb +72 -0
  31. data/lib/rvc/modules/vnc.rb +111 -0
  32. data/lib/rvc/option_parser.rb +114 -0
  33. data/lib/rvc/path.rb +37 -0
  34. data/lib/rvc/readline-ffi.rb +41 -0
  35. data/lib/rvc/shell.rb +220 -0
  36. data/lib/rvc/ttl_cache.rb +44 -0
  37. data/lib/rvc/util.rb +168 -0
  38. data/test/_test_completion.rb +27 -0
  39. data/test/_test_option_parser.rb +6 -0
  40. data/test/inventory_fixtures.rb +15 -0
  41. data/test/test_fs.rb +113 -0
  42. data/test/test_parse_path.rb +41 -0
  43. metadata +146 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
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.
@@ -0,0 +1,120 @@
1
+ = RVC - Ruby vSphere Console
2
+
3
+ == Introduction
4
+
5
+ RVC is a console UI for VMware ESX and VirtualCenter. The vSphere object graph
6
+ is presented as a virtual filesystem, allowing you to navigate and run commands
7
+ against managed entities using familiar shell syntax. RVC doesn't (yet) have
8
+ every feature vSphere Client does, but for common tasks it can be much more
9
+ efficient than clicking through a GUI.
10
+
11
+ == Installation
12
+
13
+ gem install rvc
14
+
15
+ == Usage
16
+
17
+ % rvc 192.168.1.105
18
+ username: Administrator
19
+ password:
20
+ 0 dc (datacenter)
21
+ 192.168.1.105:/> cd dc/host/192.168.1.100/
22
+ 192.168.1.105:/dc/host/192.168.1.100/> ls
23
+ 0 host [192.168.1.100] (host): cpu 2*2*2.81 GHz, memory 2.00 GB
24
+ 1 resourcePool [Resources]: cpu 4.35/4.35/normal, mem 0.48/0.48/normal
25
+ 192.168.1.105:/dc/host/192.168.1.100/> ls host/vms/
26
+ 0 foo: poweredOn
27
+ 192.168.1.105:/dc/host/192.168.1.100/> i host/vms/foo
28
+ name: foo
29
+ host: dc/host/192.168.1.100/192.168.1.100
30
+ tools: guestToolsNotRunning
31
+ VC UUID: 5259d5d2-b767-43c9-db6d-fbf5cc4b6f02
32
+ power: poweredOn
33
+ cpus: 1
34
+ memory: 128 MB
35
+ nics:
36
+ Network adapter 1: "VM Network" connected 00:0c:29:c6:5d:2a
37
+ 192.168.1.105:/dc/host/192.168.1.100/> off host/vms/foo
38
+ PowerOffVM foo: success
39
+ 192.168.1.105:/dc/host/192.168.1.100/> quit
40
+
41
+ Enter "help" to see a list of all available commands.
42
+
43
+ All RVC commands exist in modules, and may optionally have aliases. For
44
+ example, the command to power off a VM is actually "vm.off", since it exists in
45
+ the "vm" module, but since it is a common operation it has been aliased to
46
+ "off".
47
+
48
+ == Features
49
+
50
+ === Tab-completion
51
+
52
+ Commands and paths can be tab completed in the usual fashion. Whitespace must
53
+ be escaped with a backslash.
54
+
55
+ === Marks
56
+
57
+ 192.168.1.105:/> mark a dc/vm/foo
58
+ 192.168.1.105:/> on ~a
59
+ PowerOnVM foo: success
60
+ 192.168.1.105:/> off ~a
61
+ PowerOffVM foo: success
62
+
63
+ Marks allow you to save a path for later use. Refer to a mark by prefixing its
64
+ name with a tilde. The "ls" command automatically creates numeric marks for
65
+ each object listed; these are the numbers in the first column. As a special
66
+ case, you don't need to use a tilde with numeric marks. The "cd" command
67
+ automatically creates the mark "~~" pointing to the previous directory. If a
68
+ mark reference is input instead of a command then RVC will cd to the marked
69
+ object. Thus, "~~" is a convenient way to toggle between two directories.
70
+
71
+ When the working directory is a descendant of a Datacenter object, the mark "~"
72
+ refers to the Datacenter. For example "~/datastore" is a convenient way to get
73
+ the datastore folder of the current datacenter.
74
+
75
+ === Ruby mode
76
+
77
+ Beginning an input line with "/" causes RVC to treat it as Ruby code and eval
78
+ it. This gives you direct access to the underlying RbVmomi library. If the line
79
+ "//" is input then RVC will toggle between shell and Ruby mode.
80
+
81
+ Marks can be easily used in Ruby mode since there are magic variables with the
82
+ same names. Since some marks, like numeric ones, aren't valid variable names,
83
+ they also exist with a "_" prefix.
84
+
85
+ The methods "this", "conn", and "dc" are provided in Ruby mode, returning the
86
+ current object, connection, and datacenter respectively. The connection object
87
+ is an instance of RbVmomi::VIM.
88
+
89
+ === VMODL introspection
90
+
91
+ The "type" command can be used to display the properties and methods of a VMODL
92
+ class. For example: "type Datacenter".
93
+
94
+ In Ruby mode, a '#' at the end of the input line will display the output of the
95
+ "type" command for the resulting object's class. This is very useful for
96
+ exploring the vSphere API.
97
+
98
+ === Multiple connections
99
+
100
+ RVC can connect to more than one ESX or VC server at the same time. Simply add
101
+ more hosts to the command line, or use the command "connect". Each connection
102
+ is represented by a top-level node in the virtual filesystem. If more than one
103
+ host is given on the command line, RVC will start in the root of the filesystem
104
+ instead of automatically cd'ing to a connection.
105
+
106
+ == Extensibility
107
+
108
+ RVC is designed to let users easily add commands they need. You can create a
109
+ command module, or add to an existing one, by adding a Ruby file to ~/.rvc or
110
+ any directory on the RVC_MODULE_PATH environment variable. The syntax of a user
111
+ command module is the same as those built-in to RVC, so see the
112
+ "lib/rvc/modules" directory for examples.
113
+
114
+ If you create a generically useful RVC command, please consider sending in a
115
+ patch so everyone can use it.
116
+
117
+ == Development
118
+
119
+ Send patches to rlane@vmware.com, or fork the project on GitHub and send me a
120
+ pull request.
@@ -0,0 +1,39 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "rvc"
5
+ gem.summary = "vSphere console UI"
6
+ #gem.description = ""
7
+ gem.email = "rlane@vmware.com"
8
+ #gem.homepage = ""
9
+ gem.authors = ["Rich Lane"]
10
+ gem.add_dependency 'rbvmomi', '>= 1.1.5'
11
+ gem.add_dependency 'trollop', '>= 1.16.2'
12
+ gem.add_dependency 'backports', '>= 1.18.2'
13
+ gem.add_dependency 'ffi', '>= 1.0.7'
14
+ end
15
+ rescue LoadError
16
+ puts "Jeweler not available. Install it with: gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new do |t|
21
+ t.libs << "test"
22
+ t.test_files = FileList['test/test_*.rb']
23
+ t.verbose = true
24
+ t.ruby_opts << "-rubygems"
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ desc 'Measures test coverage using rcov'
30
+ Rcov::RcovTask.new do |rcov|
31
+ rcov.pattern = 'test/test_*.rb'
32
+ rcov.output_dir = 'coverage'
33
+ rcov.verbose = true
34
+ rcov.libs << "test"
35
+ rcov.rcov_opts << '--exclude "gems/*"'
36
+ end
37
+ rescue LoadError
38
+ puts "Rcov not available. Install it with: gem install rcov"
39
+ end
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ add commands for more entities
2
+ add fake subfolders for more entities
3
+ add fastpass authentication
4
+ globbing?
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
data/bin/rvc ADDED
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright (c) 2011 VMware, Inc. All Rights Reserved.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ require 'readline'
22
+ require 'pp'
23
+ require 'trollop'
24
+ require 'rbvmomi'
25
+ require 'rbvmomi/trollop'
26
+ require 'shellwords'
27
+ require 'yaml'
28
+ require 'backports'
29
+ require 'rvc'
30
+
31
+ VIM = RbVmomi::VIM
32
+ include RVC::Util
33
+
34
+ Thread.abort_on_exception = true
35
+
36
+ CMD = Module.new
37
+
38
+ $opts = Trollop.options do
39
+ banner <<-EOS
40
+ Ruby vSphere Console.
41
+
42
+ Usage:
43
+ rvc [options] [username[:password]@]hostname
44
+
45
+ where [options] are:
46
+ EOS
47
+
48
+ opt :insecure, "don't verify ssl certificate", :short => 'k', :default => (ENV['RBVMOMI_INSECURE'] == '1')
49
+ opt :path, "Initial directory", :short => :none, :default => ENV['RVC_PATH'], :type => :string
50
+ opt :create_directory, "Create the initial directory if it doesn't exist", :short => :none
51
+ opt :cmd, "command to evaluate", :short => 'c', :multi => true, :type => :string
52
+ end
53
+
54
+ Trollop.die "At least 1 argument expected" unless ARGV.length >= 1
55
+
56
+ RVC.reload_modules false
57
+
58
+ $shell = RVC::Shell.new
59
+
60
+ ARGV.each do |uri|
61
+ begin
62
+ puts "Connecting to #{uri}..." if ARGV.size > 1
63
+ CMD.vim.connect uri, :insecure => $opts[:insecure]
64
+ rescue UserError
65
+ puts "Failed to connect to #{uri}: #{$!.message}"
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ RVC::Completion.install
71
+ history_fn = "#{ENV['HOME']}/.rvc-history"
72
+ IO.foreach(history_fn) { |l| Readline::HISTORY << l.chomp } rescue puts "Welcome to RVC. Try the 'help' command."
73
+ history = File.open(history_fn, 'a')
74
+
75
+ if $opts[:path]
76
+ begin
77
+ CMD.basic.cd $opts[:path]
78
+ rescue UserError
79
+ raise unless $opts[:create_directory]
80
+ parent_path = File.dirname($opts[:path])
81
+ lookup(parent_path).CreateFolder(:name => File.basename($opts[:path]))
82
+ CMD.basic.cd $opts[:path]
83
+ end
84
+ elsif ARGV.size == 1
85
+ CMD.basic.cd $shell.connections.keys.first
86
+ end
87
+
88
+ unless CMD.vmrc.find_vmrc
89
+ $stderr.puts "VMRC is not installed. You will be unable to view virtual machine consoles. Use the vmrc.install command to install it."
90
+ end
91
+
92
+ CMD.basic.ls '.'
93
+
94
+ while true
95
+ begin
96
+ input = $opts[:cmd].shift || Readline.readline($shell.prompt, false) or break
97
+ input = input.strip
98
+ next if input.empty?
99
+ (history.puts input; Readline::HISTORY << input) unless input == Readline::HISTORY.to_a[-1]
100
+ $shell.eval_input input
101
+ rescue Interrupt
102
+ puts
103
+ end
104
+ end
@@ -0,0 +1,31 @@
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 'rbvmomi'
22
+ require 'rvc/inventory'
23
+ require 'rvc/modules'
24
+ require 'rvc/util'
25
+ require 'rvc/path'
26
+ require 'rvc/fs'
27
+ require 'rvc/completion'
28
+ require 'rvc/option_parser'
29
+ require 'rvc/shell'
30
+
31
+ RbVmomi::VIM.extension_dirs << File.join(File.dirname(__FILE__), "rvc/extensions")
@@ -0,0 +1,110 @@
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 'readline'
22
+ require 'rvc/ttl_cache'
23
+
24
+ begin
25
+ require 'rvc/readline-ffi'
26
+ rescue Exception
27
+ end
28
+
29
+ module RVC
30
+ module Completion
31
+ Cache = TTLCache.new 10
32
+
33
+ Completor = lambda do |word|
34
+ return unless word
35
+ line = Readline.line_buffer if Readline.respond_to? :line_buffer
36
+ append_char, candidates = RVC::Completion.complete word, line
37
+ Readline.completion_append_character = append_char
38
+ candidates
39
+ end
40
+
41
+ def self.install
42
+ unless Readline.respond_to? :line_buffer and
43
+ Readline.respond_to? :char_is_quoted=
44
+ $stderr.puts "Install the \"ffi\" gem for better tab completion."
45
+ end
46
+
47
+ if Readline.respond_to? :char_is_quoted=
48
+ Readline.completer_word_break_characters = " \t\n\"'"
49
+ Readline.completer_quote_characters = "\"\\"
50
+ is_quoted = lambda { |str,i| i > 0 && str[i-1] == '\\' && !is_quoted[str,i-1] }
51
+ Readline.char_is_quoted = is_quoted
52
+ end
53
+
54
+ Readline.completion_proc = Completor
55
+ end
56
+
57
+ def self.complete word, line
58
+ candidates = if line
59
+ if line[' ']
60
+ child_candidates(word)
61
+ else
62
+ cmd_candidates(word)
63
+ end
64
+ else
65
+ child_candidates(word) + cmd_candidates(word)
66
+ end
67
+
68
+ candidates += mark_candidates(word)
69
+
70
+ if candidates.size == 1 and cmd_candidates(word).member?(candidates[0])
71
+ append_char = ' '
72
+ else
73
+ append_char = '/'
74
+ end
75
+
76
+ return append_char, candidates
77
+ end
78
+
79
+ def self.cmd_candidates word
80
+ ret = []
81
+ prefix_regex = /^#{Regexp.escape(word)}/
82
+ MODULES.each do |name,m|
83
+ m.commands.each { |s| ret << "#{name}.#{s}" }
84
+ end
85
+ ret.concat ALIASES.keys
86
+ ret.sort.select { |e| e.match(prefix_regex) }
87
+ end
88
+
89
+ def self.child_candidates word
90
+ els, absolute, trailing_slash = Path.parse word
91
+ last = trailing_slash ? '' : (els.pop || '')
92
+ els.map! { |x| x.gsub '\\', '' }
93
+ base_loc = absolute ? Location.new($shell.fs.root) : $shell.fs.loc
94
+ found_loc = $shell.fs.traverse(base_loc, els) or return []
95
+ cur = found_loc.obj
96
+ els.unshift '' if absolute
97
+ children = Cache[cur, :children] rescue []
98
+ children.
99
+ select { |k,v| k.gsub(' ', '\\ ') =~ /^#{Regexp.escape(last)}/ }.
100
+ map { |k,v| (els+[k])*'/' }.
101
+ map { |x| x.gsub ' ', '\\ ' }
102
+ end
103
+
104
+ def self.mark_candidates word
105
+ return [] unless word.empty? || word[0..0] == '~'
106
+ prefix_regex = /^#{Regexp.escape(word[1..-1] || '')}/
107
+ $shell.fs.marks.keys.sort.grep(prefix_regex).map { |x| "~#{x}" }
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,42 @@
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::ClusterComputeResource
22
+ def self.ls_properties
23
+ %w(name summary.effectiveCpu summary.effectiveMemory)
24
+ end
25
+
26
+ def ls_text r
27
+ " (cluster): cpu #{r['summary.effectiveCpu']/1000} GHz, memory #{r['summary.effectiveMemory']/1000} GB"
28
+ end
29
+
30
+ # TODO add datastore, network
31
+ def children
32
+ hosts, resourcePool = collect *%w(host resourcePool)
33
+ {
34
+ 'hosts' => RVC::FakeFolder.new(self, :rvc_host_children),
35
+ 'resourcePool' => resourcePool,
36
+ }
37
+ end
38
+
39
+ def rvc_host_children
40
+ RVC::Util.collect_children self, :host
41
+ end
42
+ end