Source code for saltext.vcf.clients.vim_resource_pool

"""SOAP ops on resource pools: move + share-level config.

REST ``/api/vcenter/resource-pool`` lacks both move and the share-level
``cpuAllocation``/``memoryAllocation`` config. These go through pyVmomi
``vim.ResourcePool``.
"""

from pyVmomi import vim

from saltext.vcf.utils import vim as soap


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


[docs] def move(opts, rp_id_or_name, target_parent, profile=None): """Move *rp_id_or_name* under *target_parent*. Synchronous. *target_parent* may be a resource-pool moId, name, or ``vim.ResourcePool``. """ rp = _find_rp(opts, rp_id_or_name, profile=profile) target = ( target_parent if isinstance(target_parent, vim.ResourcePool) else _find_rp(opts, target_parent, profile=profile) ) target.MoveIntoResourcePool(list=[rp]) return {"resource_pool": rp._moId, "new_parent": target._moId} # noqa: SLF001
def _allocation(info): return { "reservation": int(info.reservation or 0), "expandable_reservation": bool(info.expandableReservation), "limit": int(info.limit if info.limit is not None else -1), "shares_level": str(info.shares.level) if info.shares else None, "shares_value": int(info.shares.shares) if info.shares else None, }
[docs] def get_shares(opts, rp_id_or_name, profile=None): """Return ``{cpu, memory}`` allocation dicts (reservation, limit, shares).""" rp = _find_rp(opts, rp_id_or_name, profile=profile) cfg = rp.config return {"cpu": _allocation(cfg.cpuAllocation), "memory": _allocation(cfg.memoryAllocation)}
def _merge_allocation(current, spec): """Merge *spec* (incoming overrides) on top of *current* (existing allocation info).""" info = vim.ResourceAllocationInfo() info.reservation = int(spec.get("reservation", current.reservation or 0)) info.expandableReservation = bool( spec.get("expandable_reservation", current.expandableReservation) ) info.limit = int(spec.get("limit", current.limit if current.limit is not None else -1)) shares = vim.SharesInfo() shares.level = spec.get("shares_level", current.shares.level if current.shares else "normal") shares.shares = int(spec.get("shares_value", current.shares.shares if current.shares else 4000)) info.shares = shares return info
[docs] def set_shares(opts, rp_id_or_name, *, cpu=None, memory=None, profile=None): """Set CPU and/or memory allocation. Each is a dict with any of: ``reservation``, ``expandable_reservation``, ``limit``, ``shares_level`` (``low|normal|high|custom``), ``shares_value`` (int). SOAP ``ResourceConfigSpec`` requires both ``cpuAllocation`` and ``memoryAllocation`` to be populated; any None argument is merged on top of the pool's current allocation so partial updates work safely. """ rp = _find_rp(opts, rp_id_or_name, profile=profile) cfg = rp.config config = vim.ResourceConfigSpec() config.cpuAllocation = _merge_allocation(cfg.cpuAllocation, cpu or {}) config.memoryAllocation = _merge_allocation(cfg.memoryAllocation, memory or {}) rp.UpdateConfig(name=rp.name, config=config) return get_shares(opts, rp_id_or_name, profile=profile)