docs: пометить отменённый заход модификаторов как LEGACY + исправить ложные факты

- баннеры «ЛОЖНЫЙ ПУТЬ — ОТМЕНЕНО» на 4 файла HISTORY/OPUS/2026-09-22_modifier_* и docs/60_strategy/modifier_resources_ideology_and_specification.md
- vIPConfigure: replace-семантика, НЕ накопительная (по тесту docs/ORG_IP_MODIFIER_TEST_2026-09-22.md)
- обновлены ссылки на перенесённые материалы (docs/... -> NOTES/..., HOW_TO/...)
This commit is contained in:
Repinoid
2026-09-24 07:51:25 +03:00
parent d93ff66482
commit 2d8e435dd4
59 changed files with 23 additions and 6 deletions
+62
View File
@@ -0,0 +1,62 @@
# Отчет о работе: Исправление ошибки 500 при модификации VM
## 1. Проблема
При попытке изменить ресурс `nubes_vm_instance` (например, изменить `vm_cpu`), Terraform получает ошибку 500 от API:
```
Status 500: {"ERROR":"Invalid call of the function [checkParam], 4th Argument [instanceOperationCfsParamUid] is of invalid type, Cannot cast String [] to a value of type [guid]","DETAIL":"the function is located at [/app/api/v1/resources/instance_operation_cfs_param_ls.cfc]"}
```
## 2. Анализ причины
Сообщение `Cannot cast String [] to a value of type [guid]` указывает на то, что бэкенд получает массив строк там, где ожидает одиночный GUID. Обычно это происходит в REST API, когда клиент отправляет несколько значений для одного ключа, или когда отправляется `POST` запрос для создания сущности, которая уже существует, и система дублирует параметр в список.
В отличие от создания (Create), операция модификации (Modify/Update) в Nubes API при инициализации (`GET /instanceOperations/...`) уже содержит текущие значения параметров (`CfsParams`).
Если мы безусловно используем метод `POST` для отправки параметров (как это было сделано в ресурсе Postgres), мы создаем дубликат параметра. По всей видимости, движок API (ColdFusion?) объединяет старое и новое значение в массив, что ломает валидацию `checkParam`.
## 3. Выполненные действия (Solution Attempt)
Я модифицировал файл `internal/provider/vm_resource.go`, полностью переписав функцию `submitVMOperationParams`.
**Суть изменений:**
1. **Динамический маппинг**: Перед отправкой параметров провайдер теперь запрашивает детали операции (`GetInstanceOperation`).
2. **Определение UID**: Мы строим карту существующих параметров: `ParamName -> { ID, UID, CurrentValue }`.
3. **Гибридная логика PUT/POST**:
* Если параметр **уже существует** в операции (есть `instanceOperationCfsParamUid`) -> Мы используем метод **`PUT`**.
* URL: `/instanceOperationCfsParams`
* Payload: включает `instanceOperationCfsParamUid`.
* Если параметр **новый** (нет UID) -> Мы используем метод **`POST`**.
* URL: `/instanceOperationCfsParams`
* Payload: включает только `instanceOperationUid` и `svcOperationCfsParamId`.
### Фрагмент кода (internal/provider/vm_resource.go):
```go
if info.Uid != "" {
// Update existing parameter -> PUT
method = "PUT"
payload = map[string]interface{}{
"instanceOperationCfsParamUid": info.Uid,
"svcOperationCfsParamId": info.Id,
"instanceOperationUid": operationUid,
"paramValue": np.Value,
}
} else {
// Create new parameter -> POST
method = "POST"
// ...
}
```
## 4. Текущий статус
Код компилируется и выполняется. Был обновлен провайдер (`terraform-provider-nubes`).
Однако, при последнем запуске (`terraform apply`) ошибка 500 воспроизвелась снова с тем же текстом.
Это означает, что либо:
1. Логика `PUT` тоже вызывает дублирование (возможно, API не поддерживает PUT для этого эндпоинта так, как мы ожидаем).
2. Или ошибка `instanceOperationCfsParamUid is String[]` возникает из-за того, что я передаю этот UID в теле JSON, но API может ожидать его в URL или query params (хотя для PUT принято в теле или URL).
## 5. Планируемые дальнейшие шаги (остановлены)
Для полного решения требовалось бы:
1. Проверить работу `PUT` через curl с разными форматами payload.
2. Попробовать передавать UID параметра в рамках URL (REST-style): `/instanceOperationCfsParams/{uid}`.
**Статус:** Работа остановлена по требованию пользователя. Код зафиксирован в текущем состоянии (Гибридный PUT/POST).