Ansible - 如何测试列表中的每个项目,直到列表长度未知

Ansible - How to test every item in list with until when list is an unknown length

我在 ansible.builtin.command 中使用 dig 命令并将结果存储到变量 result。我的一项 until 测试是 result.stdout_lines|length >= 3,因为我们正在等待 until 至少有 3 个结果可用。我还想确保每一行都是一个 IPv4 地址,但列表长度未知。有时会是 3 行,有时会更多。

我想弄清楚当我们不知道列表有多长时如何对列表中的每个项目执行 until 测试。

这是目前的任务:

- name: Get database hosts  # noqa no-changed-when
  ansible.builtin.command: dig @127.0.0.1 -p 8600 +short db-addr.service.consul
  register: result
  until: result.stdout_lines|length >= 3
  delay: 15
  retries: 40

测试是否all items are valid IP addresses

    - name: Get database hosts  # noqa no-changed-when
      ansible.builtin.command: dig @127.0.0.1 -p 8600 +short db-addr.service.consul
      register: result
      until:
        - result.stdout_lines|length >= 3
        - result.stdout_lines|map('ansible.netcommon.ipaddr')|list is all
      delay: 15
      retries: 40

问:“仅输出列表中的 IPv4 项。”

A:您可以推迟有效性测试,例如

    - ansible.builtin.command: printf '127.0.0.1\n127.0.0.2\n127.0.0.X\n'
      register: result
      until: result.stdout_lines|length >= 3
      delay: 15
      retries: 40

结果会是

result.stdout_lines:
  - 127.0.0.1
  - 127.0.0.2
  - 127.0.0.X

测试有效性给出

result.stdout_lines|map('ansible.netcommon.ipaddr')|list:
  - 127.0.0.1
  - 127.0.0.2
  - false

现在,加入项目还将包括 false 个项目

result.stdout_lines|map('ansible.netcommon.ipaddr')|join(','): 127.0.0.1,127.0.0.2,False

相反,您可能希望非常高效地 select 仅有效项目

result.stdout_lines|map('ansible.netcommon.ipaddr')|select():
  - 127.0.0.1
  - 127.0.0.2

我想通了:

  ansible.builtin.command: dig @127.0.0.1 -p 8600 +short db-addr.service.consul
  register: db_hosts
  until: db_hosts.stdout_lines | ansible.netcommon.ipv4 | length >= 3
  delay: 15
  retries: 40

这将仅输出列表中的 IPv4 项目,然后我可以检查该数据的长度。然后我可以在模板中使用 {{ db_hosts.stdout_lines | ansible.netcommon.ipv4 | join(',') }} 来仅使用 IPv4 输出,所以我没有测试每个项目,而是只提取符合我的标准的项目。