mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-23 19:01:26 -07:00
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:
parent
5b898a7732
commit
10fc4417f7
6 changed files with 364 additions and 37 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue