Viscosity
Viscosity

Reputation: 321

Ansible: How to conditional run task if a string is found?

Essentially, I am trying to use the when conditional to decide whether to proceed running a command based on the presence of a string. There seem to be all sorts of problems to overcome here, including the presence of the colon which I can't escape with "{{:}}" like I normally would because then the conditional complains.

If i truncate everything from the point of the colon and after, I get an integer evaluation error instead. I've looked through 200 posts on stackoverflow and none of the solutions seem to be able to do what I'm looking for.

Relvevant part of the sync_status.stderr_lines contents I am looking for if it comes up:

ERROR 1227 (42000) at line 1: Access denied

The code in the task which tries to run the command if the string is present with the colon:

     - name: Can we proceed?
       command: uptime
       when: ( 'ERROR 1227 (42000) at line 1"{{:}}" Access denied' in sync_status.stderr_lines )

This task's error during runtime:

fatal: [server1]: FAILED! => {"msg": "The conditional check '( 'ERROR 1227 (42000) at line 1\"{{:}}\" Access denied' in sync_status.stderr_lines )' failed. The error was: template error while templating string: unexpected ':'. String: ( 'ERROR 1227 (42000) at line 1\"{{:}}\" Access denied' in sync_status.stderr_lines )\n\nThe error appears to be in '/home/ansible/ssn-project/playbooks/i_mux-sql-upgrade.yml': line 54, column 8, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n     - name: Can we proceed?\n       ^ here\n"}

Now the "same" thing truncated:

     - name: Can we proceed?
       command: uptime
       when: ( 'ERROR 1227 (42000) at line 1' in sync_status.stderr_lines )

And it's runtime failure as well:

fatal: [mux-ds1]: FAILED! => {"msg": "The conditional check '( 'ERROR 1227 (42000) at line 1' in sync_status.stderr_lines )' failed. The error was: error while evaluating conditional (( 'ERROR 1227 (42000) at line 1' in sync_status.stderr_lines )): Unable to look up a name or access an attribute in template string ({% if ( 'ERROR 1227 (42000) at line 1' in sync_status.stderr_lines ) %} True {% else %} False {% endif %}).\nMake sure your variable name does not contain invalid characters like '-': argument of type 'AnsibleUndefined' is not iterable\n\nThe error appears to be in '/home/ansible/ssn-project/playbooks/i_mux-sql-upgrade.yml': line 54, column 8, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n     - name: Can we proceed?\n       ^ here\n"}

Is there a way to make this work as I expect? I was maybe thinking of some sort of regex filter, but maybe that's not the right way to go. Insights would be appreciated. Note, I am on ansible version 2.9

Upvotes: 0

Views: 916

Answers (1)

U880D
U880D

Reputation: 12009

I understand that you like to

"run ... a command based on the presence of a string"

on a not further specified STDERR output

ERROR 1227 (42000) at line 1: Access denied

Regarding

Relvevant part of the sync_status.stderr_lines contents I am looking for if it comes up

it seems for me that the Most Significant Information is less than the whole line and only ERROR 1227 and/or Access denied since the information/message is an ERROR 1227 42000 Access denied.

Therefore you can simplify your case as shown in the following example

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    sync_status:
      stderr_lines:
        - 'line 1: Line 1'
        - 'ERROR 1227 (42000) at line 1: Access denied'
        - 'line 2: Line 2'

  tasks:

  # Show all STDERR lines joined into one line

  - name: Show vars
    debug:
      msg: "{{ sync_status.stderr_lines | join(' ') }}"

  # Looking for most significant information only

  - name: Can we proceed?
    debug:
      msg: "No!"
    when: "sync_status.stderr_lines | join(' ') is search('ERROR 1227|Access denied')"

resulting into an output of

TASK [Show vars] *****************************************************************
ok: [localhost] =>
  msg: 'line 1: Line 1 ERROR 1227 (42000) at line 1: Access denied line 2: Line 2'

TASK [Can we proceed?] ***********************************************************
ok: [localhost] =>
  msg: No!

As already mentioned in a comment of β.εηοιτ.βε, you could also just lookup the whole line.

  - name: Can we proceed?
    debug:
      msg: "No!"
    when: "'ERROR 1227 (42000) at line 1: Access denied' in sync_status.stderr_lines"

Further Q&A

Documentation

Upvotes: 1

Related Questions