Source code for saltext.vcf.clients.vim_vapp

"""vSphere vApp container management via ``vim.VirtualApp``.

A vApp is a special kind of resource pool that wraps a group of VMs with
startup/shutdown ordering and metadata. Created via
``ResourcePool.CreateVApp`` or ``Folder.CreateVApp``.
"""

from pyVmomi import vim

from saltext.vcf.utils import vim as soap


def _content(opts, profile=None):
    return soap.content(opts, profile=profile)


def _find_vapp(opts, name_or_id, profile=None):
    content = _content(opts, profile=profile)
    container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualApp], True)
    try:
        for v in container.view:
            if name_or_id in (v._moId, v.name):  # noqa: SLF001
                return v
    finally:
        container.Destroy()
    raise LookupError(f"vApp {name_or_id!r} not found")


def _find_resource_pool(opts, name_or_id, profile=None):
    content = _content(opts, profile=profile)
    container = content.viewManager.CreateContainerView(
        content.rootFolder, [vim.ResourcePool], True
    )
    try:
        for rp in container.view:
            if name_or_id in (rp._moId, rp.name):  # noqa: SLF001
                return rp
    finally:
        container.Destroy()
    raise LookupError(f"resource pool {name_or_id!r} not found")


def _to_dict(vapp):
    summary = vapp.summary
    cfg = vapp.vAppConfig
    return {
        "id": vapp._moId,  # noqa: SLF001
        "name": vapp.name,
        "parent": vapp.parent._moId if vapp.parent else None,  # noqa: SLF001
        "overall_status": str(summary.overallStatus) if summary else None,
        "vm_count": len(list(vapp.vm)) if vapp.vm else 0,
        "annotation": cfg.annotation if cfg else None,
        "product": (
            [
                {"name": p.name, "vendor": p.vendor, "version": p.version}
                for p in (cfg.product or [])
            ]
            if cfg
            else []
        ),
    }


def list_(opts, profile=None):
    content = _content(opts, profile=profile)
    container = content.viewManager.CreateContainerView(content.rootFolder, [vim.VirtualApp], True)
    try:
        return [_to_dict(v) for v in container.view]
    finally:
        container.Destroy()


def get(opts, name_or_id, profile=None):
    return _to_dict(_find_vapp(opts, name_or_id, profile=profile))


def get_or_none(opts, name_or_id, profile=None):
    try:
        return get(opts, name_or_id, profile=profile)
    except LookupError:
        return None


[docs] def create(opts, name, parent_resource_pool, *, annotation=None, profile=None): """Create a vApp under *parent_resource_pool* (resource-pool moId or name). Synchronous; returns the new vApp dict. """ rp = _find_resource_pool(opts, parent_resource_pool, profile=profile) cfg_spec = vim.vApp.VAppConfigSpec() if annotation is not None: cfg_spec.annotation = annotation res_spec = vim.ResourceConfigSpec() res_spec.cpuAllocation = vim.ResourceAllocationInfo( reservation=0, expandableReservation=True, limit=-1, shares=vim.SharesInfo(level="normal") ) res_spec.memoryAllocation = vim.ResourceAllocationInfo( reservation=0, expandableReservation=True, limit=-1, shares=vim.SharesInfo(level="normal") ) new_vapp = rp.CreateVApp(name=name, resSpec=res_spec, configSpec=cfg_spec, vmFolder=None) return _to_dict(new_vapp)
[docs] def power_on(opts, name_or_id, profile=None): """Power on all VMs in the vApp. Returns the vim.Task moId.""" v = _find_vapp(opts, name_or_id, profile=profile) task = v.PowerOnVApp_Task() return task._moId # noqa: SLF001
def power_off(opts, name_or_id, *, force=False, profile=None): v = _find_vapp(opts, name_or_id, profile=profile) task = v.PowerOffVApp_Task(force=bool(force)) return task._moId # noqa: SLF001 def suspend(opts, name_or_id, profile=None): v = _find_vapp(opts, name_or_id, profile=profile) task = v.SuspendVApp_Task() return task._moId # noqa: SLF001 def delete(opts, name_or_id, profile=None): v = _find_vapp(opts, name_or_id, profile=profile) task = v.Destroy_Task() return task._moId # noqa: SLF001
[docs] def update(opts, name_or_id, *, annotation=None, profile=None): """Update vApp metadata fields. Returns the updated vApp dict.""" v = _find_vapp(opts, name_or_id, profile=profile) cfg_spec = vim.vApp.VAppConfigSpec() if annotation is not None: cfg_spec.annotation = annotation v.UpdateVAppConfig(spec=cfg_spec) return _to_dict(v)