首页 > 解决方案 > juju 状态和 jq 从 JSON 状态的多个对象中过滤混合内容

问题描述

tl;博士

我正在尝试获取juju status输出的 JSON 表示,它将机器、实例 ID 和单元对象化,使得 JSON 看起来类似于:

{
  "0": {
          "instance-id": "i-xxxxxxxxxxxxxx",
          "unit-name": "easyrsa/0"
       },
  "1": {
          "instance-id": "i-xxxxxxxxxxxxxx",
          "unit-name": "etcd/0"
       },
  "2": {
          "instance-id": "i-xxxxxxxxxxxxxx",
          "unit-name": "kubeapi-load-balancer/0"
       },
  "10": {
          "instance-id": "i-xxxxxxxxxxxxxx",
          "unit-name": "kubernetes-worker/4"
       },
  "11": {
          "instance-id": "i-xxxxxxxxxxxxxx",
          "unit-name": "kubernetes-worker/5"
       },
  "12": {
          "instance-id": "i-xxxxxxxxxxxxxx",
          "unit-name": "kubernetes-master/3"
       }
}

它的长处:

修改juju status --format json对我来说很复杂,因为要修改的数据在 JSON 中的两个不同主要对象之间拆分。由于机器的键是不可迭代的,但是,我以后不能像引用数组一样引用它们——或者至少那是我认为我搞砸的地方。

我尝试过但失败的一些事情(主要是因为我为如何存储.machines密钥以供以后使用而苦恼)......

juju status --format json | jq -r '.machines as $m | .machines | [foreach keys[] as $item ({m: $item, id: $m[$item]."instance-id"})]'

... | juju status --format json | jq -r '.machines | keys[] as $k...

... | juju status --format json | jq -r '.machines | keys[] as $k |...

要么我没有得到我需要的结果,要么我得到一个语法错误。我从来不需要foreach在 jq 上下文中使用。事实上,这是我试图完成的最复杂的事情,jq所以我在这里的舒适区之外。任何帮助将不胜感激。

这是一个示例juju statusJSON 对象:

