Запрос JSON для поиска новейшего снимка для хоста и устройства?

Я пытаюсь найти новейший снимок устройства и хоста в AWS с помощью команды aws ec2. Я получаю следующий вывод от aws ec2 describe-snapshots.

Как видите, у меня может быть несколько снимков для одного и того же хоста (см. Теги с ключами имя хоста и имя устройства) и устройство. Время начала отличается.

{
"Snapshots": [
    {
        "Description": "My desc.",
        "Encrypted": false,
        "VolumeId": "vol-aaa",
        "State": "completed",
        "VolumeSize": 8,
        "StartTime": "2018-02-02T19:27:56.000Z",
        "Progress": "100%",
        "OwnerId": "5674567",
        "SnapshotId": "snap-xxx"
    },  
    {
        "Description": "host1.domain.com - sdc",
        "Tags": [
            {
                "Value": "SNAP1",
                "Key": "Name"
            },
            {
                "Value": "sdc",
                "Key": "devicename"
            },
            {
                "Value": "host1.domain.com",
                "Key": "hostname"
            }
        ],
        "Encrypted": false,
        "VolumeId": "vol-xxx",
        "State": "completed",
        "VolumeSize": 140,
        "StartTime": "2018-09-21T08:39:58.000Z",
        "Progress": "100%",
        "OwnerId": "345634563456",
        "SnapshotId": "snap-xxx"
    },  
    {
        "Description": "host1.domain.com - sdc",
        "Tags": [
            {
                "Value": "SNAP2",
                "Key": "Name"
            },
            {
                "Value": "sdc",
                "Key": "devicename"
            },
            {
                "Value": "host1.domain.com",
                "Key": "hostname"
            }
        ],
        "Encrypted": false,
        "VolumeId": "vol-xxx",
        "State": "completed",
        "VolumeSize": 140,
        "StartTime": "2018-09-22T08:39:58.000Z",
        "Progress": "100%",
        "OwnerId": "345634563456",
        "SnapshotId": "snap-xxx"
    }
}

Как мне запросить этот JSON в Ansible, чтобы получить новейший снимок для имени хоста и устройства? Я не часто это делаю, поэтому борюсь с синтаксисом запроса.

Пока имею следующее.

 - shell: "aws ec2 describe-snapshots"
   register: snap
   delegate_to: localhost

 - debug:
     msg: "{{ snap.stdout | from_json | json_query(query) }}"
   vars:
     query: "Snapshots[].Tags[?Key=='hostname'].Value"

Но как выбрать все элементы моментального снимка, где Tags.Value равно определенному значению, где Key — это имя хоста? И как мне тогда выбрать самое новое из списка, который я получаю?


person Tony Stark    schedule 21.09.2018    source источник
comment
Для справки в будущем: jmespath намного лучший тег SO, чем более общий json-query один, так как этот синтаксис имеет конкретное имя, где другие люди могли бы взвесить быстрее (или даже с более точным ответом, насколько я знаю)   -  person mdaniel    schedule 22.09.2018


Ответы (1)


Согласно тонкому руководству, JMESPath поддерживает выражения спецификаторов вложенных скобок:

  vars:
    snap: |
      {
        "Snapshots": [
          {"Id": "aaa", "Tags": [{"Key": "hostname", "Value": "alpha"}]},
          {"Id": "bbb", "Tags": [{"Key": "hostname", "Value": "beta"}]}
        ]
      }
    jq: "Snapshots[? Tags[? Key=='hostname' && Value=='alpha']].Id"
  tasks:
  - debug:
      msg: "{{ snap | from_json | json_query(jq) }}"

Что касается части «для определенного хоста», эта vars: query: подлежит интерполяции jinja2, как и любая другая невозможная строка, таким образом:

vars:
  query: ... [? Value=='{{ the_hostname }}' ] ...

Просто будьте осторожны, чтобы убедиться, что значение правильно экранировано — что, скорее всего, не будет проблемой с именем хоста, но я имею в виду в целом.

Затем, что касается части «новейшее из списка», ISO8601 имеет очень приятное дополнительное преимущество сортировки по лексике, поэтому:

  vars:
    jq: "Snapshots[? Tags[? Key=='hostname' && Value=='alpha']]"
  tasks:
  - debug:
      msg: "{{ snap | from_json | json_query(jq) | sort(attribute='StartTime', reverse=True) }}"
person mdaniel    schedule 22.09.2018
comment
После сортировки мне пришлось бы использовать ключевое слово first для самых новых, верно? - person Tony Stark; 22.09.2018
comment
Да (ошибаюсь, первый фильтр). Вы также можете использовать jmespath для сортировки и реверсирования, а затем использовать [0] для выбора первого элемента: jmespath.org /спецификация.html#reverse - person james.haggerty; 23.09.2018