一、实验运行环境

1.1 主机操作系统

1.1.1 Window 10上运行Centos8(VMware虚拟机)

1.2 网络设备

1.2.1 Ensp模拟器上运行的华为三层交换机Quidway S5700-28C-HI

1.3 网络设备OS版本

1.3.1 华为IOS

1.4 Python版本

1.4.1 2

二、实验拓扑

实验六拓扑图

三、实验所用地址

3.1 局域网IP段

3.1.1 0/24

3.2 运行Python的Centos主机

3.2.1 20/24

3.3 SW1

3.3.1 11/24

3.4 SW2

3.4.1 12/24

3.5 SW3

3.5.1 23/24

注意:实验环境必须要在同一网段,这里用不同地址代表不同网段

四、实验目的

4.1 将交换机SW2登录密码修改为456并将交换机SW3的G0/0/3的接口shutdown,用来演示异常处理效果

4.2 创建一个带有try...except...异常处理语句的脚本来批量在交换机SW1-SW3上执行display clock命令,让脚本在SW2、SW3分别因为密码错误以及联通性出现故障的同时,依然不受干扰继续执行配置

五、实验准备

5.1 将交换机SW2登录密码修改为456

实验六图一

5.2 将交换机SW3的G0/0/3的接口shutdown

实验六图二

5.3 在虚拟机上创建一个包含交换机SW1、SW2、SW3的管理地址的文本文件,名为ip_list.txt

实验六图三

5.4 在虚拟机上创建一个包含执行命令'dis clock'的文件,名为cmd.txt

实验六图四

六、实验步骤

6.1 每台交换机提前配好SSH,这里不做过多描述,如有需要请参考SSH配置实验

6.2 配置互联地址,并进行Ping测试,这里不做演示

6.3 建议提前手工远程登录交换机进行测试

6.4 在虚拟机上创建名为errors.py的脚本,具体操作如下

6.4.1 执行命令'vi errors.py'创建脚本

6.4.2 输入'i'进入编辑模式

6.4.3 编写脚本内容

##使用import语句导入paramiko模块、time模块和getpass模块
import paramiko
import time
#方便将getpass.getpass("password: ")简写成getpass("password: ")
from getpass import getpass
import sys
import socket

#使用input()函数以及getpass模块实现交互式输入用户名和密码
username = input("Username: ")
password = getpass("password: ")
#获取运行 Python 程序的命令行的第一个参数(在这里具体指python3.8后面的ip_list.txt)
ip_file = sys.argv[1]
#获取运行 Python 程序的命令行的第二个参数(在这里具体指python3.8后面的cmd.txt)
cmd_file = sys.argv[2]

#创建名为switch_with_authentication_issue和switch_not_reachable的两个空列表
switch_with_authentication_issue = []
switch_not_reachable = []

#以只读的权限读取名为ip_list.txt的文件并将文件内容赋值给变量iplist
iplist = open(ip_file)
#一行一行读取ip_list.txt文件内容并将其赋值给变量line
for line in iplist.readlines():
#使用try...except...语句进行异常处理
    try:
#将ip进行去除首尾空行处理
        ip = line.strip()
#调用Paramiko的SSHClient()方法,将其赋值给变量ssh_client
        ssh_client = paramiko.SSHClient()
#使用ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())来让Paramiko接受服务端提供的公钥
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#调用paramiko.SSHClient()的函数connect()进行SSH登录,look_for_keys=False用来解决避免Paramiko使用已存在密钥来登录设备
        ssh_client.connect(hostname=ip, username=username, password=password, look_for_keys=False)
#打印提示信息
        print("--------------------------------------------------------")
        print(f"You have successfully connect to {ip}!!!")
#调用Paramiko的SSHClient()的invoke_shell()方法来唤醒shell,即设备命令行
        command = ssh_client.invoke_shell()
#设置屏显长度为0
        command.send('screen-length 0 temporary\n')
#以只读的权限读取名为cmd.txt的文件并将文件内容赋值给变量cmmand
        cmdlist = open(cmd_file)
#将文件指针移到开头位置
        cmdlist.seek(0)
#一行一行读取cmd.txt文件内容并将其赋值给变量line
        for line in cmdlist.readlines():
#执行cmd.txt文件里命令
            command.send(line + "\n")
#调用time模块下的sleep()函数手动让Python休眠2秒
        time.sleep(2)
#关闭文件
        cmdlist.close()
#设置命令行最大回显内容数并将其赋值给变量output并用decode("ascii")将其解析为ASCII编码
        output = command.recv(65535).decode('ascii')
        print(output)
#若符合认证错误则执行except语句
    except paramiko.ssh_exception.AuthenticationException:
#打印认证失败交换机的IP
        print(f"User authentication failed ip is: {ip}.")
#将认证失败交换机的IP添加到名为switch_with_authentication_issue的空列表中
        switch_with_authentication_issue.append(ip)
#若符合目的不可达错误则执行except语句
    except socket.error:
#打印目的不可达的IP
        print(f"{ip} is not reachable!")
#将目的不可达的IP添加到名为switch_not_reachable的列表
        switch_not_reachable.append(ip)
#关闭文件ip_list.txt文件
iplist.close()
#断开SSH连接
ssh_client.close()
#一个一个打印认证失败设备交换机的全部IP
print("----------------------------------------------")
print("User authentication failed for below switches: ")
for i in switch_with_authentication_issue:
    print(i)
#一个一个打印目的不可达设备交换机的全部IP
print("----------------------------------------------")
print("Below switches are not reachable: ")
for i in switch_not_reachable:
    print(i)

6.4.4 执行命令'chmod +x errors.py'赋予脚本可执行权限

切记:不给权限执行脚本会报错

6.4.5 执行命令'python3.8 errors.py ip_list.txt cmd.txt'跑脚本

这里ip_list.txt对应的是sys.argv[1],cmd.txt对应的是sys.argv[2]

6.4.6 跑完脚本结果如下:

实验六图五

6.4.7 结果和预期的一样,说明实验已经成功