網路自動化已成為現代網路管理的關鍵技術,Python 則憑藉其豐富的函式庫和易用性成為自動化指令碼的首選語言。本文將示範如何結合 Netmiko、PySNMP 等函式庫,實作網路裝置的組態生成、儲存、驗證和更新,並探討如何利用多執行緒和正規表示式進一步提升自動化指令碼的效能和靈活性。透過實際案例,展示如何生成組態範本、使用 SNMP 擷取裝置資訊、利用多執行緒平行處理多個裝置,以及使用正規表示式解析組態文字,實作 Trunk 介面狀態驗證、Loopback 介面建立與描述更新等功能。這些技術的整合應用能顯著提升網路管理效率,降低人為錯誤風險,並提升網路維運的可靠性。
網路工程師的Python自動化 Chapter 2
網路裝置組態範本的生成與儲存
在網路自動化的過程中,生成網路裝置的組態範本是一項重要的任務。瞭解需要為其生成範本的基礎設施裝置的型別至關重要。在生成組態範本時,我們可能希望將生成的組態儲存到檔案中,而不是直接推播到裝置上。這在需要驗證組態或保留將要應用於路由器的組態的歷史記錄時非常有用。
組態範本生成與檔案儲存範例
以下範例展示瞭如何生成組態並將其儲存到檔案中,而不是直接寫入路由器:
from netmiko import ConnectHandler
import os
template = """logging host 192.168.20.5 transport tcp port 514
logging trap 6
interface loopback 30
description "{rtr} loopback interface\""""
username = 'test'
password = "test"
# 步驟1:取得路由器的主機名以用於範本
for n in range(1, 5):
ip = "192.168.20.{0}".format(n)
device = ConnectHandler(device_type='cisco_ios', ip=ip, username='test', password='test')
output = device.send_command("show run | in hostname")
output = output.split(" ")
hostname = output[1]
generatedconfig = template.replace("{rtr}", hostname)
# 步驟2:為每個路由器建立不同的組態檔案
configfile = open(hostname + "_syslog_config.txt", "w")
configfile.write(generatedconfig)
configfile.close()
# 步驟3:驗證生成的組態檔案
print("Showing contents for generated config files....")
for file in os.listdir('./'):
if file.endswith(".txt"):
if ("syslog_config" in file):
hostname = file.split("_")[0]
fileconfig = open(file)
print("\nShowing contents of " + hostname)
print(fileconfig.read())
fileconfig.close()
內容解密:
- 匯入必要的函式庫:使用
netmiko函式庫連線網路裝置,使用os函式庫進行檔案操作。 - 定義組態範本:使用三引號定義了一個多行的組態範本,包含了一個待替換的變數
{rtr}。 - 遍歷裝置並生成組態:透過迴圈遍歷IP地址,連線到每個裝置,取得主機名,並將主機名替換到組態範本中。
- 儲存組態到檔案:將生成的組態儲存到以主機名命名的檔案中。
- 驗證生成的組態檔案:讀取生成的組態檔案並列印其內容,以驗證組態是否正確。
使用SNMP取得裝置資訊
在多廠商環境中,手動建立自定義組態是一項困難的任務。我們可以使用PySNMP函式庫透過簡單網路管理協定(SNMP)取得裝置的詳細資訊。
使用SNMP取得路由器版本和型號範例
# snmp_python.py
from pysnmp.hlapi import *
for n in range(1, 3):
server_ip = "192.168.20.{0}".format(n)
errorIndication, errorStatus, errorIndex, varBinds = next(
getCmd(SnmpEngine(),
CommunityData('mytest', mpModel=0),
UdpTransportTarget((server_ip, 161)),
ContextData(),
ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
)
print("\nFetching stats for...", server_ip)
for varBind in varBinds:
print(varBind[1])
內容解密:
- 匯入PySNMP函式庫:使用
pysnmp.hlapi函式庫進行SNMP操作。 - 遍歷裝置並取得資訊:透過迴圈遍歷IP地址,使用SNMP取得裝置的sysDescr資訊。
- 列印裝置資訊:列印取得到的裝置型號和版本資訊。
多執行緒在網路自動化中的應用
在對多個裝置進行操作時,如何快速完成任務是一個關鍵問題。使用多執行緒可以提高程式的執行效率。
多執行緒的優點
- 提高執行效率:透過平行處理多個裝置,可以顯著減少總的執行時間。
- 增強可擴充套件性:隨著裝置數量的增加,多執行緒可以更好地應對。
Python 自動化網路工程師:平行處理與正規表示式應用
在網路自動化的領域中,如何有效地提升程式的執行效率是個重要的課題。隨著網路規模的擴大,傳統的序列處理方式逐漸顯現出其效率上的瓶頸。因此,引入平行處理的概念變得至關重要。本文將探討如何利用 Python 中的多執行緒技術來實作平行處理,並進一步介紹正規表示式在網路組態解析中的應用。
序列處理的侷限性
在序列處理模式下,程式會逐一對網路裝置進行操作。以下是一個簡單的範例,展示瞭如何使用 netmiko 函式庫序列地連線到多台路由器並擷取其主機名稱:
# serial_query.py
from netmiko import ConnectHandler
from datetime import datetime
startTime = datetime.now()
for n in range(1, 5):
ip = "192.168.20.{0}".format(n)
device = ConnectHandler(device_type='cisco_ios', ip=ip, username='test', password='test')
output = device.send_command("show run | in hostname")
output = output.split(" ")
hostname = output[1]
print("Hostname for IP %s is %s" % (ip, hostname))
print("\nTotal execution time:")
print(datetime.now() - startTime)
內容解密:
- 匯入必要的函式庫:使用
netmiko進行網路裝置連線,使用datetime計算程式執行時間。 - 序列連線多台裝置:透過迴圈逐一連線 IP 地址範圍內的裝置,並擷取其主機名稱。
- 計算執行時間:記錄程式開始與結束的時間,並計算總執行時間。
這種序列處理方式在面對大量裝置時,會導致整體執行時間過長。
平行處理的優勢
為瞭解決序列處理的效率問題,我們可以採用多執行緒技術來實作平行處理。以下範例展示瞭如何使用 threading 模組平行地連線到多台路由器:
# parallel_query.py
from netmiko import ConnectHandler
from datetime import datetime
from threading import Thread
startTime = datetime.now()
threads = []
def checkparallel(ip):
device = ConnectHandler(device_type='cisco_ios', ip=ip, username='test', password='test')
output = device.send_command("show run | in hostname")
output = output.split(" ")
hostname = output[1]
print("\nHostname for IP %s is %s" % (ip, hostname))
for n in range(1, 5):
ip = "192.168.20.{0}".format(n)
t = Thread(target=checkparallel, args=(ip,))
t.start()
threads.append(t)
# 等待所有執行緒完成
for t in threads:
t.join()
print("\nTotal execution time:")
print(datetime.now() - startTime)
內容解密:
- 定義平行處理函式:
checkparallel函式負責連線到指定的 IP 地址並擷取主機名稱。 - 建立並啟動執行緒:為每個 IP 地址建立一個執行緒,並將其加入到
threads列表中。 - 等待所有執行緒完成:使用
join()方法確保所有執行緒完成後再繼續執行後續程式碼。
透過平行處理,我們可以顯著縮短整體執行時間。
正規表示式的應用
在網路組態解析中,正規表示式是一種強大的工具。以下範例展示瞭如何使用正規表示式來識別路由器組態中 trunk 模式的介面:
import re
sampletext = """
interface fa0/1
switchport mode trunk
no shut
interface fa0/0
no shut
interface fa1/0
switchport mode trunk
no shut
interface fa2/0
shut
interface fa2/1
switchport mode trunk
no shut
interface te3/1
switchport mode trunk
shut
"""
sampletext = sampletext.split("interface")
# 檢查 trunk 模式的介面
for chunk in sampletext:
if "mode trunk" in chunk:
intname = re.search(r"(fa|te)\d+/\d+", chunk)
print("Trunk enabled on " + intname.group(0))
內容解密:
- 分割組態文字:根據 “interface” 關鍵字將組態文字分割成多個區塊。
- 使用正規表示式匹配介面名稱:對於包含 “mode trunk” 的區塊,使用正規表示式提取介面名稱。
- 輸出結果:列印出啟用 trunk 模式的介面名稱。
網路工程師的Python自動化工具 Chapter 2
自動化組態驗證與更新
在網路自動化的領域中,驗證和更新網路裝置的組態是至關重要的任務。以下章節將詳細介紹如何使用Python實作對網路裝置的自動化組態驗證與更新。
驗證Trunk介面狀態
在進行網路自動化時,首先需要了解目前網路裝置的組態狀態。以下是一個範例,展示如何解析組態文字並檢查哪些介面被設定為Trunk模式且處於啟用狀態。
sampletext = """
interface fa1/1
switchport mode trunk
no shut
interface te3/1
switchport mode trunk
shut
"""
sampletext = sampletext.split("interface")
for chunk in sampletext:
if ("mode trunk" in chunk):
if ("no shut" in chunk):
intname = re.search("(fa|te)\d+/\d+", chunk)
print("Trunk enabled on " + intname.group(0))
內容解密:
- 文字分割:首先將組態文字按照“interface”關鍵字進行分割,得到多個組態區塊。
- 條件檢查:遍歷每個組態區塊,檢查是否包含“mode trunk”和“no shut”,確保介面被設定為Trunk模式且處於啟用狀態。
- 介面名稱提取:使用正規表示式提取介面名稱,例如“fa1/1”或“te3/1”。
- 結果輸出:列印預出被設定為Trunk模式且啟用的介面名稱。
建立Loopback介面
接下來的範例展示瞭如何驗證多台路由器上是否存在特定的Loopback介面(例如Loopback45),如果不存在,則自動建立該介面。
# usecase_loopback.py
from netmiko import ConnectHandler
from threading import Thread
from pysnmp.entity.rfc3413.oneliner import cmdgen
cmdGen = cmdgen.CommandGenerator()
threads = []
def checkloopback45(ip, interface):
loopbackpresent = False
# 使用SNMP查詢介面資訊
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd(
cmdgen.CommunityData('mytest'),
cmdgen.UdpTransportTarget((ip, 161)),
0, 25,
'1.3.6.1.2.1.2.2.1.2'
)
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
if (interface in val.prettyPrint()):
loopbackpresent = True
break
if loopbackpresent:
print("\nFor IP %s interface %s is present" % (ip, interface))
else:
print("\nFor IP %s interface %s is NOT present. Pushing the config" % (ip, interface))
pushconfig(ip, interface)
def pushconfig(ip, interface):
print("\nConfiguring router %s now..." % (ip))
device = ConnectHandler(device_type='cisco_ios', ip=ip, username='test', password='test')
configcmds = ["interface " + interface, "description " + interface + " test interface created"]
device.send_config_set(configcmds)
checkloopback45(ip, interface)
for n in range(1, 5):
ip = "192.168.20.{0}".format(n)
t = Thread(target=checkloopback45, args=(ip, "Loopback45",))
t.start()
threads.append(t)
# 等待所有執行緒完成
for t in threads:
t.join()
內容解密:
- SNMP查詢:使用PySNMP函式庫透過SNMP協定查詢路由器的介面資訊。
- 介面存在性檢查:檢查查詢結果中是否存在指定的Loopback介面。
- 組態推播:如果Loopback介面不存在,則使用Netmiko函式庫推播組態到路由器,建立該介面並設定描述。
- 多執行緒處理:使用多執行緒技術平行處理多台路由器的查詢和組態任務,提高效率。
動態組態更新
在某些場景下,需要根據實際情況動態更新網路裝置的組態。以下範例展示瞭如何檢查Loopback45介面的描述,如果描述中包含特定的文字,則更新描述為新的文字。
def pushconfig(ip, interface, description):
print("\nUpdating the config on " + ip)
device = ConnectHandler(device_type='cisco_ios', ip=ip, username='test', password='test')
configcmds = ["interface " + interface, "description " + interface + " " + description]
device.send_config_set(configcmds)
checkloopback45(ip, interface)
def checkloopback45(ip, interface):
loopbackpresent = False
# 使用SNMP查詢介面資訊和描述
# ...
內容解密:
- 條件檢查:檢查Loopback45介面是否存在以及其描述是否符合特定條件。
- 組態更新:如果條件符合,則更新介面的描述。
- 驗證:更新後再次驗證介面的狀態和描述。
透過上述範例,可以看出Python在網路自動化中的強大能力,能夠簡化網路工程師的工作,提高效率並減少錯誤。