]> Frank Brehm's Git Trees - pixelpark/create-vmware-tpl.git/commitdiff
Trying to retrieve datastore form storageResorceManager
authorFrank Brehm <frank.brehm@pixelpark.com>
Wed, 26 Aug 2020 10:12:10 +0000 (12:12 +0200)
committerFrank Brehm <frank.brehm@pixelpark.com>
Wed, 26 Aug 2020 10:12:10 +0000 (12:12 +0200)
lib/cr_vmware_tpl/handler.py

index 6274cd1552d367d06ae718c2808adc0b4bef630b..6ded21c0bfaf190d2a1f0e0e0200387839a6a42b 100644 (file)
@@ -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):