fix(hindsight): шаблон tenant_users без sprig keys (ESO отдаёт map[string]string) #63

Merged
hermes merged 1 commit from refs/pull/63/head into main 2026-09-20 12:59:37 +00:00
hermes commented 2026-09-20 12:58:33 +00:00 (Migrated from git.grachevko.ru)

Что произошло

После #62 ExternalSecret/ai/hindsight ушёл в SecretSyncedError. Точная ошибка из лога ESO:

unable to execute template at key HINDSIGHT_API_TENANT_USERS:
template: HINDSIGHT_API_TENANT_USERS:1:48: executing "HINDSIGHT_API_TENANT_USERS" at <.>:
wrong type for value; expected map[string]interface {}; got map[string]string

Причина: sprig-функция keys объявлена как func keys(dicts ...map[string]interface{}), а ESO отдаёт шаблону map[string]string — падает на приведении типа ещё до подстановки. Секрет при этом не пострадал: ESO не переписывает hindsight-secret при ошибке шаблона, поэтому API продолжал работать на старом значении (симптома в кластере не было, кроме статуса ES).

Правка

Убрал keys совсем: range по карте работает с любым типом map, а детерминированность даёт сортировка уже собранных пар (порядок обхода карты в Go случаен — без сортировки Secret менялся бы каждый refresh и reloader дёргал бы поды каждый час):

{{- $pairs := list -}}
{{- range $name, $value := . -}}
  {{- if hasPrefix "api_key_" $name -}}
    {{- $pairs = append $pairs (printf "%s:%s" (trimPrefix "api_key_" $name) $value) -}}
  {{- end -}}
{{- end -}}
{{- join "," ($pairs | sortAlpha) -}}

sortAlpha применяется к списку строк ($pairs — []interface{} из строк), поэтому приведения типов, как у keys, тут не возникает. Обращения {{ .postgres_password }} / {{ .llm_api_key }} в том же шаблоне отработали, то есть контекст ключуется по secretKey — это подтверждено ошибкой, упавшей только на составном ключе.

Проверено

  • flate test all — 77 passed, exit 0.
  • Файл в ветке побайтово равен локальному; diff против main — 1 файл, +8/−6.

Проверка после мёржа

  • kubectl -n ai get externalsecret hindsight → Ready/SecretSynced (не SecretSyncedError).
  • kubectl -n ai get secret hindsight-secret -o jsonpath='{.data.HINDSIGHT_API_TENANT_USERS}' | base64 -d | tr ',' '\n' | cut -d: -f1 → три имени (значения не печатаем).
  • Поды API перекатятся один раз (порядок пар становится алфавитным), дальше содержимое стабильно.
## Что произошло После #62 `ExternalSecret/ai/hindsight` ушёл в `SecretSyncedError`. Точная ошибка из лога ESO: ``` unable to execute template at key HINDSIGHT_API_TENANT_USERS: template: HINDSIGHT_API_TENANT_USERS:1:48: executing "HINDSIGHT_API_TENANT_USERS" at <.>: wrong type for value; expected map[string]interface {}; got map[string]string ``` Причина: sprig-функция `keys` объявлена как `func keys(dicts ...map[string]interface{})`, а ESO отдаёт шаблону `map[string]string` — падает на приведении типа ещё до подстановки. Секрет при этом не пострадал: ESO не переписывает `hindsight-secret` при ошибке шаблона, поэтому API продолжал работать на старом значении (симптома в кластере не было, кроме статуса ES). ## Правка Убрал `keys` совсем: `range` по карте работает с любым типом map, а детерминированность даёт сортировка уже собранных пар (порядок обхода карты в Go случаен — без сортировки Secret менялся бы каждый refresh и reloader дёргал бы поды каждый час): ``` {{- $pairs := list -}} {{- range $name, $value := . -}} {{- if hasPrefix "api_key_" $name -}} {{- $pairs = append $pairs (printf "%s:%s" (trimPrefix "api_key_" $name) $value) -}} {{- end -}} {{- end -}} {{- join "," ($pairs | sortAlpha) -}} ``` `sortAlpha` применяется к списку строк (`$pairs` — []interface{} из строк), поэтому приведения типов, как у `keys`, тут не возникает. Обращения `{{ .postgres_password }}` / `{{ .llm_api_key }}` в том же шаблоне отработали, то есть контекст ключуется по `secretKey` — это подтверждено ошибкой, упавшей только на составном ключе. ## Проверено - `flate test all` — **77 passed**, exit 0. - Файл в ветке побайтово равен локальному; diff против main — 1 файл, +8/−6. ## Проверка после мёржа - `kubectl -n ai get externalsecret hindsight` → `Ready/SecretSynced` (не `SecretSyncedError`). - `kubectl -n ai get secret hindsight-secret -o jsonpath='{.data.HINDSIGHT_API_TENANT_USERS}' | base64 -d | tr ',' '\n' | cut -d: -f1` → три имени (значения не печатаем). - Поды API перекатятся один раз (порядок пар становится алфавитным), дальше содержимое стабильно.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
grachevko/home-ops!63
No description provided.