lib/rvc/modules/vim.rb in rvc-1.5.0 vs lib/rvc/modules/vim.rb in rvc-1.6.0
- old
+ new
@@ -28,14 +28,35 @@
([^@]*)
)?
@
)?
([^@:]+)
- (?::(.*))?
+ (?::(\d{1,5}))?
+ (?::([0-9a-z]{64}))?
$
}x
+class RbVmomi::VIM
+ include RVC::InventoryObject
+
+ def children
+ rootFolder.children
+ end
+
+ def self.folder?
+ true
+ end
+
+ def display_info
+ puts serviceContent.about.fullName
+ end
+
+ def _connection
+ self
+ end
+end
+
opts :connect do
summary 'Open a connection to ESX/VC'
arg :uri, "Host to connect to"
opt :rev, "Override protocol revision", :type => :string
end
@@ -47,18 +68,19 @@
Trollop.die "invalid hostname" unless match
username = match[1] || ENV['RBVMOMI_USER']
password = match[2] || ENV['RBVMOMI_PASSWORD']
host = match[3]
- path = match[4]
+ port = match[4] || 443
+ certdigest = match[5] || opts[:certdigest]
bad_cert = false
vim = nil
loop do
begin
vim = RbVmomi::VIM.new :host => host,
- :port => 443,
+ :port => port,
:path => '/sdk',
:ns => 'urn:vim25',
:rev => (opts[:rev]||'4.0'),
:ssl => true,
:insecure => bad_cert
@@ -71,19 +93,31 @@
err $!.message
end
end
if bad_cert
- # Fall back to SSH-style known_hosts
peer_public_key = vim.http.peer_cert.public_key
- check_known_hosts(host, peer_public_key)
+ # if user specified a hash on the commandline, verify against that
+ if certdigest
+ if certdigest != Digest::SHA2.hexdigest(peer_public_key.to_s())
+ err "Bad certificate digest specified for #{host}!"
+ end
+ else
+ # Fall back to SSH-style known_hosts
+ check_known_hosts(host, peer_public_key)
+ end
end
unless opts[:rev]
# negotiate API version
rev = vim.serviceContent.about.apiVersion
- vim.rev = [rev, ENV['RVC_VIMREV'] || '5.0'].min
+ env_rev = ENV['RVC_VIMREV']
+ if env_rev && env_rev.to_f == 0
+ vim.rev = env_rev
+ else
+ vim.rev = [rev, env_rev || '5.0'].min
+ end
end
isVC = vim.serviceContent.about.apiType == "VirtualCenter"
# authenticate
@@ -104,19 +138,23 @@
password = keychain_password( username , host ) if password.nil?
if not password.nil?
loaded_from_keychain = password
end
- password_given = password != nil
- loop do
- begin
- password = prompt_password unless password_given
- vim.serviceContent.sessionManager.Login :userName => username,
- :password => password
- break
- rescue RbVmomi::VIM::InvalidLogin
- err $!.message if password_given
+ if opts[:cookie]
+ vim.cookie = opts[:cookie]
+ else
+ password_given = password != nil
+ loop do
+ begin
+ password = prompt_password unless password_given
+ vim.serviceContent.sessionManager.Login :userName => username,
+ :password => password
+ break
+ rescue RbVmomi::VIM::InvalidLogin
+ err $!.message if password_given
+ end
end
end
Thread.new do
while true
@@ -145,11 +183,11 @@
def prompt_password
ask("password: ") { |q| q.echo = false }
end
def keychain_password username , hostname
- return nil unless RbConfig::CONFIG['host_os'] =~ /^darwin10/
+ return nil unless RbConfig::CONFIG['host_os'] =~ /^darwin1[01]/
begin
require 'osx_keychain'
rescue LoadError
return nil
@@ -196,21 +234,11 @@
else
err "Unexpected result from known_hosts check"
end
end
-class RbVmomi::VIM
- def display_info
- puts serviceContent.about.fullName
- end
- def _connection
- self
- end
-end
-
-
opts :tasks do
summary "Watch tasks in progress"
end
def tasks
@@ -266,6 +294,55 @@
ensure
filter.DestroyPropertyFilter if filter
collector.DestroyCollector if collector
view.DestroyView if view
end
+end
+
+
+opts :logbundles do
+ summary "Download log bundles"
+ arg :servers, "VIM connection and/or ESX hosts", :lookup => [RbVmomi::VIM, VIM::HostSystem], :multi => true
+ opt :dest, "Destination directory", :default => '.'
+end
+
+DEFAULT_SERVER_PLACEHOLDER = '0.0.0.0'
+
+def logbundles servers, opts
+ vim = single_connection servers
+ diagMgr = vim.serviceContent.diagnosticManager
+ name = vim.host
+ FileUtils.mkdir_p opts[:dest]
+
+ hosts = servers.grep VIM::HostSystem
+ include_default = servers.member? vim
+
+ puts "#{Time.now}: Generating log bundles..."
+ bundles =
+ begin
+ diagMgr.GenerateLogBundles_Task(:includeDefault => include_default, :host => hosts).wait_for_completion
+ rescue VIM::TaskInProgress
+ $!.task.wait_for_completion
+ end
+
+ dest_path = nil
+ bundles.each do |b|
+ uri = URI.parse(b.url.sub('*', DEFAULT_SERVER_PLACEHOLDER))
+ bundle_name = b.system ? b.system.name : name
+ dest_path = File.join(opts[:dest], "#{bundle_name}-" + File.basename(uri.path))
+ puts "#{Time.now}: Downloading bundle #{b.url} to #{dest_path}"
+ uri.host = vim.http.address if uri.host == DEFAULT_SERVER_PLACEHOLDER
+ Net::HTTP.get_response uri do |res|
+ File.open dest_path, 'w' do |io|
+ res.read_body do |data|
+ io.write data
+ if $stdout.tty?
+ $stdout.write '.'
+ $stdout.flush
+ end
+ end
+ end
+ puts if $stdout.tty?
+ end
+ end
+ dest_path
end