Как разобрать секрет JSON для YAML в хранилище?

#kubernetes #consul #hashicorp-vault

Вопрос:

У меня есть секрет в хранилище, который на самом деле представляет собой «сложную» структуру JSON, то есть это не просто ключ/значение, но несколько ключей на разных подуровнях.

Мне нужно каким-то образом получить этот секрет и преобразовать его в представление YAML этого JSON. Если бы это была простая структура (например, несколько к/в на одном уровне), я мог бы использовать что-то столь же простое, как

       {{- with secret "secret/foo" -}}
          {{ range $k, $v := .Data.data }}
            {{ $k }}: {{ $v }}
          {{- end }}
      {{- end }}
 

однако, поскольку это не так, и структура JSON сложна, попытка придумать шаблон довольно невозможна.

Однако я обнаружил, что в хранилище используются шаблоны Консула, а у Консула есть функция parseYAML, поэтому мой вопрос в том, как я могу создать этот шаблон, чтобы получить все содержимое .Data.data и перевести его на YAML?

Я попробовал несколько подходов, подобных приведенному ниже:

 {{- with secret "secret/foo" -}}
{{ .Data.data| parseYAML }}
{{- end }}
 

но я всегда получаю одну и ту же ошибку wrong type for value; expected string; got map[string]interface {}"

Обновить

Образец yaml:

 apiVersion: v1
kind: ServiceAccount
metadata:
  name: app
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
      annotations:
        vault.hashicorp.com/agent-inject: 'true'
        vault.hashicorp.com/agent-inject-secret-foo: 'secret/foo'
        vault.hashicorp.com/agent-inject-template-secret-foo: |
          {{- with secret "secret/foo" -}}
          {{ .Data.data| parseYAML }}
          {{- end }}
        vault.hashicorp.com/role: 'app'
    spec:
      containers:
        - name: app
          image: 'app:1.0.0'
      serviceAccountName: app
 

где secret/foo находится длинный JSON без четкой структуры. Случайный пример (фактический JSON, я думаю, составляет около 300 строк).

 {
  "a": {
    "a": "a",
    "b": "b",
    "c": {
      "a": "a",
      "b": {
        "c": "c"
      },
      "d": "a"
    },
    "e": {
      "a": {
        "b": {
          "c": {
            "a": "a",
            "b": "b"
          }
        }
      }
    }
  }
}
 

Комментарии:

1. ваша .Data.data карта HCL2 или строка JSON?

2. @MattSchuchard Я сохранил в хранилище JSON, но вывод после извлечения секрета окончательно не является JSON. Он следует формату, подобному: key:map[key:map[key:value] key2:value key3:map[key4:map[.......

3. Я не уверен, что это тот формат HCL2, на который вы ссылаетесь. В основном это JSON , в котором символы { заменяются на map[ , а , символы-пробелами.

4. Так что это похоже на карту HCL2, которая была бы правильно преобразована в YAML с parseYAML помощью . Я бы предположил, что в вашем манифесте Kubernetes для значения ожидается строковый тип, и вы не передаете строку. Просмотр 1. структуры вашего секрета 2. фрагмент манифеста Кубернетеса уменьшит количество спекуляций.

5. @MattSchuchard секрет действительно большой, на самом деле это не «секрет» как таковой, но, поскольку приложение было плохо разработано, разработчики смешали секреты со стандартными настройками. Итак, просто предположим, например, случайный JSON без четкой структуры {"a":{"a":"a","b":"b","c":{"a":"a","b":{"c":"c"},"d":"a"},"e":{"a":{"b":{"c":{"a":"a","b":"b"}}}}}} . Ямл Кубернетеса-это не что иное, как стандартное определение модуля с аннотациями Хранилища для чтения секрета.

Ответ №1:

Ладно, просто разберись в этом.

 {{- with secret "secret/foo" -}}
{{ .Data.data| parseYAML }}
{{- end }}
 

это правильно, но вместо parseYAML правильной функции есть toYAML .