# Отчет о работе: Исправление ошибки 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).