在多个字典列表中搜索特定值,然后提取同一列表中的另一个值?

huangapple go评论75阅读模式
英文:

How to search for a specific value in a multiple dictionary list, then extract another value from the same list?

问题

以下是您要翻译的代码部分:

After debugging results of a task, I want to be able to get the corresponding uuid just by entering a specific snapshot_name.

This is the output of the "result" variable:
【代码部分省略】

This is my playbook:
【代码部分省略】

Snapname is a variable as I want to be able to be able to enter different snapname values in ansible controller itself, so it is meant to be a changeable variable. Then let ansible search for the snapname value and get its corresponding uuid.

I got this error for the last task in my playbook:
【代码部分省略】

How do I write my playbook in a way that when the value of snapname == "vm snapshot", it will search for "vm snapshot" in "snapshot_name" in all the lists, then get the corresponding uuid?

For example, search which list has "vm_snapshot", then output the uuid, "6f1kc72a-8916-4edd-9639-c2823b57a1cb".

请注意,这是代码的一部分,我已经帮您提取出了要翻译的部分。如果您需要任何其他翻译或有其他问题,请随时告诉我。

英文:

After debugging results of a task, I want to be able to get the corresponding uuid just by entering a specific snapshot_name.

This is the output of the "result" variable:

ok: [localhost] => {
    "msg": {
        "date": "Mon, 22 May 2023 03:39:34 GMT",
        "elapsed": 0,
        "expires": "0",
        "failed": false,
        "json": {
            "entities": [
                {
                    "created_time": 1684493611741165,
                    "deleted": false,
                    "logical_timestamp": 1,
                    "snapshot_name": "Snapshot 1",
                    "uuid": "ffa972f7-25b7-4d0c-8e92-2e7afef863c4"
                },
                {
                    "created_time": 1684502215147173,
                    "deleted": false,
                    "logical_timestamp": 1,
                    "snapshot_name": "vm snapshot",
                    "uuid": "6f1kc72a-8916-4edd-9639-c2823b57a1cb"
                },
                {
                    "created_time": 1684725225721634,
                    "deleted": false,
                    "logical_timestamp": 1,
                    "snapshot_name": "new",
                    "uuid": "ad872bde-3a94-411f-8f89-5f5ad55e4ffa"
                }
            ],
            "metadata": {
                "grand_total_entities": 3,
                "total_entities": 3
            }
        },
        "msg": "OK (unknown bytes)",
        "pragma": "no-cache",
        "redirected": false,
        "server": "envoy"
    }
}

<br />

This is my playbook:

- name: debug
  debug:
    msg: &quot;{{ result }}&quot;

- name: Snapshot name to look for
  set_fact:
    snapname: &quot;{{ snapname }}&quot;

- name: Getting the uuid of the above snapname
  debug:
    msg: &quot;{{ result.json.entities[*].uuid }}&quot;
  when: result.json.entities[*].snapshot_name == snapname 

Snapname is a variable as I want to be able to be able to enter different snapname values in ansible controller itself, so it is meant to be a changeable variable. Then let ansible search for the snapname value and get its corresponding uuid.

I got this error for the last task in my playbook:

fatal: [localhost]: FAILED! =&gt; {
    &quot;msg&quot;: &quot;The conditional check &#39;result.json.entities[*].snapshot_name == snapname&#39; failed. The error was: template error while templating string: unexpected &#39;*&#39;. String: {% if result.json.entities[*].snapshot_name == snapname %} True {% else %} False {% endif %}\n\nThe error appears to be in &#39;/var/lib/awx/projects/Nutanix/roles/vm_restore/tasks/vm_restore.yml&#39;: line 46, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: debug\n  ^ here\n&quot;
}

How do I write my playbook in a way that when the value of snapname == "vm snapshot", it will search for "vm snapshot" in "snapshot_name" in all the lists, then get the corresponding uuid?

For example, search which list has "vm_snapshot", then output the uuid, "6f1kc72a-8916-4edd-9639-c2823b57a1cb".

答案1

得分: 1

以下是您请求的部分翻译:

您可以使用 *json_query*

