Docs: full operation logic from Terraform provider (VM)
This commit is contained in:
@@ -0,0 +1,201 @@
|
|||||||
|
# Полная логика операций — из 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=...)
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user