Статус juju и jq фильтрация смешанных материалов из нескольких объектов в статусе JSON

тл;др

Я пытаюсь получить JSON-представление вывода juju status, которое объективирует машину, идентификатор экземпляра и единицу, чтобы 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 status JSON:

{
  "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"
    }
  }
}

person Jim    schedule 27.04.2018    source источник
comment
Спасибо @peak, я почистил его и исправил конечный результат. Дайте мне знать, если что-то еще нуждается в полировке.   -  person Jim    schedule 27.04.2018
comment
Откуда взялся i-xxxxxxxxxxxxxx? Не могли бы вы сделать так, чтобы значения instance-id отличались, чтобы было ясно, откуда они берутся? Кроме того, машина 10 связана с kubernetes-worker/4 в исходном коде, но с etcd/0 в ожидаемом выводе. Если бы вы могли сделать весь пример минимальным, это могло бы помочь всем.   -  person peak    schedule 28.04.2018
comment
@peak, обеспечивающий минимальный ввод, затруднен при условии, что он динамичен, и я почти ничего не знаю об этом итеративно. Удаление всего, кроме того, что я ищу, может привести к ложно представленному набору данных с учетом будущих итераций. Тем не менее, я перепроверил исходные данные (исправил). Меня не беспокоят фактические данные (т.е. rvals) так сильно, как получение правильных ключей объектов, которые я ищу от родительских объектов .machines и .applications для LHS. Другими словами, если я смогу получить правильные ключи, данные будут правильными. Я недостаточно хорошо понимаю jq, чтобы сделать это.   -  person Jim    schedule 29.04.2018


Ответы (1)


Мне неясно, как именно должно быть получено значение «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 для определения функций позволяет писать программы, которые легче читать и поддерживать, чем они были бы в противном случае.

person peak    schedule 29.04.2018
comment
Работает как чемпион! Так вот, я бы никогда не смог представить это как решение. Я собираюсь изучить этот ответ и учиться. Спасибо @peak. - person Jim; 29.04.2018