Skip to content

Instantly share code, notes, and snippets.

@zeitounator
Last active May 4, 2020 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeitounator/25e3dfc2a660f984f05712ec2e912ccc to your computer and use it in GitHub Desktop.
Save zeitounator/25e3dfc2a660f984f05712ec2e912ccc to your computer and use it in GitHub Desktop.
$ cat /tmp/test.yml
---
- hosts: localhost
gather_facts: false
vars:
with_test: |-
echo username cisco privilege 15 secret 5 \$1\$..
echo username test privilege 15 secret 5 \$1\$..
without_test: |-
echo username cisco privilege 15 secret 5 \$1\$..
echo username toto privilege 15 secret 5 \$1\$..
vars_prompt:
- name: test_user
prompt: "test user (yes/no): "
defaut: yes
private: no
tasks:
- shell: "{{ test_user | bool | ternary(with_test, without_test) }}"
register: username_contents
changed_when: false
- name: debug registered vars we will use
debug:
var: "{{ item }}"
loop:
- username_contents.stdout_lines
- username_contents.stdout
- name: Check that 'test' is in stdout_lines (wrong)
debug:
msg: Found 'test' in stdout_lines (but that's probably a lie)
when: ('test') in username_contents.stdout_lines
- name: Check that 'test' is not in stdout_line (wrong)
debug:
msg: Did not find 'test' in stdout_lines (but that's probably a lie)
when: ('test') not in username_contents.stdout_lines
- name: Check that 'test' is in output (good)
debug:
msg: Found 'test' in entire output
when: ('test') in username_contents.stdout
- name: Check that 'test' is not in output (good)
debug:
msg: Did not find 'test' in entire output
when: ('test') not in username_contents.stdout
$ ansible-playbook /tmp/test.yml
test user (yes/no): : yes
PLAY [localhost] **************************************************************************************************************************************************************************************************
TASK [shell] ******************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug registered vars we will use] **************************************************************************************************************************************************************************
ok: [localhost] => (item=username_contents.stdout_lines) => {
"ansible_loop_var": "item",
"item": "username_contents.stdout_lines",
"username_contents.stdout_lines": [
"username cisco privilege 15 secret 5 $1$..",
"username test privilege 15 secret 5 $1$.."
]
}
ok: [localhost] => (item=username_contents.stdout) => {
"ansible_loop_var": "item",
"item": "username_contents.stdout",
"username_contents.stdout": "username cisco privilege 15 secret 5 $1$..\nusername test privilege 15 secret 5 $1$.."
}
TASK [Check that 'test' is in stdout_lines (wrong)] ***************************************************************************************************************************************************************
skipping: [localhost]
TASK [Check that 'test' is not in stdout_line (wrong)] ************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Did not find 'test' in stdout_lines (but that's probably a lie)"
}
TASK [Check that 'test' is in output (good)] **********************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Found 'test' in entire output"
}
TASK [Check that 'test' is not in output (good)] ******************************************************************************************************************************************************************
skipping: [localhost]
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
$ ansible-playbook /tmp/test.yml
test user (yes/no): : no
PLAY [localhost] **************************************************************************************************************************************************************************************************
TASK [shell] ******************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug registered vars we will use] **************************************************************************************************************************************************************************
ok: [localhost] => (item=username_contents.stdout_lines) => {
"ansible_loop_var": "item",
"item": "username_contents.stdout_lines",
"username_contents.stdout_lines": [
"username cisco privilege 15 secret 5 $1$..",
"username toto privilege 15 secret 5 $1$.."
]
}
ok: [localhost] => (item=username_contents.stdout) => {
"ansible_loop_var": "item",
"item": "username_contents.stdout",
"username_contents.stdout": "username cisco privilege 15 secret 5 $1$..\nusername toto privilege 15 secret 5 $1$.."
}
TASK [Check that 'test' is in stdout_lines (wrong)] ***************************************************************************************************************************************************************
skipping: [localhost]
TASK [Check that 'test' is not in stdout_line (wrong)] ************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Did not find 'test' in stdout_lines (but that's probably a lie)"
}
TASK [Check that 'test' is in output (good)] **********************************************************************************************************************************************************************
skipping: [localhost]
TASK [Check that 'test' is not in output (good)] ******************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Did not find 'test' in entire output"
}
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0
@secpol
Copy link

secpol commented May 4, 2020

Thanks for the code, it works but with 'not' operator the result is opposite.

    - name: In on lines
      debug:
        msg: Found in stdout_lines
      when: ('test') not in username_contents.stdout_lines

    - name: In on entire string
      debug:
        msg: Found in entire output
      when: ('test') not in username_contents.stdout
PLAY [localhost] **********************************************************************************************************************************************************************************

