fix(subresource): диагностика чтения пароля + одна точка заполнения в Create

По итогам код-ревью (коммит 64328ab):
- ResolveUserPasswordFromVault теперь возвращает и текст предупреждения: если пароль
  прочитать не удалось (недоступен API/Vault, пустое имя, нет записи), в выводе apply
  появляется Warning. Раньше поле молча становилось null и причина была невидима.
  Отсутствие секретов у родителя ошибкой не считается (для части сервисов это норма).
- В шаблоне подресурса заполнение вынесено в одно замыкание applyPassword(),
  вызываемое перед каждым resp.State.Set в Create (4 сохранения — 4 вызова).
  Убирает четыре одинаковые строки и снижает риск забыть новую ветку выхода.
- Тест проверяет: замыкание есть, предупреждение есть, и вызовов applyPassword()
  не меньше, чем сохранений состояния в Create.

Проверено: generated/test/go/90_postgres_user_resource.go — 4 State.Set, 4 вызова
(плюс одно упоминание в комментарии); go test ./... ok; go build ./internal/... и
полная сборка провайдера во временной копии с новым generated — чисто.
This commit is contained in:
Repinoid
2026-10-01 19:31:35 +03:00
parent 64328abe55
commit 93784e44a7
3 changed files with 68 additions and 29 deletions
@@ -89,6 +89,12 @@ func TestWriteSubresource_VaultUserPassword(t *testing.T) {
if !strings.Contains(src, "ResolveUserPasswordFromVault(") {
t.Errorf("нет чтения пароля из Vault родителя (ResolveUserPasswordFromVault)")
}
if !strings.Contains(src, "applyPassword := func()") {
t.Errorf("нет единого замыкания applyPassword")
}
if !strings.Contains(src, "Пароль пользователя не прочитан из Vault") {
t.Errorf("нет предупреждения при неудачном чтении пароля — ошибка останется невидимой")
}
if !strings.Contains(src, "priorState.Password") {
t.Errorf("в Update нет сохранения уже полученного пароля")
}
@@ -96,7 +102,7 @@ func TestWriteSubresource_VaultUserPassword(t *testing.T) {
// КРИТИЧНО: password — Computed-атрибут. Если хотя бы одна ветка выхода из
// Create сохранит состояние, не проставив его, Terraform упадёт с
// "Provider returned invalid result object after apply ... unknown value".
// Поэтому: инициализация + вызов перед каждым сохранением состояния.
// Поэтому: инициализация + вызов заполнения перед каждым сохранением состояния.
if !strings.Contains(src, "plan.Password = types.StringNull()") {
t.Errorf("password не инициализируется конкретным значением до ветвлений")
}
@@ -108,12 +114,12 @@ func TestWriteSubresource_VaultUserPassword(t *testing.T) {
createBody = createBody[:end]
}
setCount := strings.Count(createBody, "resp.State.Set(ctx, &plan)")
resolveCount := strings.Count(createBody, "ResolveUserPasswordFromVault(")
callCount := strings.Count(createBody, "applyPassword()")
if setCount == 0 {
t.Fatalf("в Create не найдено сохранение состояния")
}
if resolveCount < setCount {
t.Errorf("в Create %d сохранений состояния, но только %d вызовов заполнения пароля — в какой-то ветке password останется unknown", setCount, resolveCount)
if callCount < setCount {
t.Errorf("в Create %d сохранений состояния, но только %d вызовов applyPassword() — в какой-то ветке password останется unknown", setCount, callCount)
}
})