Python3 自动登录全部交换机查询MAC所在端口


#_*_ coding:utf8 _*_
import paramiko     # SSH 登录操作模块
import time
import re           # 字符匹配查找模块

import logging      # 日志
Log = logging.getLogger("__name__") # 获取实例
formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s') # 指定logger输出格式
file_handler = logging.FileHandler("Network_H3C.log") # 日志文件路径
file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式
Log.addHandler(file_handler) # 为logger添加的日志处理器
# 设置记录的日志级别
Log.setLevel(logging.DEBUG)
#Log.setLevel(logging.INFO)
#Log.setLevel(logging.WARNING)
#Log.setLevel(logging.ERROR)
#Log.setLevel(logging.CRITICAL)

## 各交换机信息字典,用于判断查到的接口是接的交换机还是电脑
S1 = {
    'Version':'H3C Sxxxx-xx-xx',
    'GigabitEthernet1/0/1':['防火墙'],
    'GigabitEthernet1/0/2':['Switch','192.168.0.2'],
    'GigabitEthernet1/0/2':['Switch','192.168.0.3'],
    'GigabitEthernet1/0/3':['Null'],
    'GigabitEthernet1/0/4':['Host'],
    'GigabitEthernet1/0/19':['2F']
    }

S2 = {
    'Ethernet1/0/1':['核心'],
    'Ethernet1/0/2':['Switch','192.168.0.21'],
    'Ethernet1/0/3':['Host']
    }

S3 = {
    'Ethernet1/0/1':['核心'],
    'Ethernet1/0/2':['Switch','192.168.0.31'],
    'Ethernet1/0/3':['Host']
    }

S21 = {
    'Ethernet1/0/1':['Host'],
    'Ethernet1/0/2':['Host'],
    'GigabitEthernet1/0/25':['上级Switch','192.168.0.2'],
    'GigabitEthernet1/0/26':['Host']
    }

S31 = {
    'Ethernet1/0/1':['Host'],
    'Ethernet1/0/2':['Host'],
    'GigabitEthernet1/0/25':['上级Switch','192.168.0.3'],
    'GigabitEthernet1/0/26':['Host']
    }

## 全部交换机的对应信息
SWITCH = {
    '192.168.0.1':S1, '192.168.0.2':S2, '192.168.0.3':S3, '192.168.0.21':S21, '192.168.0.31':S31}


## 功能
def 查找MAC(深度,IP,mac):
    if 深度 > 0:
        print("剩余深度",深度)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(IP, 22, '用户名', '密码')   # 这里设置填写交换机的地址端口用户名和密码,要根据实际情况设置
        
        switch = ssh.invoke_shell()
        time.sleep(1)
        #print(switch.recv(1024))
        
        r = ''                                  # r 用来存储查找结果,先设置为空
        CMD = 'display mac-address ' + mac      # 组装执行的命令
        switch.sendall(CMD + '\n')  
        time.sleep(1)                           # 各交换机1秒反应时间
        r = switch.recv(1024).decode('utf-8')   # 把执行结果全部保存到 r
        print(r)
        Log.debug(r)
        PORT = re.search(r"[G|E](.*)[0-9]", r)  # 匹配G或E开头数字结尾的内容:GigabitEthernet1/0/1 or Ethernet1/0/1
        if PORT:
            DEBUG = "发现 MAC" + str(PORT)
            print(DEBUG)
            Log.debug(DEBUG)
            ssh.close()                                   # 交换机上的操作已经完成,可以关闭连接
            if SWITCH[IP][PORT.group()][0] == 'Switch':   # 如果查到的接口是接的交换机
                深度 = 深度 -1                            # 准备继续查询下一级的交换机,设置深度,防止错误设置造成无限循环
                IP = SWITCH[IP][PORT.group()][1]          # 从设置的交换机信息字典中查询下一级交换机的IP地址
                R = 查找MAC(深度,IP,mac)                  # 迭代执行,接收返回值
                return(R)                                 # 迭代执行必须每次都有返回给上级,不然外部接收不到返回内容,出现返回为 "None"
            else:                                         # 如果不是交换机
                return(0,IP,PORT.group())                 # 返回状态码(可以0表示)、MAC所在的交换机IP、端口
        else:
            INFO = '在 ' + IP + ' 未发现 ' + MAC
            ssh.close()
            Log.info(INFO)
            return(1,INFO)
    else:
        ERROR = IP + '的 ' + PORT.group() + ' 超出深度'
        Log.error(ERROR)
        return(1,ERROR)

## 把用户输入的MAC地址格式转换为交换机使用的格式
def New_MAC(MAC):
    mac = re.sub('[^a-fA-F0-9]', '', MAC)   # 删除不是16进制范围内容
    print(MAC)
    print(mac)
    print(len(mac))
    if len(mac) == 12:
        new_mac = mac[0:4] + '-' + mac[4:8] + '-' + mac[8:12] # 改成新格式 xxxx-xxxx-xxxx
        print(new_mac)
        print(new_mac.lower())
        return(0, new_mac.lower())
    else:
        print("ERROR", mac)
        return(1,'')


深度 = 3 # 设置本此最深可以进入第3级交换机
IP = '192.168.0.1' # 起始查找位置,使用核心交换机IP比较好

## 使用 CLI 命令行模式运行比较方便
import sys
if len(sys.argv) == 2:
    MAC = sys.argv[1]
    X = New_MAC(MAC)
    if X[0] == 0: 
        R = 查找MAC(深度,IP,X[1])
        print(R)
        if R[0] == 0:
            IP = R[1]
            PORT = R[2]
            INFO = '已找到,在 ' + str(IP) + ' 的 ' + str(PORT) + ' 详细信息 ' + str(SWITCH[IP][PORT])
            Log.info(INFO)
            print('V', INFO)
        else:
            INFO = R[1]
            Log.info(INFO)
            print('X',R[1])
    else:
        WARNING = "MAC有误,程序终止"
        Log.warning(WARNING)
        print(WARNING)
else:
    WARNING = "参数有误,参数只能一个MAC地址"
    Log.warning(WARNING)
    print(WARNING)

 

你可能感兴趣的:(python)