Initial commit: VMware vSphere API simulator scaffold.

Add the FastAPI app, PostgreSQL migrations, Docker/Helm packaging, API
contracts, docs, client examples, and the unit/integration/compatibility
test suite for local client and tooling labs without a real vCenter.
This commit is contained in:
2026-07-18 04:42:11 +03:00
commit f8d3cbdd59
422 changed files with 361335 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
**Language / Язык:** [English](README.md) | [Русский](../ru/domains/README.md)
# Domain guides
These pages summarize durable semantics by area. For exhaustive method lists,
use the Web UI catalog or OpenAPI (`/docs`), or browse
[`app/vsphere/rest/coverage.py`](../../app/vsphere/rest/coverage.py) directly
— the runtime always serves the full registered surface regardless of the
active catalog major.
| Guide | Topics |
|---|---|
| [Session](session.md) | `/api/session`, legacy `/rest` session, SOAP `Login`/`Logout` |
| [Inventory](inventory.md) | Datacenter, cluster, folder, resource pool, host, datastore, network CRUD |
| [Virtual machines](vm.md) | Create/delete, power, hardware, snapshots, clone, relocate, guest ops |
| [Storage](storage.md) | Datastores, files, host storage devices, storage policies |
| [Networking](networking.md) | Standard/distributed portgroups, DVS, host networking |
| [Tagging](tagging.md) | Categories, tags, associations |
| [Content library](content-library.md) | Libraries, items, update/download sessions, OVF deploy |
| [SOAP / VIM](soap.md) | RetrieveServiceContent, PropertyCollector, task-returning operations |
| [Tasks](tasks.md) | CIS task ids, polling, workers |
| [Appliance](appliance.md) | Version, health, networking, timesync |
| [Authorization](authz.md) | Roles, privileges, permissions |
## Persistence map
- Inventory objects (hosts, VMs, datastores, networks, folders, …) →
`vsphere_objects` (MOID, type, name, parent, `props` JSONB).
- Sessions / credentials → `vsphere_sessions`, `vsphere_credentials`.
- Tasks → `vsphere_tasks`.
- Tags / categories / associations → `vsphere_tag_categories`,
`vsphere_tags`, `vsphere_tag_associations`.
- Content libraries / items → `vsphere_libraries`, `vsphere_library_items`.
- Datastore file metadata → `vsphere_datastore_files`.
- Remaining Broadcom Automation API routes (the DB-backed stub surface) →
`vsphere_api_state` (migration `011`).
- Content-library update/download sessions → `vsphere_transfer_sessions`
(migration `012`).
- HttpNfcLease transfer state → `vsphere_nfc_leases` (migration `012`).
- PropertyCollector views / WaitForUpdates tokens → `vsphere_pc_state`
(migration `013`).
- Console tickets → `vsphere_console_tickets` (migration `013`).
+35
View File
@@ -0,0 +1,35 @@
**Language / Язык:** [English](appliance.md) | [Русский](../ru/domains/appliance.md)
# Appliance
vCenter Server Appliance (VCSA) surfaces — version, health, networking,
timesync:
[`app/vsphere/rest/appliance_ext.py`](../../app/vsphere/rest/appliance_ext.py),
[`app/vsphere/domain/appliance.py`](../../app/vsphere/domain/appliance.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/appliance/system/version` | Readable without a session; reflects the active catalog major's label |
| GET | `/api/appliance/health/system` | Overall health summary |
| GET/PUT/POST | `/api/appliance/networking` | Hostname, DNS, default gateway, interfaces, proxy |
| GET/PUT/POST | `/api/appliance/networking/dns/hostname` \| `/dns/servers` \| `/dns/domains` | Focused mirrors kept in sync with `/networking` |
| GET | `/api/appliance/timesync` | NTP mode + servers |
| GET | `/api/vcenter/certificate-management/vcenter/tls[-csr]` \| `/trusted-root-chains` | Machine-cert / CSR / trust-chain stand-ins |
## Highlights
- Defaults model a realistic single-nic VCSA (`vcenter.lab.local`,
`192.168.1.50/24`, gateway `192.168.1.1`, `8.8.8.8`/`1.1.1.1` DNS).
- `save_networking` keeps the focused DNS mirrors
(`/dns/hostname`, `/dns/servers`, `/dns/domains`) consistent with the full
`/networking` document so both shapes of Automation API client work.
- State is idempotently seeded once per fresh database
(`seed_appliance_state`) and persists in `vsphere_api_state`.
- The TLS/certificate-management endpoints are seeded stand-ins, not a real
VECS certificate store — see [API coverage](../api-coverage.md).
`/api/appliance/system/version` intentionally does not require a session in
this lab build (real vCenter behavior varies by version) so smoke scripts can
check availability before authenticating.
+52
View File
@@ -0,0 +1,52 @@
**Language / Язык:** [English](authz.md) | [Русский](../ru/domains/authz.md)
# Authorization
Role → privilege gate for REST mutate endpoints (and a decorator-style hook
for SOAP): [`app/vsphere/security/authz.py`](../../app/vsphere/security/authz.py),
[`platform_rest.py`](../../app/vsphere/rest/platform_rest.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/vcenter/privilege` | Privilege catalog |
| GET | `/api/vcenter/authorization/roles` | Role → privilege set |
| GET/POST/DELETE | `/api/vcenter/authorization/permissions[/{permission_id}]` | Principal ↔ role ↔ entity bindings |
| GET/POST/PATCH/DELETE | `/api/vcenter/identity/providers[/{provider}]` | LocalOS + OIDC + SAML identity-provider stand-ins |
## Roles (seed)
| Role | Scope |
|---|---|
| `Administrator` | Every privilege in the catalog |
| `ReadOnly` | `System.Anonymous`, `System.Read`, `System.View`, `Datastore.Browse` |
| `VirtualMachinePowerUser` | Read + power/snapshot/clone interactions |
| `VirtualMachineAdministrator` | Power-user set + create/delete/reconfigure/tag/content-library privileges |
`ROLE_PRIVILEGES` in `authz.py` defines the exact privilege sets; a
non-exhaustive sample of gated privileges: `VirtualMachine.Inventory.Create`,
`VirtualMachine.Inventory.Delete`, `VirtualMachine.Interact.PowerOn`,
`VirtualMachine.Config.CPUCount`, `VirtualMachine.Provisioning.Clone`,
`Datastore.FileManagement`, `Network.Assign`,
`InventoryService.Tagging.CreateTag`, `ContentLibrary.AddLibraryItem`,
`Authorization.ModifyPermissions`.
## How gating works
- `require_privilege(*needed)` is a FastAPI dependency factory: it resolves
the session, loads roles (from the session or `vsphere_credentials` if
absent), and raises HTTP 403 (`unauthorized`) if any listed privilege is
missing.
- `require_read` is shorthand for `require_privilege("System.Read")`.
- Permissions can also scope a role to a specific entity MOID
(`PermissionSpec(principal, role, entity_moid, propagate)`); the seed
scopes `readonly@vsphere.local` to the datacenter and the two VM-admin
principals to the VM folder.
## Seeded principals
See [Authentication](../authentication.md) for the four
`@vsphere.local` principals and their roles, and
[Seed profiles](../seed-profiles.md) for how permissions are scoped per
profile.
+38
View File
@@ -0,0 +1,38 @@
**Language / Язык:** [English](content-library.md) | [Русский](../ru/domains/content-library.md)
# Content library
Local content libraries, library items, upload/download sessions, and OVF
deploy:
[`app/vsphere/rest/content_rest.py`](../../app/vsphere/rest/content_rest.py),
[`nfc_rest.py`](../../app/vsphere/rest/nfc_rest.py),
[`app/vsphere/domain/content.py`](../../app/vsphere/domain/content.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/content/library` | List library ids |
| POST | `/api/content/local-library` | Create a local library |
| GET/POST | `/api/content/library/item` | List / create items (`?library_id=`) |
| POST | `/api/vcenter/ovf/library-item/{item_id}` | Deploy OVF item → new `VirtualMachine` + task |
| POST | `/api/content/library/item/update-session[/{session_id}[/file]]` | Push-upload flow (Ansible/Terraform-style) |
| GET/POST | `/api/content/library/item/download-session[/{session_id}[/file]]` | Pull-download flow |
| GET/PUT/POST | `/nfc/{lease}` \| `/nfc/{lease}/files/{filename}` \| `/nfc/{lease}/complete` | HttpNfcLease-style transfer endpoints for the SOAP import path |
## Highlights
- Libraries/items persist in `vsphere_libraries` / `vsphere_library_items`;
the seed creates two libraries ("Local Content", "Published Templates")
with OVF-typed items (`ubuntu-22.04`, `centos-stream-9`, `golden-image`).
- Update/download sessions persist in PostgreSQL (`vsphere_transfer_sessions`,
migration `012`) and model the file-transfer handshake — not a real
byte-for-byte OVF/VMDK store. HttpNfcLease rows live in `vsphere_nfc_leases`.
- `deploy_ovf_from_library` creates a real `VirtualMachine` row and returns a
task id, mirroring the SOAP `ImportVApp_Task` / `CreateImportSpec` +
`HttpNfcLease*` flow used by govc-style `ovf.import`.
- Requires `ContentLibrary.CreateLocalLibrary` / `.AddLibraryItem` to create,
and `VirtualMachine.Provisioning.DeployTemplate` to deploy.
See [SOAP / VIM](soap.md) for the HttpNfcLease progress/complete/abort
operations used by upload-heavy clients.
+46
View File
@@ -0,0 +1,46 @@
**Language / Язык:** [English](inventory.md) | [Русский](../ru/domains/inventory.md)
# Inventory
Datacenter, cluster, folder, resource pool, host, and datastore/network
listing + CRUD:
[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py),
[`app/vsphere/domain/inventory_ops.py`](../../app/vsphere/domain/inventory_ops.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/vcenter/datacenter` | List |
| POST/DELETE | `/api/vcenter/datacenter[/{datacenter}]` | Create seeds host/vm/datastore/network sub-folders |
| GET | `/api/vcenter/cluster` | List |
| POST/DELETE | `/api/vcenter/cluster[/{cluster}]` | Create seeds a `ResourcePool` |
| GET | `/api/vcenter/folder` | List; `GET /api/vcenter/folder/{folder}/children` |
| POST/DELETE | `/api/vcenter/folder[/{folder}]` | |
| GET | `/api/vcenter/resource-pool` | List |
| POST/DELETE | `/api/vcenter/resource-pool[/{resource_pool}]` | |
| GET | `/api/vcenter/host[/{host}]` | Connection state, CPU/memory, IP, storage devices, networking |
| POST | `/api/vcenter/host/{host}/maintenance` | Toggle maintenance mode |
| GET | `/api/vcenter/datastore[/{datastore}]` | Type, capacity, free space, accessibility |
| GET | `/api/vcenter/network` | Standard networks + distributed portgroups |
Legacy `/rest/vcenter/*` mirrors most GET paths with a `{ "value": … }`
envelope — see [API surface](../api-surface.md).
## Highlights
- Every inventory object is a row in `vsphere_objects` (MOID, type, name,
`parent_moid`, `props` JSONB) — see
[`app/vsphere/inventory.py`](../../app/vsphere/inventory.py).
- MOID conventions follow real vCenter shapes: `datacenter-NN`,
`domain-cNN` (cluster), `resgroup-NN` (resource pool), `group-vNN`/`group-hNN`/
`group-sNN`/`group-nNN` (VM/host/datastore/network folders), `host-NN`,
`datastore-NN`, `network-NN` / `dvportgroup-NN`.
- `list_hosts`/`list_clusters`/etc. filter live PostgreSQL state; there is no
separate cache to invalidate after a mutation.
- VM listing (`GET /api/vcenter/vm`) supports filters: `names`,
`power_states`, `hosts`, `folders`, `datacenters`, `clusters`,
`resource_pools`, plus `limit`/`cursor` pagination.
See [Seed profiles](../seed-profiles.md) for the default topology shape and
[Virtual machines](vm.md) for VM-specific operations.
+35
View File
@@ -0,0 +1,35 @@
**Language / Язык:** [English](networking.md) | [Русский](../ru/domains/networking.md)
# Networking
Standard networks, distributed portgroups/switches, and host networking:
[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py),
[`platform_rest.py`](../../app/vsphere/rest/platform_rest.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/vcenter/network` | Standard `Network` objects + `DistributedVirtualPortgroup` |
| GET/POST | `/api/vcenter/network/dvs` | Distributed virtual switches |
| POST | `/api/vcenter/network/dvpg` | Create a distributed portgroup |
| GET | `/api/vcenter/host/{host}/networking` | DNS, default gateway, `vmk0` interface, routing |
| GET/PUT/POST | `/api/appliance/networking` \| `/networking/dns/{hostname,servers,domains}` | vCenter appliance-level networking (see [Appliance](appliance.md)) |
Legacy `GET /rest/vcenter/network` mirrors the list.
## Highlights
- Every VM's `nics[].value.backing` points at either a `STANDARD_PORTGROUP`
(`network-41`, "VM Network") or a `DISTRIBUTED_PORTGROUP`
(`dvportgroup-4N`, tagged with a `vlan_id`).
- The default topology seeds one `VmwareDistributedVirtualSwitch`
(`dvs-51`, `mtu: 9000`) and 13 extra distributed portgroups depending on
profile size.
- Host networking (`GET /api/vcenter/host/{host}/networking`) returns DNS
servers/domains, a default gateway, and a single `vmk0` management
interface with a deterministic IPv4 address per host index.
- NSX-labelled Automation API paths (tier-0 gateway, projects, edges,
VPC/subnets) are seeded lab stand-ins under `namespace-management` — see
the "Platform surfaces" table in [API coverage](../api-coverage.md); they
are not a real NSX Manager.
+31
View File
@@ -0,0 +1,31 @@
**Language / Язык:** [English](session.md) | [Русский](../ru/domains/session.md)
# Session
Durable session identity shared by REST and SOAP:
[`app/vsphere/security/session.py`](../../app/vsphere/security/session.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| POST | `/api/session` | Basic auth → JSON string session id + `vmware-api-session-id` header/cookie |
| GET | `/api/session` | HTTP 200; `x-vmware-session-user` / `x-vmware-session-roles` headers |
| DELETE | `/api/session` | Invalidates the session, clears cookie |
| POST/GET/DELETE | `/rest/com/vmware/cis/session` | Legacy `{ "value": … }` equivalents |
| POST | SOAP `SessionManager.Login` | Returns the same session id; sets `vmware_soap_session` cookie |
| POST | SOAP `SessionManager.Logout` | Deletes the session |
## Highlights
- Sessions are opaque 32-char hex tokens stored in `vsphere_sessions` with a
**2-hour sliding TTL** — every authenticated call extends `expires_at`.
- The four lab credentials (`vsphere_credentials`, scrypt-hashed) are
idempotently ensured on first login and by every seed profile
(`ensure_default_credentials`).
- `require_session` resolves the session from either the
`vmware-api-session-id` header or cookie; missing/expired → HTTP 401.
- Roles are attached to the session at lookup time
(`vsphere_credentials.roles`) and drive [Authorization](authz.md).
See [Authentication](../authentication.md) for full request examples.
+68
View File
@@ -0,0 +1,68 @@
**Language / Язык:** [English](soap.md) | [Русский](../ru/domains/soap.md)
# SOAP / VIM
Minimal VIM SDK for pyvmomi / govmomi-style clients (Terraform's
`hashicorp/vsphere` provider, Pulumi, govc):
[`app/vsphere/soap/router.py`](../../app/vsphere/soap/router.py),
[`property_collector.py`](../../app/vsphere/soap/property_collector.py),
[`pbm.py`](../../app/vsphere/soap/pbm.py).
## Endpoint
All operations POST a SOAP envelope to `/sdk` (also `/sdk/`). Auxiliary
routes:
| Method | Path | Notes |
|---|---|---|
| GET | `/sdk/vimService.wsdl` (alias `/sdk/vim.wsdl`) | WSDL stub advertising the implemented operation list |
| GET | `/sdk/about.do` (alias `/about.do`) | Human-readable "VMware vCenter Server" page |
| POST | `/sdk/vim25/{version}/SessionManager/SessionManager/Login` | JSON-body login variant used by some SDKs |
## Implemented operations
- `RetrieveServiceContent`, `Login`, `Logout`
- `RetrieveProperties`, `RetrievePropertiesEx`, **ContinueRetrievePropertiesEx**
(pagination tokens; `<objects>` plural), `CreateFilter`,
`WaitForUpdatesEx` (version tokens; empty polls), `CreateContainerView`,
`DestroyPropertyFilter`
- `FindByInventoryPath` (paths omit the root `Datacenters` folder, matching
govmomi conventions), `FindByUuid`, `FindByDnsName`, `FindByIp`, `FindChild`
- `CreateVM_Task`, `CreateChildVM_Task`, `CreateFolder`, `PowerOnVM_Task`,
`PowerOffVM_Task`, `CloneVM_Task`, `CreateSnapshot_Task`, `Rename_Task`,
`ReconfigVM_Task`, `RelocateVM_Task`, `Destroy_Task`, `CustomizeVM_Task`,
`CancelTask`, `CurrentTime`
- Guest file ops: `InitiateFileTransferToGuest`,
`InitiateFileTransferFromGuest`, `ListFilesInGuest`, `DeleteFileInGuest`,
`MakeDirectoryInGuest`
- Import/upload: `ImportVApp_Task`, `CreateImportSpec`,
`HttpNfcLeaseComplete`, `HttpNfcLeaseProgress`, `HttpNfcLeaseAbort`,
`HttpNfcLeaseGetManifest` (paired with the REST `/nfc/{lease}` endpoints —
see [Content library](content-library.md))
- `QueryConfigOption`, `QueryConfigOptionEx`, `QueryConfigOptionDescriptor`,
`QueryConfigTarget`
- PBM (`/pbm`) stub for storage-policy-aware clients
## Highlights
- `Login` issues the same underlying session as REST (`vmware-api-session-id`
cookie/header, plus a `vmware_soap_session` cookie) — see
[Session](session.md).
- `VIM_VERSION` is pinned to `8.0.2` with ≤3 dotted components, since
`hashicorp/vsphere` parses `AboutInfo.version` strictly.
- Type-strict MOR lookup rejects a `VirtualApp:resgroup-*` reference from
resolving as a plain `ResourcePool` — matters for the Terraform
`CreateVM_Task` resource path.
- Task-returning operations create a real row in `vsphere_tasks` (shared with
REST — see [Tasks](tasks.md)), including `info.result` MoRefs on
create/clone.
- PropertyCollector filters, ContainerViews, and WaitForUpdatesEx version
tokens persist in `vsphere_pc_state` (migration `013`) across process
restarts within a lab.
- `Folder.childType` is emitted as `ArrayOfString`; string properties carry
`xsi:type="xsd:string"` so govmomi's decoder accepts them; `Datastore.host`
is `ArrayOfDatastoreHostMount`; `Cluster`/`Host` expose `environmentBrowser`.
See [Clients](../clients.md) for pyvmomi/govmomi/Terraform/Pulumi connection
examples and [examples/python/vsphere_soap_smoke.py](../../examples/python/vsphere_soap_smoke.py)
for a minimal raw-XML smoke.
+37
View File
@@ -0,0 +1,37 @@
**Language / Язык:** [English](storage.md) | [Русский](../ru/domains/storage.md)
# Storage
Datastores, datastore file metadata, host storage devices, and storage
policies:
[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py),
[`content_rest.py`](../../app/vsphere/rest/content_rest.py),
[`platform_rest.py`](../../app/vsphere/rest/platform_rest.py),
[`app/vsphere/domain/content.py`](../../app/vsphere/domain/content.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/vcenter/datastore[/{datastore}]` | Type (`VMFS`/`NFS`), capacity, free space, `multiple_host_access` |
| GET/POST | `/api/vcenter/datastore/{datastore}/files` | List / register file metadata (ISOs, VMX, VMDK paths) |
| GET | `/api/vcenter/host/{host}/storage/storage-device` | Seeded local disk devices (`naa.*`, capacity, SSD flag) |
| GET | `/api/vcenter/storage/policies[/{policy}/vm]` | Storage-based policy management, incl. `policy_type: VSAN` lab policies |
Legacy `GET /rest/vcenter/datastore` mirrors the list in a
`{ "value": … }` envelope.
## Highlights
- Datastore rows are seeded with realistic capacity/free-space pairs
(`type`, `capacity`, `free_space`, `accessible`,
`multiple_host_access`) — see
[`app/vsphere/profiles.py`](../../app/vsphere/profiles.py).
- File metadata lives in `vsphere_datastore_files` (`path`, `size`, `type`);
the seed pre-populates ISOs and a VM's `.vmx`/`.vmdk` entries
(`seed_platform_extras`).
- Storage policies include a lab `RAID1` vSAN-labelled policy — see the
"Platform surfaces" table in [API coverage](../api-coverage.md) for the
vSAN caveat (seeded lab data, not a real vSAN cluster).
- Host storage devices are per-host synthetic disks, not real ESXi VMFS
extents — capacity/SSD flags vary deterministically by host index.
+31
View File
@@ -0,0 +1,31 @@
**Language / Язык:** [English](tagging.md) | [Русский](../ru/domains/tagging.md)
# Tagging
CIS tagging service (categories, tags, object associations):
[`app/vsphere/rest/tagging_rest.py`](../../app/vsphere/rest/tagging_rest.py),
[`app/vsphere/domain/tagging.py`](../../app/vsphere/domain/tagging.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET/POST | `/api/cis/tagging/category` | List / create (`cardinality`, `associable_types`) |
| GET/DELETE | `/api/cis/tagging/category/{category_id}` | |
| GET/POST | `/api/cis/tagging/tag` | List / create under a category |
| GET/DELETE | `/api/cis/tagging/tag/{tag_id}` | |
| POST | `/api/cis/tagging/tag-association` | Attach/detach a tag to/from an object |
## Highlights
- Category and tag ids follow the real `urn:vmomi:InventoryServiceCategory:…`
/ `urn:vmomi:InventoryServiceTag:…:GLOBAL` shape.
- Rows persist in `vsphere_tag_categories`, `vsphere_tags`,
`vsphere_tag_associations` — durable across restarts, replaced on reseed.
- The seed creates two categories (`Environment`, `Owner`) with `prod`/
`staging`/`platform` tags and attaches `prod` to two seeded VMs
(`seed_platform_extras` in
[`app/vsphere/domain/content.py`](../../app/vsphere/domain/content.py)).
- Attaching/creating a tag requires
`InventoryService.Tagging.CreateCategory` / `.CreateTag` / `.AttachTag`
privileges — see [Authorization](authz.md).
+37
View File
@@ -0,0 +1,37 @@
**Language / Язык:** [English](tasks.md) | [Русский](../ru/domains/tasks.md)
# Tasks
Long-running operations (power, clone, relocate, snapshot, OVF deploy, guest
customize) return a CIS-style task id:
[`app/vsphere/domain/tasks.py`](../../app/vsphere/domain/tasks.py),
[`app/vsphere/rest/tasks.py`](../../app/vsphere/rest/tasks.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/cis/tasks` | List recent tasks (most recent 200) |
| GET | `/api/cis/tasks/{task}` | Status, progress, `service`/`operation`, `result`/`error` |
## Client pattern
1. `POST`/`DELETE` mutation → read the task id from `{ "task": "task-…" }`
(REST) or the SOAP `*_Task` MoRef.
2. Poll `GET /api/cis/tasks/{task}` until `status` is `SUCCEEDED` or `FAILED`.
3. `result` holds operation-specific output (for example `{"vm": "vm-104"}`
on create/clone/deploy).
## Highlights
- Task rows commit to `vsphere_tasks` (`id`, `description`, `status`,
`service`, `operation`, `result`, `error`, `completed_at`).
- `progress` is synthesized as `50` while running and `100` once terminal —
this simulator does not model fractional progress.
- The same task store backs both REST `/api/cis/tasks` and SOAP task MoRefs,
so a Terraform apply (SOAP `CreateVM_Task`) and a REST poll of the same id
see consistent state.
- Simulation durations honour `SIMULATION_TIME_SCALE`
(higher = faster simulated completion).
See [API surface](../api-surface.md) and [Operations](../operations.md).
+50
View File
@@ -0,0 +1,50 @@
**Language / Язык:** [English](vm.md) | [Русский](../ru/domains/vm.md)
# Virtual machines
Full REST lifecycle for `VirtualMachine` objects:
[`app/vsphere/rest/router.py`](../../app/vsphere/rest/router.py),
[`vm_ext.py`](../../app/vsphere/rest/vm_ext.py),
[`app/vsphere/domain/vm_ops.py`](../../app/vsphere/domain/vm_ops.py).
## Endpoints
| Method | Path | Notes |
|---|---|---|
| GET | `/api/vcenter/vm` | List with `names`/`power_states`/`hosts`/`folders`/`datacenters`/`clusters`/`resource_pools`/`limit`/`cursor` filters |
| GET/DELETE | `/api/vcenter/vm/{vm}` | Get / delete (must be powered off) |
| POST | `/api/vcenter/vm` | Create — `placement.{folder,host,datastore,resource_pool}`, `cpu.count`, `memory.size_MiB`, `disks`, `nics` |
| GET/POST | `/api/vcenter/vm/{vm}/power` | Get power state / `?action=start\|stop\|suspend\|reset` — returns `{ "task": "task-…" }` |
| GET | `/api/vcenter/vm/{vm}/hardware` | Summary |
| GET/PATCH | `/api/vcenter/vm/{vm}/hardware/cpu` \| `/memory` | Change CPU count / memory (privilege-gated) |
| GET/POST | `/api/vcenter/vm/{vm}/hardware/disk` \| `/ethernet` | Add disk / NIC |
| GET | `/api/vcenter/vm/{vm}/hardware/boot` | Boot type/order |
| GET/POST/DELETE | `/api/vcenter/vm/{vm}/snapshots[/{snapshot}]` | Create, revert (`?action=revert`), delete |
| POST | `/api/vcenter/vm/{vm}/clone` \| `/relocate` | Task-returning |
| GET/POST | `/api/vcenter/vm/{vm}/tools` | Guest tools status / upgrade |
| GET | `/api/vcenter/vm/{vm}/guest/identity` \| `/networking` | Guest OS name, synthetic IP |
| GET/POST | `/api/vcenter/vm/{vm}/guest/power` | Guest-level power ops |
| POST | `/api/vcenter/vm/{vm}/guest/customization` | Sysprep/cloud-init-style customization spec |
| POST | `/api/vcenter/vm/{vm}/console/tickets` | Console (VNC/WebMKS-style) ticket |
| GET/PUT/DELETE | `/api/vcenter/vm/{vm}/guest/filesystem` | Lab virtual guest filesystem (Ansible/Terraform write-a-file flows) |
| GET | `/api/vcenter/vm/{vm}/guest/filesystem/files` \| `/guest/local-filesystem` | Listing |
## Highlights
- Every VM row carries a realistic device shape: `nics`, `disks`, `cdroms`,
`floppies`, `serials`, `scsi_adapters`, `boot`/`boot_devices`, `identity`
(`instance_uuid`, `bios_uuid`), and a synthetic `guest_ip` /
`guest_filesystems` map — the same fields power both the REST hardware
endpoints and SOAP `VirtualMachineConfigInfo`.
- Create requires `VirtualMachine.Inventory.Create`; delete requires
`VirtualMachine.Inventory.Delete` **and** the VM must be `POWERED_OFF`.
- Power/clone/snapshot/relocate/customize all create a durable CIS task (see
[Tasks](tasks.md)) rather than mutating synchronously in the response body.
- Console tickets from `/api/vcenter/vm/{vm}/console/tickets` persist in
`vsphere_console_tickets` (migration `013`).
- MOIDs follow the `vm-{100+n}` convention seeded by
[`app/vsphere/profiles.py`](../../app/vsphere/profiles.py).
See [Storage](storage.md) for datastore/disk-file semantics and
[SOAP / VIM](soap.md) for the equivalent `CreateVM_Task`/`PowerOnVM_Task`/…
operations used by pyvmomi, govmomi, Terraform, and Pulumi.