Files
tf_provider/docs/20_discovery/resource-creation-pattern.md
T
2026-06-30 15:45:24 +04:00

92 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Паттерн создания ресурсов "Tubulus" (Platinum Standard)
В платформе Nubes Cloud большинство ресурсов (VDC, S3, DBaaS, Tubulus-болванки) подчиняются строгому 7-шаговому циклу создания. Простого `POST /instances` недостаточно — ресурс появится в UI, но останется в статусе "not created", пока не будет выполнен финальный `POST /run`.
## Пошаговый алгоритм
### Шаг 1: Инициализация (Create Instance)
Отправляем `POST /instances`.
- **Payload**: `contractId`, `serviceId`, `specificationItemId`, `displayName`.
- **Результат**: Получаем `instanceUid`.
### Шаг 2: Создание операции (Create Operation)
Отправляем `POST /instanceOperations` для привязки операции создания к инстансу.
- **Payload**: `instanceUid`, `operation: "create"`.
- **Результат**: Получаем `instanceOperationUid`.
### Шаг 3: Получение параметров (Fetch Parameters)
Отправляем `GET /instanceOperations/{uid}?fields=cfsParams`.
- **Цель**: Получить список параметров (`svcOperationCfsParamId`), которые платформа ожидает для этого ресурса.
### Шаг 4: Отправка параметров (Submit Parameters) — **Критично!**
Для **каждого** параметра из списка (даже если он пустой или имеет значение по умолчанию) нужно отправить `POST /instanceOperationCfsParams`.
- **Payload**: `instanceOperationUid`, `svcOperationCfsParamId`, `paramValue`.
- **Важно**: Браузер всегда переотправляет все параметры. Пропуск этого шага может привести к ошибкам валидации.
### Шаг 5: Валидация (Validate)
Отправляем `GET /instanceOperations/{uid}/validate-cfs`.
- Проверяем, что ответ `200 OK` и нет ошибок в теле ответа.
### Шаг 6: Запуск (Run) — **Самый важный шаг!**
Отправляем `POST /instanceOperations/{uid}/run`.
- **Payload**: Обязательно `{}` (пустой JSON-объект). **НЕ `nil`**, а именно `{}`.
- **Результат**: После этого шага бэкенд начинает реальную работу (например, вызывает Jenkins или Ansible).
### Шаг 7: Ожидание готовности (Polling)
Периодически опрашиваем `GET /instances/{uid}`.
- Ждем, когда `explainedStatus` станет `running` (для S3) или `Active`.
---
## Специфика S3 бакетов (`nubes_s3_bucket`)
1. **Модификация (Update)**: В текущем UI и API **отсутствует** операция `modify`. Ресурс S3 является иммутабельным в плане параметров бакета через этот API. Для изменения (например, размера) требуется пересоздание или использование других API (если они будут найдены).
2. **Удаление (Delete)**: Выполняется через стандартный `DELETE /instances/{id}`.
3. **Уникальность**: `displayName` и `bucket_name` должны быть уникальны в рамках контракта/платформы. Рекомендуется использовать суффиксы с временной меткой в тестах.
4. **Placement**: Допустимые значения: `HOT` (по умолчанию) или `COLD`.
---
## Рекомендации для разработчика провайдера
- Объединяйте шаги 1-6 в одну функцию клиента (например, `CreateInstance` в `client_impl.go`).
- Всегда передавайте пустую карту `map[string]interface{}{}` в метод `Run`, чтобы она сериализовалась в `{}`.
- Тщательно логируйте `instanceOperationUid`, так как по нему можно отследить ошибки в логах платформы.
### Troubleshooting
- **Висит в "not created"**: Вы забыли вызвать Шаг 6 (Run) или отправили неверный payload.
- **Ошибка 400 на параметрах**: Проверьте, что все ID параметров соответствуют результату из Шага 3.
## Operation Lifecycle & Success Criteria (Official Developer Info)
Операции в Nubes Cloud выполняются асинхронно.
- **201 Created**: Операция запущена успешно.
- **Polling (GET status)**: Каждый запрос статуса возвращает `200 OK`. Это означает, что платформа успешно обрабатывает запрос состояния, но не гарантирует успех самой операции.
- **Completion Timestamp**: Операция считается завершенной только тогда, когда в ответе появляется временная метка завершения.
- **isSuccessful**: Ключевой флаг, который определяет успех операции и отрисовывает "зелёную галочку" в интерфейсе. Если операция завершена, но `isSuccessful: false`, ресурс может находиться в неконсистентном состоянии.
---
## Suspend/Resume и совпадение параметров (Discovery Notes)
Контекст: в Nubes Cloud многие сервисы **не удаляются напрямую**. `destroy` приводит к `suspend` и двухнедельному карантину. Это означает, что следующий `apply` может столкнуться с существующим инстансом в `suspend`.
### Принцип восстановления
Если найден `suspended` инстанс с тем же `resource_name`, корректное поведение:
1. **Сравнить параметры** в Terraform (createparams) с `instance.state.params`.
2. **Resume** выполнять только при полном совпадении параметров.
3. При несовпадении — вернуть стандартную ошибку "resource already exists".
### Потенциальные мины
- **Несовпадение ключей**: `state.params` может использовать ключи, отличные от `code` в YAML — сравнение даст false.
- **Типы/форматы**: bool/int/JSON/масивы могут быть сериализованы по‑разному (строка vs JSON).
- **Defaults**: если параметр не задан в TF и приходит default от API, возможны ложные mismatches.
- **RefSvcId**: в create могут отправляться UUID, а в `state.params` может быть имя — mismatch.
- **Ручные изменения**: любые правки вне TF делают resume невозможным.
- **Пустые params**: если API не возвращает `state.params`, сравнение всегда провалится.
- **YAML/Go рассинхрон**: неверный маппинг ID→code приводит к ложным mismatch.
- **Сеть/таймауты**: дополнительный GET `/instances/{id}` может фейлиться и блокировать resume.
### Экономический аспект
`suspend` сохраняет данные и продолжает потреблять дисковое пространство — пользователь **продолжает платить**. Регулярное создание новых инстансов вместо восстановления `suspended` приведёт к росту расходов.