Files
tf_provider/docs/inverse_rollback_analysis_2026-09-23.md
T

4.3 KiB
Raw Blame History

Inverse-откат модификаторов: анализ ответа Опуса — 2026-09-23

Источник: prompt_for_opus_inverse_architecture.md → ответ Опуса (принят, анализ ниже).

Принятые решения (по Опусу)

  1. Модель delete_params → заменить плоский {Code, Value} на {Code, Mode, Value?}:
    • Mode: static — значение из Value (дефолт, обратная совместимость).
    • Mode: zero_count — обнулить integer-поля в элементах array-map-fixed, взяв live.
  2. Баланс данные/логика: форма преобразования выводится из dataType (boolean→"false", array-map-fixed→zero integer); сентинелы-значения — ТОЛЬКО данные в реестре.
  3. Маркер поля: явный zero_fields:["count"] (или флаг на sub_param), а НЕ «обнулить все integer» (риск: порт/приоритет/индекс в том же object).
  4. Порядок destroy — обратный порядок создания из depends_on.

Мои замечания к ответу (что Опуc недоговорил)

  • A. Граф уже правильный. Факт: edge_net (SNAT) зависит от org_ips (IP), org_ips — от edge. Обратный порядок destroy: edge_net → org_ips → edge → vdc уже корректен. Рекомендация Опуса «сделать ip_space зависимым от edge_net» — перепутана направлением; граф уже такой.
  • B. Источник live для zero_count в Delete не указан. Delete модификатора имеет только TF state, а live vIPConfigure надо читать через GetInstanceStateParams в рантайме Delete.
  • C. Отличие sentinel от имени в valueList не разобрано (valueList без разметки sentinel в данных API).
  • D. Идемпотентность zero_count при повторном destroy не поднята (count=0 → снова 0: no-op?).

Открытые вопросы (второй раунд к Опусу) — ЗАКРЫТЫ

  1. Источник live для zero_count в Delete → GetInstanceStateParams (не TF state). ✅
  2. Sentinel в valueList → явный off_value:"no-needed" в реестре (данные, не логика). ✅
  3. Идемпотентность zero_count → пропускать run, если live уже count=0 (применимо и к static). ✅
  4. count=0 → канонический inverse; полное удаление ipSpace = отдельный опциональный Mode:remove (не подменять zero_count). ✅

ИТОГ — финальная модель inverse

delete_params: []{ Code, Mode, Value?, zero_fields?, off_value? }

  • Mode: static — обратное значение = Value (boolean→"false"; string→off_value).
  • Mode: zero_count — взять live array-map-fixed, обнулить поля из zero_fields:["count"].
  • Mode: remove (опц., не для FullPipe) — полное удаление элемента.

Рантайм: Delete → GetInstanceStateParams → построить inverse → если live уже целевое → no-op (skip run) → иначе modify.

Реестр (yaml-generator main.go):

  • vc_org.ip_space: inverse, param vIPConfigure Mode:zero_count, zero_fields:[count].
  • vc_nsxt.network: inverse, params needEnableAVI=static "false", ipSpaceName=static off_value "no-needed".

Порядок destroy (уже корректен в .tf): edge_net → org_ips → edge → vdc.

Факты (не менять, проверено)

  • count=0 принимается API (minvalue:1 в схеме — не отвергает), идемпотентно (ORG_IP_MODIFIER_TEST_2026-09-22).
  • SNAT off = ipSpaceName="no-needed" (sentinel в valueList, HAR_SNAT_MODIFY_FINDINGS).
  • needEnableAVI boolean → inverse "false".
  • vc_org.ip_space: error → нужен inverse (zero_count). vc_nsxt.network: inverse+static needEnableAVI=false, добавить ipSpaceName="no-needed".