docs(opus): дописать ответы №2 (inverse/schema/current/idempotency/skip)
This commit is contained in:
@@ -113,3 +113,81 @@ No-op Delete = скрытый drift (класс D). Пока обратный pa
|
|||||||
(а не хардкодом в коде reconcile)?
|
(а не хардкодом в коде reconcile)?
|
||||||
5. **Что если желаемое == текущее, но была «частичная» ошибка ранее** — пропускать run
|
5. **Что если желаемое == текущее, но была «частичная» ошибка ранее** — пропускать run
|
||||||
безопасно всегда, или есть исключения?
|
безопасно всегда, или есть исключения?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ответы Opus №2 (уточнения по 5 вопросам)
|
||||||
|
|
||||||
|
## 1. inverse-Delete — только декларативно в YAML, хардкод запрещён
|
||||||
|
|
||||||
|
Обратный payload зависит от параметров: `needEnableAVI:false` валиден, а
|
||||||
|
`virtualServicesCount` (`integer > 0`) обнулить нечем → `0` невозможен.
|
||||||
|
Значит inverse-значения задаются **явным блоком в YAML**. Если хоть один параметр
|
||||||
|
не имеет валидного inverse — стратегия `inverse` недопустима (fail-fast в загрузчике).
|
||||||
|
Для `ip_space` inverse нет вообще → только `noop_warn`.
|
||||||
|
|
||||||
|
## 2. Точная схема YAML новых полей
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
operations:
|
||||||
|
- kind: modifier
|
||||||
|
modifier: network
|
||||||
|
action: modify
|
||||||
|
delete_strategy: noop_warn # enum: noop_warn | inverse | error
|
||||||
|
idempotency: check_before_run # enum: none | check_before_run
|
||||||
|
delete_params: # обязателен ТОЛЬКО при delete_strategy: inverse
|
||||||
|
- code: needEnableAVI
|
||||||
|
value: "false"
|
||||||
|
params: [...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Go-контракт (`OperationSpec`):
|
||||||
|
```go
|
||||||
|
DeleteStrategy string `yaml:"delete_strategy,omitempty"` // "" → noop_warn
|
||||||
|
Idempotency string `yaml:"idempotency,omitempty"` // "" → none
|
||||||
|
DeleteParams []ParamSpec `yaml:"delete_params,omitempty"`
|
||||||
|
```
|
||||||
|
|
||||||
|
Дефолты: `delete_strategy` → `noop_warn`; `idempotency` → `none`.
|
||||||
|
Fail-fast в `ValidateSpec`: значение вне enum → ошибка; `inverse` с пустым
|
||||||
|
`delete_params` → ошибка; `delete_params.code` нет в `params` → ошибка; inverse-значение
|
||||||
|
нарушает constraint параметра → ошибка на этапе генерации.
|
||||||
|
`GenModifier` получает `DeleteStrategy`, `Idempotency`, `DeleteParams`.
|
||||||
|
|
||||||
|
## 3. Откуда читать current + как сравнивать
|
||||||
|
|
||||||
|
**Читать из `state_params`, отдельный GET не делать** (это уже источник истины для Read;
|
||||||
|
второй источник = риск рассогласования).
|
||||||
|
|
||||||
|
Сравнение по типу:
|
||||||
|
| Тип | Как сравнивать |
|
||||||
|
|---|---|
|
||||||
|
| bool/int/string | равенство после `normalizeUniversalValueV6` |
|
||||||
|
| map-fixed | `JSONStringsEquivalent` (игнор порядка ключей) |
|
||||||
|
| array-map-fixed | deep-equal с сохранением **порядка элементов** (порядок значим) |
|
||||||
|
|
||||||
|
Порядок ключей map-fixed — нормализовать (не значим). Порядок элементов
|
||||||
|
array-map-fixed — НЕ нормализовать (значим).
|
||||||
|
|
||||||
|
## 4. idempotency декларативно
|
||||||
|
|
||||||
|
Поле `idempotency` на modify-операции в YAML → `ValidateSpec` → `GenModifier.Idempotency`
|
||||||
|
→ шаблон `modifier.go` в `reconcile()` эмитит pre-check `{{- if eq .Idempotency "check_before_run" }}`.
|
||||||
|
Для `ip_space` — в YAML; для остальных — дефолт `none`.
|
||||||
|
|
||||||
|
## 5. Когда безопасно skip run при desired == current (НЕ всегда)
|
||||||
|
|
||||||
|
Три условия безопасного skip:
|
||||||
|
1. **Инстанс idle** — если pending/in-progress, сначала `waitForInstanceIdle`, потом
|
||||||
|
перечитать `state_params` (иначе mid-flight аллокация даст ложное «уже равно»).
|
||||||
|
2. **current из живого state_params, НЕ из TF-state** — после частичной ошибки TF-state
|
||||||
|
может врать, а state_params отражает реальную платформу.
|
||||||
|
3. **Сравнение по всем полям, не по одному** — skip только при совпадении ВСЕХ полей.
|
||||||
|
|
||||||
|
Итог:
|
||||||
|
```
|
||||||
|
idle? нет → wait, re-read
|
||||||
|
всё-live == всё-desired? да → skip run
|
||||||
|
иначе → reconcile (полный payload)
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user