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
+43
View File
@@ -0,0 +1,43 @@
**Language / Язык:** [English](../../domains/README.md) | [Русский](README.md)
# Руководства по доменам
Эти страницы описывают устойчивую семантику по областям API. Для исчерпывающих
списков методов используйте каталог Web UI или OpenAPI (`/docs`), либо
непосредственно
[`app/vsphere/rest/coverage.py`](../../../app/vsphere/rest/coverage.py) —
runtime всегда обслуживает полную зарегистрированную поверхность независимо от
активного catalog major.
| Руководство | Темы |
|---|---|
| [Session](session.md) | `/api/session`, legacy `/rest` session, SOAP `Login`/`Logout` |
| [Inventory](inventory.md) | Datacenter, cluster, folder, resource pool, host, datastore, network CRUD |
| [Виртуальные машины](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 |
| [Авторизация](authz.md) | Roles, privileges, permissions |
## Карта персистентности
- Объекты inventory (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 → `vsphere_datastore_files`.
- Оставшиеся маршруты Broadcom Automation API (DB-backed stub surface) →
`vsphere_api_state` (миграция `011`).
- Update/download sessions content library → `vsphere_transfer_sessions`
(миграция `012`).
- Состояние transfer HttpNfcLease → `vsphere_nfc_leases` (миграция `012`).
- Views PropertyCollector / токены WaitForUpdates → `vsphere_pc_state`
(миграция `013`).
- Console tickets → `vsphere_console_tickets` (миграция `013`).
+35
View File
@@ -0,0 +1,35 @@
**Language / Язык:** [English](../../domains/appliance.md) | [Русский](appliance.md)
# Appliance
Поверхности vCenter Server Appliance (VCSA) — 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).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/appliance/system/version` | Читается без сессии; отражает метку активного catalog major |
| GET | `/api/appliance/health/system` | Сводка общего health |
| GET/PUT/POST | `/api/appliance/networking` | Hostname, DNS, default gateway, interfaces, proxy |
| GET/PUT/POST | `/api/appliance/networking/dns/hostname` \| `/dns/servers` \| `/dns/domains` | Сфокусированные зеркала, синхронизированные с `/networking` |
| GET | `/api/appliance/timesync` | Режим NTP + servers |
| GET | `/api/vcenter/certificate-management/vcenter/tls[-csr]` \| `/trusted-root-chains` | Stand-in'ы machine-cert / CSR / trust-chain |
## Основные моменты
- Defaults моделируют реалистичный single-nic VCSA (`vcenter.lab.local`,
`192.168.1.50/24`, gateway `192.168.1.1`, DNS `8.8.8.8`/`1.1.1.1`).
- `save_networking` держит сфокусированные DNS-зеркала
(`/dns/hostname`, `/dns/servers`, `/dns/domains`) согласованными с полным
документом `/networking`, чтобы работали оба стиля клиентов Automation API.
- Состояние идемпотентно засевается один раз на свежую БД
(`seed_appliance_state`) и хранится в `vsphere_api_state`.
- Эндпоинты TLS/certificate-management — seeded stand-in'ы, не настоящее
хранилище сертификатов VECS — см. [Покрытие API](../api-coverage.md).
`/api/appliance/system/version` намеренно не требует сессию в этой lab-сборке
(поведение реального vCenter зависит от версии), чтобы smoke-скрипты могли
проверить доступность до аутентификации.
+51
View File
@@ -0,0 +1,51 @@
**Language / Язык:** [English](../../domains/authz.md) | [Русский](authz.md)
# Авторизация
Gate роль → privilege для мутирующих REST-эндпоинтов (и decorator-style hook
для SOAP): [`app/vsphere/security/authz.py`](../../../app/vsphere/security/authz.py),
[`platform_rest.py`](../../../app/vsphere/rest/platform_rest.py).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/vcenter/privilege` | Каталог привилегий |
| GET | `/api/vcenter/authorization/roles` | Role → набор privilege |
| GET/POST/DELETE | `/api/vcenter/authorization/permissions[/{permission_id}]` | Привязки principal ↔ role ↔ entity |
| GET/POST/PATCH/DELETE | `/api/vcenter/identity/providers[/{provider}]` | Stand-in'ы identity-provider LocalOS + OIDC + SAML |
## Роли (seed)
| Роль | Область |
|---|---|
| `Administrator` | Каждая привилегия в каталоге |
| `ReadOnly` | `System.Anonymous`, `System.Read`, `System.View`, `Datastore.Browse` |
| `VirtualMachinePowerUser` | Read + взаимодействия power/snapshot/clone |
| `VirtualMachineAdministrator` | Набор power-user + привилегии create/delete/reconfigure/tag/content-library |
`ROLE_PRIVILEGES` в `authz.py` задаёт точные наборы привилегий; неполный
пример gated-привилегий: `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`.
## Как работает gating
- `require_privilege(*needed)` — фабрика зависимостей FastAPI: резолвит
сессию, загружает роли (из сессии или `vsphere_credentials`, если нет),
и поднимает HTTP 403 (`unauthorized`), если отсутствует любая из
перечисленных привилегий.
- `require_read` — сокращение для `require_privilege("System.Read")`.
- Permissions также могут ограничить роль конкретным entity MOID
(`PermissionSpec(principal, role, entity_moid, propagate)`); seed
ограничивает `readonly@vsphere.local` datacenter'ом, а двух VM-admin
принципалов — папкой VM.
## Seeded-принципалы
Четыре принципала `@vsphere.local` и их роли — в
[Аутентификация](../authentication.md); как permissions скоупятся по
профилю — в [Профили seed](../seed-profiles.md).
+38
View File
@@ -0,0 +1,38 @@
**Language / Язык:** [English](../../domains/content-library.md) | [Русский](content-library.md)
# Content library
Локальные content libraries, library items, upload/download sessions и 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).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/content/library` | Список library ids |
| POST | `/api/content/local-library` | Создать local library |
| GET/POST | `/api/content/library/item` | Список / create items (`?library_id=`) |
| POST | `/api/vcenter/ovf/library-item/{item_id}` | Deploy OVF item → новая `VirtualMachine` + task |
| POST | `/api/content/library/item/update-session[/{session_id}[/file]]` | Поток push-upload (стиль Ansible/Terraform) |
| GET/POST | `/api/content/library/item/download-session[/{session_id}[/file]]` | Поток pull-download |
| GET/PUT/POST | `/nfc/{lease}` \| `/nfc/{lease}/files/{filename}` \| `/nfc/{lease}/complete` | Эндпоинты transfer в стиле HttpNfcLease для SOAP import path |
## Основные моменты
- Libraries/items живут в `vsphere_libraries` / `vsphere_library_items`;
seed создаёт две libraries («Local Content», «Published Templates») с
OVF-typed items (`ubuntu-22.04`, `centos-stream-9`, `golden-image`).
- Update/download sessions живут в PostgreSQL (`vsphere_transfer_sessions`,
миграция `012`) и моделируют handshake передачи файлов — не реальное
byte-for-byte хранилище OVF/VMDK. Строки HttpNfcLease — в `vsphere_nfc_leases`.
- `deploy_ovf_from_library` создаёт реальную строку `VirtualMachine` и
возвращает task id, зеркаля SOAP-поток `ImportVApp_Task` /
`CreateImportSpec` + `HttpNfcLease*`, используемый govc-style `ovf.import`.
- Для create нужны `ContentLibrary.CreateLocalLibrary` / `.AddLibraryItem`,
для deploy — `VirtualMachine.Provisioning.DeployTemplate`.
Операции HttpNfcLease progress/complete/abort для upload-heavy клиентов —
[SOAP / VIM](soap.md).
+46
View File
@@ -0,0 +1,46 @@
**Language / Язык:** [English](../../domains/inventory.md) | [Русский](inventory.md)
# Inventory
Listing + CRUD для datacenter, cluster, folder, resource pool, host и
datastore/network:
[`app/vsphere/rest/router.py`](../../../app/vsphere/rest/router.py),
[`app/vsphere/domain/inventory_ops.py`](../../../app/vsphere/domain/inventory_ops.py).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/vcenter/datacenter` | Список |
| POST/DELETE | `/api/vcenter/datacenter[/{datacenter}]` | Create засевает подпапки host/vm/datastore/network |
| GET | `/api/vcenter/cluster` | Список |
| POST/DELETE | `/api/vcenter/cluster[/{cluster}]` | Create засевает `ResourcePool` |
| GET | `/api/vcenter/folder` | Список; `GET /api/vcenter/folder/{folder}/children` |
| POST/DELETE | `/api/vcenter/folder[/{folder}]` | |
| GET | `/api/vcenter/resource-pool` | Список |
| 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` | Переключение maintenance mode |
| GET | `/api/vcenter/datastore[/{datastore}]` | Type, capacity, free space, accessibility |
| GET | `/api/vcenter/network` | Standard networks + distributed portgroups |
Legacy `/rest/vcenter/*` зеркалит большинство GET-путей с конвертом
`{ "value": … }` — см. [Поверхность API](../api-surface.md).
## Основные моменты
- Каждый объект inventory — строка в `vsphere_objects` (MOID, type, name,
`parent_moid`, `props` JSONB) — см.
[`app/vsphere/inventory.py`](../../../app/vsphere/inventory.py).
- Конвенции MOID следуют формам реального vCenter: `datacenter-NN`,
`domain-cNN` (cluster), `resgroup-NN` (resource pool), `group-vNN`/`group-hNN`/
`group-sNN`/`group-nNN` (папки VM/host/datastore/network), `host-NN`,
`datastore-NN`, `network-NN` / `dvportgroup-NN`.
- `list_hosts`/`list_clusters`/и т.п. фильтруют живое состояние PostgreSQL;
отдельного кэша для инвалидации после мутации нет.
- Список VM (`GET /api/vcenter/vm`) поддерживает фильтры: `names`,
`power_states`, `hosts`, `folders`, `datacenters`, `clusters`,
`resource_pools`, плюс пагинацию `limit`/`cursor`.
Форма топологии по умолчанию — [Профили seed](../seed-profiles.md);
операции по VM — [Виртуальные машины](vm.md).
+35
View File
@@ -0,0 +1,35 @@
**Language / Язык:** [English](../../domains/networking.md) | [Русский](networking.md)
# Networking
Standard networks, distributed portgroups/switches и host networking:
[`app/vsphere/rest/router.py`](../../../app/vsphere/rest/router.py),
[`platform_rest.py`](../../../app/vsphere/rest/platform_rest.py).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/vcenter/network` | Объекты standard `Network` + `DistributedVirtualPortgroup` |
| GET/POST | `/api/vcenter/network/dvs` | Distributed virtual switches |
| POST | `/api/vcenter/network/dvpg` | Создать distributed portgroup |
| GET | `/api/vcenter/host/{host}/networking` | DNS, default gateway, интерфейс `vmk0`, routing |
| GET/PUT/POST | `/api/appliance/networking` \| `/networking/dns/{hostname,servers,domains}` | Networking на уровне appliance vCenter (см. [Appliance](appliance.md)) |
Legacy `GET /rest/vcenter/network` зеркалит список.
## Основные моменты
- `nics[].value.backing` каждой VM указывает либо на `STANDARD_PORTGROUP`
(`network-41`, «VM Network»), либо на `DISTRIBUTED_PORTGROUP`
(`dvportgroup-4N`, с `vlan_id`).
- Топология по умолчанию засевает один `VmwareDistributedVirtualSwitch`
(`dvs-51`, `mtu: 9000`) и 1–3 дополнительных distributed portgroup в
зависимости от размера профиля.
- Host networking (`GET /api/vcenter/host/{host}/networking`) возвращает DNS
servers/domains, default gateway и один management-интерфейс `vmk0` с
детерминированным IPv4 по индексу host.
- Пути Automation API с меткой NSX (tier-0 gateway, projects, edges,
VPC/subnets) — seeded lab stand-in'ы под `namespace-management` — см.
таблицу «Platform surfaces» в [Покрытие API](../api-coverage.md); это не
реальный NSX Manager.
+32
View File
@@ -0,0 +1,32 @@
**Language / Язык:** [English](../../domains/session.md) | [Русский](session.md)
# Session
Устойчивая идентичность сессии, общая для REST и SOAP:
[`app/vsphere/security/session.py`](../../../app/vsphere/security/session.py).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| POST | `/api/session` | Basic auth → JSON-строка session id + заголовок/cookie `vmware-api-session-id` |
| GET | `/api/session` | HTTP 200; заголовки `x-vmware-session-user` / `x-vmware-session-roles` |
| DELETE | `/api/session` | Инвалидирует сессию, очищает cookie |
| POST/GET/DELETE | `/rest/com/vmware/cis/session` | Legacy-эквиваленты `{ "value": … }` |
| POST | SOAP `SessionManager.Login` | Возвращает тот же session id; ставит cookie `vmware_soap_session` |
| POST | SOAP `SessionManager.Logout` | Удаляет сессию |
## Основные моменты
- Сессии — непрозрачные 32-символьные hex-токены в `vsphere_sessions` со
**скользящим TTL 2 часа** — каждый аутентифицированный вызов продлевает
`expires_at`.
- Четыре лабораторные учётки (`vsphere_credentials`, scrypt-хеш) идемпотентно
обеспечиваются при первом login и каждым профилем seed
(`ensure_default_credentials`).
- `require_session` резолвит сессию из заголовка или cookie
`vmware-api-session-id`; отсутствует/истекла → HTTP 401.
- Роли привязываются к сессии при lookup (`vsphere_credentials.roles`) и
управляют [Авторизацией](authz.md).
Полные примеры запросов — [Аутентификация](../authentication.md).
+68
View File
@@ -0,0 +1,68 @@
**Language / Язык:** [English](../../domains/soap.md) | [Русский](soap.md)
# SOAP / VIM
Минимальный VIM SDK для клиентов в стиле pyvmomi / govmomi (провайдер
Terraform `hashicorp/vsphere`, 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).
## Эндпоинт
Все операции POST'ят SOAP-конверт на `/sdk` (также `/sdk/`). Вспомогательные
маршруты:
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/sdk/vimService.wsdl` (alias `/sdk/vim.wsdl`) | WSDL stub со списком реализованных операций |
| GET | `/sdk/about.do` (alias `/about.do`) | Человекочитаемая страница «VMware vCenter Server» |
| POST | `/sdk/vim25/{version}/SessionManager/SessionManager/Login` | Login-вариант с JSON-телом, используемый некоторыми SDK |
## Реализованные операции
- `RetrieveServiceContent`, `Login`, `Logout`
- `RetrieveProperties`, `RetrievePropertiesEx`, **ContinueRetrievePropertiesEx**
(токены пагинации; plural `<objects>`), `CreateFilter`,
`WaitForUpdatesEx` (version tokens; пустые polls), `CreateContainerView`,
`DestroyPropertyFilter`
- `FindByInventoryPath` (пути без корневой папки `Datacenters`, как в
конвенциях govmomi), `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` (в паре с REST `/nfc/{lease}`
см. [Content library](content-library.md))
- `QueryConfigOption`, `QueryConfigOptionEx`, `QueryConfigOptionDescriptor`,
`QueryConfigTarget`
- Stub PBM (`/pbm`) для клиентов, учитывающих storage policy
## Основные моменты
- `Login` выдаёт ту же underlying-сессию, что и REST (`vmware-api-session-id`
cookie/header плюс cookie `vmware_soap_session`) — см.
[Session](session.md).
- `VIM_VERSION` зафиксирован как `8.0.2` с ≤3 компонентами через точку, так
как `hashicorp/vsphere` строго парсит `AboutInfo.version`.
- Type-strict MOR lookup отклоняет ссылку `VirtualApp:resgroup-*`,
резолвящуюся как plain `ResourcePool` — важно для Terraform resource path
`CreateVM_Task`.
- Операции, возвращающие задачу, создают реальную строку в `vsphere_tasks`
(общую с REST — см. [Tasks](tasks.md)), включая MoRefs `info.result` при
create/clone.
- Filters PropertyCollector, ContainerViews и version tokens WaitForUpdatesEx
живут в `vsphere_pc_state` (миграция `013`) между перезапусками процесса
в рамках лаборатории.
- `Folder.childType` отдаётся как `ArrayOfString`; строковые свойства несут
`xsi:type="xsd:string"`, чтобы их принимал decoder govmomi; `Datastore.host`
`ArrayOfDatastoreHostMount`; у `Cluster`/`Host` есть `environmentBrowser`.
Примеры подключений pyvmomi/govmomi/Terraform/Pulumi — [Клиенты](../clients.md);
минимальный raw-XML smoke —
[examples/python/vsphere_soap_smoke.py](../../../examples/python/vsphere_soap_smoke.py).
+37
View File
@@ -0,0 +1,37 @@
**Language / Язык:** [English](../../domains/storage.md) | [Русский](storage.md)
# Storage
Datastores, метаданные файлов datastore, устройства хранения host и 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).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/vcenter/datastore[/{datastore}]` | Type (`VMFS`/`NFS`), capacity, free space, `multiple_host_access` |
| GET/POST | `/api/vcenter/datastore/{datastore}/files` | Список / регистрация метаданных файлов (пути ISO, VMX, VMDK) |
| GET | `/api/vcenter/host/{host}/storage/storage-device` | Seeded local disk devices (`naa.*`, capacity, флаг SSD) |
| GET | `/api/vcenter/storage/policies[/{policy}/vm]` | Storage-based policy management, в т.ч. lab-политики `policy_type: VSAN` |
Legacy `GET /rest/vcenter/datastore` зеркалит список в конверте
`{ "value": … }`.
## Основные моменты
- Строки datastore засеваются реалистичными парами capacity/free-space
(`type`, `capacity`, `free_space`, `accessible`,
`multiple_host_access`) — см.
[`app/vsphere/profiles.py`](../../../app/vsphere/profiles.py).
- Метаданные файлов живут в `vsphere_datastore_files` (`path`, `size`, `type`);
seed заранее заполняет ISO и записи `.vmx`/`.vmdk` VM
(`seed_platform_extras`).
- Среди storage policies есть lab-политика с меткой vSAN `RAID1` — оговорку
по vSAN (seeded lab data, не реальный кластер vSAN) см. в таблице
«Platform surfaces» в [Покрытие API](../api-coverage.md).
- Устройства хранения host — синтетические диски на host, не реальные extents
ESXi VMFS; флаги capacity/SSD детерминированно зависят от индекса host.
+33
View File
@@ -0,0 +1,33 @@
**Language / Язык:** [English](../../domains/tagging.md) | [Русский](tagging.md)
# Tagging
Сервис CIS tagging (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).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET/POST | `/api/cis/tagging/category` | Список / create (`cardinality`, `associable_types`) |
| GET/DELETE | `/api/cis/tagging/category/{category_id}` | |
| GET/POST | `/api/cis/tagging/tag` | Список / create под category |
| GET/DELETE | `/api/cis/tagging/tag/{tag_id}` | |
| POST | `/api/cis/tagging/tag-association` | Attach/detach тега к/от объекта |
## Основные моменты
- Id category и tag следуют реальной форме
`urn:vmomi:InventoryServiceCategory:…` /
`urn:vmomi:InventoryServiceTag:…:GLOBAL`.
- Строки живут в `vsphere_tag_categories`, `vsphere_tags`,
`vsphere_tag_associations` — устойчивы между перезапусками, заменяются
при reseed.
- Seed создаёт две categories (`Environment`, `Owner`) с тегами `prod`/
`staging`/`platform` и прикрепляет `prod` к двум seeded VM
(`seed_platform_extras` в
[`app/vsphere/domain/content.py`](../../../app/vsphere/domain/content.py)).
- Attach/create тега требует привилегии
`InventoryService.Tagging.CreateCategory` / `.CreateTag` / `.AttachTag`
см. [Авторизация](authz.md).
+38
View File
@@ -0,0 +1,38 @@
**Language / Язык:** [English](../../domains/tasks.md) | [Русский](tasks.md)
# Tasks
Длительные операции (power, clone, relocate, snapshot, OVF deploy, guest
customize) возвращают CIS-style task id:
[`app/vsphere/domain/tasks.py`](../../../app/vsphere/domain/tasks.py),
[`app/vsphere/rest/tasks.py`](../../../app/vsphere/rest/tasks.py).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/cis/tasks` | Список недавних задач (до 200 последних) |
| GET | `/api/cis/tasks/{task}` | Status, progress, `service`/`operation`, `result`/`error` |
## Паттерн клиента
1. Мутация `POST`/`DELETE` → прочитайте task id из `{ "task": "task-…" }`
(REST) или SOAP MoRef `*_Task`.
2. Опрашивайте `GET /api/cis/tasks/{task}`, пока `status` не станет
`SUCCEEDED` или `FAILED`.
3. В `result` — результат операции (например `{"vm": "vm-104"}` при
create/clone/deploy).
## Основные моменты
- Строки задач коммитятся в `vsphere_tasks` (`id`, `description`, `status`,
`service`, `operation`, `result`, `error`, `completed_at`).
- `progress` синтезируется как `50` во время выполнения и `100` в терминальном
состоянии — дробный progress этот симулятор не моделирует.
- Одно и то же хранилище задач обслуживает и REST `/api/cis/tasks`, и SOAP
task MoRefs, поэтому Terraform apply (SOAP `CreateVM_Task`) и REST-опрос
того же id видят согласованное состояние.
- Длительности симуляции учитывают `SIMULATION_TIME_SCALE`
(больше = быстрее завершение).
См. [Поверхность API](../api-surface.md) и [Эксплуатация](../operations.md).
+50
View File
@@ -0,0 +1,50 @@
**Language / Язык:** [English](../../domains/vm.md) | [Русский](vm.md)
# Виртуальные машины
Полный REST lifecycle для объектов `VirtualMachine`:
[`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).
## Эндпоинты
| Метод | Путь | Заметки |
|---|---|---|
| GET | `/api/vcenter/vm` | Список с фильтрами `names`/`power_states`/`hosts`/`folders`/`datacenters`/`clusters`/`resource_pools`/`limit`/`cursor` |
| GET/DELETE | `/api/vcenter/vm/{vm}` | Get / delete (должна быть 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` — возвращает `{ "task": "task-…" }` |
| GET | `/api/vcenter/vm/{vm}/hardware` | Сводка |
| GET/PATCH | `/api/vcenter/vm/{vm}/hardware/cpu` \| `/memory` | Смена CPU count / memory (privilege-gated) |
| GET/POST | `/api/vcenter/vm/{vm}/hardware/disk` \| `/ethernet` | Добавить 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` | Возвращают задачу |
| GET/POST | `/api/vcenter/vm/{vm}/tools` | Статус guest tools / upgrade |
| GET | `/api/vcenter/vm/{vm}/guest/identity` \| `/networking` | Имя guest OS, синтетический IP |
| GET/POST | `/api/vcenter/vm/{vm}/guest/power` | Guest-level power ops |
| POST | `/api/vcenter/vm/{vm}/guest/customization` | Спека customization в стиле sysprep/cloud-init |
| POST | `/api/vcenter/vm/{vm}/console/tickets` | Console-тикет (стиль VNC/WebMKS) |
| GET/PUT/DELETE | `/api/vcenter/vm/{vm}/guest/filesystem` | Lab virtual guest filesystem (потоки write-a-file Ansible/Terraform) |
| GET | `/api/vcenter/vm/{vm}/guest/filesystem/files` \| `/guest/local-filesystem` | Listing |
## Основные моменты
- У каждой строки VM реалистичная форма устройств: `nics`, `disks`, `cdroms`,
`floppies`, `serials`, `scsi_adapters`, `boot`/`boot_devices`, `identity`
(`instance_uuid`, `bios_uuid`) и синтетическая карта `guest_ip` /
`guest_filesystems` — те же поля питают и REST hardware-эндпоинты, и SOAP
`VirtualMachineConfigInfo`.
- Create требует `VirtualMachine.Inventory.Create`; delete требует
`VirtualMachine.Inventory.Delete` **и** VM должна быть `POWERED_OFF`.
- Power/clone/snapshot/relocate/customize создают устойчивую CIS-задачу (см.
[Tasks](tasks.md)), а не мутируют синхронно в теле ответа.
- Console tickets из `/api/vcenter/vm/{vm}/console/tickets` живут в
`vsphere_console_tickets` (миграция `013`).
- MOID следуют конвенции `vm-{100+n}`, засеваемой
[`app/vsphere/profiles.py`](../../../app/vsphere/profiles.py).
Семантика datastore/disk-file — [Storage](storage.md); эквивалентные
операции `CreateVM_Task`/`PowerOnVM_Task`/… для pyvmomi, govmomi, Terraform и
Pulumi — [SOAP / VIM](soap.md).