Is there a better way to search through a list using when and regex_search

Still learning Ansible, but getting somewhat better. I’m trying to use a list that I have in a playbook just for ease of testing. Is there a simple way of writing to a file when one of the items in the list is found in the output?

This basically looks like grep? What is your goal.

Can you post a real output of ‘show snmpcommunity’? I’m a bit rusty on snmp.

I can share that later, not in front of my laptop. What I was looking for is not just with snmp, I just started with snmp since I was working on other playbooks. I was looking to see if I can simplify the “when” to check if the output has the any of the variables defined in the list. What I have is working, but is there a better way?

-Scott

Here is a sample output when I run a show snmpcommunity. The one with ‘*’ are hashed and read-only, so I will not be able to match on those, it is the read-only strings i’m worried about.

rusred991c55p1

IPSec mode: Disabled / Profile: none

SNMP Community Name Client IP Address Client IP Mask Access Mode Status


********** 10.200.250.0 255.255.255.0 Read/Write Enable
********** 10.100.10.208 10.100.10.208 Read/Write Enable
xxxxxxxxxx 0.0.0.0 0.0.0.0 Read Only Enable
yyyyyyyyyy 0.0.0.0 0.0.0.0 Read Only Enable
zzzzzzzzzz 0.0.0.0 0.0.0.0 Read Only Enable

Is there any chance you can have a single var that is a list for those strings?
I.e.:

snmp_strings:
  - aaaaaaaaa
  - bbbbbbbbb
  - cccccccccc

So you mean define it like the following in a playbook:

vars:
  snmp_strings:
   - aaaaaaaaa
   - bbbbbbbbb
   - cccccccccc

-Scott

Okay, this is what I have now that is working, but can I simplify the when?

... can I simplify the when?
(when one of the items in the list is found in the output?)

It's possible to create a list of the "search" results and use the test
"any". For example the playbook
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-strings
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#test-if-a-list-contains-a-value

    > cat pb.yml
    - hosts: localhost
      vars:
        my_output: "aa bb cc"
        my_list: [aa, bb, xx]
      tasks:
        - set_fact:
            my_search: "{{ my_search|default() +
                           [my_output is search(item)] }}"
          loop: "{{ my_list }}"
        - debug:
            var: my_search
        - debug:
            msg: Write to file
          when: my_search is any

gives

    "my_search": [
        true,
        true,
        false
    ]

    "msg": "Write to file"

HTH,

  -vlado

Add these tasks:

    - set_fact:
        matches: "{{ matches|default('') +
preOutputSummary.stdout_lines | regex_search(item + '\\s+.*\\n') }}"
      loop: "{{ oldSnmp }}"

    - copy:
        dest: "./{{ ansible_play_name }}_output.txt"
        content: "{{ matches }}"

This should give this result:

xxxxxxxxxx 0.0.0.0 0.0.0.0
       Read Only Enable
yyyyyyyyyy 0.0.0.0 0.0.0.0
       Read Only Enable
zzzzzzzzzz 0.0.0.0 0.0.0.0
       Read Only Enable

Vladimir,

I’m a bit confused on how I can use the register: preOutputSummary in the set_facts search. My output when running the command: show snmpcommunity outputs this:

IPSec mode: Disabled / Profile: none

SNMP Community Name Client IP Address Client IP Mask Access Mode Status



********** 10.200.250.0 255.255.255.0 Read/Write Enable
********** 10.100.10.208 10.100.10.208 Read/Write Enable
xxxxxxxxxx 0.0.0.0 0.0.0.0 Read Only Enable
yyyyyyyyyy 0.0.0.0 0.0.0.0 Read Only Enable
zzzzzzzzzz 0.0.0.0 0.0.0.0 Read Only Enable

I do understand what you posted in regard to the test, but don’t know how to integrate your feedback to my playbook.

-Scott

Searching "preOutputSummary.stdout[0]" doesn't make sense.

To clarify the difference between ".stdout" and ".stdout_lines" of registered
output. ".stdout" is a string and ".stdout_lines" is a list of the lines. As
a result ".stdout[0]" is the first character of the output. For example

    - hosts: localhost
      tasks:
        - command: cat /etc/passwd
          register: output
        - debug:
            var: output.stdout_lines[0]
        - debug:
            var: output.stdout[0]

gives

    "output.stdout_lines[0]": "root:x:0:0:root:/root:/bin/bash"
    "output.stdout[0]": "r"

In your case 1) use "preOutputSummary.stdout" to search the items from the
list "oldSnmp" and 2) use "preOutputSummary.stdout_lines" to write the file.

Try this

This can be simplified further

    - name: write output to a file if snmp if found
      template:
        src: output.txt.j2
        dest: "{{ ansible_play_name }}_output.txt"
      when: oldSnmp|
            select('in', preOutputSummary.stdout)|
            list>
            length > 0

Thanks for the follow up. I will give this a try today and let you know. I’m not familiar with the set_facts and using templates.

-Scott

Thanks for this! I will give this a try later also.

-Scott

I gave it a try and got an error I don’t know how to resolve it. The set_facts my_search is over my head:)

search_snmp.yml

I have tried your example also and got the same error using Vlad’s example also.

search_snmp.yml

Okay, well from doing some online searching and tinkering, maybe the aireos module does something different. I saw this post stating the following:

you need intermediate join here, because for ios-family modules stdout is a list of strings, and stdout_lines is a list of lists (whereas for usual command module stdout is a string and stdout_lines is a list of strings).

I have also posted the output using stdout, stdout_lines with the aireos_command module, but here is my playbook that seems to work. Curious what I would need to do if using set_facts.

This is where I got the info from: https://stackoverflow.com/questions/45737295/using-when-conditional-to-match-string-in-output-register-ansible

Okay sorry for all the post… I think I have something I can work with now. Here is my playbook that is working with the set_fact:

Vlad,

When trying to use the jinja2 template and running this playbook over multiple hosts, the file gets overwritten. This works for a single device if there is a match.

{{ inventory_hostname }}

{% for line in preOutputSummary.stdout_lines[0] %}
{{ line }}
{% endfor %}

-Scott