vmware_guest: use the datacenter as a context for clone specs (#26511)

* Slight refactor on vmware_guest to fix path searching and vcsim compatibility.
* Clean up pep8 errors
* Fix more pep8 issues
* Add assertions
* Remove debug failure
* Update docsting for folder with examples
* Revise _get_vm_prop based on suggestions
* Implement folder walker to find a folder path
* More enhancements for datacenter->datacenter cloning
* Fix a few pep8 issues
* Remove useless check for subclass of None
* Fix a few suggestions
* Move serialize_spec to a util function
* Group exceptions together

Fixes #25011
This commit is contained in:
jctanner 2017-07-11 23:07:00 -04:00 committed by GitHub
parent 5b898a7732
commit 10fc4417f7
6 changed files with 364 additions and 37 deletions

View file

@ -213,6 +213,17 @@ def find_host_portgroup_by_name(host, portgroup_name):
return None
def _get_vm_prop(vm, attributes):
"""Safely get a property or return None"""
result = vm
for attribute in attributes:
try:
result = getattr(result, attribute)
except (AttributeError, IndexError):
return None
return result
def gather_vm_facts(content, vm):
""" Gather facts from vim.VirtualMachine object. """
facts = {
@ -225,8 +236,8 @@ def gather_vm_facts(content, vm):
'hw_processor_count': vm.config.hardware.numCPU,
'hw_memtotal_mb': vm.config.hardware.memoryMB,
'hw_interfaces': [],
'guest_tools_status': vm.guest.toolsRunningStatus,
'guest_tools_version': vm.guest.toolsVersion,
'guest_tools_status': _get_vm_prop(vm, ('guest', 'toolsRunningStatus')),
'guest_tools_version': _get_vm_prop(vm, ('guest', 'toolsVersion')),
'ipv4': None,
'ipv6': None,
'annotation': vm.config.annotation,
@ -249,8 +260,10 @@ def gather_vm_facts(content, vm):
facts['customvalues'][kn] = value_obj.value
net_dict = {}
for device in vm.guest.net:
net_dict[device.macAddress] = list(device.ipAddress)
vmnet = _get_vm_prop(vm, ('guest', 'net'))
if vmnet:
for device in vmnet:
net_dict[device.macAddress] = list(device.ipAddress)
for k, v in iteritems(net_dict):
for ipaddress in v:
@ -317,6 +330,9 @@ def get_current_snap_obj(snapshots, snapob):
def list_snapshots(vm):
result = {}
snapshot = _get_vm_prop(vm, ('vm', 'snapshot'))
if not snapshot:
return result
if vm.snapshot is None:
return result
@ -360,7 +376,7 @@ def connect_to_api(module, disconnect_atexit=True):
service_instance = connect.SmartConnect(host=hostname, user=username, pwd=password, sslContext=context)
else:
module.fail_json(msg="Unable to connect to vCenter or ESXi API on TCP/443.", apierror=str(connection_error))
except Exception as e:
except:
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.verify_mode = ssl.CERT_NONE
service_instance = connect.SmartConnect(host=hostname, user=username, pwd=password, sslContext=context)
@ -533,3 +549,58 @@ def run_command_in_guest(content, vm, username, password, program_path, program_
result['failed'] = True
return result
def serialize_spec(clonespec):
"""Serialize a clonespec or a relocation spec"""
data = {}
attrs = dir(clonespec)
attrs = [x for x in attrs if not x.startswith('_')]
for x in attrs:
xo = getattr(clonespec, x)
if callable(xo):
continue
xt = type(xo)
if xo is None:
data[x] = None
elif issubclass(xt, list):
data[x] = []
for xe in xo:
data[x].append(serialize_spec(xe))
elif issubclass(xt, str):
data[x] = xo
elif issubclass(xt, unicode):
data[x] = xo
elif issubclass(xt, int):
data[x] = xo
elif issubclass(xt, float):
data[x] = xo
elif issubclass(xt, long):
data[x] = xo
elif issubclass(xt, bool):
data[x] = xo
elif issubclass(xt, dict):
data[x] = {}
for k, v in xo.items():
data[x][k] = serialize_spec(v)
elif isinstance(xo, vim.vm.ConfigSpec):
data[x] = serialize_spec(xo)
elif isinstance(xo, vim.vm.RelocateSpec):
data[x] = serialize_spec(xo)
elif isinstance(xo, vim.vm.device.VirtualDisk):
data[x] = serialize_spec(xo)
elif isinstance(xo, vim.Description):
data[x] = {
'dynamicProperty': serialize_spec(xo.dynamicProperty),
'dynamicType': serialize_spec(xo.dynamicType),
'label': serialize_spec(xo.label),
'summary': serialize_spec(xo.summary),
}
elif hasattr(xo, 'name'):
data[x] = str(xo) + ':' + xo.name
elif isinstance(xo, vim.vm.ProfileSpec):
pass
else:
data[x] = str(xt)
return data