from ..xlate import XLATOR
-__version__ = '3.10.0'
+__version__ = '4.0.0'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
steps = (
'init', 'vmw-init', 'read-yaml', 'pdns-zones', 'vmw-test', 'collect-folders',
- 'vmw-clusters', 'vmw-datastores', 'vmw-ds-clusters', 'vmw-networks', 'vmw-templates',
+ 'vmw-clusters', 'vmw-datastores', 'vmw-ds-clusters', 'vmw-vms', 'vmw-networks', 'vmw-templates',
'validate-yaml', 'validate-storage', 'validate-iface', 'validate-dns',
'perform-dns', 'project-dir', 'tf-files', 'ensure-vmw-folders',
)
'vmw-test': _('After testing VSPhere handlers.'),
'collect-folders': _('After collecting all VMWare and local folders.'),
'vmw-clusters': _('After collecting all VMWare clusters.'),
+ 'vmw-vms': _('After caching all VMWare VMs and templates.'),
'vmw-datastores': _('After collecting all VMWare datastores.'),
'vmw-ds-clusters': _('After collecting all VMWare datastore clusters.'),
'vmw-networks': _('After collecting all VMWare networks.'),
self.vsphere_folders = []
+ self.vsphere_vm_cache = []
+
self.vsphere_user = None
self.vsphere_password = None
LOG.info(_("Retrieving information from vSphere."))
self.exec_vmw_clusters()
+ self.exec_cache_vmw_vms()
self.exec_vmw_datastores()
self.exec_vmw_ds_clusters()
self.exec_vmw_networks()
# Own modules
from ..errors import AbortExecution
+from ..slim_vm import SlimVm
+
from ..xlate import XLATOR
-__version__ = '0.1.3'
+__version__ = '0.2.0'
LOG = logging.getLogger(__name__)
_ = XLATOR.gettext
for vname in self.vsphere:
self.vsphere[vname].get_datacenter()
- LOG.debug(_("Collecting vSphere folders."))
+ LOG.debug(_("Collecting used vSphere folders."))
self.vsphere_folders = []
for vm in self.vms:
if vm.folder:
if vm.folder not in self.vsphere_folders:
self.vsphere_folders.append(vm.folder)
self.vsphere_folders.sort(key=str.lower)
- LOG.debug(_("Collected vSphere folders:") + "\n" + pp(self.vsphere_folders))
+ LOG.debug(_("Collected used vSphere folders:") + "\n" + pp(self.vsphere_folders))
# Set project name and directory
yfile = Path(yaml_file)
if self.stop_at_step == 'vmw-clusters':
raise AbortExecution('vmw-clusters')
+ # -------------------------------------------------------------------------·
+ def exec_cache_vmw_vms(self):
+
+ # if self.stop_at_step == 'vmw-vms':
+ # self.incr_verbosity()
+
+ self.explore_vsphere_vms()
+
+ if self.eval_errors:
+ msg = ngettext(
+ "Found one error in exploring vSphere VMs.",
+ "Found {n} errors in exploring vSphere VMs.",
+ self.eval_errors).format(n=self.eval_errors)
+ raise ExpectedHandlerError(msg)
+
+ LOG.info(_("Finished step {!r}.").format('vmw-vms'))
+ if self.stop_at_step == 'vmw-vms':
+ raise AbortExecution('vmw-vms')
+
# -------------------------------------------------------------------------·
def exec_vmw_datastores(self):
if self.stop_at_step == 'ensure-vmw-folders':
raise AbortExecution('ensure-vmw-folders')
+ # -------------------------------------------------------------------------·
+ def explore_vsphere_vms(self):
+
+ LOG.info(_("Exploring and caching all vSphere VMs and templates ..."))
+
+ for vsphere_name in self.vsphere:
+
+ re_vm = re.compile(r'.*')
+ vm_list = self.vsphere[vsphere_name].get_vms(re_vm, as_obj=True, stop_at_found=False)
+
+ for vm in vm_list:
+ slim_vm = SlimVm(vsphere_name, vm.name, vm.path, is_template=vm.template)
+ self.vsphere_vm_cache.append(slim_vm)
+
+ msg = ngettext(
+ 'Found one VM or template in vSphere.',
+ 'Found {nr} VMs and templates in vSphere.', len(self.vsphere_vm_cache))
+ msg = msg.format(nr=len(self.vsphere_vm_cache))
+ LOG.debug(msg)
+
+ if self.verbose > 1:
+ msg = _("All explored vSphere VMs and templates:")
+ LOG.debug(msg + "\n" + pp(self.vsphere_vm_cache))
+
# -------------------------------------------------------------------------·
def explore_vsphere_templates(self):
LOG.info(_("Exploring all vSphere templates ..."))
- for vname in self.vsphere:
+ for vsphere_name in self.vsphere:
- if vname not in self.vsphere_templates:
- self.vsphere_templates[vname] = {}
+ if vsphere_name not in self.vsphere_templates:
+ self.vsphere_templates[vsphere_name] = {}
- self.config.vsphere[vname].used_templates = []
+ self.config.vsphere[vsphere_name].used_templates = []
for vm in self.vms:
template_name = vm.vm_template
if template_name:
- if template_name not in self.config.vsphere[vname].used_templates:
- self.config.vsphere[vname].used_templates.append(template_name)
+ if template_name not in self.config.vsphere[vsphere_name].used_templates:
+ self.config.vsphere[vsphere_name].used_templates.append(template_name)
else:
LOG.error(_("VM {!r} has not template defined.").format(vm.name))
self.eval_errors += 1
- msg = _("All {} VSPhere templates to explore:").format(vname)
- msg += "\n" + pp(self.config.vsphere[vname].used_templates)
+ msg = _("All {} VSPhere templates to explore:").format(vsphere_name)
+ msg += "\n" + pp(self.config.vsphere[vsphere_name].used_templates)
LOG.debug(msg)
- for template_name in self.config.vsphere[vname].used_templates:
+ found_template = False
+ for template_name in self.config.vsphere[vsphere_name].used_templates:
- if template_name in self.vsphere_templates[vname]:
+ if template_name in self.vsphere_templates[vsphere_name]:
continue
LOG.debug(_("Searching for template {t!r} in VSPhere {v!r} ...").format(
- t=template_name, v=vname))
+ t=template_name, v=vsphere_name))
re_vm = re.compile(r'^' + re.escape(template_name) + r'$', re.IGNORECASE)
- vm_list = self.vsphere[vname].get_vms(re_vm, as_obj=True, stop_at_found=True)
+ vm_list = self.vsphere[vsphere_name].get_vms(re_vm, as_obj=True, stop_at_found=True)
if vm_list:
vm = vm_list[0]
tname = vm.name.lower()
- if tname not in self.vsphere_templates[vname]:
- self.vsphere_templates[vname][template_name] = vm
+ if tname not in self.vsphere_templates[vsphere_name]:
+ self.vsphere_templates[vsphere_name][template_name] = vm
else:
LOG.error(_("Template {t!r} not found in VSPhere {v!r}.").format(
- t=template_name, v=vname))
+ t=template_name, v=vsphere_name))
self.eval_errors += 1
if self.verbose > 2:
msg = _("All explored vSphere templates:")
out_dict = {}
- for vname in self.vsphere_templates:
- out_dict[vname] = {}
- for tname in self.vsphere_templates[vname]:
- out_dict[vname][tname] = self.vsphere_templates[vname][tname].as_dict()
+ for vsphere_name in self.vsphere_templates:
+ out_dict[vsphere_name] = {}
+ for tname in self.vsphere_templates[vsphere_name]:
+ out_dict[vsphere_name][tname] = self.vsphere_templates[vsphere_name][tname].as_dict()
msg += "\n" + pp(out_dict)
LOG.debug(msg)
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2024 by Frank Brehm, Berlin
+@summary: A module for providing a slim VM object.
+"""
+from __future__ import absolute_import
+
+# Standard module
+import logging
+
+# Third party modules
+from fb_tools.obj import FbGenericBaseObject
+
+from .xlate import XLATOR
+
+__version__ = '0.1.0'
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+
+# =============================================================================
+class SlimVm(FbGenericBaseObject):
+ """Class for encapsulation very basic data of a VM or a template in VMWare."""
+
+ # -------------------------------------------------------------------------
+ def __init__(self, vs_name, name, path, is_template=False):
+ """Initialize the SlimVm object."""
+ self._vs_name = None
+ self._name = None
+ self._path = ''
+ self._is_template = False
+
+ self.vs_name = vs_name
+ self.name = name
+ self.path = path
+ self.is_template = is_template
+
+ # -----------------------------------------------------------
+ @property
+ def vs_name(self):
+ """Return the name of the vSphere of the VM or the template."""
+ return self._vs_name
+
+ @vs_name.setter
+ def vs_name(self, value):
+ if value is None:
+ raise TypeError(_('The vSphere name of a VM or template may not be None.'))
+ val = str(value).strip().lower()
+ if val == '':
+ raise ValueError(_('The vSphere name of a VM or template may not be empty.'))
+
+ self._vs_name = val
+
+ # -----------------------------------------------------------
+ @property
+ def name(self):
+ """Return the name of the VM or the template."""
+ return self._name
+
+ @name.setter
+ def name(self, value):
+ if value is None:
+ raise TypeError(_('The name of a VM or template may not be None.'))
+ val = str(value).strip().lower()
+ if val == '':
+ raise ValueError(_('The name of a VM or template may not be empty.'))
+
+ self._name = val
+
+ # -----------------------------------------------------------
+ @property
+ def path(self):
+ """Return the path in VSphere of the VM or the template."""
+ return self._path
+
+ @path.setter
+ def path(self, value):
+ if value is None:
+ self._path = ''
+ return
+ val = str(value).strip()
+ self._path = val
+
+ # -----------------------------------------------------------
+ @property
+ def is_template(self):
+ """Return, whether the object points to a template or a normal VM."""
+ return self._is_template
+
+ @is_template.setter
+ def is_template(self, value):
+ self._is_template = bool(value)
+
+ # -------------------------------------------------------------------------
+ def __repr__(self):
+ """Typecasting into a string for reproduction."""
+ out = '<%s(' % (self.__class__.__name__)
+
+ fields = []
+ fields.append('vs_name={!r}'.format(self.vs_name))
+ fields.append('name={!r}'.format(self.name))
+ fields.append('path={!r}'.format(self.path))
+ fields.append('is_template={!r}'.format(self.is_template))
+
+ out += ', '.join(fields) + ')>'
+ return out
+
+ # -------------------------------------------------------------------------
+ def as_dict(self, short=True):
+ """
+ Transform the elements of the object into a dict.
+
+ @param short: don't include local properties in resulting dict.
+ @type short: bool
+
+ @return: structure as dict
+ @rtype: dict
+ """
+ res = super(SlimVm, self).as_dict(short=short)
+
+ res['vs_name'] = self.vs_name
+ res['name'] = self.name
+ res['path'] = self.path
+ res['is_template'] = self.is_template
+
+ return res
+
+ # -------------------------------------------------------------------------
+ def __eq__(self, other):
+ """Compare for equality."""
+ if not isinstance(other, SlimVm):
+ return False
+
+ if self.vs_name.lower() != other.vs_name.lower():
+ return False
+
+ if self.name.lower() != other.name.lower():
+ return False
+
+ if self.path != other.PATH:
+ return False
+
+ return True
+
+# =============================================================================
+
+if __name__ == '__main__':
+
+ pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4