jetole
jetole

Reputation: 686

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

I am using the dig command in an ansible.builtin.command and storing the results to the variable result. One of my until tests is result.stdout_lines|length >= 3 as we are waiting until as least 3 results are available. I also want to ensure that every line is an IPv4 address but the list length is unknown. Sometimes it will be 3 lines and sometimes it will be more.

I am trying to figure out how I can perform an until test on every item in a list when we don't know how long the list is.

Here's the task so far:

- 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

Upvotes: 2

Views: 1607

Answers (2)

Vladimir Botka
Vladimir Botka

Reputation: 68144

Test if 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

Q: "Output only items in the list that are IPv4."

A: You can postpone the testing of the validity, e.g.

    - 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

The result will be

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

Testing the validity gives

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

Now, joining the items will include also false item(s)

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

Instead, you might want to very efficiently select valid items only

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

Upvotes: 2

jetole
jetole

Reputation: 686

I figured it out:

  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

This will output only items in the list that are IPv4 and then I can check the length of that data. I can then use {{ db_hosts.stdout_lines | ansible.netcommon.ipv4 | join(',') }} in a template to only use the IPv4 output so, I'm not testing each item but I am only extracting items that meet my criteria.

Upvotes: 0

Related Questions