From 0023fc09e4b8c7682ca73cc1be289e5b008a942f Mon Sep 17 00:00:00 2001 From: Frank Brehm Date: Wed, 26 Aug 2020 12:12:10 +0200 Subject: [PATCH] Trying to retrieve datastore form storageResorceManager --- lib/cr_vmware_tpl/handler.py | 88 +++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 12 deletions(-) diff --git a/lib/cr_vmware_tpl/handler.py b/lib/cr_vmware_tpl/handler.py index 6274cd1..6ded21c 100644 --- a/lib/cr_vmware_tpl/handler.py +++ b/lib/cr_vmware_tpl/handler.py @@ -29,12 +29,14 @@ from pyVmomi import vim from fb_tools.common import pp, to_str from fb_tools.errors import HandlerError, ExpectedHandlerError +from fb_tools.errors import VSphereDatacenterNotFoundError from fb_tools.handler import BaseHandler from fb_tools.vsphere.errors import VSphereExpectedError from fb_tools.vsphere.server import VsphereServer from fb_tools.vsphere.iface import VsphereVmInterface +from fb_tools.vsphere.ds import VsphereDatastore from .config import CrTplConfiguration @@ -412,32 +414,94 @@ class CrTplHandler(BaseHandler): # ------------------------------------------------------------------------- def select_data_store_from_cluster(self): - ################################### - # TODO - ################################### - # Continue here ... + # Searching for the right storage cluster + c_name = self.config.storage_cluster + used_c_name = None + for cluster_name in self.vsphere.ds_clusters.keys(): + if cluster_name.lower() == c_name.lower(): + msg = _("Found storage cluster {!r}.").format(cluster_name) + used_c_name = cluster_name + break + if not used_c_name: + return None + + cluster = self.vsphere.ds_clusters[used_c_name] + if cluster.free_space_gb <= self.config.data_size_gb: + msg = _( + "Cannot use datastore cluster {n!r}, free space " + "{free:0.1f} GiB is less than {min:0.1f} GiB.").format( + n=used_c_name, free=cluster.free_space_gb, min=self.config.data_size_gb) + LOG.warn(msg) + return None + pod = self._get_storage_pod_obj(used_c_name) + if not pod: + msg = _("Could not get {c} object with name {n!r}.").format( + c="vim.StoragePod", n=used_c_name) + raise HandlerError(msg) + + vmconf = vim.vm.ConfigSpec() podsel = vim.storageDrs.PodSelectionSpec() - pod = get_obj(content, [vim.StoragePod], datastorecluster_name) podsel.storagePod = pod storagespec = vim.storageDrs.StoragePlacementSpec() storagespec.podSelectionSpec = podsel storagespec.type = 'create' - storagespec.folder = destfolder - storagespec.resourcePool = resource_pool + storagespec.folder = self.config.folder + storagespec.resourcePool = self.cluster.resource_pool storagespec.configSpec = vmconf + LOG.debug(_( + "Trying to get a recommendation for a datastore from " + "VSphere storageResourceManager ...")) + content = self.vsphere.service_instance.RetrieveContent() try: - rec = content.storageResourceManager.RecommendDatastores( - storageSpec=storagespec) + rec = content.storageResourceManager.RecommendDatastores(storageSpec=storagespec) rec_action = rec.recommendations[0].action[0] real_datastore_name = rec_action.destination.name - except: - real_datastore_name = template.datastore[0].info.name + except Exception as e: + msg = _( + "Got no recommendation for a datastore from VSphere storageResourceManager: " + "{c} - {e}").format(c=e.__class.__name__, e=e) + LOG.warn(msg) + return None + + datastore = self.vsphere.get_obj(content, [vim.Datastore], real_datastore_name) + ds = VsphereDatastore.from_summary( + datastore, appname=self.appname, verbose=self.verbose, base_dir=self.base_dir) + return ds + + # ------------------------------------------------------------------------- + def _get_storage_pod_obj(self, used_c_name): + + content = self.vsphere.service_instance.RetrieveContent() + dc = self.config.get_obj(content, [vim.Datacenter], self.config.dc) + if not dc: + raise VSphereDatacenterNotFoundError(self.config.dc) + + for child in dc.datastoreFolder.childEntity: + pod = self._get_storage_pod_obj_rec(child, used_c_name) + if pod: + return pod - datastore = get_obj(content, [vim.Datastore], real_datastore_name) + return pod + # ------------------------------------------------------------------------- + def _get_storage_pod_obj_rec(self, child, used_c_name, depth=1): + +A if hasattr(child, 'childEntity'): + if depth > self.vsphere.max_search_depth: + return None + for sub_child in child.childEntity: + pod = self._get_storage_pod_obj_rec(sub_child, used_c_name, depth + 1) + if pod: + return pod + + if isinstance(child, vim.StoragePod): + if child.summary.name == used_c_name: + return child + + return None # ------------------------------------------------------------------------- def select_simple_data_store(self): -- 2.39.5