'JMESPath - how to prune a tree

I have a JSON data structure (actually, YAML) and want to reformat the stucture, but can't figure out how to get this to work correctly. This will be used within a jinja2 template in Ansible. The tool I have tried to use is the json_query filter, which uses JMESPath.

Input:

"users": {
  "Administrators": [
    "user1",
    "user2": {
       "ssh_keys": "...."
    },
    "user3"
  ],
  "Users": [
     "user4"
  ]
}

I would like to reform this JSON into this (stripping the ssh_key part in the process)

"Administrators": [
  "user1",
  "user2",
  "user3"
],
"Users": [
  "user4"
]

How can I do that in jinja2? I have found the json_query filter that seems like the right tool for the job, but haven't found a query that accomplishes what I am looking for.



Solution 1:[1]

Firstlly i would recommand reformatting the json if you can. A good format would make this extremely easy, for instance:

"users": {
  "Administrators": [
    {"name": "user1, "ssh_keys": None},
    {"name": "user2, "ssh_keys": "...."},
    {"name": "user3, "ssh_keys": None},
  ],
  "Users": [
     "user4"
  ]
}

If your unable to do so, try this (this refers to the Administrators but applies for whatever):

 - set_fact:
      admins: "{{ (users | json_query(item) | default([])) | union(admins | default([])) }}"
   with_items:
      - "Administrators[?type(@) == 'object'][keys(@)][][]"
      - "Administrators[?type(@)=='string']"

This would create a admins array with only usernames from your users json. Than you can set another fact that contains admins and users

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nadavbrkt