Last active
November 15, 2024 02:10
-
-
Save prziborowski/ba3ebf610dd6cca3f4e7be5e2874499f to your computer and use it in GitHub Desktop.
Use property collector to retrieve names quickly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Written by Nathan Prziborowski | |
Github: https://github.com/prziborowski | |
This code is released under the terms of the Apache 2 | |
http://www.apache.org/licenses/LICENSE-2.0.html | |
The property collector can be used to fetch a subset of properties | |
for a large amount of objects with fewer round trips that iterating. | |
This sample shows how to use the TraversalSpec to get properties | |
of another object without multiple calls. | |
""" | |
import sys | |
from pyVmomi import vim, vmodl | |
from pyVim.connect import SmartConnectNoSSL, Disconnect | |
from pyVim.task import WaitForTask | |
from tools import cli | |
__author__ = 'prziborowski' | |
def setup_args(): | |
parser = cli.build_arg_parser() | |
return cli.prompt_for_password(parser.parse_args()) | |
def get_obj(si, root, vim_type): | |
container = si.content.viewManager.CreateContainerView(root, vim_type, | |
True) | |
view = container.view | |
container.Destroy() | |
return view | |
def get_filter_spec(containerView, objType, path): | |
traverse_spec = vmodl.query.PropertyCollector.TraversalSpec() | |
traverse_spec.name = 'traverse' | |
traverse_spec.path = 'view' | |
traverse_spec.skip = False | |
traverse_spec.type = vim.view.ContainerView | |
obj_spec = vmodl.query.PropertyCollector.ObjectSpec() | |
obj_spec.obj = containerView | |
obj_spec.skip = True | |
obj_spec.selectSet.append(traverse_spec) | |
prop_spec = vmodl.query.PropertyCollector.PropertySpec() | |
prop_spec.type = objType | |
prop_spec.pathSet = path | |
return vmodl.query.PropertyCollector.FilterSpec(propSet=[prop_spec], | |
objectSet=[obj_spec]) | |
def process_result(result, objects): | |
for o in result.objects: | |
if o.obj not in objects: | |
objects[o.obj] = {} | |
for p in o.propSet: | |
objects[o.obj][p.name] = p.val | |
def collect_properties(si, root, vim_type, props): | |
objects = {} | |
# Start with all the VMs from container, which is easier to write than | |
# PropertyCollector to retrieve them. | |
view_mgr = si.content.viewManager | |
container = view_mgr.CreateContainerView(root, | |
[vim_type], True) | |
try: | |
filter_spec = get_filter_spec(container, vim_type, props) | |
options = vmodl.query.PropertyCollector.RetrieveOptions() | |
pc = si.content.propertyCollector | |
result = pc.RetrievePropertiesEx([filter_spec], options) | |
process_result(result, objects) | |
while result.token is not None: | |
result = pc.ContinueRetrievePropertiesEx(result.token) | |
process_result(result, objects) | |
finally: | |
container.Destroy() | |
return objects | |
def main(): | |
args = setup_args() | |
si = SmartConnectNoSSL(host=args.host, | |
user=args.user, | |
pwd=args.password, | |
port=args.port) | |
vms = collect_properties(si, si.content.rootFolder, vim.VirtualMachine, | |
['config', 'name', 'guest', 'parent', 'runtime']) | |
hosts = collect_properties(si, si.content.rootFolder, vim.HostSystem, | |
['name']) | |
print("VMs: %d" % len(vms)) | |
print("Hosts: %d" % len(hosts)) | |
# Start program | |
if __name__ == "__main__": | |
main() |
The filter_spec part is mainly showing how to traverse from one object (ContainerView) to another (VirtualMachine/HostSytem) through looking at the 'view' property of ContainerView.
I still need to learn a bit more about how to do that with multiple types of objects at once 😄
You can use retrievePropertiesEx to fetch config.name for all vms and this is pretty fast.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes! I use the function to deal with many container views, I later updated my method with your gist example and the effect is remarkable.
At the same time, I change my method again, Use a single container view to get the corresponding data.
Thank you very much for solving one of my problems.
What's the principle of your gist with that example? expecially
fiter_spec
.Thanks again!