Accessing Managed Object Properties with the JSON Protocol
You retrieve a property of a managed object by appending the property name to the
URL, after the managed object reference. Property names always begin with a lowercase
letter, matching the name in the vSphere Web Services API Reference.
For example, you can retrieve the string
property
HostProfile.validationState
with a URL similar to this:
https://vcenter_fqdn/sdk/vim25/8.0.1.0/hostprofile_mo_ref/validationState
You cannot modify properties
directly. To modify properties of a managed object, you must invoke a method of the
managed object or a related managed object that affects its state on the
server.
Retrieving Nested
Properties
You can retrieve a top-level property by
naming it in the URL, but nested properties are not directly accessible. Many
top-level properties are data objects or arrays, containing nested properties of
interest. To access nested properties, first retrieve the top-level property, then
deserialize the JSON in the response body. After deserialization, you can access the
nested properties of the data object or array in the client.
For example, code this
request:
Then extract and display the nested property like this:GET https://vcenter_fqdn/sdk/vim25/8.0.1.0/vm_mo_ref/runtime
The nested property displays.data_object = json.loads(response_body) state = data_object['powerState'] print('VM powerState = ' + state)
VM powerState = poweredOff
Retrieving Managed Object
Reference Properties
Managed objects often have properties to
reference other managed objects. In these cases, you can use a GET request to obtain
the managed object reference, but to access the properties or methods of the other
managed object you must issue a new GET request, using the managed object reference
in the request URL.
If you need to follow a chain of managed
object references, you can avoid extra requests by using the
PropertyCollector
managed object. The purpose of the
PropertyCollector
is to delegate the search functions to the
server, where they can be done more efficiently.Using the Property Collector to
Retrieve Object Properties
You can use the
PropertyCollector
to retrieve properties from one or more
managed objects, whether or not they are related to each other, if you can specify
the set of objects in your request. The PropertyCollector
provides
a flexible interface by which you can specify search criteria to execute in the
server.To specify a property retrieval, several
approaches are available to you. A few of them are:
- Provide a managed object reference and a set of its properties that you want to retrieve.
- Provide a managed object reference as a starting point for a search that traverses inventory paths to find related managed objects and return their properties.
- Provide a reference to a previous search set as a starting point for a traversal search, often directed to the managed objects contained in the set.
This example shows a hybrid approach
where you first locate a
Datacenter
managed object by using the
SearchIndex
method. Then you use that managed object as a
starting point to traverse to VirtualMachine
objects in the data
center's virtual machine folder. If there are subfolders within the virtual machine
folder, the search specifications traverse the subfolders recursively.The goal of this example is to report
whether the virtual machines are powered on or powered off. That information is in
the
VirtualMachine.runtime.powerState
property.The
powerState
property
is a nested property of the virtual machine, so you need to locate the
VirtualMachine
managed objects and specify a property within
the runtime
data object belonging to each
VirtualMachine
. The JSON protocol has the ability to retrieve
the entire runtime data object as a single property, but the
PropertyCollector
is able to extract the nested property in a
single query.Use the following procedure to build a
server-side specification that retrieves the power states of virtual machines in the
data center's virtual machine folder.
For simplicity, this procedure
ignores vApps.
- Build aPropertySpecdata object to identify the managed object type (VirtualMachine) and the nested property name (runtime.powerState).propSet = [ {'_typeName': 'PropertySpec', 'type': 'VirtualMachine', 'pathSet': ['runtime.powerState'], 'all': False}]Theallproperty, ifTrue, overrides thepathSetproperty and collects all properties of the managed object. This behavior is useful if you want to maintain a client-side copy in synch with the server-side managed object.
- (Optional) If it helps to clarify the inventory paths to the virtual machines, sketchVirtualMachineobjects and their parent managed objects, all the way up the chain to the startingDatacentermanaged object.For each path between managed objects, note the name of the property in the parent object that links to the child object. You must create aTraversalSpec(or aSelectionSpecreference to aTraversalSpec) to follow each of those links to the next managed object. TheVirtualMachinemanaged objects whose properties you want to retrieve do not needTraversalSpecobjects.
- Working backwards fromVirtualMachineobjects toDatacenterobject, create a namedTraversalSpecdata object for each path segment.traverse_folder = {'_typeName': 'TraversalSpec'} traverse_folder['name'] = 'traverse_folder' traverse_folder['type'] = 'Folder' traverse_folder['path'] = 'childEntity' traverse_folder['skip'] = False dc_to_vmfolder = {'_typeName': 'TraversalSpec'} dc_to_vmfolder['name'] = 'dc_to_vmfolder' dc_to_vmfolder['type'] = 'Datacenter' dc_to_vmfolder['path'] = 'vmFolder' dc_to_vmfolder['skip'] = TrueYou do not need aTraversalSpecfor theVirtualMachineobject, because it is a leaf object in the traversal tree. You do need aTraversalSpecfor theDatacenterobject and theFolderobject, so thePropertyCollectorwill know how to traverse down the chain to the child objects. Theskipproperty is an optimization. It tells thePropertyCollectorthat the next managed object after the traversal can be traversed without checking thePropertySpec.TheTraversalSpec.selectSet[]property is not yet set. You will use it to link the specs together.
- If your data center might have nested folders inside its VM folder, create aSelectionSpecdata object that specifies the name of theTraversalSpecforFolderobjects, so thePropertyCollectorcan follow thechildEntitypath recursively for any nested folders it finds.folder_recursion = {'_typeName': 'SelectionSpec', 'name': 'traverse_folder'}
- Link theTraversalSpecobjects together by using theselectSet[]property to build a managed object traversal chain.traverse_folder['selectSet'] = [folder_recursion] dc_to_vmfolder['selectSet'] = [traverse_folder]
- Create anObjectSpecdata object to specify starting from yourDatacentermanaged object, and to direct thePropertyCollectorto theTraversalSpecthat leads to the top-level VM folder.objectSet = [{'_typeName': 'ObjectSpec', 'obj': dc_moref, 'skip': False, 'selectSet': [dc_to_vmfolder] }]Theskipproperty in theObjectSpecis different from theskipproperty in aTraversalSpec. In theObjectSpec, it tells thePropertyCollectorthat the starting object is not one of the managed objects it is looking for.
- Combine thePropertySpecand theObjectSpecinto aPropertyFilterSpecthat will be a parameter to thePropertyCollector.RetrievePropertiesExmethod.specSet = [{'_typeName': 'PropertyFilterSpec', 'propSet': propSet, 'objectSet': objectSet}]
- Specify theRetrievePropertiiesExmethod parameters in the request body.import json param_dict = {'options': {'_typeName': 'RetrieveOptions', 'maxObjects': 1000}, 'specSet': specSet} request_body = json.dumps(param_dict).encode('utf-8')
- Send the request, using the POST verb.from urllib.request import urlopen, Request import ssl moref = si_content['propertyCollector'] method = 'RetrievePropertiesEx' url = make_url(domain, mo=moref, m_p=method) request_headers = {} request_headers['vmware-api-session-id'] = token request_headers['Content-Type'] = 'application/json' headers['Content-Type'] = 'application/json' # Skip certificate verification on test systems only: unverified_context = ssl._create_unverified_context() request = Request(url, headers, data=body) with urlopen(request, context=unverified_context) as response : response_headers = response.headers response_body = response.read() json_body = json.loads(response_body) print(json_body)
The results are returned in a
RetrieveResult
data object, which encloses an array of
ObjectContent
data objects. Each ObjectContent
contains a managed object reference and a corresponding array of named properties
found by the PropertyCollector
that match your
PropertySpec
. For this example, the managed object references
identify VirtualMachine
objects, and the property name-value pairs
show the powerState
of each VirtualMachine
.