rvc 1.0.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.
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
@@ -0,0 +1,28 @@
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::Network
22
+ def display_info
23
+ summary, = collect(:summary)
24
+ puts "name: #{summary.name}"
25
+ puts "accessible: #{summary.accessible}"
26
+ puts "IP pool name: #{summary.ipPoolName}" unless summary.ipPoolName.empty?
27
+ end
28
+ end
@@ -0,0 +1,52 @@
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::ResourcePool
22
+ def self.ls_properties
23
+ %w(name config.cpuAllocation config.memoryAllocation)
24
+ end
25
+
26
+ def ls_text r
27
+ cpuAlloc, memAlloc = r['config.cpuAllocation'], r['config.memoryAllocation']
28
+
29
+ cpu_shares_text = cpuAlloc.shares.level == 'custom' ? cpuAlloc.shares.shares.to_s : cpuAlloc.shares.level
30
+ mem_shares_text = memAlloc.shares.level == 'custom' ? memAlloc.shares.shares.to_s : memAlloc.shares.level
31
+
32
+ ": cpu %0.2f/%0.2f/%s, mem %0.2f/%0.2f/%s" % [
33
+ cpuAlloc.reservation/1000.0, cpuAlloc.limit/1000.0, cpu_shares_text,
34
+ memAlloc.reservation/1000.0, memAlloc.limit/1000.0, mem_shares_text,
35
+ ]
36
+ end
37
+
38
+ def children
39
+ {
40
+ 'vms' => RVC::FakeFolder.new(self, :children_vms),
41
+ 'pools' => RVC::FakeFolder.new(self, :children_pools),
42
+ }
43
+ end
44
+
45
+ def children_vms
46
+ RVC::Util.collect_children self, :vm
47
+ end
48
+
49
+ def children_pools
50
+ RVC::Util.collect_children self, :resourcePool
51
+ end
52
+ end
@@ -0,0 +1,72 @@
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::VirtualMachine
22
+ def display_info
23
+ config, runtime, guest = collect :config, :runtime, :guest
24
+
25
+ puts "name: #{config.name}"
26
+ puts "note: #{config.annotation}" if config.annotation and !config.annotation.empty?
27
+ puts "host: #{runtime.host.path[1..-1].map { |x| x[1] } * '/'}" if runtime.host
28
+ puts "tools: #{guest.toolsRunningStatus}"
29
+ puts "hostname: #{guest.hostName} (#{guest.ipAddress})" if guest.hostName and guest.ipAddress
30
+ puts "VC UUID: #{config.instanceUuid}" if config.instanceUuid and !config.instanceUuid.empty?
31
+ puts "power: #{runtime.powerState}"
32
+ if runtime.question
33
+ puts "question: #{runtime.question.text.lines.to_a.join("> ")}"
34
+ puts "choices: #{runtime.question.choice.choiceInfo.map(&:label) * ', '}"
35
+ if i = runtime.question.choice.defaultIndex
36
+ puts "default: #{runtime.question.choice.choiceInfo[i].label}"
37
+ end
38
+ end
39
+ puts "cpus: #{config.hardware.numCPU}"
40
+ puts "memory: #{config.hardware.memoryMB} MB"
41
+
42
+ puts "nics:"
43
+ config.hardware.device.grep RbVmomi::VIM::VirtualEthernetCard do |dev|
44
+ backing_info = case dev.backing
45
+ when RbVmomi::VIM::VirtualEthernetCardNetworkBackingInfo
46
+ dev.backing.deviceName.inspect
47
+ when RbVmomi::VIM::VirtualEthernetCardDistributedVirtualPortBackingInfo
48
+ dev.backing.port.portgroupKey.inspect
49
+ else
50
+ dev.backing.class.name
51
+ end
52
+ guest_net = guest.net.find { |x| x.macAddress == dev.macAddress }
53
+ puts " #{dev.deviceInfo.label}: #{backing_info} #{dev.connectable.connected ? :connected : :disconnected} #{dev.macAddress} #{guest_net ? (guest_net.ipAddress * ' ') : ''}"
54
+ end
55
+ end
56
+
57
+ def self.ls_properties
58
+ %w(name runtime.powerState)
59
+ end
60
+
61
+ def ls_text r
62
+ ": #{r['runtime.powerState']}"
63
+ end
64
+
65
+ def children
66
+ host, resourcePool = collect *%w(runtime.host resourcePool)
67
+ {
68
+ 'host' => host,
69
+ 'resourcePool' => resourcePool,
70
+ }
71
+ end
72
+ end
@@ -0,0 +1,123 @@
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
+ module RVC
22
+
23
+ class Location
24
+ attr_reader :stack
25
+
26
+ def initialize root
27
+ @stack = [['', root]]
28
+ end
29
+
30
+ def initialize_copy src
31
+ super
32
+ @stack = @stack.dup
33
+ end
34
+
35
+ def push name, obj
36
+ @stack << [name, obj]
37
+ end
38
+
39
+ def pop
40
+ @stack.pop
41
+ end
42
+
43
+ def obj
44
+ @stack.empty? ? nil : @stack[-1][1]
45
+ end
46
+
47
+ def path
48
+ @stack.map { |name,obj| name }
49
+ end
50
+ end
51
+
52
+ class FS
53
+ attr_reader :root, :loc, :marks
54
+
55
+ MARK_REGEX = /^~(?:([\d\w]*|~|@))$/
56
+
57
+ def initialize root
58
+ @root = root
59
+ @loc = Location.new root
60
+ @marks = {}
61
+ end
62
+
63
+ def cur
64
+ @loc.obj
65
+ end
66
+
67
+ def display_path
68
+ @loc.path * '/'
69
+ end
70
+
71
+ def lookup path
72
+ (lookup_loc(path) || return).obj
73
+ end
74
+
75
+ def cd path
76
+ new_loc = lookup_loc(path) or return false
77
+ mark '~', @loc
78
+ @loc = new_loc
79
+ true
80
+ end
81
+
82
+ def lookup_loc path
83
+ els, absolute, trailing_slash = Path.parse path
84
+ base_loc = absolute ? Location.new(@root) : @loc
85
+ traverse(base_loc, els)
86
+ end
87
+
88
+ def traverse base_loc, els
89
+ loc = base_loc.dup
90
+ els.each_with_index do |el,i|
91
+ case el
92
+ when '.'
93
+ when '..'
94
+ loc.pop unless loc.obj == @root
95
+ when '...'
96
+ loc.push(el, loc.obj.parent) unless loc.obj == @root
97
+ when MARK_REGEX
98
+ return unless i == 0
99
+ loc = @marks[$1] or return
100
+ loc = loc.dup
101
+ else
102
+ # XXX check for ambiguous child
103
+ if i == 0 and el =~ /^\d+$/ and @marks.member? el
104
+ loc = @marks[el].dup
105
+ else
106
+ x = loc.obj.traverse_one(el) or return
107
+ loc.push el, x
108
+ end
109
+ end
110
+ end
111
+ loc
112
+ end
113
+
114
+ def mark key, loc
115
+ if loc == nil
116
+ @marks.delete key
117
+ else
118
+ @marks[key] = loc
119
+ end
120
+ end
121
+ end
122
+
123
+ end
@@ -0,0 +1,125 @@
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
+ module RVC
22
+
23
+ module InventoryObject
24
+ module ClassMethods
25
+ def ls_properties
26
+ %w()
27
+ end
28
+
29
+ def folder?
30
+ false
31
+ end
32
+ end
33
+
34
+ def self.included m
35
+ m.extend ClassMethods
36
+ end
37
+
38
+ def display_info
39
+ puts "class: #{self.class.name}"
40
+ end
41
+
42
+ def ls_text r
43
+ self.class.folder? ? '/' : ''
44
+ end
45
+
46
+ def traverse_one arc
47
+ children[arc]
48
+ end
49
+
50
+ def children
51
+ {}
52
+ end
53
+
54
+ def parent
55
+ nil
56
+ end
57
+ end
58
+
59
+ class FakeFolder
60
+ include RVC::InventoryObject
61
+
62
+ def initialize target, method
63
+ @target = target
64
+ @method = method
65
+ end
66
+
67
+ def children
68
+ @target.send @method
69
+ end
70
+
71
+ def self.folder?
72
+ true
73
+ end
74
+
75
+ def parent
76
+ @target
77
+ end
78
+
79
+ def eql? x
80
+ @target == x.instance_variable_get(:@target) &&
81
+ @method == x.instance_variable_get(:@method)
82
+ end
83
+
84
+ def hash
85
+ @target.hash ^ @method.hash
86
+ end
87
+ end
88
+
89
+ class RootNode
90
+ include RVC::InventoryObject
91
+
92
+ def children
93
+ $shell.connections
94
+ end
95
+
96
+ def parent
97
+ nil
98
+ end
99
+
100
+ def self.folder?
101
+ true
102
+ end
103
+
104
+ def pretty_print pp
105
+ pp.text "Root"
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ class RbVmomi::VIM
112
+ include RVC::InventoryObject
113
+
114
+ def children
115
+ rootFolder.children
116
+ end
117
+
118
+ def parent
119
+ $shell.fs.root
120
+ end
121
+
122
+ def self.folder?
123
+ true
124
+ end
125
+ end
@@ -0,0 +1,74 @@
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
+ module RVC
22
+
23
+ ALIASES = {}
24
+ MODULES = {}
25
+
26
+ class CmdModule
27
+ def initialize module_name
28
+ @module_name = module_name
29
+ @opts = {}
30
+ super()
31
+ end
32
+
33
+ def commands
34
+ @opts.keys
35
+ end
36
+
37
+ def opts cmd, &b
38
+ @opts[cmd] = b
39
+ end
40
+
41
+ def opts_for cmd
42
+ @opts[cmd]
43
+ end
44
+
45
+ def rvc_alias cmd, target=nil
46
+ target ||= cmd
47
+ RVC::ALIASES[target.to_s] = "#{@module_name}.#{cmd}"
48
+ end
49
+ end
50
+
51
+ BULTIN_MODULE_PATH = [File.expand_path(File.join(File.dirname(__FILE__), 'modules')),
52
+ File.join(ENV['HOME'], ".rvc")]
53
+ ENV_MODULE_PATH = (ENV['RVC_MODULE_PATH'] || '').split ':'
54
+
55
+ def self.reload_modules verbose=true
56
+ RVC::MODULES.clear
57
+ RVC::ALIASES.clear
58
+ RVC::MODULES['custom'] = CmdModule.new 'custom'
59
+ module_path = (BULTIN_MODULE_PATH+ENV_MODULE_PATH).select { |d| File.directory?(d) }
60
+ globs = module_path.map { |d| File.join(d, '*.rb') }
61
+ Dir.glob(globs) do |f|
62
+ module_name = File.basename(f)[0...-3]
63
+ puts "loading #{module_name} from #{f}" if verbose
64
+ code = File.read f
65
+ unless RVC::MODULES.member? module_name
66
+ m = CmdModule.new module_name
67
+ CMD.define_singleton_method(module_name.to_sym) { m }
68
+ RVC::MODULES[module_name] = m
69
+ end
70
+ RVC::MODULES[module_name].instance_eval code, f
71
+ end
72
+ end
73
+
74
+ end