使用JMESPath,如何过滤至少定义了一个标签的Consul服务?

时间:2018-05-29 15:22:03

标签: json ansible jmespath

我有一份在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 :(得分:1)

我认为JMESPath不可能这样做(至少不是一种简单的方法)。 the other answer

另一方面,用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 }}"

答案 1 :(得分:1)

在Ansible 2.5及更高版本中:

可以通过将JMESPath查询与Ansible dict2items过滤器和Jinja2 dict函数结合使用:

- debug:
    msg: "{{ dict(json | dict2items | json_query('@[?value].[key, value]')) }}"