Использование ключей из документа json src в хэше множественного выбора с Jmespath
У меня есть исходный документ JSON, который выглядит следующим образом:
# Source json
{
"nics": {
"vlan_internal": {
"mac": "aa:aa:aa:aa:aa:aa"
},
"vlan_external": {
"mac": "aa:aa:aa:aa:aa:bb"
}
}
}
Использование ansible json_query
Фильтр (который использует jmespath), я хочу манипулировать json выше, чтобы выходной документ json выглядел так:
# Desired output json
{
"vlan_internal": "aa:aa:aa:aa:aa:aa",
"vlan_external": "aa:aa:aa:aa:aa:ab"
}
Кажется, что я должен использовать хеш-код некоторого вида, но я не могу найти хороший способ получить имена vlan (которые являются ключами хеш-функции в исходном json-документе, а не значениями хеш-функции) в выходной json-документ.
Я не буду знать имена Vlans раньше времени, поэтому я не могу жестко закодировать vlan_internal
или же vlan_external
в выражение jmespath.
Самое близкое, что я пришел, это выражение jmespath:
nics.{ vlans: keys(@), macs: *.mac }
Что приводит к выходному документу json, который был почти полезен:
{
"vlans": [
"vlan_internal",
"vlan_external"
],
"macs": [
"aa:aa:aa:aa:aa:aa",
"aa:aa:aa:aa:aa:bb"
]
}
Это сработало бы для меня, если бы было гарантировано, что порядок списка имен vlan и порядок списка mac адресов совпадают с порядком в исходном документе json. Но спецификация jmespath ясно показывает, что keys()
Функция не обязана возвращать результаты в каком-либо определенном порядке. Поскольку мне нужно связать имя VLAN с правильным MAC-адресом, это не будет работать для меня.
Кто-нибудь знает способ сделать это с помощью jmespath?
1 ответ
Только с JMESPath вы можете использовать этот запрос:
@.nics | {vlan_internal: @.vlan_internal | values(@)[0], vlan_external: @.vlan_external | values(@)[0]}
с этим вашим исходным JSON вы получите:
{
"vlan_internal": "aa:aa:aa:aa:aa:aa",
"vlan_external": "aa:aa:aa:aa:aa:bb"
}
Прежде всего, я не уверен, что вы должны пройти через все эти проблемы. Если вы не знаете, какие ключи вы собираетесь получить, то вы, вероятно, будете перебирать весь свой JSON, и, таким образом, вы знаете свой item
ключ.
Тем не менее, если вы просто хотите экспортировать новый json, я не смог найти способ использовать собственный JMESPath для этого. вместо этого я использовал ответ with_dict
цикл как следует:
- name: Create new nic_dict json
set_fact:
nic_dict: "{{ {item.key: item.value.mac} | combine(nic_dict | default({})) }}"
with_dict: "{{ nics }}"
Теперь вы можете использовать nic_dict
это выглядит так:
"nic_dict": {
"vlan_external": "aa:aa:aa:aa:aa:bb",
"vlan_internal": "aa:aa:aa:aa:aa:aa"
}