Advertisement
Guest User

mob.rb library to execute programs on guest

a guest
Jun 22nd, 2016
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.65 KB | None | 0 0
  1. require 'rbvmomi'
  2.  
  3. class String
  4.   # Tokenizes a string, split on spaces and considers anything in single/doublequotes as one token
  5.   # Requires a string, returns an array of strings
  6.   def tokenize
  7.     self.
  8.       split(/\s(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/).
  9.      select {|s| not s.empty? }.
  10.      map {|s| s.gsub(/(^ +)|( +$)|(^["']+)|(["']+$)/,'')}
  11.   end
  12. end
  13.  
  14. module Findvms
  15.   # Find a VM (including Folders) in a Datacenter
  16.   # Requires
  17.   #   :name => string to search for
  18.   # Optional
  19.   #   :folder => RbVmomi::VIM::Folder, RbVmomi::VIM::Datacenter object to search within
  20.   #
  21.   # Returns Array of RbVmomi::VIM::VirtualMachine objects or nil
  22.   #
  23.  
  24.   def find_vms(args = {})
  25.     a = {
  26.       :name => "",
  27.       :folder => (defined?(self.vmFolder) ? self.vmFolder : nil ||
  28.                   defined?(self.rootFolder) ? self.rootFolder : nil ||
  29.                   self
  30.                  )
  31.     }.merge(args)
  32.  
  33.     name = a[:name]
  34.     folder = a[:folder]
  35.     found = []
  36.  
  37.     folder.childEntity.each do |x|
  38.        case x.class.to_s
  39.        when "Folder"
  40. #         puts "Searching Folder #{x.name}"
  41.          ret = find_vms(:name => name, :folder => x)
  42.          if ! ret.nil?
  43.            ret.each do |r|
  44.              if r.name.index(name)
  45.                found << r
  46. #               puts "Found"
  47.              end
  48.            end
  49.          end
  50.        when "VirtualMachine"
  51. #         puts "Searching VM #{x.name}"
  52.          if x.name.index(name)
  53.            found << x
  54.          end
  55.        when "Datacenter"
  56. #         puts "Searching DC #{x.name}"
  57.          found += find_vms(:name => name, :folder => x.vmFolder)
  58.        else
  59. #         puts "# Unrecognized Entity " + x.class.to_s
  60.        end
  61.     end
  62.     return found
  63.   end
  64. end
  65.  
  66. RbVmomi::VIM::Folder.class_eval do
  67.   include Findvms
  68. end
  69.  
  70. RbVmomi::VIM::Datacenter.class_eval do
  71.   include Findvms
  72. end
  73.  
  74. RbVmomi::VIM.class_eval do
  75.   include Findvms
  76. end
  77.  
  78. RbVmomi::VIM::GuestOperationsManager.class_eval do
  79.  
  80.   # Execute Program In Guest with output
  81.   # Requires
  82.   #   :vm   => RbVmomi::VIM::VirtualMachine
  83.   #   :local_user => string
  84.   #   :local_pass => string
  85.   #   :command => string
  86.   # Outputs Hash
  87.   #   :exitCode => int return code of executed program
  88.   #   :stdout => string STDOUT of executed program
  89.   #   :stderr => string STDERR of executed program
  90.   #
  91.  
  92.   def executeProgramInGuest(args = {})
  93.     a = {
  94.       :vm => nil,
  95.       :local_user => "",
  96.       :local_pass => "",
  97.       :command => "",
  98.     }.merge(args)
  99.  
  100.     vm = a[:vm]
  101.     local_user = a[:local_user]
  102.     local_pass = a[:local_pass]
  103.     command = a[:command]
  104.  
  105.  
  106.     bin, arg = command.tokenize
  107.     arg ||= ""
  108.  
  109.     fail "VM Object Requred" if vm.nil?
  110.     fail "VMWare Tools must be running on #{vm.name}" if vm.guest.toolsRunningStatus != "guestToolsRunning"
  111.  
  112.     case vm.guest.guestFamily
  113.     when "linuxGuest"
  114.       workingdir = '/tmp'
  115.       outfile = "#{workingdir}/toolsout"
  116.       arg += " 2>#{outfile}.stderr >#{outfile}.stdout"
  117.     when "windowsGuest"
  118.       workingdir = 'C:\\'
  119.       outfile = "C:\\Users\\#{local_user}\\toolsout"
  120.       arg = "-command \"#{bin} #{arg} 2>#{outfile}.stderr >#{outfile}.stdout"
  121.       bin = "C:\\Windows\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe"
  122.     else
  123.       fail "Unknown VM Type: #{vm.guest.guestFamily}"
  124.     end
  125.  
  126.     spec = RbVmomi::VIM::GuestProgramSpec(:programPath => bin, :arguments => arg, :workingDirectory => workingdir)
  127.     auth = RbVmomi::VIM::NamePasswordAuthentication(:interactiveSession => false, :username => local_user, :password => local_pass)
  128.  
  129.     pid = processManager.StartProgramInGuest(:vm => vm, :auth => auth, :spec => spec)
  130.  
  131.     while processManager.ListProcessesInGuest(:vm => vm, :auth => auth, :pids => [ pid.to_s ])[0].exitCode == nil
  132.       sleep 1
  133.     end
  134.  
  135.     outhash = {}
  136.     outhash[:exitCode] = processManager.ListProcessesInGuest(:vm => vm, :auth => auth, :pids => [ pid.to_s ])[0].exitCode
  137.  
  138.     [:stdout, :stderr].each do |out|
  139.       file = fileManager.InitiateFileTransferFromGuest(:vm => vm, :auth => auth, :guestFilePath => "#{outfile}.#{out}")
  140.       warn "Warning: File #{out} over 1MB" if file.size > 1000000
  141.  
  142.       uri = URI.parse(file.url)
  143.       http = Net::HTTP.new(uri.host, uri.port)
  144.       http.use_ssl = true
  145.       http.open_timeout = 5
  146.       http.read_timeout = 5
  147.       http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  148.  
  149.       outhash[out] = http.request(Net::HTTP::Get.new(uri.request_uri)).body
  150.       outhash[out].encode!(Encoding.find('UTF-8'), :binary => true, :invalid => :replace, :undef => :replace, :replace => '')
  151.       outhash[out].delete!("\u0000")
  152.       outhash[out].delete!("\r")
  153.     end
  154.     outhash
  155.   end
  156. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement