Using Ansible to delete old usernames across entire company network devices - ansible

Created below test yml file against test switches to nail down configs, error below. I defined provider in last task with no luck as well
---
- hosts: aus2-mdf-testswitches
gather_facts: no
connection: local
tasks:
- name: OBTAIN LOGIN CREDENTIALS
include_vars: secret.yml
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
auth_pass: "{{ creds['auth_pass'] }}"
- name: Delete users with aggregate
ios_user:
aggregate:
- name: chase
state: absent
Error that was presented. Please keep in mind that I am new with ansible and this problem might be super easy for this group but I appreciate any help. FYI, reading from https://docs.ansible.com/ansible/2.4/ios_user_module.html
[ansible#dc1netansible automation]$ ansible-playbook -i inventories/prod/hosts playbooks/deleteUsername.yml
PLAY [aus2-mdf-testswitches] ********************************************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] *****************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [DEFINE PROVIDER] **************************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [Delete users with aggregate] **************************************************************************************************************************************
fatal: [aus2-mdf-testsw1]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
fatal: [aus2-mdf-testsw2]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
to retry, use: --limit #/home/ansible/automation/playbooks/deleteUsername.retry
PLAY RECAP **************************************************************************************************************************************************************
aus2-mdf-testsw1 : ok=2 changed=0 unreachable=0 failed=1
aus2-mdf-testsw2 : ok=2 changed=0 unreachable=0 failed=1
****updated error with new yml config****
---
- hosts: aus2-mdf-testswitches
gather_facts: no
connection: local
tasks:
- name: OBTAIN LOGIN CREDENTIALS
include_vars: secret.yml
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
auth_pass: "{{ creds['auth_pass'] }}"
- name: Delete users with aggregate
ios_user:
users:
- name: chase
authorize: yes
provider: "{{ provider }}"
state: absent
register: result
[ansible#dc1netansible automation]$ ansible-playbook -i inventories/prod/hosts playbooks/deleteUsername.yml
PLAY [aus2-mdf-testswitches] ********************************************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] *****************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [DEFINE PROVIDER] **************************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [Delete users with aggregate] **************************************************************************************************************************************
fatal: [aus2-mdf-testsw1]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
fatal: [aus2-mdf-testsw2]: FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}
to retry, use: --limit #/home/ansible/automation/playbooks/deleteUsername.retry
PLAY RECAP **************************************************************************************************************************************************************
aus2-mdf-testsw1 : ok=2 changed=0 unreachable=0 failed=1
aus2-mdf-testsw2 : ok=2 changed=0 unreachable=0 failed=1
Could be my IOS version is too old, as I am using 12x train on a Cisco switch. Ansible mentions this is tested on the 15x train.
****last update****
PLAY [aus2-mdf-testswitches] ********************************************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] *****************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [DEFINE PROVIDER] **************************************************************************************************************************************************
ok: [aus2-mdf-testsw1]
ok: [aus2-mdf-testsw2]
TASK [Delete users with aggregate] **************************************************************************************************************************************
fatal: [aus2-mdf-testsw2]: FAILED! => {"changed": false, "msg": "unable to retrieve current config", "stderr": "show running-config | section username\r\n ^\r\n% Invalid input detected at '^' marker.\r\n\r\naus2-mdf-testsw2#", "stderr_lines": ["show running-config | section username", " ^", "% Invalid input detected at '^' marker.", "", "aus2-mdf-testsw2#"]}
fatal: [aus2-mdf-testsw1]: FAILED! => {"changed": false, "msg": "unable to retrieve current config", "stderr": "show running-config | section username\r\n ^\r\n% Invalid input detected at '^' marker.\r\n\r\naus2-mdf-testsw1#", "stderr_lines": ["show running-config | section username", " ^", "% Invalid input detected at '^' marker.", "", "aus2-mdf-testsw1#"]}
to retry, use: --limit #/home/ansible/automation/playbooks/deleteUsername.retry
Configs listed here do not work on the IOS I have on my Cisco switch.

Related

Ansible for event automation with Cisco Nessus device. need to extract past 15 minutes logs from show clock of the device

