网络工程师的Python之路——抛出认证失败和主机不可达的异常

抛出异常(认证失败、主机不可达)

实验拓扑

一如既往
在这里插入图片描述

不过,SW3的ssh用户名密码不再是eichi 123了,而是将密码修改为456;并且SW4的Ethernet0/0接口是down的,即模拟了认证失败和主机不可达的异常
在这里插入图片描述
在这里插入图片描述
centos8主机上验证:
在这里插入图片描述

需求

  • 登录、主机不可达的异常不受干扰,直接抛出
  • ssh到switch上输出show clock信息

重点

  • 使用sys模块中的argv[x]来输入本地文件 ip_list、cmd_list
    举例: python3 argv[0] argv[1] argv[2] …
    参考资料:argv[x]怎么玩?
    这样做的好处就是,可以根据文件来指定ip、cmd等信息,比如不同厂商的设备输出接口信息命令是不同的(cisco是show ip interface brief、huawei是display ip interface brief),这样就可以在执行程序的时候将文件名称作为参数传给程序中

  • 抛出可能出现的异常

    try:    
    except paramiko.ssh_exception.AuthenticationException:
    	pass
    except socket.error:
       pass
    

交换机的管理地址与需要执行命令的两个本地文件:

[root@localhost ~]# cat ip_list.txt
192.168.2.110
192.168.2.112
192.168.2.113
192.168.2.114
192.168.2.55

[root@localhost ~]# cat cmd.txt
show clock

py程序如下:

import paramiko
from getpass import getpass
import sys
import socket
import time

username = input("Username: ")
password = getpass("Password: ")

#用于读取外部参数  .py结尾的文件默认为argv[0] 其后的从1开始
ip_file = sys.argv[1]
cmd_file = sys.argv[2]

#将认证失败、主机不可达信息记录在一个list中
sw_authentication_issue = []
sw_not_reachable = []

iplist = open(ip_file,'r')
#通过遍历iplist来登录每个switch
for line in iplist.readlines():
    try:
        ip = line.strip()
        ssh_client = paramiko.SSHClient()
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_client.connect(hostname=ip,username=username,password=password)
        print("successfully connected to ",  ip)
        cmd = ssh_client.invoke_shell()
        cmdlist = open(cmd_file,'r')
        #seek()将文件指针从末尾移动到开头,意义是每轮循环都使文件指针指向开头
        cmdlist.seek(0)
        #输入想要得到的命令 这里使用的是show clock
        for line in cmdlist.readlines():
            cmd.send(line + "\n")
        time.sleep(2)
        #注意文件使用完毕后关闭文件
        cmdlist.close()
        output = cmd.recv(65535)
        print(output.decode('ascii'))
    #异常处理的方式,打印语句,append列表,但是程序不会中断,只是将异常抛出了
    except paramiko.ssh_exception.AuthenticationException:
        print("USer authentication failed for " + ip + ".")
        sw_authentication_issue.append(ip)
    except socket.error:
        print(ip + " is not reachable.")
        sw_not_reachable.append(ip)
#for循环结束后,就不使用iplist这个文件了,即关闭即可
iplist.close()
ssh_client.close

#循环输出认证失败的switch
print('\nUser authentication failed for below switches: ')
for i in sw_authentication_issue:
    print(i)

#循环输出主机不可达的switch
print('\nBelow switches are not reachable: ')
for j in sw_not_reachable:
    print(j)

运行程序

在这里插入图片描述
在这里插入图片描述
通过输出的内容可以发现,异常登录的switch并没有中断程序的异常,但是程序并没有按照预期输出,下面开始debug

debug

有问题的点

  • SW5正常登录,正常输入clock内容,其后不应该输出 is not reachable.
  • 主机不可达之后没有指定换行,所以最后一行不应该为空

经过检查发现iplist文件中多了一行;这样就会导致line为空,遍历的ip也是空,这样的ip肯定登陆不了并且会有主机不可达的异常

  • 所以才会在192.168.2.55之后出现这行的输出
  • 因为空的ip也会append到主机不可达的list中,最后也会有一行空的输出
    在这里插入图片描述

正常的输出
在这里插入图片描述

总结

  • readlines()的使用,因为其输出的是一个list,所以要配合strip()的转换
  • 抛出异常的做法,打印?记录?
  • 把控每一个细节,输出内容?抛出的是否确实是有异常的机器
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值