VMware: Add support for storagePod (#58627)

* User now can be specify datastore cluster for deploying OVF
* Added find_resource_pool_by_cluster API

Fixes: #57849

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
This commit is contained in:
Abhijeet Kasurde 2019-07-16 13:14:21 +05:30 committed by GitHub
parent a63e17cd63
commit de66abe521
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 20 deletions

View file

@ -1252,6 +1252,52 @@ class PyVmomi(object):
return dsc return dsc
return None return None
# Resource pool
def find_resource_pool_by_name(self, resource_pool_name, folder=None):
"""
Get resource pool managed object by name
Args:
resource_pool_name: Name of resource pool
Returns: Resource pool managed object if found else None
"""
if not folder:
folder = self.content.rootFolder
resource_pools = get_all_objs(self.content, [vim.ResourcePool], folder=folder)
for rp in resource_pools:
if rp.name == resource_pool_name:
return rp
return None
def find_resource_pool_by_cluster(self, resource_pool_name='Resources', cluster=None):
"""
Get resource pool managed object by cluster object
Args:
resource_pool_name: Name of resource pool
cluster: Managed object of cluster
Returns: Resource pool managed object if found else None
"""
desired_rp = None
if not cluster:
return desired_rp
if resource_pool_name != 'Resources':
# Resource pool name is different than default 'Resources'
resource_pools = cluster.resourcePool.resourcePool
if resource_pools:
for rp in resource_pools:
if rp.name == resource_pool_name:
desired_rp = rp
break
else:
desired_rp = cluster.resourcePool
return desired_rp
# VMDK stuff # VMDK stuff
def vmdk_disk_path_split(self, vmdk_path): def vmdk_disk_path_split(self, vmdk_path):
""" """

View file

@ -31,16 +31,21 @@ options:
default: ha-datacenter default: ha-datacenter
description: description:
- Datacenter to deploy to. - Datacenter to deploy to.
type: str
cluster: cluster:
description: description:
- Cluster to deploy to. - Cluster to deploy to.
type: str
datastore: datastore:
default: datastore1 default: datastore1
description: description:
- Datastore to deploy to. - Datastore to deploy to.
- "You can also specify datastore storage cluster. version_added: 2.9"
type: str
deployment_option: deployment_option:
description: description:
- The key of the chosen deployment option. - The key of the chosen deployment option.
type: str
disk_provisioning: disk_provisioning:
choices: choices:
- flat - flat
@ -56,6 +61,7 @@ options:
default: thin default: thin
description: description:
- Disk provisioning type. - Disk provisioning type.
type: str
fail_on_spec_warnings: fail_on_spec_warnings:
description: description:
- Cause the module to treat OVF Import Spec warnings as errors. - Cause the module to treat OVF Import Spec warnings as errors.
@ -75,6 +81,7 @@ options:
- ' folder: /folder1/datacenter1/vm' - ' folder: /folder1/datacenter1/vm'
- ' folder: folder1/datacenter1/vm' - ' folder: folder1/datacenter1/vm'
- ' folder: /folder1/datacenter1/vm/folder2' - ' folder: /folder1/datacenter1/vm/folder2'
type: str
inject_ovf_env: inject_ovf_env:
description: description:
- Force the given properties to be inserted into an OVF Environment and injected through VMware Tools. - Force the given properties to be inserted into an OVF Environment and injected through VMware Tools.
@ -84,11 +91,13 @@ options:
description: description:
- Name of the VM to work with. - Name of the VM to work with.
- Virtual machine names in vCenter are not necessarily unique, which may be problematic. - Virtual machine names in vCenter are not necessarily unique, which may be problematic.
type: str
networks: networks:
default: default:
VM Network: VM Network VM Network: VM Network
description: description:
- 'C(key: value) mapping of OVF network name, to the vCenter network name.' - 'C(key: value) mapping of OVF network name, to the vCenter network name.'
type: dict
ovf: ovf:
description: description:
- 'Path to OVF or OVA file to deploy.' - 'Path to OVF or OVA file to deploy.'
@ -102,10 +111,12 @@ options:
properties: properties:
description: description:
- The assignment of values to the properties found in the OVF as key value pairs. - The assignment of values to the properties found in the OVF as key value pairs.
type: dict
resource_pool: resource_pool:
default: Resources default: Resources
description: description:
- 'Resource Pool to deploy to.' - Resource Pool to deploy to.
type: str
wait: wait:
default: true default: true
description: description:
@ -172,8 +183,7 @@ from ansible.module_utils._text import to_native
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils.urls import generic_urlparse, open_url, urlparse, urlunparse from ansible.module_utils.urls import generic_urlparse, open_url, urlparse, urlunparse
from ansible.module_utils.vmware import (HAS_PYVMOMI, connect_to_api, find_datacenter_by_name, find_datastore_by_name, from ansible.module_utils.vmware import (find_network_by_name, find_vm_by_name, PyVmomi,
find_network_by_name, find_resource_pool_by_name, find_vm_by_name, find_cluster_by_name,
gather_vm_facts, vmware_argument_spec, wait_for_task, wait_for_vm_ip) gather_vm_facts, vmware_argument_spec, wait_for_task, wait_for_vm_ip)
try: try:
from ansible.module_utils.vmware import vim from ansible.module_utils.vmware import vim
@ -290,9 +300,9 @@ class VMDKUploader(Thread):
self.e = sys.exc_info() self.e = sys.exc_info()
class VMwareDeployOvf: class VMwareDeployOvf(PyVmomi):
def __init__(self, module): def __init__(self, module):
self.si = connect_to_api(module) super(VMwareDeployOvf, self).__init__(module)
self.module = module self.module = module
self.params = module.params self.params = module.params
@ -309,22 +319,39 @@ class VMwareDeployOvf:
self.entity = None self.entity = None
def get_objects(self): def get_objects(self):
self.datastore = find_datastore_by_name(self.si, self.params['datastore']) self.datacenter = self.find_datacenter_by_name(self.params['datacenter'])
if not self.datastore:
self.module.fail_json(msg='%(datastore)s could not be located' % self.params)
self.datacenter = find_datacenter_by_name(self.si, self.params['datacenter'])
if not self.datacenter: if not self.datacenter:
self.module.fail_json(msg='%(datacenter)s could not be located' % self.params) self.module.fail_json(msg='%(datacenter)s could not be located' % self.params)
self.datastore = None
datastore_cluster_obj = self.find_datastore_cluster_by_name(self.params['datastore'])
if datastore_cluster_obj:
datastore = None
datastore_freespace = 0
for ds in datastore_cluster_obj.childEntity:
if isinstance(ds, vim.Datastore) and ds.summary.freeSpace > datastore_freespace:
# If datastore field is provided, filter destination datastores
if ds.summary.maintenanceMode != 'normal' or not ds.summary.accessible:
continue
datastore = ds
datastore_freespace = ds.summary.freeSpace
if datastore:
self.datastore = datastore
else:
self.datastore = self.find_datastore_by_name(self.params['datastore'])
if not self.datastore:
self.module.fail_json(msg='%(datastore)s could not be located' % self.params)
if self.params['cluster']: if self.params['cluster']:
cluster = find_cluster_by_name(self.si, self.params['cluster']) resource_pools = []
cluster = self.find_cluster_by_name(self.params['cluster'], datacenter_name=self.datacenter)
if cluster is None: if cluster is None:
self.module.fail_json(msg="Unable to find cluster '%(cluster)s'" % self.params) self.module.fail_json(msg="Unable to find cluster '%(cluster)s'" % self.params)
self.resource_pool = self.find_resource_pool_by_cluster(self.params['resource_pool'], cluster=cluster)
else: else:
self.resource_pool = cluster.resourcePool self.resource_pool = self.find_resource_pool_by_name(self.params['resource_pool'])
else:
self.resource_pool = find_resource_pool_by_name(self.si, self.params['resource_pool'])
if not self.resource_pool: if not self.resource_pool:
self.module.fail_json(msg='%(resource_pool)s could not be located' % self.params) self.module.fail_json(msg='%(resource_pool)s could not be located' % self.params)
@ -665,9 +692,6 @@ def main():
supports_check_mode=True, supports_check_mode=True,
) )
if not HAS_PYVMOMI:
module.fail_json(msg='pyvmomi python library not found')
deploy_ovf = VMwareDeployOvf(module) deploy_ovf = VMwareDeployOvf(module)
deploy_ovf.upload() deploy_ovf.upload()
deploy_ovf.complete() deploy_ovf.complete()

View file

@ -1248,7 +1248,6 @@ lib/ansible/modules/cloud/vmware/vmware_datastore_cluster.py E337
lib/ansible/modules/cloud/vmware/vmware_datastore_facts.py E337 lib/ansible/modules/cloud/vmware/vmware_datastore_facts.py E337
lib/ansible/modules/cloud/vmware/vmware_datastore_maintenancemode.py E337 lib/ansible/modules/cloud/vmware/vmware_datastore_maintenancemode.py E337
lib/ansible/modules/cloud/vmware/vmware_deploy_ovf.py E337 lib/ansible/modules/cloud/vmware/vmware_deploy_ovf.py E337
lib/ansible/modules/cloud/vmware/vmware_deploy_ovf.py E338
lib/ansible/modules/cloud/vmware/vmware_dns_config.py E337 lib/ansible/modules/cloud/vmware/vmware_dns_config.py E337
lib/ansible/modules/cloud/vmware/vmware_drs_group_facts.py E337 lib/ansible/modules/cloud/vmware/vmware_drs_group_facts.py E337
lib/ansible/modules/cloud/vmware/vmware_drs_group.py E337 lib/ansible/modules/cloud/vmware/vmware_drs_group.py E337