Search code examples
ansiblejmespathjson-query

JMESPathError in json_query filter: Unknown function: regex_search()


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"
    }
]

Solution

  • 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