977b3449b7
Fix #6085
730 lines
21 KiB
Ruby
730 lines
21 KiB
Ruby
# -*- coding: binary -*-
|
|
module Msf
|
|
|
|
module Exploit::Remote::VIMSoap
|
|
include Msf::Exploit::Remote::HttpClient
|
|
|
|
def vim_soap_envelope(body)
|
|
soap_data = '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
|
|
soap_data << '<env:Body>'
|
|
soap_data << body
|
|
soap_data << '</env:Body></env:Envelope>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_propset(type,path,all = false)
|
|
soap_data = '<propSet xsi:type="PropertySpec">'
|
|
soap_data << '<type>' + type + '</type>'
|
|
if all
|
|
soap_data << '<all>true</all>'
|
|
else
|
|
soap_data << '<pathSet>' + path + '</pathSet>'
|
|
end
|
|
soap_data << '</propSet>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_objset(type, ref)
|
|
soap_data = '<objectSet>'
|
|
soap_data << '<obj type="' + type + '">' + ref + '</obj>'
|
|
soap_data << '</objectSet>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_specset(path,type,ref,all=false)
|
|
soap_data = '<specSet>'
|
|
soap_data << vim_soap_propset(type,path,all)
|
|
soap_data << vim_soap_objset(type,ref)
|
|
soap_data << '</specSet>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_retrieve_properties(path,type,ref,all=false)
|
|
soap_data = '<RetrieveProperties xmlns="urn:vim25">'
|
|
soap_data << '<_this type="PropertyCollector">' + @server_objects['propertyCollector'] + '</_this>'
|
|
soap_data << vim_soap_specset(path,type,ref,all)
|
|
soap_data << '</RetrieveProperties>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_retrieve_service_content
|
|
soap_data = '<RetrieveServiceContent xmlns="urn:vim25">'
|
|
soap_data << '<_this type="ServiceInstance">ServiceInstance</_this>'
|
|
soap_data << '</RetrieveServiceContent>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_login(user,pass)
|
|
soap_data = '<Login xmlns="urn:vim25">'
|
|
soap_data << '<_this type="SessionManager">' + @server_objects['sessionManager'] + '</_this>'
|
|
soap_data << '<userName>' + user + '</userName>'
|
|
soap_data << '<password>' + pass + '</password>'
|
|
soap_data << '</Login>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_session_active?(key, user)
|
|
soap_data = '<SessionIsActive xmlns="urn:vim25">'
|
|
soap_data << '<_this type="SessionManager">' + @server_objects['sessionManager'] + '</_this>'
|
|
soap_data << '<sessionID>' + key+ '</sessionID>'
|
|
soap_data << '<userName>' + user + '</userName>'
|
|
soap_data << '</SessionIsActive>'
|
|
end
|
|
|
|
|
|
|
|
|
|
def vim_soap_terminate_session(key)
|
|
soap_data = '<TerminateSession xmlns="urn:vim25">'
|
|
soap_data << '<_this xsi:type="ManagedObjectReference" type="SessionManager" >' + @server_objects['sessionManager'] + '</_this>'
|
|
soap_data << '<sessionId>' + key + '</sessionId>'
|
|
soap_data << '</TerminateSession>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_retrieve_usergroups(domain=nil)
|
|
soap_data = '<RetrieveUserGroups xmlns="urn:internalvim25">'
|
|
soap_data << '<_this xsi:type="ManagedObjectReference" type="UserDirectory">' + @server_objects['userDirectory'] + '</_this>'
|
|
soap_data << '<domain>' + domain + '</domain>' if domain
|
|
soap_data << '<searchStr></searchStr><exactMatch>false</exactMatch><findUsers>true</findUsers><findGroups>true</findGroups>'
|
|
soap_data << '</RetrieveUserGroups>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_log_user_event_vm(vm_ref,msg)
|
|
soap_data = '<LogUserEvent xmlns="urn:vim25">'
|
|
soap_data << '<_this type="EventManager">' + @server_objects['eventManager'] + '</_this>'
|
|
soap_data << '<entity type="VirtualMachine">' + vm_ref + '</entity>'
|
|
soap_data << '<msg>' + msg + '</msg>'
|
|
soap_data << '</LogUserEvent>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_retrieve_all_permissions
|
|
soap_data = '<RetrieveAllPermissions xmlns="urn:vim25">'
|
|
soap_data << '<_this type="AuthorizationManager">' + @server_objects['authorizationManager'] + '</_this>'
|
|
soap_data << '</RetrieveAllPermissions>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_find_child_byname(type,entity,name)
|
|
soap_data = '<FindChild xmlns="urn:vim25">'
|
|
soap_data << '<_this type="SearchIndex">' + @server_objects['searchIndex'] + '</_this>'
|
|
soap_data << '<entity type="' + type + '">' + entity + '</entity>'
|
|
soap_data << '<name>' + name + '</name>'
|
|
soap_data << '</FindChild>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_power_on_vm(vm_ref)
|
|
soap_data = '<PowerOnVM_Task xmlns="urn:vim25">'
|
|
soap_data << '<_this type="VirtualMachine">' + vm_ref + '</_this>'
|
|
soap_data << '</PowerOnVM_Task>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_power_off_vm(vm_ref)
|
|
soap_data = '<PowerOffVM_Task xmlns="urn:vim25">'
|
|
soap_data << '<_this type="VirtualMachine">' + vm_ref + '</_this>'
|
|
soap_data << '</PowerOffVM_Task>'
|
|
end
|
|
|
|
|
|
|
|
def vim_soap_create_screenshot(vm_ref)
|
|
soap_data = '<CreateScreenshot_Task xmlns="urn:vim25">'
|
|
soap_data << '<_this type="VirtualMachine">' + vm_ref + '</_this>'
|
|
soap_data << '</CreateScreenshot_Task>'
|
|
end
|
|
|
|
|
|
|
|
def vim_send_soap_request(soap_data)
|
|
res = send_request_cgi({
|
|
'uri' => '/sdk',
|
|
'method' => 'POST',
|
|
'agent' => 'VMware VI Client',
|
|
'cookie' => @vim_cookie,
|
|
'data' => soap_data,
|
|
'headers' => { 'SOAPAction' => @soap_action}
|
|
}, 25)
|
|
return :noresponse unless res
|
|
if res.body.include? "NotAuthenticatedFault"
|
|
return :expired
|
|
elsif res.body.include? "<faultstring>"
|
|
@vim_soap_error = res.body.match(/<faultstring>([^\c ]+?)<\/faultstring>/)[1]
|
|
return :error
|
|
elsif res.code != 200
|
|
@vim_soap_error = "An unknown error was encountered"
|
|
return :error
|
|
else
|
|
return Hash.from_xml(res.body)['Envelope']['Body']
|
|
end
|
|
end
|
|
|
|
def vim_get_session
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_service_content)
|
|
res = send_request_cgi({
|
|
'uri' => '/sdk',
|
|
'method' => 'POST',
|
|
'agent' => 'VMware VI Client',
|
|
'data' => soap_data,
|
|
'headers' => { 'SOAPAction' => @soap_action}
|
|
}, 25)
|
|
return false unless res and res.code == 200
|
|
@server_objects = (((Hash.from_xml(res.body)['Envelope'] || {})['Body'] || {})['RetrieveServiceContentResponse'] || {})['returnval']
|
|
@soap_action = "urn:vim25/#{(@server_objects['about'] || {})['apiVersion']}"
|
|
if res.headers['Set-Cookie']
|
|
@vim_cookie = res.headers['Set-Cookie']
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_do_login(user, pass)
|
|
unless vim_get_session
|
|
return false
|
|
end
|
|
soap_data = vim_soap_envelope(vim_soap_login(user,pass))
|
|
res = send_request_cgi({
|
|
'uri' => '/sdk',
|
|
'method' => 'POST',
|
|
'agent' => 'VMware VI Client',
|
|
'cookie' => @vim_cookie,
|
|
'data' => soap_data,
|
|
'headers' => { 'SOAPAction' => @soap_action}
|
|
}, 25)
|
|
if res.code == 200
|
|
return :success
|
|
else
|
|
return :fail
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_session_list
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('sessionList','SessionManager', @server_objects['sessionManager']))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
session_list = []
|
|
session_list << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['UserSession']
|
|
return session_list.flatten.compact
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_session_is_active(key, username)
|
|
soap_data = vim_soap_envelope(vim_soap_session_active?(key,username))
|
|
res = vim_send_soap_request(soap_data)
|
|
print_status "Error: #{@vim_soap_error}"
|
|
if res.class == Hash
|
|
active = res['SessionIsActiveResponse']['returnval']
|
|
return active
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_terminate_session(key)
|
|
soap_data = vim_soap_envelope(vim_soap_terminate_session(key))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
return :success
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_domains
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('domainList', 'UserDirectory', @server_objects['userDirectory']))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
domains = []
|
|
domains << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['string']
|
|
return domains.flatten.compact
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_user_list(domain=nil)
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_usergroups(domain))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
return nil unless res['RetrieveUserGroupsResponse']['returnval']
|
|
user_list = []
|
|
user_list << res['RetrieveUserGroupsResponse']['returnval']
|
|
return user_list.flatten.compact
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_log_event_vm(vm_ref, msg)
|
|
soap_data = vim_soap_envelope(vim_soap_log_user_event_vm(vm_ref,msg))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
return :success
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_all_permissions
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_all_permissions)
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
permissions = []
|
|
permissions << res['RetrieveAllPermissionsResponse']['returnval']
|
|
return permissions.flatten.compact
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_roles
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('roleList', 'AuthorizationManager', @server_objects['authorizationManager']))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
roles = []
|
|
roles << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['AuthorizationRole']
|
|
return roles.flatten.compact
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_dc_name(dc)
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('name','Datacenter',dc))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
return res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
def vim_get_dcs
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_service_content)
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
@server_objects.merge!(res['RetrieveServiceContentResponse']['returnval'])
|
|
else
|
|
return res
|
|
end
|
|
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('content', 'ServiceInstance', 'ServiceInstance'))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
hash = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
hash.delete('xsi:type')
|
|
@server_objects.merge!(hash)
|
|
else
|
|
return res
|
|
end
|
|
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('childEntity', 'Folder', @server_objects['rootFolder']))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
tmp_dcs = []
|
|
tmp_dcs << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
|
|
tmp_dcs.flatten!
|
|
tmp_dcs.each{|dc| @dcs << { 'name' => vim_get_dc_name(dc) , 'ref' => dc}}
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_hosts(datacenter)
|
|
dc_hosts = []
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('hostFolder', 'Datacenter' , datacenter))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
host_folders = []
|
|
host_folders << res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
host_folders.flatten!
|
|
else
|
|
return res
|
|
end
|
|
|
|
compute_refs = []
|
|
host_folders.each do |folder|
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('childEntity', 'Folder' , folder))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
ref = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
|
|
unless ref.nil?
|
|
compute_refs << ref
|
|
end
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
compute_refs.flatten!
|
|
|
|
compute_refs.each do |ref|
|
|
next if ref.start_with? "group-"
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('host', 'ComputeResource' , ref))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
dc_hosts << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
dc_hosts.flatten!
|
|
return dc_hosts
|
|
end
|
|
|
|
|
|
|
|
def vim_get_all_hosts
|
|
@dcs.each{|dc| @hosts << vim_get_hosts(dc['ref'])}
|
|
@hosts.flatten!
|
|
end
|
|
|
|
|
|
|
|
def vim_get_host_hw(host)
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('hardware', 'HostSystem' , host))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
return res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
def vim_get_all_host_summary(hw=false)
|
|
vim_setup_references
|
|
summaries = []
|
|
@hosts.each do |host|
|
|
details = {}
|
|
details[host] = vim_get_host_summary(host)
|
|
if details and hw
|
|
details.merge!(vim_get_host_hw(host))
|
|
end
|
|
summaries << details
|
|
end
|
|
return summaries.flatten.compact
|
|
end
|
|
|
|
def vim_get_vm_datastore(vm)
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('datastore', 'VirtualMachine' , vm))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
datastore_refs = []
|
|
datastore_refs << res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
|
|
datastore_refs.flatten!
|
|
datastore_refs.compact!
|
|
datastores = []
|
|
else
|
|
return res
|
|
end
|
|
|
|
datastore_refs.each do |datastore_ref|
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Datastore' , datastore_ref))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
datastore_name = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['name']
|
|
datastore = { 'name' => datastore_name, 'ref' => datastore_ref}
|
|
datastores << datastore
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
return datastores
|
|
|
|
end
|
|
|
|
def vim_find_vm_by_name(name)
|
|
vim_setup_references
|
|
@dcs.each do |dc|
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('vmFolder', 'Datacenter' , dc['ref']))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
vm_folders = []
|
|
vm_folders << res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
vm_folders.flatten!
|
|
vm_folders.compact!
|
|
else
|
|
return res
|
|
end
|
|
|
|
|
|
vm_folders.each do |vm_folder|
|
|
soap_data = vim_soap_envelope(vim_soap_find_child_byname('Folder', vm_folder, name))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
vmref = res['FindChildResponse']['returnval']
|
|
if vmref
|
|
return vmref
|
|
else
|
|
next
|
|
end
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
|
|
|
|
def vim_powerON_vm(vm_ref)
|
|
soap_data = vim_soap_envelope(vim_soap_power_on_vm(vm_ref))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
task_id = res['PowerOnVM_TaskResponse']['returnval']
|
|
else
|
|
return res
|
|
end
|
|
|
|
state= "running"
|
|
while state == "running"
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Task', task_id))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
state = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['state']
|
|
case state
|
|
when 'running'
|
|
select(nil, nil, nil, 5)
|
|
when 'error'
|
|
if res['RetrievePropertiesResponse']['returnval']['propSet']['val']['error']['fault']['existingState'] == 'poweredOn'
|
|
return 'alreadyON'
|
|
end
|
|
end
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
return state
|
|
end
|
|
|
|
|
|
|
|
def vim_powerOFF_vm(vm_ref)
|
|
soap_data = vim_soap_envelope(vim_soap_power_off_vm(vm_ref))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
task_id = res['PowerOffVM_TaskResponse']['returnval']
|
|
else
|
|
return res
|
|
end
|
|
|
|
state= "running"
|
|
while state == "running"
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Task', task_id))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
state = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['state']
|
|
case state
|
|
when 'running'
|
|
select(nil, nil, nil, 5)
|
|
when 'error'
|
|
if res['RetrievePropertiesResponse']['returnval']['propSet']['val']['error']['fault']['existingState'] == 'poweredOn'
|
|
return 'alreadyON'
|
|
end
|
|
end
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
return state
|
|
end
|
|
|
|
|
|
|
|
def vim_take_screenshot(vm, user, pass)
|
|
soap_data = vim_soap_envelope(vim_soap_create_screenshot(vm['ref']))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
task_id = res['CreateScreenshot_TaskResponse']['returnval']
|
|
else
|
|
return res
|
|
end
|
|
|
|
state= "running"
|
|
while state == "running"
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('info', 'Task', task_id))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
state = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['state']
|
|
screenshot_file = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['result']
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
unless screenshot_file
|
|
return :error
|
|
end
|
|
(ss_folder, ss_file) = screenshot_file.split('/').last(2)
|
|
ss_folder = Rex::Text.uri_encode(ss_folder)
|
|
ss_file = Rex::Text.uri_encode(ss_file)
|
|
ss_path = "#{ss_folder}/#{ss_file}"
|
|
datastores = vim_get_vm_datastore(vm['ref'])
|
|
user_pass = Rex::Text.encode_base64(user + ":" + pass)
|
|
datastores.each do |datastore|
|
|
ss_uri = "/folder/#{ss_path}?dcPath=#{vm['dc_name']}&dsName=#{datastore['name']}"
|
|
res = send_request_cgi({
|
|
'uri' => ss_uri,
|
|
'method' => 'GET',
|
|
'agent' => 'VMware VI Client',
|
|
'cookie' => @vim_cookie,
|
|
'headers' => { 'Authorization' => "Basic #{user_pass}"}
|
|
}, 25)
|
|
next unless res
|
|
if res.code == 200
|
|
return res.body
|
|
elsif res.code == 404
|
|
next
|
|
end
|
|
end
|
|
return :error
|
|
end
|
|
|
|
|
|
|
|
def vim_get_host_summary(host)
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('summary', 'HostSystem', host))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
hash = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
hash['runtime'].delete('healthSystemRuntime')
|
|
hash.delete('xsi:type')
|
|
hash.delete('host')
|
|
return hash
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def vim_get_vms
|
|
vim_setup_references
|
|
@vmrefs = []
|
|
vmlist= []
|
|
@dcs.each do |dc|
|
|
dc_vm_refs = vim_get_dc_vms(dc['ref'])
|
|
next if dc_vm_refs.nil? or dc_vm_refs.empty?
|
|
dc_vm_refs.flatten!
|
|
dc_vm_refs.compact!
|
|
next if dc_vm_refs.nil? or dc_vm_refs.empty?
|
|
print_status "#{datastore['RHOST']} - DataCenter: #{dc['name']} Found a Total of #{dc_vm_refs.length} VMs"
|
|
print_status "#{datastore['RHOST']} - DataCenter: #{dc['name']} Estimated Time: #{((dc_vm_refs.length * 7) /60)} Minutes"
|
|
dc_vm_refs.each do |ref|
|
|
print_status "#{datastore['RHOST']} - DataCenter: #{dc['name']} - Getting Data for VM: #{ref}..."
|
|
details = vim_get_vm_info(ref)
|
|
if details
|
|
details['ref'] = ref
|
|
details['dc_ref'] = dc['ref']
|
|
details['dc_name'] = dc['name']
|
|
vmlist << details
|
|
end
|
|
end
|
|
end
|
|
return vmlist
|
|
end
|
|
|
|
|
|
|
|
def vim_get_dc_vms(datacenter)
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('vmFolder', 'Datacenter', datacenter))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
vmfolder = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
else
|
|
return res
|
|
end
|
|
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('childEntity', 'Folder', vmfolder))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
vm_index_array = res['RetrievePropertiesResponse']['returnval']['propSet']['val']['ManagedObjectReference']
|
|
vm_index_array.delete_if{|ref| ref.start_with? "group"} unless vm_index_array.nil? or vm_index_array.empty? or vm_index_array.class != Array
|
|
return vm_index_array
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
def vim_get_vm_info(vm_ref)
|
|
vim_setup_references
|
|
soap_data = vim_soap_envelope(vim_soap_retrieve_properties('summary', 'VirtualMachine', vm_ref))
|
|
res = vim_send_soap_request(soap_data)
|
|
if res.class == Hash
|
|
hash = res['RetrievePropertiesResponse']['returnval']['propSet']['val']
|
|
vm = hash['config']
|
|
vm['runtime'] = hash['runtime']
|
|
vm['guest'] = hash['guest']
|
|
vm['quickStats'] = hash['quickStats']
|
|
return vm
|
|
else
|
|
return res
|
|
end
|
|
end
|
|
|
|
def vim_logged_in?
|
|
return true if @vim_cookie
|
|
return false
|
|
end
|
|
|
|
def vim_instance_vars_set?
|
|
return false if @server_objects.nil? or @server_objects.empty?
|
|
return false if @host.nil? or @host.empty?
|
|
return true
|
|
end
|
|
|
|
def vim_setup_references
|
|
unless vim_instance_vars_set?
|
|
@dcs = []
|
|
@hosts = []
|
|
vim_get_dcs
|
|
vim_get_all_hosts
|
|
@hosts.flatten!
|
|
@hosts.compact!
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|