Credential Checker with Netmiko Direct Task

Hi Kirk,

I was previously discussing this with you a while back. In this scrip I need to check certain creds against network devices for validity with the benefit of Nornir mulithreading, as this test will need to be run against many devices in parallel. Here is my code so far:

def cred_check(task):

with open('lab_inventory') as f:
    file_content = f.read().splitlines()

devices = list()
for item in file_content:
    tmp = item.split(':')
    devices.append(tmp)


cred_list = [('whatever','whatever'),('whatever','whatever'),('whatever','whatever')]

for credentials in cred_list:
    username = credentials[0]
    password = credentials[1]

    verbose = True

    for device in devices:
        net_device = {
            'device_type': 'cisco_ios',
            'ip': device[0],
            'username': username,
            'password': password,
            'host': device[1],
            'port': 22,
            'secret': 'whatever',
            'verbose': True
        }


        try:
            connection = ConnectHandler(**net_device)
        except (AuthenticationException):
            print('Authetication failure: ' + device[1] + str(credentials))
            continue
            print("Found Valid credentials for device: " + device[1] + str(credentials))
        except (NetMikoTimeoutException):
            print ('Timeout to device: ' +  device[1])
            continue
        except (EOFError):
            print ('End of file while attempting device ' + device[1])
            continue
        except (SSHException):
            print ('SSH Issue. No SSH enabled on device ' + device[1])
            paramiko.util.log_to_file("paramiko.log")
            continue


        try:
            if not connection.check_enable_mode():
                connection.enable()
        except ValueError:
            print('Wrong enable password on device: ' + device[1])
            continue

        config_file = open("cmd_file" , "r")
        output = connection.send_config_set(config_file)
        config_file.close()
        print(output)
        print('Sending commands to device.................')
        print('Disconnecting.................')
        print('#' * 40)

        connection.disconnect()

if name == “main”:

nr = InitNornir(config_file="config.yaml")
nr = nr.filter(F(groups__contains="routers"))
nr.run(task=cred_check, num_workers=4)

Whenever I run the code it runs serially, but calls the devices twice. I know I don’t need to have the seperate inventory file in the function, I should probably be passing in these from hosts.yaml, but I’m lost then as to how to pass in the creds list to the Nornir Inventory, any help much appreciated.

Ken

Managed to get this to work with the Nornir Netmiko Plugin, the only issue I have now is trying to suppress the exceptions. I tried from a previous post here to enable logging but this doesn’t do anything
Here’s my code:

def main():

cred_list = [('cisco221','cisco221'), ('bogus', 'bogus'), ('cisco', 'cisco'), ('xa', 'xa')]

try:

    for credentials in cred_list:
                
        username = credentials[0]
        password = credentials[1]

        config = f"./config_file"
        nr = InitNornir(config_file="config.yaml", logging={"enabled": True})
        # nr = nr.filter(F(groups__contains="routers"))
        print("Checking credentials............")

        for hostname, host_obj in nr.inventory.hosts.items():
            host_obj.username = username
            host_obj.password = password
            print(hostname + str(credentials))
        results = nr.run(task=netmiko_send_config, config_file=config, num_workers=4)
        print()
        for k, v in results.items():
            print("-" * 50)
            print(k)
            print(v[0].result)
            print("-" * 50)
        print()
except NornirSubTaskError as e:
    if isinstance(e.result.exception, NetMikoTimeoutException):
        print(f"{task.host.name} : Error! Timeout")
    elif isinstance(e.result.exception, NetMikoAuthenticationException):
        print(f"{task.host.name} : Error! Failed authentication")
    else:
        raise e           

if name == “main”:
main()

And the output, which is a generic traceback:
Traceback (most recent call last):
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/nornir/core/task.py”, line 85, in start
r = self.task(self, **self.params)
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/nornir/plugins/tasks/networking/netmiko_send_config.py”, line 24, in netmiko_send_config
net_connect = task.host.get_connection(“netmiko”, task.nornir.config)
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/nornir/core/inventory.py”, line 302, in get_connection
extras=conn.extras,
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/nornir/core/inventory.py”, line 352, in open_connection
configuration=configuration,
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/nornir/plugins/connections/netmiko.py”, line 58, in open
self.connection = ConnectHandler(**parameters)
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/netmiko/ssh_dispatcher.py”, line 246, in ConnectHandler
return ConnectionClass(*args, **kwargs)
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/netmiko/base_connection.py”, line 317, in init
self._open()
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/netmiko/base_connection.py”, line 322, in _open
self.establish_connection()
File “/home/xadmin/VENV/nornir/lib/python3.6/site-packages/netmiko/base_connection.py”, line 897, in establish_connection
raise NetMikoAuthenticationException(msg)
netmiko.ssh_exception.NetMikoAuthenticationException: Authentication failure: unable to connect cisco_ios cwdwan02:22
Authentication failed.