Search code examples
dictionaryansiblejinja2jmespath

How to filter dictionaries in Jinja?


I have a dictionary of packages with package-name being the key and a dictionary of some details being the value:

{
        "php7.1-readline": {
            "latest": "7.1.9-1+ubuntu14.04.1+deb.sury.org+1", 
            "origins": [
                "ppa.launchpad.net"
            ], 
            "version": "7.1.6-2~ubuntu14.04.1+deb.sury.org+1", 
            "www": "http://www.php.net/"
        }, 
        "php7.1-xml": {
            "latest": "7.1.9-1+ubuntu14.04.1+deb.sury.org+1", 
            "origins": [
                "ppa.launchpad.net"
            ], 
            "version": "7.1.6-2~ubuntu14.04.1+deb.sury.org+1", 
            "www": "http://www.php.net/"
        }, 
        "plymouth": {
            "version": "0.8.8-0ubuntu17.1"
        },
    ....
}

I'd like to reduce the above to a dictionary with only the packages, that have the latest-attribute in their values.

It would seem like json_query is the filter to use, but I can't figure out the syntax. The examples out there all seem to operate on lists of dictionaries, not dictionaries of same...

For example, if I "pipe" the above dictionary into json_query('*.latest'), I get the list of the actual latest versions:

[
  "7.1.9-1+ubuntu14.04.1+deb.sury.org+1",
  "7.1.9-1+ubuntu14.04.1+deb.sury.org+1",
  "7.1.6-2~ubuntu14.04.1+deb.sury.org+1"
]

How can I get the entire dictionary-elements instead?

Any hope?


Solution

  • With dict2items filter added in December 2017, it is possible using native functionality:

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

    The result:

    "msg": {
        "php7.1-readline": "7.1.9-1+ubuntu14.04.1+deb.sury.org+1",
        "php7.1-xml": "7.1.9-1+ubuntu14.04.1+deb.sury.org+1"
    }