Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the speed of finding an individual VM #422

Merged
merged 5 commits into from
Mar 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions lib/chef/knife/search_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Some helpers for faster searching of the inventory
module SearchHelper
# Retrieves all the VM objects and returns their ObjectContents
# Note that since it's a ObjectContent coming back, the individual
# object's [] will return only the properties you asked for
# and `#obj` will return the actual object (but make a call to the server)
# param [Array<String>] properties to retrieve
# @return [Array<RbVmomi::VIM::ObjectContent>]
def get_all_vm_objects(properties = ['name'])
pc = vim_connection.serviceInstance.content.propertyCollector
viewmgr = vim_connection.serviceInstance.content.viewManager
root_folder = vim_connection.serviceInstance.content.rootFolder
vmview = viewmgr.CreateContainerView(container: root_folder,
type: ['VirtualMachine'],
recursive: true)

filter_spec = RbVmomi::VIM.PropertyFilterSpec(
objectSet: [
obj: vmview,
skip: true,
selectSet: [
RbVmomi::VIM.TraversalSpec(
name: 'traverseEntities',
type: 'ContainerView',
path: 'view',
skip: false
)
]
],
propSet: [
{ type: 'VirtualMachine', pathSet: properties }
]
)
pc.RetrieveProperties(specSet: [filter_spec])
end

def get_vm_by_name(vmname)
vm = get_all_vm_objects.detect { |r| r['name'] == vmname }
vm ? vm.obj : nil
end
end
9 changes: 3 additions & 6 deletions lib/chef/knife/vsphere_vm_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

require 'chef/knife'
require 'chef/knife/base_vsphere_command'
require 'rbvmomi'
require 'netaddr'
require 'chef/knife/search_helper'

# VsphereVMconfig extends the BaseVspherecommand
class Chef::Knife::VsphereVmConfig < Chef::Knife::BaseVsphereCommand
include SearchHelper
banner "knife vsphere vm config VMNAME PROPERTY VALUE.
See \"http://pubs.vmware.com/vi3/sdk/ReferenceGuide/vim.vm.ConfigSpec.html\"
for allowed ATTRIBUTE values (any property of type xs:string is supported)."
Expand Down Expand Up @@ -39,10 +39,7 @@ def run

vim_connection

dc = datacenter
folder = find_folder(get_config(:folder)) || dc.vmFolder

vm = traverse_folders_for_vm(folder, vmname) || abort("VM #{vmname} not found")
vm = get_vm_by_name(vmname) || fatal_exit("Could not find #{vmname}")

properties = {}
properties[property_name] = property_value
Expand Down
7 changes: 4 additions & 3 deletions lib/chef/knife/vsphere_vm_disk_list.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
require 'chef/knife'
require 'chef/knife/base_vsphere_command'
require 'chef/knife/search_helper'

# List the disks attached to a VM
# VsphereVmdisklist extends the BaseVspherecommand
class Chef::Knife::VsphereVmDiskList < Chef::Knife::BaseVsphereCommand
include SearchHelper

banner 'knife vsphere vm disk list VMNAME'

common_options
Expand All @@ -18,9 +21,7 @@ def run
fatal_exit 'You must specify a virtual machine name'
end

vim_connection
vm = get_vm(vmname)
fatal_exit "Could not find #{vmname}" unless vm
vm = get_vm_by_name(vmname) || fatal_exit("Could not find #{vmname}")

disks = vm.config.hardware.device.select do |device|
device.is_a? RbVmomi::VIM::VirtualDisk
Expand Down
7 changes: 3 additions & 4 deletions lib/chef/knife/vsphere_vm_property_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

require 'chef/knife'
require 'chef/knife/base_vsphere_command'
require 'rbvmomi'
require 'netaddr'
require 'chef/knife/search_helper'

# VsphereVMPropertySet extends Basevspherecommand
class Chef::Knife::VsphereVmPropertySet < Chef::Knife::BaseVsphereCommand
include SearchHelper
banner 'knife vsphere vm property set VMNAME PROPERTY VALUE. Sets a vApp Property on VMNAME.'

common_options
Expand Down Expand Up @@ -42,9 +42,8 @@ def run
vim_connection

dc = datacenter
folder = find_folder(get_config(:folder)) || dc.vmFolder

vm = find_in_folder(folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
vm = get_vm_by_name(vmname) || fatal_exit("Could not find #{vmname}")

if vm.config.vAppConfig && vm.config.vAppConfig.property
existing_property = vm.config.vAppConfig.property.find { |p| p.props[:id] == property_name.to_s }
Expand Down
15 changes: 4 additions & 11 deletions lib/chef/knife/vsphere_vm_snapshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

require 'chef/knife'
require 'chef/knife/base_vsphere_command'
require 'rbvmomi'
require 'netaddr'
require 'chef/knife/search_helper'

# Manage snapshots of a virtual machine
class Chef::Knife::VsphereVmSnapshot < Chef::Knife::BaseVsphereCommand
include SearchHelper
banner 'knife vsphere vm snapshot VMNAME (options)'

common_options
Expand Down Expand Up @@ -44,7 +44,7 @@ class Chef::Knife::VsphereVmSnapshot < Chef::Knife::BaseVsphereCommand
description: 'Indicates whether to wait for creation/removal to complete',
boolean: false

option :find,
option :find, # imma deprecate this
long: '--find',
description: 'Finds the virtual machine by searching all folders'

Expand Down Expand Up @@ -77,14 +77,7 @@ def run

vim_connection

vm = if get_config(:find)
puts "No folder entered, searching for #{vmname}"
src_folder = find_folder(get_config(:folder))
traverse_folders_for_vm(src_folder, vmname)
else
base_folder = find_folder get_config(:folder)
find_in_folder(base_folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
end
vm = get_vm_by_name(vmname) || fatal_exit("Could not find #{vmname}")

if vm.snapshot
snapshot_list = vm.snapshot.rootSnapshotList
Expand Down
17 changes: 3 additions & 14 deletions lib/chef/knife/vsphere_vm_state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

require 'chef/knife'
require 'chef/knife/base_vsphere_command'
require 'rbvmomi'
require 'netaddr'
require 'chef/knife/search_helper'

# Manage power state of a virtual machine
# VsphereVmState extends the BaseVspherecommand
class Chef::Knife::VsphereVmState < Chef::Knife::BaseVsphereCommand
include SearchHelper
# The Different power states that vSphere reports
POWER_STATES = {
PS_ON => 'powered on',
Expand Down Expand Up @@ -56,18 +56,7 @@ def run

vim_connection

if get_config(:recursive)
vms = get_vms(vmname)
if vms.length > 1
abort "More than one VM with name #{vmname} found:\n" + vms.map { |vm| get_path_to_object(vm) }.join("\n")
end
abort "VM #{vmname} not found" if vms.length == 0
vm = vms[0]
else
base_folder = find_folder(get_config(:folder))

vm = find_in_folder(base_folder, RbVmomi::VIM::VirtualMachine, vmname) || abort("VM #{vmname} not found")
end
vm = get_vm_by_name(vmname) || fatal_exit("Could not find #{vmname}")

state = vm.runtime.powerState

Expand Down