O.K.
O.K.

Reputation: 95

Ansible "when" condition is not functioning even if the condition is met

I don't get it why my condition doesn't work, maybe someone here can help me with it. I have the following in my playbook:

...
tasks:
- fail: msg="This and that, you can't run this job"
  when: (variable1.find(',') != -1 or variable1.find('-')) and (variable2.find("trunk") != -1 )

this should be interpreted in my opinion like this: if variable1 is containing a comma (,) OR hyphen (-) AND variable2 is equal to "trunk" than it is true! When it is true, the condition is met and it should fail but instead, the whole job is done successfully. What I'm missing here? Thank you in advance.

Upvotes: 1

Views: 1246

Answers (1)

Zeitounator
Zeitounator

Reputation: 44615

TL;DR

tasks:
  - fail:
      msg: "This and that, you can't run this job"
    when:
      - variable1 is search('[,-]+')
      - variable2 is search("trunk")

(Note: listing conditions in a when clause joins them with an and)

Explanation

variable1.find('-') is returning X where X is the integer index of the character in the string or -1 if it is not present, not a boolean.

$ ansible localhost -m debug -a msg="{{ variable1.find('-') }}" -e variable1="some-val"
localhost | SUCCESS => {
    "msg": "4"
}

Note here that an hyphen on the first letter of the string will result in an index of 0.

You are evaluating X directly as a boolean which is a bad practice. Anyhow, even if you evaluate it correctly to a boolean, the result will still be:

$ ansible localhost -m debug -a msg="{{ variable1.find('-') | bool }}" -e variable1="no hyphen"
localhost | SUCCESS => {
    "msg": false
}
$ ansible localhost -m debug -a msg="{{ variable1.find('-') | bool }}" -e variable1="hyphen- <= here"
localhost | SUCCESS => {
    "msg": false
}

except in the very specific case where the hyphen is on index 1 (head banging ahead to find the bugs in such a scenario....)

$ ansible localhost -m debug -a msg="{{ variable1.find('-') | bool }}" -e variable1="a-val with hyphen at index 1"
localhost | SUCCESS => {
    "msg": true
}

Knowing the above, your actual test for the presence of the hyphen should be:

$ ansible localhost -m debug -a msg="{{ variable1.find('-') >= 0 }}" -e variable1="-hyphen at start"
localhost | SUCCESS => {
    "msg": true
}
$ ansible localhost -m debug -a msg="{{ variable1.find('-') >= 0 }}" -e variable1="hyphen- <= here"
localhost | SUCCESS => {
    "msg": true
}
$ ansible localhost -m debug -a msg="{{ variable1.find('-') >= 0 }}" -e variable1="no hyphen"
localhost | SUCCESS => {
    "msg": false
}

This is more or less the same as in your other comparisons (i.e. != -1) except more precise (in case the function would return some other negative value one day...) and I also guess dropping the comparison for this specific search is a typo in your above code.

Nonetheless, this is IMO a poor way of writing such a test and I would much prefer using available ansible tests for this:

$ ansible localhost -m debug -a msg="{{ variable1 is search('-') }}" -e variable1="no hyphen"
localhost | SUCCESS => {
    "msg": false
}
$ ansible localhost -m debug -a msg="{{ variable1 is search('-') }}" -e variable1="-hyphen at start"
localhost | SUCCESS => {
    "msg": true
}
$ ansible localhost -m debug -a msg="{{ variable1 is search('-') }}" -e variable1="hyphen- <= here"
localhost | SUCCESS => {
    "msg": true
}

Since search accepts regexps, you can even look for several mandatory chars in one go:

$ ansible localhost -m debug -a msg="{{ variable1 is search('[,-]+') }}" -e variable1="a,value"
localhost | SUCCESS => {
    "msg": true
}
$ ansible localhost -m debug -a msg="{{ variable1 is search('[,-]+') }}" -e variable1="some-value"
localhost | SUCCESS => {
    "msg": true
}
$ ansible localhost -m debug -a msg="{{ variable1 is search('[,-]+') }}" -e variable1="some value"
localhost | SUCCESS => {
    "msg": false
}

Which gives as a final result the example in my TL;DR above.

Upvotes: 2

Related Questions