What I am trying to achieve with this ansible code: Ansible code should be triggered during an interface flapping with cisco nessus device. It should fetch the time of nessus device(show clock) and try to pull the past 15 minutes from the "show logging" output of nessus device.
Ansible experts, I need to help to manipulate the time to get past 15 minutes from show logging. Below s the code written so far.
cat interfaceflapping.yml
---
- name: Cisco NXOS
hosts: all
connection: network_cli
gather_facts: false
vars:
- cmdlist: sh clock
- ansible_python_interpreter: /usr/bin/python3
- ansible_network_os: nxos
tasks:
- name: Execute command
nxos_command:
commands: "{{ cmdlist }}"
register: output
- set_fact:
arr: "{{ output.stdout_lines[0][1].split() }}"
- debug:
msg: "{{ arr[0] }}"
- name: print variable
set_fact:
my_string_var: "{{ arr[0].split(':') | default('') }}"
- debug:
msg: "{{my_string_var}}"
- name: Execute command
nxos_command:
commands: sh logging | include 2/3
register: output1
- debug:
msg: "{{ output1 }}"
when: output1.stdout is search(my_string_var)
```ansible
==================
output as below
[LABPC#lab-jump-host dow]$ ansible-playbook interfaceflapping.yml -i inventory1.txt --limit nxos --verbose
Using /etc/ansible/ansible.cfg as config file
PLAY [Cisco NXOS] ******************************************************************************************************************************************************************************************
TASK [Execute command] *************************************************************************************************************************************************************************************
ok: [nxos] => {"changed": false, "stdout": ["Time source is NTP\n18:50:15.681 UTC Sat Jul 02 2022"], "stdout_lines": [["Time source is NTP", "18:50:15.681 UTC Sat Jul 02 2022"]]}
TASK [set_fact] ********************************************************************************************************************************************************************************************
ok: [nxos] => {"ansible_facts": {"arr": ["18:50:15.681", "UTC", "Sat", "Jul", "02", "2022"]}, "changed": false}
TASK [debug] ***********************************************************************************************************************************************************************************************
ok: [nxos] => {
"msg": "18:50:15.681"
}
TASK [print variable] **************************************************************************************************************************************************************************************
ok: [nxos] => {"ansible_facts": {"my_string_var": ["18", "50", "15.681"]}, "changed": false}
TASK [debug] ***********************************************************************************************************************************************************************************************
ok: [nxos] => {
"msg": [
"18",
"50",
"15.681"
]
}
TASK [Execute command] *************************************************************************************************************************************************************************************
ok: [nxos] => {"changed": false, "stdout": [""], "stdout_lines": [[""]]}
TASK [debug] ***********************************************************************************************************************************************************************************************
fatal: [nxos]: FAILED! => {"msg": "The conditional check 'output1.stdout is search(my_string_var)' failed. The error was: Unexpected templating type error occurred on ({% if output1.stdout is search(my_string_var) %} True {% else %} False {% endif %}): unhashable type: 'list'\n\nThe error appears to be in '/home/LABPC/gomathi/dow/root/dow/interfaceflapping.yml': line 32, 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 - debug:\n ^ here\n"}
PLAY RECAP *************************************************************************************************************************************************************************************************
nxos : ok=6 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
==============
PLZ HELP ME TO GET THE PAST 15 MINUTES OUTPUT FROM SHOW LOGGING. I HAVE HARDCODED THE INTERFACE NUMBER AS 2/3 .

How to ignore specific errors in an Ansible task

If have an Ansible task, that can fails sometimes, due to some error during the creation of an user account. Especially if the user account is already in use and the user is logged in. If the task fails with a specific error message, like "user account in use" the play must continue. There is no need to fail then, but only on predefined error messages. The task looks like this.
- name: modify user
user:
state: "{{ user.state | default('present') }}"
name: "{{ user.name }}"
home: "{{ user_base_path }}/{{ user.name }}"
createhome: true
Since it's not a shell command, I cannot simply register a var and check the output of .rc. Also I don't get stderr or stdout, when i register a var and print it in debug mode. That was my first approach on check for the error message. I am running out of ideas, how to filter for a specific error and passing the task, but failing on everything else. ignore_errors: yes is not a good solution, because the task should fail in some cases.
As per ansible doc we get stdout and stderr as return fields.
I would suggest to use flag ignore_errors: yes and catch the return as per this example
---
- hosts: localhost
vars:
user:
name: yash
user_base_path: /tmp
tasks:
- name: modify user
user:
state: "{{ user.state | default('present') }}"
name: "{{ user.name }}"
home: "{{ user_base_path }}/{{ user.name }}"
createhome: true
register: user_status
ignore_errors: yes
- name: stdout_test
debug:
msg: "{{ user_status.err }}"
- name: Fail on not valid
fail:
msg: failed
when: '"user account in use" not in user_status.err'
Output:
PLAY [localhost] *************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************
ok: [localhost]
TASK [modify user] ***********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "err": "<main> attribute status: eDSPermissionError\n<dscl_cmd> DS Error: -14120 (eDSPermissionError)\n", "msg": "Cannot create user \"yash\".", "out": "", "rc": 40}
...ignoring
TASK [stdout_test] ***********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "<main> attribute status: eDSPermissionError\n<dscl_cmd> DS Error: -14120 (eDSPermissionError)\n"
}
TASK [Fail on not valid] *****************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "failed"}
PLAY RECAP *******************************************************************************************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=1
You can use when, save the return value by the register and set_fact and then bet what will happen according to that value.

Ansible playbook is failing for 'become:yes'

The following ansible-playbook works fine for non-sudo access.
But fails when I un-comment become:yes
---
- hosts: all
become: yes
tasks:
- name: Register the policy file in a variable
read_csv:
path: policy.csv
delegate_to: localhost
register: csv_file
- name: Check rules pre-remediation
command: "{{ item.Compliance_check }}"
register: output
with_items:
"{{ csv_file.list }}"
- name: Perform remediation
command: "{{ item.item.Remediation }}"
when: item.item.Expected_result != item.stdout
with_items:
"{{ output.results }}"
The inventory file looks like:
10.136.59.110 ansible_ssh_user=username ansible_ssh_pass=password ansible_sudo_pass=password
Error I'm facing is:
user#hostname:~/git-repo/MCI$ ansible-playbook playbook.yaml -i inventory
PLAY [all] *******************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************
ok: [10.136.59.109]
TASK [Register the policy file in a variable] ********************************************************************************************
Sorry, try again.
fatal: [10.136.59.109 -> localhost]: FAILED! => {"changed": false, "module_stderr": "[sudo via ansible, key=mjcqjbcyeemygkxwycgeftiikivnylsj] password:\nsudo: no password was provided\nsudo: 1 incorrect password attempt\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
PLAY RECAP *******************************************************************************************************************************
10.136.59.109 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Can't understand why this error is showing. I have tried providing correct sudo passwords in both inventory as well as at run-time using --ask-become-pass
Please help find out the cause of the error.

ansible: failed_when is not working to validate user input

i am trying ansible playbook to prompt for a user input and if condition is not satisfied it should fail & exit.
my playbook is as below.
[ansible#localhost ~]$ cat dummy.yml
---
- name: testing failed_when
hosts: localhost
gather_facts: no
tasks:
- pause:
prompt: "\nPlease ente 1:\n"
register: given
failed_when: given.user_input != 1
- set_fact:
SER: "{{ given.user_input }}"
- fail:
msg: "unacceptable"
when: SER is undefined
and when i execute this, it's getting failed even though i give input as 1..
[ansible#localhost ~]$ ansible-playbook dummy.yml
PLAY [testing failed_when] *********************************************************************************************************************
TASK [pause] ***********************************************************************************************************************************
[pause]
Please ente 1:
:1
fatal: [localhost]: FAILED! => {"changed": false, "delta": 1, "echo": true, "failed_when_result": true, "rc": 0, "start": "2020-05-29 02:52:27.318633", "stderr": "", "stdout": "Paused for 0.02 minutes", "stop": "2020-05-29 02:52:28.556987", "user_input": "1"}
NO MORE HOSTS LEFT *****************************************************************************************************************************
PLAY RECAP *************************************************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
[ansible#localhost ~]$
and i have tried using "fail" as shown below, it's not working too.
tasks:
- pause:
prompt: "\nPlease ente 1:\n"
register: given
- set_fact:
SER: "{{ given.user_input }}"
- fail:
msg: "unacceptable"
when: SER != 1
result:
[ansible#localhost ~]$ ansible-playbook dummy.yml
PLAY [testing failed_when] *********************************************************************************************************************
TASK [pause] ***********************************************************************************************************************************
[pause]
Please ente 1:
:1
ok: [localhost]
TASK [set_fact] ********************************************************************************************************************************
ok: [localhost]
TASK [fail] ************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "unacceptable"}
PLAY RECAP *************************************************************************************************************************************
localhost
in both of above cases, i have entered "1" as user input & it's still failing.. Not sure what mistake i did.
please help.
thanks in advance.
The condition when expands by default the variable to string. Either compare SER to string
when: SER != "1"
or convert SER to integer
when: SER|int != 1

ansible ios_command timeout when doing "show conf" on cisco 3850

I've got a simple ansible playbook that works fine on most ios devices. It fails on some of my 3850 switches with what looks like a timeout when doing a "show conf". How do I specify a longer, non-default timeout for command completion with the ios_command module (and presumably also ios_config)?
Useful details:
Playbook:
---
- hosts: ios_devices
gather_facts: no
connection: local
tasks:
- name: OBTAIN LOGIN CREDENTIALS
include_vars: secrets.yaml
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
- name: LIST NAME SERVERS
ios_command:
provider: "{{ provider }}"
commands: "show run | inc name-server"
register: dns_servers
- debug: var=dns_servers.stdout_lines
successful run:
$ ansible-playbook listnameserver.yaml -i inventory/onehost
PLAY [ios_devices] *****************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] ****************************************************************************************************
ok: [iosdevice1.example.com]
TASK [DEFINE PROVIDER] *************************************************************************************************************
ok: [iosdevice1.example.com]
TASK [LIST NAME SERVERS] ***********************************************************************************************************
ok: [iosdevice1.example.com]
TASK [debug] ***********************************************************************************************************************
ok: [iosdevice1.example.com] => {
"dns_servers.stdout_lines": [
[
"ip name-server 10.1.1.166",
"ip name-server 10.1.1.168"
]
]
}
PLAY RECAP *************************************************************************************************************************
iosdevice1.example.com : ok=4 changed=0 unreachable=0 failed=0
unsuccessful run:
$ ansible-playbook listnameserver.yaml -i inventory/onehost
PLAY [ios_devices] *****************************************************************************************************************
TASK [OBTAIN LOGIN CREDENTIALS] ****************************************************************************************************
ok: [iosdevice2.example.com]
TASK [DEFINE PROVIDER] *************************************************************************************************************
ok: [iosdevice2.example.com]
TASK [LIST NAME SERVERS] ***********************************************************************************************************
fatal: [iosdevice2.example.com]: FAILED! => {"changed": false, "msg": "timeout trying to send command: show run | inc name-server", "rc": 1}
to retry, use: --limit #/home/sample/ansible-playbooks/listnameserver.retry
PLAY RECAP *************************************************************************************************************************
iosdevice2.example.com : ok=2 changed=0 unreachable=0 failed=1
The default timeout is 10 seconds if the request takes longer than this ios_command will fail.
You can add the timeout as a key in the provider variable, like this:
- name: DEFINE PROVIDER
set_fact:
provider:
host: "{{ inventory_hostname }}"
username: "{{ creds['username'] }}"
password: "{{ creds['password'] }}"
timeout: 30
If you've already got a timeout value in provider here's a handy way to update only that key in the variable.
- name: Update existing provider timeout key
set_fact:
provider: "{{ provider | combine( {'timeout': '180'} ) }}"

Resources