TASK [shell] **************************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug registered vars we will use] **********************************************************************************************************************************************************
ok: [localhost] => (item=username_contents.stdout_lines) => {
    "ansible_loop_var": "item", 
    "item": "username_contents.stdout_lines", 
    "username_contents.stdout_lines": [
        "username cisco privilege 15 secret 5 $1$..", 
        "username test privilege 15 secret 5 $1$.."
    ]
}
ok: [localhost] => (item=username_contents.stdout) => {
    "ansible_loop_var": "item", 
    "item": "username_contents.stdout", 
    "username_contents.stdout": "username cisco privilege 15 secret 5 $1$..\nusername test privilege 15 secret 5 $1$.."
}

TASK [In on lines] ********************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Found in stdout_lines"
}

TASK [In on entire string] ************************************************************************************************************************************************************************
skipping: [localhost]

PLAY RECAP ****************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

@zeitounator
Copy link
Author

It sill does what you want when using stdout: look for a substring (not) in the entire result.

@zeitounator
Copy link
Author

See update that lets you test all conditions with and without a test user in the output

@secpol
Copy link

secpol commented May 4, 2020

That bloody thing is broken or my eyes are, take a look at this

- name: check if user exists, if not add user
    #ios_config:
    #  lines: username test privilege 15 secret test
    debug:
      msg: 'Adding user'
    when: ('test') not in username_contents.stdout

- name: debug
   debug:
      var: username_contents.stdout

TASK [ios_command] ********************************************************************************************************************************************************************************
ok: [r5]

TASK [check if user exists, if not add user] ******************************************************************************************************************************************************
ok: [r5] => {
    "msg": "Adding user"
}

TASK [debug] **************************************************************************************************************************************************************************************
ok: [r5] => {
    "username_contents.stdout": [
        "username cisco privilege 15 secret 5 $1$rIId$7X8jj.iJiU3s4AKladf2dE/\nusername test privilege 15 secret 5 $1$aLpg$UnHXbCENzJxBonbdWshXA."
    ]
}

@secpol
Copy link

secpol commented May 4, 2020

What you are trying to show me makes absolute sense, it's logical. I cannot understand why my code won't work, the results are opposite to what I expect.

---
- name: gather facts
  hosts: r5
  #gather_facts: yes

  tasks:

  - name:
    ios_command:
      commands: sh run | s user
    register: username_contents

  - name: debug
    debug:
      var: username_contents.stdout

  - name: check if user exists, if not add user
    #ios_config:
    #  lines: username test privilege 15 secret test
    debug:
      msg: User exists
    when: ('test') in username_contents.stdout
PLAY [gather facts] *******************************************************************************************************************************************************************************

TASK [ios_command] ********************************************************************************************************************************************************************************
ok: [r5]

TASK [debug] **************************************************************************************************************************************************************************************
ok: [r5] => {
    "username_contents.stdout": [
        "username cisco privilege 15 secret 5 $1$rIId$7X8jj.iJiU3s4AKladf2dE/\nusername test privilege 15 secret 5 $1$aLpg$UnHXbCENzJxBonbdWshXA."
    ]
}

TASK [check if user exists, if not add user] ******************************************************************************************************************************************************
skipping: [r5]

PLAY RECAP ****************************************************************************************************************************************************************************************
r5                         : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

@zeitounator
Copy link
Author

zeitounator commented May 4, 2020

Which version of ansible are your using and which version of the jinja2 library ? Try to update.

$ ansible --version
ansible 2.9.7
config file = None
configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.6/dist-packages/ansible
executable location = /usr/local/bin/ansible
python version = 3.6.9 (default, Apr 18 2020, 01:56:04) [GCC 8.4.0]

$ pip list | grep Jinja2
Jinja2 2.11.2

@zeitounator
Copy link
Author

zeitounator commented May 4, 2020

Other (weird) things you can try:

Quote your entire test and remove parenthesis.
when: "'test' in username_contents.stdout"

Change for the search test:
when: username_contents.stdout is search('test')

@secpol
Copy link

secpol commented May 4, 2020

I really appreciate your help, thanks! So this one works: when: username_contents.stdout is search('test').
I may found a issue. When ansible generates output, it creates a list. That's why this doesn't work in my case too: username_contents.stdout.find('test') != -1

Error:
fatal: [r5]: FAILED! => {"msg": "The conditional check 'username_contents.stdout.find(usr) != -1' failed. The error was: error while evaluating conditional (username_contents.stdout.find(usr) != -1): 'list object' has no attribute 'find'\n\nThe error appears to be in '/var/production/Cisco/configure_ospf/g_facts_copy.yml': line 23, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: check if user exists\n ^ here\n"}

Even though I've tried using python interpretation for finding string in list/dictionary when: usr in username_contents['stdout'] but no luck so I'm guessing it's Ansible bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment