首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JMESPath在查询中的使用

JMESPath在查询中的使用
EN

Stack Overflow用户
提问于 2021-07-14 13:41:48
回答 1查看 458关注 0票数 1

我使用以下JSON文件:

sample.json

代码语言:javascript
复制
{
    "lldp_output['gathered']": [
        {
            "mode": "trunk",
            "name": "GigabitEthernet0/0",
            "trunk": {
                "encapsulation": "dot1q"
            }
        },
        {
            "access": {
                "vlan": 12
            },
            "mode": "access",
            "name": "GigabitEthernet0/1"
        },
        {
            "name": "GigabitEthernet0/2"
        }
    ]
}

还有剧本:

代码语言:javascript
复制
---
- hosts: localhost
  gather_facts: no
  vars:
    tmpdata: "{{ lookup('file','sample.json') | from_json }}"

  tasks:
    - name: Take 4
      debug:
        msg: "{{ tmpdata | community.general.json_query(lldp_output['gathered']) }}"

我得到以下错误:

代码语言:javascript
复制
TASK [Take 4] ********************************************************************************************
task path: /root/scripts/atest.yml:18
fatal: [localhost]: FAILED! => {
    "msg": "Error in jmespath.search in json_query filter plugin:\n'lldp_output' is undefined"
}

如何查询显示的JSON,以便获得所有具有mode: trunk的端口的列表

当我在一本剧本里奔跑时:

代码语言:javascript
复制
---
- name: Find trunk ports
  hosts: ios

  tasks:
    - name: Collect interface output
      cisco.ios.ios_l2_interfaces:
        config:
        state: gathered
      register:
         "intf_output"

    - debug:
        var=intf_output

    - name: Take 4
      debug:
        msg: "{{ intf_output | json_query(query) }}"
      vars:
        query: >-
          "lldp_output['gathered']"[?mode=='trunk']

返回的结构如下:

代码语言:javascript
复制
{
    "intf_output": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python3"
        },
        "changed": false,
        "failed": false,
        "gathered": [
            {
                "name": "GigabitEthernet0/0"
            },
            {
                "mode": "trunk",
                "name": "GigabitEthernet0/1",
                "trunk": {
                    "allowed_vlans": [
                        "10",
                        "20",
                        "30",
                        "100"
                    ],
                    "encapsulation": "dot1q"
                }
            },
            {
                "mode": "trunk",
                "name": "GigabitEthernet0/2",
                "trunk": {
                    "allowed_vlans": [
                        "10",
                        "20",
                        "30",
                        "100"
                    ],
                    "encapsulation": "dot1q"
                }
            },
            {
                "mode": "trunk",
                "name": "GigabitEthernet0/3",
                "trunk": {
                    "allowed_vlans": [
                        "10",
                        "20",
                        "30",
                        "100"
                    ],
                    "encapsulation": "dot1q"
                }
            },
            {
                "mode": "trunk",
                "name": "GigabitEthernet1/0",
                "trunk": {
                    "allowed_vlans": [
                        "10",
                        "20",
                        "30",
                        "100"
                    ],
                    "encapsulation": "dot1q"
                }
            },
            {
                "mode": "trunk",
                "name": "GigabitEthernet1/1",
                "trunk": {
                    "allowed_vlans": [
                        "10",
                        "20",
                        "30",
                        "100"
                    ],
                    "encapsulation": "dot1q"
                }
            },
            {
                "name": "GigabitEthernet1/2"
            },
            {
                "name": "GigabitEthernet1/3"
            },
            {
                "name": "GigabitEthernet2/0"
            },
            {
                "name": "GigabitEthernet2/1"
            },
            {
                "name": "GigabitEthernet2/2"
            },
            {
                "name": "GigabitEthernet2/3"
            },
            {
                "name": "GigabitEthernet3/0"
            },
            {
                "name": "GigabitEthernet3/1"
            },
            {
                "name": "GigabitEthernet3/2"
            },
            {
                "name": "GigabitEthernet3/3"
            }
        ]
    }
}

对于每一位主人,我都会与剧本相冲突。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-14 13:55:30

json_query的参数必须是字符串。因为您没有引用您的论点,Ansible正在寻找一个名为lldp_output的变量。但是您有附加的问题,因为您试图访问一个名为lldp_output['gathered']的键,但是[在JSON (和JMESPath查询)中是一个语法上重要的字符,所以也需要转义。

为了避免所有类型的引号转义扭曲,我们可以将查询本身放入一个变量中,这样我们就可以:

代码语言:javascript
复制
- hosts: localhost
  vars:
    tmpdata: "{{ lookup('file','sample.json') | from_json }}"

  tasks:
    - name: Take 4
      debug:
        msg: "{{ tmpdata | json_query(query) }}"
      vars:
        query: >-
          "lldp_output['gathered']"

注意,我们使用的是>-块引号操作符,这意味着query的值是文字字符串"lldp_output['gathered']",包括外部引号。

该剧本输出如下:

代码语言:javascript
复制
TASK [Take 4] *********************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "mode": "trunk",
            "name": "GigabitEthernet0/0",
            "trunk": {
                "encapsulation": "dot1q"
            }
        },
        {
            "access": {
                "vlan": 12
            },
            "mode": "access",
            "name": "GigabitEthernet0/1"
        },
        {
            "name": "GigabitEthernet0/2"
        }
    ]
}

要获得那些mode等于trunk的系统,只需将该条件添加到查询中:

代码语言:javascript
复制
- hosts: localhost
  vars:
    tmpdata: "{{ lookup('file','sample.json') | from_json }}"

  tasks:
    - name: Take 4
      debug:
        msg: "{{ tmpdata | json_query(query) }}"
      vars:
        query: >-
          "lldp_output['gathered']"[?mode=='trunk']

这将产生以下结果:

代码语言:javascript
复制
TASK [Take 4] *********************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "mode": "trunk",
            "name": "GigabitEthernet0/0",
            "trunk": {
                "encapsulation": "dot1q"
            }
        }
    ]
}

更新

考虑到您在更新的问题中显示的数据,情况要简单得多,因为您没有原始问题中的奇怪引用。使用如图所示的intf_output定义,您可以编写:

代码语言:javascript
复制
  tasks:
    - name: Take 4
      debug:
        msg: "{{ intf_output | json_query(query) }}"
      vars:
        query: >-
          gathered[?mode=='trunk']
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68379233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档