關於使用python批量操作網絡設備(交換機,路由器)的知識點小結


關於使用python批量操作網絡設備,這里本人目前只接觸了兩個模塊,netmiko和pratmiko,后面的腳本也都將基於這兩個模塊。

一、netmiko模塊

1、使用netmiko模塊連接操作設備

import netmiko          #導入netmiko模塊
import time             #導入time模塊


#使用with語句打開用於ssh連接所需要的相關信息(用戶名,密碼,ip地址,需要配置的命令),這個打開了兩個文件用戶信息文件,命令文件,分別命名為devices_file,cmd_file
with open("ip_user_pass.txt", "r") as devices_file, open("cmdlist.txt", "r") as cmd_file: #將用戶信息文件按行讀取賦值給devices
    devices = devices_file.readlines() #將命令文件按行讀取賦值給cmdlist
    cmdlist = cmd_file.readlines() #使用循環將用戶名,密碼,IP地址,分別賦值給username,password,ip_address變量,並依次登陸
    for line in devices: line = line.strip("\n") ip_address = line.split(",")[0]   #split() 通過指定分隔符對字符串進行切片,如果參數 num 有指定值,則分隔 num+1 個子字符串
        username = line.split(",")[1] password = line.split(",")[2] #創建一個名為SW2的字典,該字典包含“device_type”“ip”“username”和“password”4個必選的鍵,如果設備類型是netmiko不支持的類型,不清楚還能不能連接
        SW2 = { 'device_type': 'huawei', 'ip': ip_address, 'username': username, 'password': password, } connect = netmiko.ConnectHandler(**SW2)     #函數ConnectHandler()。該函數用來實現SSH登錄網絡設備,是Netmiko最重要的函數。
        print("Successfully connect to" + SW2['ip']) #config_commands = ['dis arp']
        #output = connect.send_config_set(config_commands)
        #rint(output)


        #使用循環將cmdlist中的命令依次輸入
        for cmd in cmdlist: output2 = connect.send_config_set(cmd)    #send_config_set()則可向設備一次輸入多個命令
            print(output2) time.sleep(1) print("*" * 50 + "分割線" + "*" * 50) #result = connect.send_command('dis int LoopBack 0')
        #print(result)

腳本運行結果如下:

 

2、ssh_netmiko_多線程

使用netmiko實現多線程操作網絡設備

 

#coding=utf-8
import threading        #Python 3已經內置了threading模塊來實現多線程,這里引入
from queue import Queue   #多線程中需要用的隊列,這里引入,多線程中需要用的隊列,這里引入,通過隊列傳遞數據,安全,不會造成多個線程訪問時混亂
import netmiko
import time


#定義連接函數,使用netmiko連接設備,並輸入預定義命令
def ssh_session(ip, username, password,cmdlist, output_q):
    SW2 = {
        'device_type': 'huawei',
        'ip': ip_address,
        'username': username,
        'password': password,
        }


    connect = netmiko.ConnectHandler(**SW2)
    print("Successfully connect to" + SW2['ip'])
    '''
    config_commands = ['dis arp', 'dis ip routing-table', 'dis int brief']
    output = connect.send_config_set(config_commands)
    print(output)
    print("*" * 50 + "分割線" + "*" * 50)
    '''

    for cmd in cmdlist:
        output = connect.send_config_set(cmd)
        print(output)
        time.sleep(1)
        print("*" * 50 + "分割線" + "*" * 50)

    #result = connect.send_command('dis int LoopBack 0')
    #print(result)



print("程序於 {} 開始執行\n".format(time.strftime("%X")))
threads = []
with open("ip_user_pass.txt", "r") as devices_file, open("cmdlist.txt", "r") as cmd_file:
    devices = devices_file.readlines()
    cmdlist = cmd_file.readlines()
    for line in devices:
        line = line.strip("\n")
        ip_address = line.split(",")[0]   #split() 通過指定分隔符對字符串進行切片,如果參數 num 有指定值,則分隔 num+1 個子字符串
        username = line.split(",")[1]
        password = line.split(",")[2]
        #使用threading的Thread()函數為ssh_session函數創建一個線程並將它賦值給變量t,注意Thread()函數的target參數對應的是函數名稱(即ssh_session)
        #args對應的是該ssh_session函數的參數
        t = threading.Thread(target=ssh_session, args=(ip_address, username, password, cmdlist, Queue()))
        t.start()
        threads.append(t)

    
for i in threads:
    i.join()    #threading的join()方法的作用是強制阻塞調用它的線程,直到該線程運行完畢或者終止(類似單線程同步)

print("程序於 {} 執行結束\n".format(time.strftime("%X")))

 

腳本缺少錯誤控制加入try語句,可以更好的應用腳本,不會因為地址和用戶名密碼錯誤導致腳本中斷,另外關於腳本里的使用了隊列實現線程控制,但是為什么要寫成這個形式

 t = threading.Thread(target=ssh_session, args=(ip_address, username, password, cmdlist, Queue())),目前我還不太了解。希望知道原理的大大能告訴我一下~

 

二、prarmiko模塊

1、使用prarmiko模塊連接網絡設備操作(連接協議ssh)

'''
需在命令行運行程序,並給四個文件參數,存放ip的文件在前,存放命令的文件在后,例如:python lab3_1.py ip.txt cmdlist.txt username.txt password.txt
'''


import paramiko
import time
import getpass
import sys
import socket


