Reputation: 185
Here is my playbook:
- hosts: localhost
vars:
{
"result": [
{
"_ref": "vlan/ZG5zLnZsYW4kLmNvbS5pbmZvYmxveC5kbnMudmxhbl92aWV3JElORlJBTEFCLjEuNDA5NC4xMQ:LAB1/test1/11",
"id": 11,
"name": "test1",
"parent": {
"_ref": "vlanview/ZG5zLnZsYW5fdmlldyRJTkZSQUxBQi4xLjQwOTQ:LAB1/1/4094"
}
},
{
"_ref": "vlan/ZG5zLnZsYW4kLmNvbS5pbmZvYmxveC5kbnMudmxhbl92aWV3JFNDTEFCLU9PQi4xLjQwOTQuMTE:LAB2/test1/11",
"id": 11,
"name": "test1,
"parent": {
"_ref": "vlanview/ZG5zLnZsYW5fdmlldyRTQ0xBQi1PT0IuMS40MDk0:LAB2/1/4094"
}
}
]
}
tasks:
- set_fact:
var1: "{{result|json_query(jquery)}}"
vars:
jquery: "[].{vlan_view: _ref|regex_search('(?<=:)[^/]*'), vlan_id: id, vlan_name: name}"
- debug: msg={{var1}}
Which errors with:
fatal: [localhost]: FAILED! => {"msg": "JMESPathError in json_query filter plugin:\nUnknown function: regex_search()"}
My desired output
[
{
"vlan_view": LAB1,
"vlan_id": 11,
"vlan_name": "test1"
},
{
"vlan_id": 11,
"vlan_name": "test1",
"vlan_view": "LAB2"
}
]
Upvotes: 2
Views: 1154
Reputation: 68034
Get the attributes vlan_view
vlan_view: "{{ result|map(attribute='_ref')|
map('split', ':')|map('last')|
map('split', '/')|map('first')|
map('community.general.dict_kv', 'vlan_view')|
list }}"
gives
vlan_view:
- vlan_view: LAB1
- vlan_view: LAB2
Then use json_query to get the other attributes and combine the dictionaries
var1: "{{ result|json_query('[].{vlan_id: id, vlan_name: name}')|
zip(vlan_view)|map('combine')|list }}"
gives the expected result
var1:
- vlan_id: 11
vlan_name: test1
vlan_view: LAB1
- vlan_id: 11
vlan_name: test1
vlan_view: LAB2
Example of a complete playbook (simplified for testing)
- hosts: localhost
vars:
result:
- _ref: vlan/ZG5z...4xMQ:LAB1/test1/11
id: 11
name: test1
parent:
_ref: vlanview/ZG5zL...wOTQ:LAB1/1/4094
- _ref: vlan/ZG5zL...uMTE:LAB2/test1/11
id: 11
name: test1
parent:
_ref: vlanview/ZG5zL...MDk0:LAB2/1/4094
vlan_view: "{{ result|map(attribute='_ref')|
map('split', ':')|map('last')|
map('split', '/')|map('first')|
map('community.general.dict_kv', 'vlan_view')|
list }}"
var1: "{{ result|json_query('[].{vlan_id: id, vlan_name: name}')|
zip(vlan_view)|map('combine')|list }}"
tasks:
- debug:
var: vlan_view
- debug:
var: var1
Upvotes: 1
Reputation: 39129
You cannot do regex operation in JMESPath, as per this issue on their tracker.
And you surely cannot use a Jinja filter as a JMESPath function, as the error is pointing out.
So, you will have to achieve this with Jinja filters and Ansible alone.
And with a loop, it is definitely possible to create a list corresponding to your desired output:
- set_fact:
var1: "{{ var1 | default([]) + [_vlan] }}"
loop: "{{ result }}"
loop_control:
label: "{{ item.id }}"
vars:
_vlan:
vlan_id: "{{ item.name }}"
vlan_name: "{{ item.id }}"
vlan_view: >-
{{
item.parent._ref
| regex_search(':(.*?)\/', '\1')
| first
}}
Given the two tasks:
- set_fact:
var1: "{{ var1 | default([]) + [_vlan] }}"
loop: "{{ result }}"
loop_control:
label: "{{ item.id }}"
vars:
_vlan:
vlan_id: "{{ item.name }}"
vlan_name: "{{ item.id }}"
vlan_view: >-
{{
item.parent._ref
| regex_search(':(.*?)\/', '\1')
| first
}}
- debug:
var: var1
This will yield:
TASK [set_fact] ***************************************************************
ok: [localhost] => (item=11)
ok: [localhost] => (item=11)
TASK [debug] ******************************************************************
ok: [localhost] =>
var1:
- vlan_id: test1
vlan_name: '11'
vlan_view: LAB1
- vlan_id: test1
vlan_name: '11'
vlan_view: LAB2
Upvotes: 1