debug: bump 5.0.67, log PlanExistingResourceDiagnostics entry
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
# 2026-07-08 — FindInstanceByDisplayName: анализ Opus
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
|
||||||
|
`FindInstanceByDisplayName("NaeelOrg", 19)` возвращает nil → adopt не работает → план показывает `+ create`.
|
||||||
|
|
||||||
|
## Три кандидата (Opus)
|
||||||
|
|
||||||
|
### 🔴 #1: silent error swallow в GetInstanceStateRaw
|
||||||
|
`client.go:~605` — `GetInstanceStateRaw` может возвращать ошибку, которая проглатывается `continue`. Ни search-путь, ни fallback не логируют ошибку.
|
||||||
|
|
||||||
|
### 🟡 #2: fields с URL-encoded запятыми
|
||||||
|
`url.Values.Encode()` кодирует `,` → `%2C`. Если API не понимает `%2C`, search возвращает пустой массив → fallback → провал.
|
||||||
|
|
||||||
|
### 🟡 #3: API возвращает другое имя поля
|
||||||
|
Если API возвращает `display_name` вместо `displayName` — `item.DisplayName` = "", `EqualFold("", "NaeelOrg")` = false.
|
||||||
|
|
||||||
|
## Что делать (по приоритету)
|
||||||
|
|
||||||
|
1. **Добавить stderr-лог** на каждый `continue` в `FindInstanceByDisplayName` — покажет точную причину.
|
||||||
|
2. **Убрать `fields`** из search-запроса (строка ~574) — проверить кандидата #2.
|
||||||
|
3. **Включить `NUBES_DEBUG_HTTP=1`** — лог doRequest.
|
||||||
|
|
||||||
|
## Доп. баг
|
||||||
|
|
||||||
|
Fallback использует `size=100`, search-путь — `pageSize=100`. Разные параметры пагинации.
|
||||||
@@ -14,9 +14,10 @@ provider "nubes" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# S3 bucket — замени "buck0" на своё имя везде ниже
|
# S3 bucket — замени "buck0" на своё имя везде ниже
|
||||||
resource "nubes_s3bucket" "bukka" { # ← замени buck0 на своё имя ресурса
|
resource "nubes_s3bucket" "bukka0" { # ← замени buck0 на своё имя ресурса
|
||||||
resource_name = "Бакет тест1" # ← замени buck0 на своё имя ресурса
|
resource_name = "btst" # ← замени buck0 на своё имя ресурса
|
||||||
s3_user_uid = "naeel-s3"
|
#s3_user_uid = "naeel-s3"
|
||||||
# s3_user_uid = var.s3_user_uid
|
s3_user_uid = var.s3_user_uid
|
||||||
bucket_name = "buck0" # ← замени buck0 на своё имя бакета
|
bucket_name = "buck01" # ← замени buck0 на своё имя бакета
|
||||||
|
adopt_existing_on_create = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ terraform {
|
|||||||
required_providers {
|
required_providers {
|
||||||
nubes = {
|
nubes = {
|
||||||
source = "terra.k8c.ru/nubes-test/nubes"
|
source = "terra.k8c.ru/nubes-test/nubes"
|
||||||
version = "5.0.66"
|
version = "5.0.67"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ NUBES_API_ENDPOINT="https://lk-api-gateway-test.ngcloud.ru/api/v1/svc"
|
|||||||
TOKEN_FILE="secrets/test.token"
|
TOKEN_FILE="secrets/test.token"
|
||||||
|
|
||||||
# Version
|
# Version
|
||||||
VERSION="5.0.66"
|
VERSION="5.0.67"
|
||||||
|
|
||||||
# Docs generation — ONLY from docs_gen/<stand>/ (never from docs/)
|
# Docs generation — ONLY from docs_gen/<stand>/ (never from docs/)
|
||||||
DOCS_GEN_DIR="provider/docs_gen/test"
|
DOCS_GEN_DIR="provider/docs_gen/test"
|
||||||
|
|||||||
+25
-50
@@ -1,53 +1,28 @@
|
|||||||
# Prompt for Opus — поиск багов в 3 файлах
|
# Задача: FindInstanceByDisplayName не находит существующий инстанс — анализ
|
||||||
|
|
||||||
Проверь эти 3 конкретных файла на баги, аналогичные `skip_missing_on_delete` (провайдерский параметр с плохим дефолтом, которого нет в API YAML).
|
|
||||||
|
|
||||||
## Файл 1: Шаблон генератора
|
|
||||||
`/home/naeel/tf_provider/TOOLS/resource-generator/internal/templates/templates.go`
|
|
||||||
|
|
||||||
Смотри все хардкодженные атрибуты (НЕ из `.SchemaParams` / `.OutputParams`):
|
|
||||||
- `resource_name`
|
|
||||||
- `operation_timeout`
|
|
||||||
- `log_level`
|
|
||||||
- `suspend_on_destroy`
|
|
||||||
- `adopt_existing_on_create`
|
|
||||||
- `skip_missing_on_delete`
|
|
||||||
- `git_revision`
|
|
||||||
- `{service}_id`
|
|
||||||
|
|
||||||
Вопросы:
|
|
||||||
- У каждого: правильный ли дефолт?
|
|
||||||
- Не создаёт ли проблем при параллельных/повторных apply?
|
|
||||||
- `skip_missing_on_delete` с дефолтом `false` — уже известный баг. Есть ли другие?
|
|
||||||
|
|
||||||
## Файл 2: CRUD-логика
|
|
||||||
`/home/naeel/tf_provider/provider/internal/resources_core/crud.go`
|
|
||||||
|
|
||||||
Вопросы:
|
|
||||||
- `FindSubresourceInStateOut` — не должна ли проверка молча пропускать удаление?
|
|
||||||
- `IsSubresourceMissingError` — все ли ошибки ловит?
|
|
||||||
- `adoptExistingInstanceOnCreate` — есть ли гонки при параллельном adopt?
|
|
||||||
|
|
||||||
## Файл 3: Сгенерированный subresource
|
|
||||||
`/home/naeel/tf_provider/generated/test/go/90_postgres_database_resource.go`
|
|
||||||
|
|
||||||
Вопросы:
|
|
||||||
- Delete (строки 251-330): правильный ли handling "объект уже удалён"?
|
|
||||||
- Create: что при duplicate?
|
|
||||||
- `skipMissingOnDelete` — везде ли корректно?
|
|
||||||
|
|
||||||
## Что искать
|
|
||||||
1. Ошибки вместо идемпотентности (delete/create должны быть идемпотентны)
|
|
||||||
2. Плохие дефолты (как `skip_missing_on_delete=false`)
|
|
||||||
3. Гонки при параллельных операциях
|
|
||||||
4. Провайдерские параметры не из API — все ли оправданы?
|
|
||||||
|
|
||||||
## Контекст
|
## Контекст
|
||||||
- API не поддерживает параллельные операции на одном инстансе
|
|
||||||
- Subresource delete падает с ошибкой если объект уже удалён
|
|
||||||
- `skip_missing_on_delete` — костыль для обхода, дефолт `false` (баг)
|
|
||||||
- Уже добавлен instance-level mutex в v5.0.63
|
|
||||||
|
|
||||||
## Формат ответа
|
Провайдер `terraform-provider-nubes` v5.0.65, test-стенд.
|
||||||
Для каждого бага: `файл:строка` → симптом → причина → исправление.
|
Инстанс: `NaeelOrg`, serviceId=19, instanceUid=`3f0850f2-3506-4efd-b84b-7270b5027ab5`, статус Running.
|
||||||
Не читай другие файлы без необходимости.
|
|
||||||
|
## Симптом
|
||||||
|
|
||||||
|
`terraform plan` с `adopt_existing_on_create=true`, `resource_name="NaeelOrg"` → `+ create`. Apply → «уже существует».
|
||||||
|
|
||||||
|
## Доказано curl-тестами
|
||||||
|
|
||||||
|
1. Search API: `GET /instances?search=NaeelOrg&serviceId=19&isAuxiliary=false&isDeleted=false` + `UA: Mozilla/5.0` → находит.
|
||||||
|
2. GetInstanceStateRaw: `GET /instances/3f0850f2-...` → возвращает, isDeleted=false, Running.
|
||||||
|
|
||||||
|
## Ключевые файлы
|
||||||
|
|
||||||
|
- `provider/internal/core/client.go` — `FindInstanceByDisplayName()`:568, `doRequest()`:949, `GetInstanceStateRaw()`:753, `isInstanceDeleted()`:741
|
||||||
|
- `provider/internal/resources_core/resource_diagnostics.go` — `PlanExistingResourceDiagnostics()`:14
|
||||||
|
- `provider/internal/resources_core/crud.go` — `CreateResource()`:21, `adoptExistingInstanceOnCreate()`:142
|
||||||
|
- `generated/test/go/19_vc_org_resource.go` — `ModifyPlan()`
|
||||||
|
- `TEST_STAND/kuber/resources.tf` — манифест
|
||||||
|
- `HISTORY/OPUS/3006_0_answers.md`:220 — search ✅ / fallback ❌
|
||||||
|
|
||||||
|
## Задание
|
||||||
|
|
||||||
|
Найти **точно**, почему `FindInstanceByDisplayName("NaeelOrg", 19)` возвращает nil. Если не хватает данных — сказать, какой curl-тест запустить.
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version string = "5.0.66"
|
version string = "5.0.67"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user