Ansible json_query() 以变量为键

Ansible json_query() with variable as key

我有以下 JSON 输入:

{
  "a goo": {
      "link": "google.com"
  }, 
  "b ms": {
      "link": "microsoft.com"
  }, 
  "c amz": {
    "link": "amazon.com"
  }
}

我想根据变量 {{ target }} 获取 link 字符串 ("google.com"…) {{ target }} 变量的内容将包含 "a goo"、"b ms"、"c amz" 字符串之一。

类似于:

- name:
  set_fact:
    target: "c amz"
- debug:
    msg: "{{ input.json | json_query('{{ target }}'.link) }}"

应该显示:

   msg: "amazon.com"

谢谢你的建议。

+FE

你的表达有几个问题:

  1. 在 jmespath 中,标识符用双引号引起来。单引号用于字符串。参见 jmespath specification
  2. 您传递给 json_query 的整个 jmespath 表达式应该是一个 yaml/jinja2 字符串。如您所写,.link 将被解释为 jinja2/yaml var 标识符。
  3. 您不得重叠 jinja2 模板标记 ({{ X }})。此外,在您当前的表达式中, '{{ target }}' 按字面解释为字符串而不是要扩展为其值的变量。

以下剧本演示了一种修复当前剧本并满足您的要求的方法:

---
 - hosts: localhost
   gather_facts: false

   vars:
     input:
       json: { 
         "a goo": { 
           "link": "google.com"
         },
         "b ms": { 
           "link": "microsoft.com"
         },
         "c amz": { 
           "link": "amazon.com"
         } 
       } 

   tasks:
     - name: Debug the var we want to show
       vars:
         target: "c amz"
       debug:
         msg: "{{ input.json | json_query('\"' + target + '\".link') }}"

给出:

$ ansible-playbook play.yml 

PLAY [localhost] ***************************************************************************************************************************************************************

TASK [Debug the var we want to show] *******************************************************************************************************************************************
ok: [localhost] => {
    "msg": "amazon.com"
}

PLAY RECAP *********************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0