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

Using JMESPath, how to filter Consul services which have at least one label defined?

我在我的 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] 过滤器,但它没有显示任何值。

我应该更改什么以获得非空结果?

我认为 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 }}"

在 Ansible 2.5 及更高版本中:

通过将 JMESPath 查询与 Ansible dict2items 过滤器和 Jinja2 dict 函数相结合是可能的:

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