Using keys from json src doc in multi-element hash with Jmespath

I have a source json document that looks like this:

# Source json
{
  "nics": {
    "vlan_internal": {
      "mac": "aa:aa:aa:aa:aa:aa"
    },
    "vlan_external": {
      "mac": "aa:aa:aa:aa:aa:bb"
    }
  }
}

      

Using an ansible filter json_query

(which uses jmespath), I want to manipulate the json above so that the output json document looks like this:

# Desired output json
{
  "vlan_internal": "aa:aa:aa:aa:aa:aa",
  "vlan_external": "aa:aa:aa:aa:aa:ab"
}

      

It seems like I should be using a multi-element hash of some kind, but I can't seem to find a good way to get the vlan names (which are hash keys in the original json doc, not hash values) in the output json doc.

I won't know the vlans names ahead of time, so I can't hardcode vlan_internal

or vlan_external

into the jmespath expression.

The closest I came up with this jmespath expression:

nics.{ vlans: keys(@), macs: *.mac }

      

This results in an output json document that was almost useful:

{
  "vlans": [
    "vlan_internal",
    "vlan_external"
  ],
  "macs": [
    "aa:aa:aa:aa:aa:aa",
    "aa:aa:aa:aa:aa:bb"
  ]
}

      

It would work for me if it was guaranteed that the order of the list of vlan names and the order of the mac address list are the same as the order of the original json document. But the jmespath spec makes it very clear that a function keys()

doesn't have to return results in any particular order. Since I need to concatenate the vlan name with the correct mac address, this doesn't work for me.

Does anyone know how to do this using jmespath?

+3


source to share


1 answer


First of all, I'm not sure if you have to go through all of this. If in doubt that you need the witch keys, then you can use your key for your json and you know your key item

.

However, if you just want to export new json, I couldn't find a way to use the native JMESPath to do this. instead, I used a closed loop with_dict

like this:

     - name: Create new nic_dict json
       set_fact:
          nic_dict: "{{ {item.key: item.value.mac} | combine(nic_dict | default({})) }}"
       with_dict: "{{ nics }}"

      



Now you can use nic_dict

which looks like this:

"nic_dict": {
    "vlan_external": "aa:aa:aa:aa:aa:bb",
    "vlan_internal": "aa:aa:aa:aa:aa:aa"
}

      

0


source







All Articles