Source code for saltext.vcf.resources.esxi

"""
``esxi`` resource type — one **standalone** ESXi host per resource ID.

ESXi joined to a vCenter has its direct REST API locked; for those hosts
use the cluster-level :mod:`saltext.vcf.modules.vcf_cluster_config`
instead. This resource type targets ESXi hosts that respond to vAPI
session on ``POST /api/session`` directly.

Configuration::

    resources:
      esxi:
        instances:
          esxi-standalone:
            host: esxi01.example.com
            username: root
            password: VMware123!
            verify_ssl: false
"""

import logging

import requests
import urllib3

from saltext.vcf.clients import esxi_advanced
from saltext.vcf.clients import esxi_firewall
from saltext.vcf.clients import esxi_host
from saltext.vcf.clients import esxi_ntp
from saltext.vcf.clients import esxi_service
from saltext.vcf.clients import esxi_syslog
from saltext.vcf.resources import pillar_resources_tree

log = logging.getLogger(__name__)

CONTEXT_KEY = "esxi_resource"


def __virtual__():
    return True


def _resource_id():
    return __resource__["id"]  # pylint: disable=undefined-variable


def _instance_cfg(resource_id):
    return __context__[CONTEXT_KEY]["instances"].get(  # pylint: disable=undefined-variable
        resource_id, {}
    )


def _opts():
    return {"pillar": {"saltext.vcf": {"esxi": _instance_cfg(_resource_id())}}}


# ---------------------------------------------------------------------------
# Framework interface
# ---------------------------------------------------------------------------


def init(opts):
    instances = pillar_resources_tree(opts).get("esxi", {}).get("instances", {})
    __context__[CONTEXT_KEY] = {  # pylint: disable=undefined-variable
        "initialized": True,
        "instances": instances,
    }
    log.debug("esxi resource init: managing %s", list(instances))


def initialized():
    return __context__.get(CONTEXT_KEY, {}).get(  # pylint: disable=undefined-variable
        "initialized", False
    )


def discover(opts):
    return list(pillar_resources_tree(opts).get("esxi", {}).get("instances", {}))


def grains():
    rid = _resource_id()
    cfg = _instance_cfg(rid)
    g = {"resource_type": "esxi", "resource_id": rid, "host": cfg.get("host", "")}
    try:
        info = esxi_host.info(_opts())
        if isinstance(info, dict):
            for key in ("version", "build", "product_line_id", "vendor"):
                if key in info:
                    g[key] = info[key]
    except requests.RequestException as exc:
        log.warning("esxi grains: host.info call failed for %s: %s", rid, exc)
    return g


def grains_refresh():
    return grains()


[docs] def ping(): """Probe ``/api/session`` to confirm the ESXi host is reachable.""" cfg = _instance_cfg(_resource_id()) host = cfg.get("host") verify = cfg.get("verify_ssl", True) if not verify: urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) try: resp = requests.post( f"https://{host}/api/session", auth=(cfg.get("username"), cfg.get("password")), verify=verify, timeout=10, ) return resp.status_code == 200 except requests.RequestException as exc: log.warning("esxi ping failed for %s: %s", host, exc) return False
def shutdown(opts): __context__.pop(CONTEXT_KEY, None) # pylint: disable=undefined-variable # --------------------------------------------------------------------------- # Per-resource operations # --------------------------------------------------------------------------- def host_info(): return esxi_host.info(_opts()) def host_lockdown_get(): return esxi_host.lockdown_get(_opts()) def host_lockdown_set(mode, exception_users=None): return esxi_host.lockdown_set(_opts(), mode, exception_users=exception_users) def host_enter_maintenance(): return esxi_host.enter_maintenance(_opts()) def host_exit_maintenance(): return esxi_host.exit_maintenance(_opts()) def host_reboot(force=False): return esxi_host.reboot(_opts(), force=force) def host_shutdown(force=False): return esxi_host.shutdown(_opts(), force=force) def service_list(): return esxi_service.list_(_opts()) def service_get(service): return esxi_service.get(_opts(), service) def service_start(service): return esxi_service.start(_opts(), service) def service_stop(service): return esxi_service.stop(_opts(), service) def service_restart(service): return esxi_service.restart(_opts(), service) def service_set_policy(service, policy): return esxi_service.set_policy(_opts(), service, policy) def firewall_list(): return esxi_firewall.list_(_opts()) def firewall_get(rule): return esxi_firewall.get(_opts(), rule) def firewall_set_enabled(rule, enabled): return esxi_firewall.set_enabled(_opts(), rule, enabled) def firewall_set_allowed_ips(rule, allowed_ips, all_ip=False): return esxi_firewall.set_allowed_ips(_opts(), rule, allowed_ips, all_ip=all_ip) def ntp_get(): return esxi_ntp.get(_opts()) def ntp_set_servers(servers): return esxi_ntp.set_servers(_opts(), servers) def ntp_set_enabled(enabled): return esxi_ntp.set_enabled(_opts(), enabled) def syslog_get(): return esxi_syslog.get(_opts()) def syslog_set_servers(servers): return esxi_syslog.set_servers(_opts(), servers) def syslog_set_log_level(level): return esxi_syslog.set_log_level(_opts(), level) def advanced_list(): return esxi_advanced.list_(_opts()) def advanced_get(key): return esxi_advanced.get(_opts(), key) def advanced_set(key, value): return esxi_advanced.set_value(_opts(), key, value)