{
  "model": {
    "name": "xxxxxxxxxx",
    "controller": "xxxxxxxxxx",
    "cloud": "xxxxxxxxxx",
    "region": "xxxxxxxxxx",
    "version": "xxxxxxxxxx",
    "model-status": {
      "current": "xxxxxxxxxx",
      "since": "xxxxxxxxxx"
    },
    "sla": "xxxxxxxxxx"
  },
  "machines": {
    "0": {
      "juju-status": {
        "current": "xxxxxxxxxx",
        "since": "xxxxxxxxxx",
        "version": "xxxxxxxxxx"
      },
      "dns-name": "xxxxxxxxxx",
      "ip-addresses": [
        "10.0.0.229",
        "252.0.229.1"
      ],
      "instance-id": "i-xxxxxxxxxxxxxx",
      "machine-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "series": "xxxxxxxxxx",
      "network-interfaces": {
        "eth0": {
          "ip-addresses": [
            "10.0.0.229"
          ],
          "mac-address": "xxxxxxxxxx",
          "gateway": "xxxxxxxxxx",
          "is-up": true
        },
        "fan-252": {
          "ip-addresses": [
            "252.0.229.1"
          ],
          "mac-address": "xxxxxxxxxx",
          "is-up": true
        }
      },
      "constraints": "xxxxxxxxxx",
      "hardware": "xxxxxxxxxx"
    },
    "1": {
      "juju-status": {
        "current": "xxxxxxxxxx",
        "since": "xxxxxxxxxx",
        "version": "xxxxxxxxxx"
      },
      "dns-name": "xxxxxxxxxx",
      "ip-addresses": [
        "10.0.0.61",
        "252.0.61.1"
      ],
      "instance-id": "i-xxxxxxxxxxxxxx",
      "machine-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "series": "xxxxxxxxxx",
      "network-interfaces": {
        "eth0": {
          "ip-addresses": [
            "10.0.0.61"
          ],
          "mac-address": "xxxxxxxxxx",
          "gateway": "xxxxxxxxxx",
          "is-up": true
        },
        "fan-252": {
          "ip-addresses": [
            "252.0.61.1"
          ],
          "mac-address": "xxxxxxxxxx",
          "is-up": true
        }
      },
      "constraints": "xxxxxxxxxx",
      "hardware": "xxxxxxxxxx"
    },
    "10": {
      "juju-status": {
        "current": "xxxxxxxxxx",
        "since": "xxxxxxxxxx",
        "version": "xxxxxxxxxx"
      },
      "dns-name": "xxxxxxxxxx",
      "ip-addresses": [
        "10.0.0.37",
        "252.0.37.1"
      ],
      "instance-id": "i-xxxxxxxxxxxxxx",
      "machine-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "series": "xxxxxxxxxx",
      "network-interfaces": {
        "ens5": {
          "ip-addresses": [
            "10.0.0.37"
          ],
          "mac-address": "xxxxxxxxxx",
          "gateway": "xxxxxxxxxx",
          "is-up": true
        },
        "fan-252": {
          "ip-addresses": [
            "252.0.37.1"
          ],
          "mac-address": "xxxxxxxxxx",
          "is-up": true
        }
      },
      "constraints": "xxxxxxxxxx",
      "hardware": "xxxxxxxxxx"
    },
    "11": {
      "juju-status": {
        "current": "xxxxxxxxxx",
        "since": "xxxxxxxxxx",
        "version": "xxxxxxxxxx"
      },
      "dns-name": "xxxxxxxxxx",
      "ip-addresses": [
        "10.0.0.54"
      ],
      "instance-id": "i-xxxxxxxxxxxxxx",
      "machine-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "series": "xxxxxxxxxx",
      "network-interfaces": {
        "ens5": {
          "ip-addresses": [
            "10.0.0.54"
          ],
          "mac-address": "xxxxxxxxxx",
          "gateway": "xxxxxxxxxx",
          "is-up": true
        }
      },
      "constraints": "xxxxxxxxxx",
      "hardware": "xxxxxxxxxx"
    },
    "12": {
      "juju-status": {
        "current": "xxxxxxxxxx",
        "since": "xxxxxxxxxx",
        "version": "xxxxxxxxxx"
      },
      "dns-name": "xxxxxxxxxx",
      "ip-addresses": [
        "10.0.0.101"
      ],
      "instance-id": "i-xxxxxxxxxxxxxx",
      "machine-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "series": "xxxxxxxxxx",
      "network-interfaces": {
        "ens5": {
          "ip-addresses": [
            "10.0.0.101"
          ],
          "mac-address": "xxxxxxxxxx",
          "gateway": "xxxxxxxxxx",
          "is-up": true
        }
      },
      "constraints": "xxxxxxxxxx",
      "hardware": "xxxxxxxxxx"
    },
    "2": {
      "juju-status": {
        "current": "xxxxxxxxxx",
        "since": "xxxxxxxxxx",
        "version": "xxxxxxxxxx"
      },
      "dns-name": "xxxxxxxxxx",
      "ip-addresses": [
        "10.0.0.184",
        "252.0.184.1"
      ],
      "instance-id": "i-xxxxxxxxxxxxxx",
      "machine-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "series": "xxxxxxxxxx",
      "network-interfaces": {
        "eth0": {
          "ip-addresses": [
            "10.0.0.184"
          ],
          "mac-address": "xxxxxxxxxx",
          "gateway": "xxxxxxxxxx",
          "is-up": true
        },
        "fan-252": {
          "ip-addresses": [
            "252.0.184.1"
          ],
          "mac-address": "xxxxxxxxxx",
          "is-up": true
        }
      },
      "constraints": "xxxxxxxxxx",
      "hardware": "xxxxxxxxxx"
    }
  },
  "applications": {
    "easyrsa": {
      "charm": "xxxxxxxxxx",
      "series": "xxxxxxxxxx",
      "os": "xxxxxxxxxx",
      "charm-origin": "xxxxxxxxxx",
      "charm-name": "xxxxxxxxxx",
      "charm-rev": 39,
      "can-upgrade-to": "xxxxxxxxxx",
      "exposed": false,
      "application-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "relations": {
        "client": [
          "etcd",
          "kubeapi-load-balancer",
          "kubernetes-master",
          "kubernetes-worker"
        ]
      },
      "units": {
        "easyrsa/0": {
          "workload-status": {
            "current": "xxxxxxxxxx",
            "message": "xxxxxxxxxx",
            "since": "xxxxxxxxxx"
          },
          "juju-status": {
            "current": "xxxxxxxxxx",
            "since": "xxxxxxxxxx",
            "version": "xxxxxxxxxx"
          },
          "leader": true,
          "machine": "0",
          "public-address": "xxxxxxxxxx"
        }
      },
      "version": "xxxxxxxxxx"
    },
    "etcd": {
      "charm": "xxxxxxxxxx",
      "series": "xxxxxxxxxx",
      "os": "xxxxxxxxxx",
      "charm-origin": "xxxxxxxxxx",
      "charm-name": "xxxxxxxxxx",
      "charm-rev": 77,
      "can-upgrade-to": "xxxxxxxxxx",
      "exposed": false,
      "application-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "relations": {
        "certificates": [
          "easyrsa"
        ],
        "cluster": [
          "etcd"
        ],
        "db": [
          "flannel",
          "kubernetes-master"
        ]
      },
      "units": {
        "etcd/0": {
          "workload-status": {
            "current": "xxxxxxxxxx",
            "message": "xxxxxxxxxx",
            "since": "xxxxxxxxxx"
          },
          "juju-status": {
            "current": "xxxxxxxxxx",
            "since": "xxxxxxxxxx",
            "version": "xxxxxxxxxx"
          },
          "leader": true,
          "machine": "1",
          "open-ports": [
            "2379/tcp"
          ],
          "public-address": "xxxxxxxxxx"
        }
      },
      "version": "xxxxxxxxxx"
    },
    "flannel": {
      "charm": "xxxxxxxxxx",
      "series": "xxxxxxxxxx",
      "os": "xxxxxxxxxx",
      "charm-origin": "xxxxxxxxxx",
      "charm-name": "xxxxxxxxxx",
      "charm-rev": 52,
      "can-upgrade-to": "xxxxxxxxxx",
      "exposed": false,
      "application-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "relations": {
        "cni": [
          "kubernetes-master",
          "kubernetes-worker"
        ],
        "etcd": [
          "etcd"
        ]
      },
      "subordinate-to": [
        "kubernetes-master",
        "kubernetes-worker"
      ],
      "version": "xxxxxxxxxx"
    },
    "kubeapi-load-balancer": {
      "charm": "xxxxxxxxxx",
      "series": "xxxxxxxxxx",
      "os": "xxxxxxxxxx",
      "charm-origin": "xxxxxxxxxx",
      "charm-name": "xxxxxxxxxx",
      "charm-rev": 57,
      "can-upgrade-to": "xxxxxxxxxx",
      "exposed": true,
      "application-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "relations": {
        "apiserver": [
          "kubernetes-master"
        ],
        "certificates": [
          "easyrsa"
        ],
        "loadbalancer": [
          "kubernetes-master"
        ],
        "website": [
          "kubernetes-worker"
        ]
      },
      "units": {
        "kubeapi-load-balancer/0": {
          "workload-status": {
            "current": "xxxxxxxxxx",
            "message": "xxxxxxxxxx",
            "since": "xxxxxxxxxx"
          },
          "juju-status": {
            "current": "xxxxxxxxxx",
            "since": "xxxxxxxxxx",
            "version": "xxxxxxxxxx"
          },
          "leader": true,
          "machine": "2",
          "open-ports": [
            "443/tcp"
          ],
          "public-address": "xxxxxxxxxx"
        }
      },
      "version": "xxxxxxxxxx"
    },
    "kubernetes-master": {
      "charm": "xxxxxxxxxx",
      "series": "xxxxxxxxxx",
      "os": "xxxxxxxxxx",
      "charm-origin": "xxxxxxxxxx",
      "charm-name": "xxxxxxxxxx",
      "charm-rev": 102,
      "can-upgrade-to": "xxxxxxxxxx",
      "exposed": false,
      "application-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "relations": {
        "certificates": [
          "easyrsa"
        ],
        "cni": [
          "flannel"
        ],
        "etcd": [
          "etcd"
        ],
        "kube-api-endpoint": [
          "kubeapi-load-balancer"
        ],
        "kube-control": [
          "kubernetes-worker"
        ],
        "loadbalancer": [
          "kubeapi-load-balancer"
        ]
      },
      "units": {
        "kubernetes-master/3": {
          "workload-status": {
            "current": "xxxxxxxxxx",
            "message": "xxxxxxxxxx",
            "since": "xxxxxxxxxx"
          },
          "juju-status": {
            "current": "xxxxxxxxxx",
            "since": "xxxxxxxxxx",
            "version": "xxxxxxxxxx"
          },
          "leader": true,
          "machine": "12",
          "open-ports": [
            "6443/tcp"
          ],
          "public-address": "xxxxxxxxxx",
          "subordinates": {
            "flannel/9": {
              "workload-status": {
                "current": "xxxxxxxxxx",
                "message": "xxxxxxxxxx",
                "since": "xxxxxxxxxx"
              },
              "juju-status": {
                "current": "xxxxxxxxxx",
                "since": "xxxxxxxxxx",
                "version": "xxxxxxxxxx"
              },
              "upgrading-from": "xxxxxxxxxx",
              "public-address": "xxxxxxxxxx"
            }
          }
        }
      },
      "version": "xxxxxxxxxx"
    },
    "kubernetes-worker": {
      "charm": "xxxxxxxxxx",
      "series": "xxxxxxxxxx",
      "os": "xxxxxxxxxx",
      "charm-origin": "xxxxxxxxxx",
      "charm-name": "xxxxxxxxxx",
      "charm-rev": 114,
      "can-upgrade-to": "xxxxxxxxxx",
      "exposed": false,
      "application-status": {
        "current": "xxxxxxxxxx",
        "message": "xxxxxxxxxx",
        "since": "xxxxxxxxxx"
      },
      "relations": {
        "certificates": [
          "easyrsa"
        ],
        "cni": [
          "flannel"
        ],
        "kube-api-endpoint": [
          "kubeapi-load-balancer"
        ],
        "kube-control": [
          "kubernetes-master"
        ]
      },
      "units": {
        "kubernetes-worker/4": {
          "workload-status": {
            "current": "xxxxxxxxxx",
            "message": "xxxxxxxxxx",
            "since": "xxxxxxxxxx"
          },
          "juju-status": {
            "current": "xxxxxxxxxx",
            "since": "xxxxxxxxxx",
            "version": "xxxxxxxxxx"
          },
          "machine": "10",
          "open-ports": [
            "80/tcp",
            "443/tcp"
          ],
          "public-address": "xxxxxxxxxx",
          "subordinates": {
            "flannel/7": {
              "workload-status": {
                "current": "xxxxxxxxxx",
                "message": "xxxxxxxxxx",
                "since": "xxxxxxxxxx"
              },
              "juju-status": {
                "current": "xxxxxxxxxx",
                "since": "xxxxxxxxxx",
                "version": "xxxxxxxxxx"
              },
              "upgrading-from": "xxxxxxxxxx",
              "public-address": "xxxxxxxxxx"
            }
          }
        },
        "kubernetes-worker/5": {
          "workload-status": {
            "current": "xxxxxxxxxx",
            "message": "xxxxxxxxxx",
            "since": "xxxxxxxxxx"
          },
          "juju-status": {
            "current": "xxxxxxxxxx",
            "since": "xxxxxxxxxx",
            "version": "xxxxxxxxxx"
          },
          "leader": true,
          "machine": "11",
          "open-ports": [
            "80/tcp",
            "443/tcp"
          ],
          "public-address": "xxxxxxxxxx",
          "subordinates": {
            "flannel/8": {
              "workload-status": {
                "current": "xxxxxxxxxx",
                "message": "xxxxxxxxxx",
                "since": "xxxxxxxxxx"
              },
              "juju-status": {
                "current": "xxxxxxxxxx",
                "since": "xxxxxxxxxx",
                "version": "xxxxxxxxxx"
              },
              "leader": true,
              "upgrading-from": "xxxxxxxxxx",
              "public-address": "xxxxxxxxxx"
            }
          }
        }
      },
      "version": "xxxxxxxxxx"
    }
  }
}

标签: jsonjqjuju

解决方案


我不清楚“unit-name”的值应该如何得出,但以下内容应该可以帮助您:

def machine($id):
  first(.applications[]
    | (.units? // empty)
    | to_entries[]
    | select(.value.machine == $id)
    | .key ) ;

. as $in
| .machines
| to_entries[]
| .key as $key
| {($key): {
             "unit-name": (.value |.["instance-id"]),
             "machine": ($in|machine($key))
           } }

使用您的输入,这会产生一个对象流,开始:

{
  "0": {
    "unit-name": "xxxxxxxxxx",
    "machine": "easyrsa/0"
  }
}
{
  "1": {
    "unit-name": "xxxxxxxxxx",
    "machine": "etcd/0"
  }
}

外卖

该解决方案说明了三个值得注意的点:

  1. to_entries当一个人必须使用键/值组合,而感兴趣的特定键(或多个键)是(或)事​​先未知的时,这很有用;另一种方法是使用keys_unsorted;

  2. 当从不同来源收集信息时,美元变量很方便;

  3. jq 对函数定义的支持使得编写比其他方式更具可读性和可维护性的程序成为可能。


推荐阅读