Files
autotest/DOCS/terraform-operations-full-logic.md
T

202 lines
6.9 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.
# Полная логика операций — из Terraform-провайдера (ВМ)
> Источник: `/home/naeel/tf_provider/provider/internal/core/client.go` (1581 строка)
> Скопировано с ВМ 5.172.178.213, 2026-07-26
---
## HTTP-клиент (`doRequest`)
### Заголовки
```
User-Agent: Mozilla/5.0
Accept: */*
Content-Type: application/json (для POST/PUT/PATCH)
Authorization: Bearer <TOKEN>
```
### Retry
- До 3 попыток (2s, 4s, 8s задержка)
- Только для GET и только на 429/503/502/504/401
- POST/PUT/PATCH: `req.Close = true` (новое TCP-соединение, DDoS-Guard)
### URL
- Legacy proxy: `{endpoint}?endpoint=/instances&page=1`
- Новый REST: `{endpoint}/instances?page=1`
---
## CREATE (`CreateGenericInstanceUniversalV6`)
```
serviceId, displayName, params map[int]string → instanceUid
```
### Шаги
| # | Метод | Путь | Тело | Ответ |
|---|-------|------|------|-------|
| 1 | POST | `/instances` | `{serviceId, displayName, descr}` | Location → instanceUid |
| 2 | POST | `/instanceOperations` | `{instanceUid, operation:"create"}` | Location → opUid |
| 3 | GET | `/instanceOperations/{opUid}?fields=cfsParams` | — | `cfsParams[]` (полные параметры с defaults) |
| 4 | — | resolveRefSvcParamValues | — | резолв refSvc-параметров |
| 5 | POST | `/instanceOperationCfsParams` | `{instanceOperationUid, svcOperationCfsParamId, paramValue}` | 201 (×N — все params из вызова) |
| 6 | POST | `/instanceOperationCfsParams` | то же для **required** параметров с **defaultValue** (которые не были в params) | 201 (×M) |
| 7 | GET | `/instanceOperations/{opUid}/validate-cfs` | — | валидация |
| 8 | POST | `/instanceOperations/{opUid}/run` | `{}` | запуск |
| 9 | GET | `/instanceOperations/{opUid}?fields=dtFinish,...` | — | поллинг до dtFinish |
| 10 | — | `ensureInstanceCreated` | — | проверка что инстанс создан |
### Важно
- Параметры из вызова отправляются **первыми**
- Затем **required + defaultValue** (те что не были в вызове, но обязательны)
- `/validate-cfs` — отдельный шаг
- `/run` — обязателен
- **Критерий завершения: `dtFinish != nil && dtFinish != ""`** (НЕ `isInProgress`)
---
## MODIFY / SUSPEND / DELETE / RESUME (`RunInstanceOperationUniversal`)
```
instanceUid, action, params → ok/error
```
### Шаги
| # | Метод | Путь | Тело | Примечание |
|---|-------|------|------|------------|
| 1 | GET | `/instances` | — | Получить `availableOperations[]` и `svcOperationId` для action |
| 2 | — | `waitForInstanceIdle` | — | Если `operationIsPending || operationIsInProgress` — ждать |
| 3 | POST | `/instanceOperations` | `{instanceUid, svcOperationId, operation}` | **ВАЖНО: svcOperationId обязателен** |
| 4 | POST | `/instanceOperationCfsParams` | `{instanceOperationUid, svcOperationCfsParamId, paramValue}` | Для каждого параметра (если есть) |
| 5 | POST | `/instanceOperations/{opUid}/run` | `{}` | **ЗАПУСК** |
| 6 | GET | `/instanceOperations/{opUid}?fields=dtFinish,...` | — | Поллинг до dtFinish |
---
## REDEPLOY (`RunRedeployOperation`)
```
instanceUid, timeoutOverride → ok/error
```
| # | Метод | Путь | Тело | Примечание |
|---|-------|------|------|------------|
| 1 | GET | `/instances` | — | Получить `availableOperations` |
| 2 | — | `waitForInstanceIdle` | — | Ждать idle |
| 3 | POST | `/instanceOperations` | `{instanceUid, svcOperationId, operation:"redeploy"}` | — |
| 4 | POST | `/instanceOperations/{opUid}/run` | `{}` | **СРАЗУ /run, без параметров** |
| 5 | GET | `/instanceOperations/{opUid}?fields=dtFinish,...` | — | Поллинг |
---
## Ожидание завершения (`waitForOperationFinish`)
```
opUid, timeout → ok/error
```
### Поллинг (каждые 5 сек)
Эндпоинт: `GET /instanceOperations/{opUid}?fields=dtFinish,isSuccessful,errorLog,isInProgress,isPending,duration,stages`
Ответ:
```json
{
"instanceOperation": {
"dtFinish": "2026-07-24T15:22:20...",
"isSuccessful": true,
"errorLog": null,
"isInProgress": false,
"isPending": false,
"duration": 27.89,
"stages": [...]
}
}
```
### Критерий завершения
```go
if status.InstanceOperation.DtFinish != nil && strings.TrimSpace(*status.InstanceOperation.DtFinish) != "" {
// операция завершена
if !isSuccessful ошибка (errorLog)
else OK
}
```
**НЕ `isInProgress == false`**, a **`dtFinish != nil && dtFinish != ""`**.
### Стадии
Поле `stages[]` содержит:
- `instanceOperationStageUid` — UUID
- `stage` — название этапа
- `isSuccessful` — true/false
- `dtStart` / `dtFinish` — время
- `duration` — длительность в секундах
- `stageMsg` — JSON-строка `[["имя","текст"],...]`
---
## Ожидание простоя (`waitForInstanceIdle`)
```go
for {
state := GetInstanceState(instanceUid)
if !state.OperationIsPending && !state.OperationIsInProgress {
return nil // готов
}
sleep(5s)
}
```
---
## GetInstanceState
Эндпоинт: `GET /instances?pageSize=200&page=N` (пагинация)
Ищет instanceUid в результатах. Возвращает:
```go
type InstanceStateResponse struct {
InstanceUid string
ServiceId int
ExplainedStatus string
IsDeleted bool
OperationIsInProgress bool
OperationIsPending bool
AvailableOperations []ApiOperation // {SvcOperationId, Operation}
}
```
---
## СВОДКА: обязательные поля в /instanceOperations
| Операция | Поля |
|----------|------|
| create | `{instanceUid, operation}` |
| modify | `{instanceUid, svcOperationId, operation}` |
| suspend | `{instanceUid, svcOperationId, operation}` |
| delete | `{instanceUid, svcOperationId, operation}` |
| resume | `{instanceUid, svcOperationId, operation}` |
| redeploy | `{instanceUid, svcOperationId, operation}` |
**Не-create операции требуют `svcOperationId`!**
---
## СВОДКА: последовательность для не-create
```
1. GetInstanceState → svcOperationId для нужного action
2. waitForInstanceIdle
3. POST /instanceOperations {instanceUid, svcOperationId, operation} → opUid
4. POST /instanceOperationCfsParams {instanceOperationUid, svcOperationCfsParamId, paramValue} (×N, если есть params)
5. POST /instanceOperations/{opUid}/run {}
6. waitForOperationFinish (поллинг /instanceOperations/{opUid}?fields=...)
```