Source code for saltext.vcf.clients.vim_cluster_config

"""Cluster-level DRS / HA / EVC / DPM settings via SOAP.

DRS rules + VM/host groups live in ``vim_drs_rule``. This module
manages the cluster-wide *behavior* knobs: whether DRS is on, what
automation level, HA tolerations, EVC mode, etc.

All writes go through ``ClusterComputeResource.ReconfigureComputeResource_Task``
with a ``vim.cluster.ConfigSpecEx`` carrying the relevant sub-spec.
"""

from pyVmomi import vim

from saltext.vcf.utils import vim as soap


def _cluster(opts, name, profile=None):
    content = soap.content(opts, profile=profile)
    for dc in content.rootFolder.childEntity:
        if not isinstance(dc, vim.Datacenter):
            continue
        for entity in dc.hostFolder.childEntity:
            if isinstance(entity, vim.ClusterComputeResource) and name in (
                entity._moId,  # noqa: SLF001
                entity.name,
            ):
                return entity
    raise LookupError(f"cluster {name!r} not found")


# ---------------------------------------------------------------------------
# DRS
# ---------------------------------------------------------------------------


[docs] def drs_get(opts, cluster, profile=None): """Return current DRS config as a dict.""" cfg = _cluster(opts, cluster, profile=profile).configurationEx.drsConfig return { "enabled": bool(cfg.enabled), "default_vm_behavior": str(cfg.defaultVmBehavior), "vm_monitoring_enabled": bool(getattr(cfg, "enableVmBehaviorOverrides", False)), "migration_threshold": int(cfg.vmotionRate), }
[docs] def drs_set( opts, cluster, enabled=None, default_vm_behavior=None, migration_threshold=None, vm_monitoring_enabled=None, profile=None, ): """Update DRS settings. Only non-None fields are applied.""" cfg = vim.cluster.DrsConfigInfo() if enabled is not None: cfg.enabled = bool(enabled) if default_vm_behavior is not None: cfg.defaultVmBehavior = default_vm_behavior if migration_threshold is not None: cfg.vmotionRate = int(migration_threshold) if vm_monitoring_enabled is not None: cfg.enableVmBehaviorOverrides = bool(vm_monitoring_enabled) spec = vim.cluster.ConfigSpecEx(drsConfig=cfg) cl = _cluster(opts, cluster, profile=profile) task = cl.ReconfigureComputeResource_Task(spec=spec, modify=True) return task._moId # noqa: SLF001
# --------------------------------------------------------------------------- # HA (das = "Distributed Availability Services") # --------------------------------------------------------------------------- def ha_get(opts, cluster, profile=None): cfg = _cluster(opts, cluster, profile=profile).configurationEx.dasConfig out = { "enabled": bool(cfg.enabled), "host_monitoring": str(cfg.hostMonitoring), "vm_monitoring": str(cfg.vmMonitoring), "admission_control_enabled": bool(getattr(cfg, "admissionControlEnabled", False)), } if cfg.defaultVmSettings: out["restart_priority"] = str(cfg.defaultVmSettings.restartPriority) out["isolation_response"] = str(cfg.defaultVmSettings.isolationResponse) return out
[docs] def ha_set( opts, cluster, enabled=None, host_monitoring=None, vm_monitoring=None, restart_priority=None, isolation_response=None, admission_control_enabled=None, profile=None, ): """Update HA settings.""" cfg = vim.cluster.DasConfigInfo() if enabled is not None: cfg.enabled = bool(enabled) if host_monitoring is not None: cfg.hostMonitoring = host_monitoring if vm_monitoring is not None: cfg.vmMonitoring = vm_monitoring if admission_control_enabled is not None: cfg.admissionControlEnabled = bool(admission_control_enabled) if restart_priority is not None or isolation_response is not None: vm_settings = vim.cluster.DasVmSettings() if restart_priority is not None: vm_settings.restartPriority = restart_priority if isolation_response is not None: vm_settings.isolationResponse = isolation_response cfg.defaultVmSettings = vm_settings spec = vim.cluster.ConfigSpecEx(dasConfig=cfg) cl = _cluster(opts, cluster, profile=profile) task = cl.ReconfigureComputeResource_Task(spec=spec, modify=True) return task._moId # noqa: SLF001
# --------------------------------------------------------------------------- # EVC (Enhanced vMotion Compatibility) — separate API on the cluster # ---------------------------------------------------------------------------
[docs] def evc_get(opts, cluster, profile=None): """Return the EVC mode and supported baselines.""" cl = _cluster(opts, cluster, profile=profile) summary = cl.summary return { "current_mode": getattr(summary, "currentEVCModeKey", None), "current_graphics_mode": getattr(summary, "currentEVCGraphicsModeKey", None), }
[docs] def evc_set(opts, cluster, mode, profile=None): """Configure (or enable) cluster EVC at *mode* (e.g. ``intel-skylake``). Uses ``EvcManager.ConfigureEvcMode_Task``. """ cl = _cluster(opts, cluster, profile=profile) evc_mgr = cl.EvcManager() task = evc_mgr.ConfigureEvcMode_Task(evcModeKey=mode) return task._moId # noqa: SLF001
def evc_disable(opts, cluster, profile=None): cl = _cluster(opts, cluster, profile=profile) evc_mgr = cl.EvcManager() task = evc_mgr.DisableEvcMode_Task() return task._moId # noqa: SLF001 # --------------------------------------------------------------------------- # DPM (Distributed Power Management) — part of DRS config block on cluster # --------------------------------------------------------------------------- def dpm_get(opts, cluster, profile=None): cfg = _cluster(opts, cluster, profile=profile).configurationEx.dpmConfigInfo if cfg is None: return {"enabled": False, "default_behavior": None, "host_power_action_rate": None} return { "enabled": bool(cfg.enabled), "default_behavior": str(cfg.defaultDpmBehavior), "host_power_action_rate": int(cfg.hostPowerActionRate), } def dpm_set( opts, cluster, enabled=None, default_behavior=None, host_power_action_rate=None, profile=None ): cfg = vim.cluster.DpmConfigInfo() if enabled is not None: cfg.enabled = bool(enabled) if default_behavior is not None: cfg.defaultDpmBehavior = default_behavior if host_power_action_rate is not None: cfg.hostPowerActionRate = int(host_power_action_rate) spec = vim.cluster.ConfigSpecEx(dpmConfig=cfg) cl = _cluster(opts, cluster, profile=profile) task = cl.ReconfigureComputeResource_Task(spec=spec, modify=True) return task._moId # noqa: SLF001