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
@@ -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