Skip to content

ESXi Plugin Implementation

The ESXi plugin provides Cloudify lifecycle management for standalone ESXi hosts and their virtual machines, leveraging the govc CLI tool for infrastructure interaction. It defines three primary node types - esxi.nodes.Host, esxi.nodes.VM, and esxi.nodes.Snapshot - each mapped to specific Python task handlers in esxi_plugin.tasks . The plugin enforces a “reconcile-first” pattern, where operations first check for existing resources to adopt them rather than failing on duplicates, ensuring idempotent state convergence 1.

The plugin defines three node types derived from cloudify.nodes.Root, each exposing specific lifecycle interfaces .

  • esxi.nodes.Host: Represents the ESXi host connection. It requires host (FQDN/IP) and password properties, with optional user (defaulting to root), verify_tls, ca_bundle, and thumbprint for TLS configuration . Its lifecycle maps create to probe_host (validating connectivity), configure to record_host_facts (capturing version/build info), and delete to noop_op .
  • esxi.nodes.VM: Represents a virtual machine. Key properties include name, ova_url (required if the VM doesn’t exist), datastore, and resource specs (cpu, memory_mb) . It supports create, configure, start, stop, and delete operations .
  • esxi.nodes.Snapshot: Represents a VM snapshot. Properties include name, description, memory (include memory state), and quiesce (quiesce guest filesystem) . It exposes create and delete interfaces .
diagram

The GovcClient class in esxi_plugin/govc.py wraps the vendored govc binary, handling environment setup and subprocess execution 2.

  • Binary Management: The binary is located via importlib.resources (or pkg_resources) and made executable if necessary.
  • Environment & Security: Credentials are passed via environment variables (GOVC_USERNAME, GOVC_PASSWORD), never on the command line. TLS verification is controlled via GOVC_INSECURE, GOVC_TLS_CA_CERTS, or GOVC_TLS_KNOWN_HOSTS.
  • Execution: The run method constructs the argv, inserting -json immediately after the subcommand to ensure proper parsing. It captures stderr, redacting passwords, and raises GovcError on non-zero exit codes.

Task handlers in esxi_plugin/tasks.py implement the Cloudify lifecycle operations, utilizing a reconcile-first strategy 1.

  • probe_host: Runs govc about to verify connectivity and credentials. It logs the API type, warning if it is not HostAgent (indicating vCenter, which is handled by a different plugin).
  • record_host_facts: Captures ESXi version, build, and API type into runtime properties. It also enumerates existing VMs using govc ls and govc vm.info, storing their MOID, power state, and config in ctx.instance.runtime_properties["vms"].
  • create_vm: Checks for an existing VM using find_vm_by_name. If found, it adopts the VM and powers it on if configured. If not, it imports the OVA using govc import.ova. It then resolves the MOID and optionally waits for an IP address using govc vm.ip.
  • configure_vm: Reshapes CPU and memory using govc vm.change if properties differ.
  • start_vm / stop_vm: Manages power state via govc vm.power. stop_vm and delete_vm swallow “not found” errors to ensure idempotency.
  • delete_vm: Powers off the VM, destroys it via govc vm.destroy, and cleans up runtime properties.
  • create_snapshot: Resolves the target VM name via relationships. Checks for existing snapshots using find_snapshot_by_name. If not found, creates it via govc snapshot.create with optional -m (memory) and -q (quiesce) flags.
  • delete_snapshot: Removes the snapshot via govc snapshot.remove and cleans up runtime properties.

The esxi_plugin.reconcile module provides helper functions to support the reconcile-first pattern 3.

  • find_vm_by_name: Uses govc vm.info to find a VM by name and returns its MOID.
  • find_snapshot_by_name: Uses govc snapshot.tree to traverse the snapshot hierarchy and find a snapshot by name, returning its MOID.