Ansible loop till the condition matches.

2019-08-14 09:56发布

问题:

I want to make the series of API calls, after each call check for a particular parameter in the result, if it greater than particular value save it in register and continue further playbook execution.

Basically I am making an API call to RHEV to check the storage domain. Then I want to check if storage domain have the sufficient space, if yes, store that storage domain id in register to create the disk on the storage domain.

Below is the snippet how I do it for single API call to storagedomain.

 - name: Get Free Storage Domain On RHEV
  uri:
    url: "{{ rhevurl }}/storagedomains/7649aea2-d87c-4066-acca-4399d5261ade"
    method: GET
    user: "{{ rhevusername }}"
    password: "{{ rhevpassword }}"
    return_content: yes
    headers:
      Version: 4
      Accept: "application/xml"
      Content-type: "application/xml"
  register: storagedomain
  tags: storagedomain


- name: Retriving size.
  xml:
    xmlstring: "{{ storagedomain.content }}"
    xpath: /storage_domain/available
    content: text
  register: availablesize
  tags: storagedomain


- name: storage_domain size
  debug:
    var: availablesize.matches[0].available
  tags: storagedomain

Now I want to do this process for multiple storage domain, and loop should break when it gets storagedomain with available space.

Something like below.

- name: Get Free Storage Domain On RHEV
  uri:
    url: "{{ rhevurl }}/storagedomains/{{ item }}"
    method: GET
    user: "{{ rhevusername }}"
    password: "{{ rhevpassword }}"
    return_content: yes
    headers:
      Version: 4
      Accept: "application/xml"
      Content-type: "application/xml"
  loop:
    - 7649aea2-d87c-4066-acca-4399d5261ade
    - 40cceee7-a8d3-45af-a2d0-70c414be32cc
    - a81411b0-4ddb-4467-a4c6-ac9364905248
    - b288c547-231c-44b9-8329-98adcbdfc726 
    - 8cdef991-3edc-4c35-9228-feeef8f29004
    - 837a2e1b-6365-4309-a526-0cd05801fe43
    - 8981bf82-a1da-405e-a7f5-d84f2c94d71d
    - 7a9e3904-e37b-48fd-b850-0f026dc5cde9

In the loop how should I parse xml using xml module and then check for condition of available space greater the particular size

回答1:

You cannot break the loop, but can skip the loop execution if your condition satisfy at any item. check out the below example.

test.yml this playbook will execute shell module with ignore errors & set var1 variable. but the block module will only execute until var1 is not defined.

- block:
  - shell: expr {{item}} + 1
    ignore_errors: yes
    register: cmd_stat

  - set_fact: var1={{item}}
    when: cmd_stat.rc == 0
  when: var1 is not defined

sites.yml this play includes test.yml playbook multiple times based on your loops items.

---
- hosts: localhost
  connection: local
  vars:
  tasks:
    - include: test.yml
      loop: ["abc","def", "ghi",1, "jkl"]

    - name: increase var1 variable by 1 and write to text file
      shell: expr {{var1}} + 1 > text

So, using the same logic you can implement in your playbook. like if url get 200 status then set storage variable & use it with when condition.

I Hope you'll be able to understand the example.



回答2:

until: with retries: (and perhaps delay:) or async: (which has its own section in the fine manual) with poll: might do what you want



标签: ansible