任意のRTに任意のコマンドを実行して結果を出力するスクリプト


スクリプト

from netmiko import ConnectHandler
from netmiko import NetMikoAuthenticationException
from netmiko import NetMikoTimeoutException
import getpass

Routers = {
"R19" : "192.168.122.19",
"R20" : "192.168.122.20",
"R21" : "192.168.122.21",
"R29" : "192.168.122.29",
"R30" : "192.168.122.30",
"R31" : "192.168.122.31"
}

ipaddr = input("Which router do you want to connect?\navailable router: R19, R20, R21, R29, R30, R31\n: ")
router = Routers.get(ipaddr, f"{ipaddr} does not exist")

for i in router:
    if router == f"{ipaddr} does not exist":
        print("\n",router)
        ipaddr = input("Which router do you want to connect?\navailable router: R19, R20, R21, R29, R30, R31\n: ")
        router = Routers.get(ipaddr, f"{ipaddr} does not exist")
    
uname = input("Please enter your Username: ")
passwd = getpass.getpass("Please enter your Password: ")
cmd = input("Please enter the command you want to execute: ")

Router = ConnectHandler(ip = router, username = uname, password = passwd, device_type = "cisco_xe")

def rtr_function(dev):
    dev.send_command("terminal length 0")
    hostname = dev.send_command("show run | in hostname").split()[1]
    print(f"*****The result of `{cmd}` on {hostname}*****")
    print("\n")
    result = dev.send_command(cmd)
    print(result)
    print("\n")
    dev.disconnect()

try:
    rtr_function(Router)
    except(NetMikoAuthenticationException):
        print("Authentication Failure")
    except(NetMikoTimeoutException):
        print(f"Connecting to {router} Time out")

こだわりポイント

・前回の反省で挙げていた、想定外のルータが指定されたときに入力し直させ、正しい値が入力するまで繰り返させる動作を実装した

出力例

root@*****# python3 output.py
Which router do you want to connect?
available router: R19, R20, R21, R29, R30, R31
: R2

 R2 does not exist
Which router do you want to connect?
available router: R19, R20, R21, R29, R30, R31
: R6

 R6 does not exist
Which router do you want to connect?
available router: R19, R20, R21, R29, R30, R31
: adsljfaldjsf

 adsljfaldjsf does not exist
Which router do you want to connect?
available router: R19, R20, R21, R29, R30, R31
: R19
Please enter your Username: admin
Please enter your Password: 
Please enter the command you want to execute: show ip int bri
*****The result of `show ip int bri` on R19*****


Interface                  IP-Address      OK? Method Status                Protocol
GigabitEthernet0/0         10.19.21.19     YES NVRAM  up                    up      
GigabitEthernet0/1         10.19.29.19     YES NVRAM  up                    up      
GigabitEthernet0/2         10.19.20.19     YES NVRAM  up                    up      
GigabitEthernet0/3         unassigned      YES NVRAM  administratively down down    
GigabitEthernet0/4         unassigned      YES NVRAM  administratively down down    
GigabitEthernet0/5         100.3.19.19     YES NVRAM  up                    up      
GigabitEthernet0/6         100.6.19.19     YES NVRAM  up                    up      
GigabitEthernet0/7         unassigned      YES NVRAM  administratively down down    
Loopback0                  150.19.19.19    YES NVRAM  up                    up      


root@*****# 

次回に向けて

①ipaddr = input("Which router do you want to connect?\navailable router: R19, R20, R21, R29, R30, R31\n: ")
②router = Routers.get(ipaddr, f"{ipaddr} does not exist")
・上記2文を全く同じ形で2回使っているのが気持ち悪い。どうにかしたい。

・ConnectHandler()を使用中にSSHのパスワードがミスマッチすると、Pythonスクリプトのエラーログを返す。おそらく、.establish_connection()に代替すれば解決すると思うのでそれを実装したい

root@*****# python3 output.py
Which router do you want to connect?
available router: R19, R20, R21, R29, R30, R31
: R19
Please enter your Username: admin
Please enter your Password: 
Please enter the command you want to execute: show ip int bri
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/netmiko/base_connection.py", line 884, in establish_connection
    self.remote_conn_pre.connect(**ssh_connect_params)
  File "/usr/lib/python3/dist-packages/paramiko/client.py", line 435, in connect
    self._auth(
  File "/usr/lib/python3/dist-packages/paramiko/client.py", line 764, in _auth
    raise saved_exception
  File "/usr/lib/python3/dist-packages/paramiko/client.py", line 751, in _auth
    self._transport.auth_password(username, password)
  File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 1509, in auth_password
    return self.auth_handler.wait_for_response(my_event)
  File "/usr/lib/python3/dist-packages/paramiko/auth_handler.py", line 250, in wait_for_response
    raise e
paramiko.ssh_exception.AuthenticationException: Authentication failed.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "output.py", line 28, in <module>
    Router = ConnectHandler(ip = router, username = uname, password = passwd, device_type = "cisco_xe")
  File "/usr/lib/python3/dist-packages/netmiko/ssh_dispatcher.py", line 246, in ConnectHandler
    return ConnectionClass(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/netmiko/base_connection.py", line 317, in __init__
    self._open()
  File "/usr/lib/python3/dist-packages/netmiko/base_connection.py", line 322, in _open
    self.establish_connection()
  File "/usr/lib/python3/dist-packages/netmiko/base_connection.py", line 897, in establish_connection
    raise NetMikoAuthenticationException(msg)
netmiko.ssh_exception.NetMikoAuthenticationException: Authentication failure: unable to connect cisco_xe 192.168.122.19:22
Authentication failed.
root@*****# 

うまいこといかないことも多々あるけど楽しすぎる。

この記事が気に入ったらサポートをしてみませんか?