1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
#!/usr/bin/env ruby
# TODO keepalive
# TODO rc file
# TODO proxy support?
require 'trollop'
require 'readline'
require 'rbvmomi'
require 'rbvmomi/trollop'
VIM = RbVmomi::VIM
opts = Trollop.options do
banner <<-EOS
vSphere API console.
Usage:
rbvmomish [options]
Predefined methods:
conn: Returns the VIM connection
si: Returns the ServiceInstance
help: Displays this text.
Special syntax:
Adding a '#' suffix to an expression displays information about the type of the
result, including its properties and methods, instead of the value.
VIM connection options:
EOS
rbvmomi_connection_opts
text <<-EOS
Other options:
EOS
$trollop = self
end
begin
$vim = VIM.connect opts
rescue Errno::EHOSTUNREACH
abort $!.message
end
typenames = VIM.loader.typenames
Readline.completion_append_character = " "
Readline.completion_proc = lambda do |word|
return unless word
prefix_regex = /^#{Regexp.escape(word)}/
candidates = typenames.sort
candidates.find_all { |e| e.match(prefix_regex) }
end
history_fn = "#{ENV['HOME']}/.rbvmomish-history"
IO.foreach(history_fn) { |l| Readline::HISTORY << l.chomp } rescue nil
history = File.open(history_fn, 'a')
def type name
klass = VIM.type(name) rescue err("invalid type #{name.inspect}")
q = lambda { |x| x =~ /^xsd:/ ? $' : x }
if klass < VIM::DataObject
puts "Data Object #{klass}"
klass.full_props_desc.each do |desc|
puts " #{desc['name']}: #{q[desc['wsdl_type']]}#{desc['is-array'] ? '[]' : ''}"
end
elsif klass < VIM::ManagedObject
puts "Managed Object #{klass}"
puts
puts "Properties:"
klass.full_props_desc.each do |desc|
puts " #{desc['name']}: #{q[desc['wsdl_type']]}#{desc['is-array'] ? '[]' : ''}"
end
puts
puts "Methods:"
klass.full_methods_desc.sort_by(&:first).each do |name,desc|
params = desc['params']
puts " #{name}(#{params.map { |x| "#{x['name']} : #{q[x['wsdl_type'] || 'void']}#{x['is-array'] ? '[]' : ''}" } * ', '}) : #{q[desc['result']['wsdl_type'] || 'void']}"
end
else
err("cannot introspect type #{klass}")
end
nil
end
class UserError < RuntimeError; end
def err msg
raise UserError.new(msg)
end
def cookie str
$vim.cookie = str
end
def conn
$vim
end
def si
$vim.serviceInstance
end
def help
$trollop.educate
:no_result
end
$binding = $vim.instance_eval { binding }
loop do
begin
input = Readline.readline("#{opts[:host]}> ", false) or break
input = input.strip
next if input.empty?
(history.puts input; Readline::HISTORY << input) unless input == Readline::HISTORY.to_a[-1]
result = eval(input, $binding)
if input =~ /\#$/
type result.class.wsdl_name
else
pp result unless result == :no_result
end
rescue SystemExit, IOError
raise
rescue RuntimeError, RbVmomi::Fault
puts "#{$!.class}: #{$!.message}"
puts $!.backtrace * "\n"
rescue UserError
puts $!.message
rescue Interrupt
puts
rescue Exception
puts "#{$!.class}: #{$!.message}"
puts $!.backtrace * "\n"
end
end
|