首页 > 解决方案 > 查找特定字段并使用 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
    }
  ]
}

此配置文件通过 init-container 注入容器,因此 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

标签: jsonbashkubernetesjq

解决方案


假设您想在示例 JSON (local.json) 上调用 jq,如图所示,您可以运行:

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。


推荐阅读