6.3 KiB
6.3 KiB
Спроектировать С НУЛЯ архитектуру/логику «ресурсов-модификаторов» (kind: modifier)
Цель
Перепроектировать модификаторы целиком, чтобы исключить ВСЕ классы багов, не латать по одному. Нужна единая, полная модель поведения — без догадок и костылей. Перечислить ВСЕ кейсы.
Что такое модификатор (текущая фактура)
В YAML (генерируется из API) операции бывают:
kind: instance(create/modify/suspend/resume/delete) — обычный CRUD-ресурс;kind: modifier+modifier: <name>— отдельный TF-ресурс, который вызываетmodifyна родительском инстансе. Сейчас их два:vc_org.ip_space,vc_nsxt.network.
Реальные примеры:
vc_org→ modifierip_space(modify 207), параметрvIPConfigure(array-map-fixed);vc_nsxt→ modifiernetwork(modify 111), параметрыneedEnableAVI(bool),virtualServicesCount(int>0),qosProfile(string),ipSpaceName(string),routedNetConfiguration(map-fixed).
Текущий механизм (что есть — факты, не догадки)
- Генератор:
TOOLS/resource-generator/internal/templates/modifier.go- Create и Update идентичны: оба шлют
modifyс полным набором полей. Delete— no-op (комментарий: «no confirmed inverse payload»).- Схема:
idcomputed,<service>_idrequired, поля Optional (или Required если нет default).
- Create и Update идентичны: оба шлют
resources_core.CompactParams— выбрасывает пустые строки из payload.resources_core.BuildActionID(instanceUID, operation, modifierName)— константный ID, не привязан к реальной операции (opUid не сохраняется).core.RunInstanceOperationUniversalByCode— резолвит code→id черезGET /instanceOperations/{opUid}?fields=cfsParams(fallback на/default/{opId}); отправляет переданные params, затем дозаполняет остальные их live-значением (guard: пропускает параметр, если нет ни ParamValue, ни DefaultValue).Read— черезRefreshResourceState: читаетstate_paramsинстанса и перезаписывает input-поля из них.
Уже выявленные КЛАССЫ багов (все реально случились)
- A. Сброс create-поля при modify. modify со сброшенными (null) параметрами
трактуется бэкендом как reset-to-default:
needEnableAVIстал false после create=true. Причина: модификатор шлёт только свои поля,CompactParamsвыкидывает пустые, бэкенд видит «отсутствующий» и сбрасывает. - B. Досылка синтетики. фикс «досылать всё» слал
"0"дляinteger > 0(параметрvirtualServicesCount), API 400 «Invalid format integer > 0». - C. Ложное «Нельзя изменить».
ComputeCreateOnlyсчиталneedEnableAVICreateOnly (change-forbidden), хотя в YAMLis_modifiable: true— потому что генератор не учитывал modifier-канал и терялIsModifiable. (Зафиксировано отдельно.) - D. No-op Delete оставляет эффект на платформе. destroy модификатора убирает ресурс из state, но выделенные IP / включённый ALB остаются на платформе → drift.
- E. Повторный apply после taint/replace снова гонит modify — риск повторной
аллокации (для
ip_space), идемпотентность не гарантирована.
Вопросы к Опусу (ответить ПОЛНО, по пунктам, с точными местами правки)
- Канон «как сравнить и применить». Должен ли модификатор перед modify читать текущее состояние и слать ДЕЛЬТУ (только реально изменившиеся поля), или ПТЦ полный payload? Как детектить drift в Read?
- Досылка незаданных полей (паер-заливы A и B). Какое каноническое правило:
когда досылать live-значение, когда дефолт, когда пропускать? Как не сломать
integer > 0и прочие constraints? - Delete/rollback. Где искать обратный payload? Как правильно поступить, пока обратный payload НЕ подтверждён API (no-op допустим? явная ошибка? suspend?).
- Idempotency + ID. Как сделать ID модификатора отражающим фактическую операцию (opUid?) и как предотвратить двойную аллокацию при replace/повторном apply?
- Связь с родителем. Должен ли модификатор использовать
<service>_idкак ссылку на родителя (depends_on / borrow state), и как читать UUID родителя? - Create vs Update. Допустимо ли иметь их идентичными, или нужен строго Update-семантик (нет create, только apply-по-десяти)?
- Полный перечень кейсов. Перечислить ВСЕ edge-кейсы, которые надо покрыть: create родителя → modifier; remove modifier; replace; partial params; unknown/absent.
Ответ — архитектурный документ (краткий, структурированный), с конкретными файлами и функциями. НЕ код-ревью, а ПРОЕКТ.