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 forios
-family modulesstdout
is a list of strings, andstdout_lines
is a list of lists (whereas for usualcommand
modulestdout
is a string andstdout_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