Ansible 中的 JMESPath 查询

JMESPath Query in Ansible


--- 编辑 ---

部分解决方案:搞乱了 JMESPath 语法,并且能够使用以下方法成功地匹配第一个测试用例(没有可选变量):

jmesquery: "{{ datacenter }}{{ subcategory }}.{{ refine_hosts }}.[*][].[*][][]"

我正在编写一个 Ansible Playbook,它从网络服务器获取主机列表,解析 JSON 列表,并在用户将 playbook 作为 Jenkin 的作业部署时找到与用户输入匹配的主机名API.

我遇到的问题是无法成功查询JSON主机列表。目前,我只尝试 运行 以下测试用例:

datacenter: a
subcategory: bc
refine_hosts: QA

但是,此剧本的最终版本应该能够接受 datacentersubcategoryrefine_hosts 的值,以及可选的输入值 host_type .包含可选输入值的示例测试用例如下:

datacenter: a
subcategory: bc
refine_hosts: QA
host_type: WEBSITE

在我的剧本中,我在以下任务中使用 JMESPath:

- name: Build HOSTS list
  set_fact:
    hosts_list: "{{ jsondata | json_query(jmesquery) }}"
  vars:
    jmesquery: '%%datacenter%%-%%subcategory%%.%%refine_hosts%%.[*][*][][]'

JSON 主机列表的结构如下(我无法编辑主机列表的结构,但它将始终遵循以下结构):

{
   "a-bc":{
      "all":{
         "webServer":[

         ],
         "archive":[
            "someHostAlias-123.privateDomain.com"
         ],
         "central":[
            "someHostAlias-456.privateDomain.com"
         ]
      },
      "QA":{
         "xyz":{
            "INBOUND_HTTP":[
               "someHostAlias-789.privateDomain.com"
            ],
            "WEBSITE":[
               "someHostAlias-1011.privateDomain.com"
            ]
         }
      }
   }
}

我一直在使用以下网站来解决这个问题:

如果查询看起来很明显,我深表歉意,这是我第一次尝试使用 Ansible Playbook。非常感谢所有 help/feedback。

您的查询问题之一是您混淆了 [*]list projection — that selects all the elements of a list with .* — an object projection — 选择字典的所有属性。

因此,JMESPath 中的一种解决方案是:

jmesquery: >-
  "{{ datacenter }}-{{ subcategory }}".{{ refine_hosts }}.*.
  {{ host_type if host_type | default('') != '' else '*' }}[] | []

鉴于剧本:

- hosts: localhost
  gather_facts: no

  tasks:
    - debug:
        msg: "{{ jsondata | json_query(jmesquery) }}"
      loop: "{{ fake_user_input }}"
      loop_control:
        label: "{{ jmesquery }}"
      vars:
        jmesquery: >-
          "{{ datacenter }}-{{ subcategory }}".{{ refine_hosts }}.*.
          {{ host_type if host_type | default('') != '' else '*' }}[] | []
        
        datacenter: "{{ item.datacenter }}"
        subcategory: "{{ item.subcategory }}"
        refine_hosts: "{{ item.refine_hosts }}"
        host_type: "{{ item.host_type | default('') }}"

        fake_user_input:
          - datacenter: a
            subcategory: bc
            refine_hosts: QA
            host_type: WEBSITE
          - datacenter: a
            subcategory: bc
            refine_hosts: QA

        jsondata:
          a-bc:
            all:
              webServer: []
              archive:
              - someHostAlias-123.privateDomain.com
              central:
              - someHostAlias-456.privateDomain.com
            QA:
              xyz:
                INBOUND_HTTP:
                - someHostAlias-789.privateDomain.com
                WEBSITE:
                - someHostAlias-1011.privateDomain.com

这产生:

ok: [localhost] => (item="a-bc".QA.*. WEBSITE[] | []) => 
  msg:
  - someHostAlias-1011.privateDomain.com
ok: [localhost] => (item="a-bc".QA.*. *[] | []) => 
  msg:
  - someHostAlias-789.privateDomain.com
  - someHostAlias-1011.privateDomain.com