json 带阵列的Ansible回路

nwwlzxa7  于 2022-12-05  发布在  其他
关注(0)|答案(2)|浏览(159)

有人可以让我知道我们如何可以创建一个代码如下?

- name: TEST1
  set_fact:
    list_a: "{{ list_a + [item.json.SearchResult.resources] }}"
  with_items: 
    - "{{ source_list.results[0] }}"
    - "{{ source_list.results[1] }}"
    - "{{ source_list.results[x] }}"
    ... (unknown how many items in result from API)
  vars:
    list_a: []

source_list.results[x]来自一个API结果,我需要创建一个数组的原因是API结果的数量最多为100,但是有500多个项。

pes8fvy9

pes8fvy91#

您的理解方式不对。只需使用map(attribute=x) Jinja2过滤器从每个结果中提取所需的属性即可。

对于以下内容,我推断(参见上述注解):

  • 您在循环中使用ansible.builtin.uri调用了API,以获得100个结果的批处理,这些结果作为列表返回到SearchResult.ressources字段中
  • 最后您需要一个所有resources都位于顶层的扁平列表
- name: Show my list of single attributes
  ansible.builtin.debug:
    var: "source_list.results
      | map(attribute='json.SearchResult.resources') | flatten"

实际上,您不需要set_fact

  • 对于单次使用,只需在相关参数(例如loop或模块参数....)中直接使用上述表达式,或最终在任务级的变量中声明此表达式。
  • 如果你想在剧本的不同部分重用它,只需在剧本级别声明一个var,并在调用API并填充source_list var后将其扩展到任何地方。在这种情况下,只需添加一个默认值,以防止在尚未调用API时出现错误。

本伪行动手册中上述第二种情况的示例

---
- hosts: localhost
  gather_facts: false

  vars:
    list_a: "{{ source_list.results | d([])
      | map(attribute='json.SearchResult.resources') | flatten }}"

  tasks:
    - name: "This will return an empty list (i.e. [])
        as we did not populate source_list yet"
      ansible.builtin.debug:
        var: list_a

    - name: Call our API and register source_list
      ansible.builtin.uri:
        uri: https://my.api.com/api/v1/some/endpoint
        # [... more parameters here ... ]
      loop: "{{ my_list_of_ressources }}"
      register: source_list

    - name: "This will now return a populated list
        after calling the API and registering source_list"
      ansible.builtin.debug:
        var: list_a

现在,还是直接回答你最初的问题:您可以在一个set_fact任务中迭代地构造该列表。这肯定不是有效的因为它涉及一个在循环中运行的任务(如上所述,这两个任务都是不需要的),并且可能在您的播放器中的多个主机上运行。但是为了学习的目的,这里是:

- name: very inefficient way to get the same result as above
  set_fact:
    list_a: "{{ list_a | d([]) + item.SearchResult.resources }}"
  loop: "{{ source_list.results }}"
bxgwgixi

bxgwgixi2#

谢谢你的回复。我意识到这是错误的方式。我用你的想法('json查询'和'扁平化'),我改变了下面,它的工作,因为我预期!!!

- name: Create ID list from API result data
  set_fact:
    list_a: "{{ source_list | json_query('results[*].json.SearchResult.resources[*].id') | flatten }}"

- name: API get again with id
  uri:
    url: "{{ request_url }}/{{ item }}"
    ... 
  register: result_data
  with_items:
    - "{{ list_a }}"

相关问题