```yaml
     - debug:
         msg: "{{ result.json.entities|
                  json_query('[?snapshot_name == `vm snapshot`].uuid') }}"

,或者 selectattrmap

     - debug:
         msg: "{{ result.json.entities|
                  selectattr('snapshot_name', '==', 'vm snapshot')|
                  map(attribute='uuid') }}"

两种方法都会产生相同的结果

  msg:
  - 6f1kc72a-8916-4edd-9639-c2823b57a1cb

下面的代码显示如何替换变量

     - debug:
         msg: "{{ result.json.entities|json_query(_query) }}"
       vars:
         snapname: vm snapshot
         _query: '[?snapshot_name == `{{ snapname }}`].uuid'
     - debug:
         msg: "{{ result.json.entities|
                  selectattr('snapshot_name', '==', snapname)|
                  map(attribute='uuid') }}"
       vars:
         snapname: vm snapshot

但是,如果 snapshot_name 的值是唯一的,您可以首先创建一个字典

  snapshot_uuid: "{{ result.json.entities|
                     items2dict(key_name='snapshot_name', value_name='uuid') }}"

会产生

  snapshot_uuid:
    Snapshot 1: ffa972f7-25b7-4d0c-8e92-2e7afef863c4
    new: ad872bde-3a94-411f-8f89-5f5ad55e4ffa
    vm snapshot: 6f1kc72a-8916-4edd-9639-c2823b57a1cb

现在搜索变得简单。


测试的完整playbook示例

- hosts: all

  vars:

    result:
      date: Mon, 22 May 2023 03:39:34 GMT
      elapsed: 0
      expires: '0'
      failed: false
      json:
        entities:
        - created_time: 1684493611741165
          deleted: false
          logical_timestamp: 1
          snapshot_name: Snapshot 1
          uuid: ffa972f7-25b7-4d0c-8e92-2e7afef863c4
        - created_time: 1684502215147173
          deleted: false
          logical_timestamp: 1
          snapshot_name: vm snapshot
          uuid: 6f1kc72a-8916-4edd-9639-c2823b57a1cb
        - created_time: 1684725225721634
          deleted: false
          logical_timestamp: 1
          snapshot_name: new
          uuid: ad872bde-3a94-411f-8f89-5f5ad55e4ffa
        metadata:
          grand_total_entities: 3
          total_entities: 3
      msg: OK (unknown bytes)
      pragma: no-cache
      redirected: false
      server: envoy

    snapshot_uuid: "{{ result.json.entities|
                       items2dict(key_name='snapshot_name', value_name='uuid') }}"
      
  tasks:

     - debug:
         var: snapshot_uuid

     - debug:
         msg: "{{ result.json.entities|
                  selectattr('snapshot_name', '==', 'vm snapshot')|
                  map(attribute='uuid') }}"
     
     - debug:
         msg: "{{ result.json.entities|
                  json_query('[?snapshot_name == `vm snapshot`].uuid') }}"


```

英文:

You can use either json_query

     - debug:
         msg: &quot;{{ result.json.entities|
                  json_query(&#39;[?snapshot_name == `vm snapshot`].uuid&#39;) }}&quot;

, or selectattr and map

     - debug:
         msg: &quot;{{ result.json.entities|
                  selectattr(&#39;snapshot_name&#39;, &#39;==&#39;, &#39;vm snapshot&#39;)|
                  map(attribute=&#39;uuid&#39;) }}&quot;

Both tasks give the same result

  msg:
  - 6f1kc72a-8916-4edd-9639-c2823b57a1cb

<hr>

The code below shows how to substitute a variable

     - debug:
         msg: &quot;{{ result.json.entities|json_query(_query) }}&quot;
       vars:
         snapname: vm snapshot
         _query: &#39;[?snapshot_name == `{{ snapname }}`].uuid&#39;
     - debug:
         msg: &quot;{{ result.json.entities|
                  selectattr(&#39;snapshot_name&#39;, &#39;==&#39;, snapname)|
                  map(attribute=&#39;uuid&#39;) }}&quot;
       vars:
         snapname: vm snapshot

<hr>

But, if the values of snapshot_name are unique, you can create a dictionary first

  snapshot_uuid: &quot;{{ result.json.entities|
                     items2dict(key_name=&#39;snapshot_name&#39;, value_name=&#39;uuid&#39;) }}&quot;

gives

  snapshot_uuid:
    Snapshot 1: ffa972f7-25b7-4d0c-8e92-2e7afef863c4
    new: ad872bde-3a94-411f-8f89-5f5ad55e4ffa
    vm snapshot: 6f1kc72a-8916-4edd-9639-c2823b57a1cb

The search is trivial now.

<hr>

<sup>

Example of a complete playbook for testing

- hosts: all

  vars:

    result:
      date: Mon, 22 May 2023 03:39:34 GMT
      elapsed: 0
      expires: &#39;0&#39;
      failed: false
      json:
        entities:
        - created_time: 1684493611741165
          deleted: false
          logical_timestamp: 1
          snapshot_name: Snapshot 1
          uuid: ffa972f7-25b7-4d0c-8e92-2e7afef863c4
        - created_time: 1684502215147173
          deleted: false
          logical_timestamp: 1
          snapshot_name: vm snapshot
          uuid: 6f1kc72a-8916-4edd-9639-c2823b57a1cb
        - created_time: 1684725225721634
          deleted: false
          logical_timestamp: 1
          snapshot_name: new
          uuid: ad872bde-3a94-411f-8f89-5f5ad55e4ffa
        metadata:
          grand_total_entities: 3
          total_entities: 3
      msg: OK (unknown bytes)
      pragma: no-cache
      redirected: false
      server: envoy

    snapshot_uuid: &quot;{{ result.json.entities|
                       items2dict(key_name=&#39;snapshot_name&#39;, value_name=&#39;uuid&#39;) }}&quot;
      
  tasks:

     - debug:
         var: snapshot_uuid

     - debug:
         msg: &quot;{{ result.json.entities|
                  selectattr(&#39;snapshot_name&#39;, &#39;==&#39;, &#39;vm snapshot&#39;)|
                  map(attribute=&#39;uuid&#39;) }}&quot;

     - debug:
         msg: &quot;{{ result.json.entities|
                  json_query(&#39;[?snapshot_name == `vm snapshot`].uuid&#39;) }}&quot;

</sup>

huangapple
  • 本文由 发表于 2023年5月22日 12:35:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76303063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定