#username = input("username:")
#password = getpass.getpass("password:")
ip_file = sys.argv[1]       #sys.argv[]就是一個從程序外部獲取參數的橋梁,外部取得的參數可以是多個,所以獲得的是一個列表(list),其第一個元素是程序本身,隨后才依次是外部給予的參數,                  
cmd_file = sys.argv[2]      #這里使用sys.argv(),即將保存的ip和命令的文件作為參數賦值給變量
user_file = sys.argv[3]
pass_file = sys.argv[4]


switch_with_authentication_issue = []   #認證失敗的列表,用於存放用戶認證失敗的IP地址
switch_not_reachable = []               #連接失敗的列表,用於存放連接失敗的ip地址


#打開文件用戶信息文件,IP地址文件
iplist = open(ip_file, "r")
userlist = open(user_file, "r")
passlist = open(pass_file, "r")


#使用循環按行讀取,文件內容,這個用zip() 函數將可迭代的對象作為參數,將對象中對應的元素打包成一個個元組,然后返回由這些元組組成的對象
#例如:    192.168.1.1    admin    123
for line1, line2, line3  in zip(iplist.readlines(), userlist.readlines(), passlist.readlines()):
    try:
        ip = line1.strip()
        username = line2.strip()
        password = line3.strip()
        ssh_client = paramiko.SSHClient()   #調用paramiko的SSHClient方法連接網絡設備,及本地設備為客戶端
        '''
        默認情況下,Paramiko會拒絕任何未知的SSH公鑰(publickey),這里我們需要使用ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        來讓Paramiko接受SSH服務端(也就是SW3)提供的公鑰,這是任何時候使用Paramiko都要用到的標准配置。
        '''
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())    
        ssh_client.connect(hostname=ip, username=username, password=password)   #調用connect()方法,輸入連接設備所需的ip,用戶名,密碼
        print("登錄成功", ip)
        command = ssh_client.invoke_shell() #調用Paramiko.SSHClient()的invoke_shell()方法來喚醒shell
        cmdlist = open(cmd_file, "r")   #讀入命令文件
        cmdlist.seek(0)      #seek() 方法用於移動文件讀取指針到指定位置,參數為0代表從文件開頭開始算起。
        for line in cmdlist.readlines():
            command.send(line + "\n")
        time.sleep(5)
        cmdlist.close()
        output = command.recv(65535)
        print(output.decode("ascii"))
    except paramiko.ssh_exception.AuthenticationException:
        print("用戶認證失敗:" + ip)
        switch_with_authentication_issue.append(ip)
    except socket.error:
        print(ip + "連接失敗")
        switch_not_reachable.append(ip)


iplist.close()
userlist.close()
passlist.close()
ssh_client.close


print("*" * 50 + "分割線" + "*" * 50)
print("\n用戶認證失敗的交換機:\n")
for i in switch_with_authentication_issue:
    print(i)

print("\n網絡連接失敗交換機:\n")
for i in switch_not_reachable:
    print(i)

 

三、配置文件備份

1、使用netmiko備份,用於備份netmiko支持的設備,使用h3c設備測試此腳本,備份失敗(可能是netmiko中沒有h3c的相關函數)

import netmiko
import time


with open("devices.txt") as devices_file:
    devices = devices_file.readlines()
    for line in devices:
        line = line.strip("\n")
        ipaddr = line.split(",")[0]   #split() 通過指定分隔符對字符串進行切片,如果參數 num 有指定值,則分隔 num+1 個子字符串
        username = line.split(",")[1]
        password = line.split(",")[2]
        vendor = line.split(",")[3]


SW2 = {
    'device_type': vendor,
    'ip': ipaddr,
    'username': username,
    'password': password,
    }



now = time.strftime("%Y-%m-%d", time.localtime())

connect = netmiko.ConnectHandler(**SW2)
print("Successfully connect to" + SW2['ip'])
backup_cfg = connect.send_command("dis cur")    #將命令內容賦值給變量
print(backup_cfg)
#將變量的值寫入文件,文件命名按時間划分
with open( "C:\\ftp\\交換機_"  + str(now) + "_{}.txt".format(ipaddr), "w") as f:
    f.write(backup_cfg)

2、使用prarmiko,基於tftp備份配置文件

首先要搭建一個tftp服務器,使用tftp相關軟件即可

其次運行腳本

import paramiko
import time


with open("ip_user_pass.txt") as devices_file:
    devices = devices_file.readlines()
    for line in devices:
        line = line.strip("\n")
        ip_address = line.split(",")[0]   #split() 通過指定分隔符對字符串進行切片,如果參數 num 有指定值,則分隔 num+1 個子字符串
        username = line.split(",")[1]
        password = line.split(",")[2]
        now = time.strftime("%Y-%m-%d", time.localtime())
        ssh_client = paramiko.SSHClient()
        ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh_client.connect(hostname=ip_address, username=username, password=password)
        print("登陸成功:",ip_address)
        command = ssh_client.invoke_shell()
        command.send("copy startup.cfg {}_{}.cfg\n".format(now,ip_address))
        command.send("y\n")
        command.send("tftp 192.168.134.222 put {}_{}.cfg\n".format(now,ip_address))
        time.sleep(15)
        command.send("delete  {}_{}.cfg\n".format(now,ip_address))
        command.send("y\n")
        time.sleep(5)
        output = command.recv(65535)
        print(output.decode("ascii"))
    ssh_client.close

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM