найдите конкретное поле и вставьте новое значение с помощью jq

#json #bash #kubernetes #jq

Вопрос:

У меня есть эта команда в скрипте bash

 kubectl get svc --selector='app.kubernetes.io/component=sentinel' --all-namespaces -o json |
jq -r '
.items
   | map(
   {label:.metadata.name,
   sentinels: [{host:(.metadata.name   "."   .metadata.namespace   "."   "svc"   "."   "cluster"   "."   "local"),port: .spec.ports[0].port}],
   sentinelName:"mymaster",
   sentinelPassword: ""
   dbIndex: 0
   })
| {connections: . }' /
>local.json
 

который выдает что-то вроде этого вывода

 {
  "connections": [
    {
      "label": "Redis1",
      "sentinels": [
        {
          "host": "Redis1.default.svc.cluster.local",
          "port": 26379
        }
      ],
      "sentinelName": "mymaster",
      "sentinelPassword": "",
      "dbIndex": 0
    },
    {
      "label": "Redis2",
      "sentinels": [
        {
          "host": "Redis2.development.svc.cluster.local",
          "port": 26379
        }
      ],
      "sentinelName": "mymaster",
      "sentinelPassword": "",
      "dbIndex": 0
    }
  ]
}
 

Этот файл конфигурации вводится в контейнер через контейнер инициализации, поэтому Redis-Commander извлекает экземпляры redis без необходимости вручную вводить какие-либо данные конфигурации подключения. Однако это работает нормально, но для одного из экземпляров требуется sentinelPassword значение.

Я могу получить пароль с помощью kubectl get secret , но я пытаюсь понять, как вставить этот пароль в файл конфигурации для конкретного экземпляра, который его требует.

Я пытался что-то в этом роде, но неправильно понял синтаксис jq. Любая помощь или альтернативные способы обхода будут оценены по достоинству.

 #store output in var
JSON=$(kubectl get svc --selector='app.kubernetes.io/component=sentinel' --all-namespaces -o json |
jq -r '
.items
   | map(
   {label:.metadata.name,
   sentinels: [{host:(.metadata.name   "."   .metadata.namespace   "."   "svc"   "."   "cluster"   "."   "local"),port: .spec.ports[0].port}],
   sentinelName:"mymaster",
   sentinelPassword: "",
   dbIndex: 0
   })
| {connections: . }')

# Find instance by their host value which is unique. (Can't figure out how to do this bit)
  if $JSON host name contains "Redis2.development.svc.cluster.local"
#then do something like this
    "$JSON" | jq '.[]'| .sentinelPassword = "$password" #var stored from kubectl get secret cmd

#save output to file
"$JSON">/local.json

 

Ответ №1:

Предполагая на данный момент, что вы хотите вызвать jq в образце JSON (local.json), как показано, вы можете запустить:

 password=mypassword
< local.json jq --arg password "$password" '
  .connections[] |= if any(.sentinels[].host; index("Redis2.development.svc.cluster.local"))
                    then .sentinelPassword = $password else . end'
 

Однако, если возможно, вероятно, было бы лучше вызвать jq только один раз.

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

1. Мило! Рад, что я неправильно ответил здесь за возможность изучить веревки jq. Сейчас я просто удалю свой ответ.

2. Большое спасибо!