Используя JMESPath, как фильтровать сервисы Consul, для которых определена хотя бы одна метка? - PullRequest
0 голосов
/ 29 мая 2018

У меня есть список услуг, определенный в моем каталоге Consul, и я хотел бы удалить те, для которых не определена метка.

Этот список услуг выглядит следующим образом:

{
    "json": {
        "consul": [],
        "consul-exporter": [],
        "consul-8600": [
            "traefik.enable=false",
            "udp"
        ],
        "snmp-gateway": [],
    }
}

Я бы хотел отфильтровать его с помощью JMESPath, чтобы результат содержал только

{
    "json": {
        "consul-8600": [
            "traefik.enable=false",
            "udp"
        ],
    }
}

Но синтаксис фильтрации JMESPath остается для меня неясным.

Думаю, мне следует использовать length функция для получения размера массива атрибутов, но как?

Пока у меня есть фильтр json.[length(*)>0], но он не показывает значения.

Что я должен изменить, чтобы иметьненулевой результат?

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

В Ansible 2.5 и более поздних версиях:

Это возможно путем объединения запроса JMESPath с фильтром Ansible dict2items и функцией Jinja2 dict:

- debug:
    msg: "{{ dict(json | dict2items | json_query('@[?value].[key, value]')) }}"
0 голосов
/ 29 мая 2018

Я не думаю, что это возможно с JMESPath (по крайней мере, не простым способом). См. другой ответ .

С другой стороны, тривиально написать свой собственный фильтр на Python (filter_plugins/myfilters.py):

class FilterModule(object):
    def filters(self):
        return {
            'remove_keys_with_empty_values': self.remove_keys_with_empty_values
        }

    def remove_keys_with_empty_values(self, mydict):
        newdict = dict((key, value) for key, value in mydict.iteritems() if value)
        return newdict

и использовать его в пьесе:

- debug:
    msg: "{{ json | remove_keys_with_empty_values }}"
...