網路自動化指令碼需要具備檔案傳輸、資料視覺化等功能以提升管理效率。本文以 Python 搭配 Netmiko 和 matplotlib 模組示範如何收集網路裝置資訊、繪製圖表、進行軟體升級及告警處理。首先,透過 Netmiko 連線至 Cisco 路由器,收集特定介面頻寬資料,並利用 matplotlib 繪製成圖表,方便觀察網路流量變化。接著,示範如何使用 Netmiko 將檔案傳輸至 Cisco 裝置,執行軟體升級流程,包含上傳檔案、驗證檔案完整性、設定啟動檔案及重新啟動裝置等步驟。最後,介紹如何從 Juniper 裝置收集告警資訊,利用正規表示式解析告警訊息,統計不同嚴重程度的告警數量,並將所有資訊匯出至 Excel 報表,實作告警資訊的集中管理與分析。

網路自動化中的檔案傳輸與繪圖功能

在前面的章節中,我們學習瞭如何使用不同的Python模組來進行網路自動化任務。本章節將重點介紹檔案傳輸和繪圖功能,特別是如何使用ftplibftprettyparamikonetmikonornir等模組來傳輸檔案,以及如何使用matplotlib模組來繪製從網路裝置收集的資料。

使用Netmiko收集和繪製路由器的介面頻寬值

以下是一個例子,展示如何使用Netmiko連線到Cisco路由器,並收集其GigabitEthernet0/1介面的輸入和輸出頻寬值,然後使用matplotlib繪製這些值。

程式碼範例

from matplotlib import pyplot as plt
import re
from netmiko import Netmiko
from time import sleep
from datetime import datetime

# 設定裝置資訊
host = {"host": "10.10.10.1", "username": "admin", "password": "cisco", "device_type": "cisco_ios", "global_delay_factor": 0.1}
count = 5  # 收集資料的次數
delay = 3  # 每次收集之間的延遲(秒)
interface = "GigabitEthernet0/1"  # 要監控的介面
command = f"show interfaces {interface}"  # 要執行的命令

inbound_rate = []  # 輸入頻寬值列表
outbound_rate = []  # 輸出頻寬值列表
time_list = []  # 時間戳列表

# 連線到裝置
net_connect = Netmiko(**host)

for i in range(1, count):
    output = net_connect.send_command(command)
    time = datetime.now().strftime("%H:%M:%S")
    time_list.append(time)
    
    # 使用正規表示式提取輸入和輸出頻寬值
    input_level = re.findall("5 minute input rate (\d+)", output)
    output_level = re.findall("5 minute output rate (\d+)", output)
    
    inbound_rate.append(int(input_level[0]))
    outbound_rate.append(int(output_level[0]))
    
    sleep(delay)
    
    print("Input Level: ", input_level[0])
    print("Output Level: ", output_level[0])

# 繪製輸入和輸出頻寬值
plt.plot(time_list, inbound_rate, color="blue", label="Inbound")
plt.plot(time_list, outbound_rate, color="red", label="Outbound")
plt.xlabel("Time")
plt.ylabel("Interface Levels in MBs")
plt.title(f"Interface Rate of {host['host']} - {interface}")
plt.show()

內容解密:

  1. 設定裝置資訊:首先,我們設定了要連線的裝置的資訊,包括主機IP、使用者名稱、密碼、裝置型別等。
  2. 初始化變數:我們初始化了幾個列表來儲存輸入頻寬值、輸出頻寬值和時間戳。
  3. 連線到裝置:使用Netmiko的Netmiko類別連線到Cisco路由器。
  4. 收集資料:在迴圈中,我們傳送命令到裝置,提取輸入和輸出頻寬值,並將它們儲存在相應的列表中。
  5. 繪製資料:最後,我們使用matplotlib的plot函式繪製輸入和輸出頻寬值。

重點回顧

  • 使用ftplibftprettyparamikonetmikonornir等模組進行檔案傳輸。
  • 使用matplotlib模組繪製從網路裝置收集的資料。

練習題

  1. 使用paramiko模組下載三台裝置的組態檔案,並使用concurrent模組實作平行下載。
  2. 從一台裝置收集所有警示,統計Minor、Major、Critical警示的數量,並使用matplotlib繪製柱狀圖。

第7章:維護和故障排除網路問題

本章將重點介紹如何使用Python腳原本維護和故障排除網路問題,包括升級網路裝置、收集警示、使用SNMP通訊、傳送電子郵件通知以及進行網路連通性測試。

升級網路裝置

升級網路裝置通常涉及三個步驟:上傳新的軟體檔案、設定啟動檔案以及重新啟動裝置。以下是一個例子,展示如何使用Netmiko升級Cisco裝置。

程式碼範例

from netmiko import Netmiko, file_transfer
from re import findall
import os

# 設定裝置資訊
device = {"host": "10.10.10.1", "username": "admin", "password": "cisco", "device_type": "cisco_ios", "global_delay_factor": 0.1}
filename = "universalk9.17.08.01.bin"  # 新的軟體檔案名稱
set_software = [f"boot system {filename}", "config-register 0x2102"]  # 設定啟動檔案的命令
local_filesize = os.path.getsize(filename)  # 本地軟體檔案的大小

# 連線到裝置並傳輸軟體檔案
net_connect = Netmiko(**device)

內容解密:

  1. 設定裝置資訊:首先,我們設定了要連線的裝置的資訊。
  2. 設定軟體檔案資訊:我們指定了新的軟體檔案名稱、設定啟動檔案的命令以及本地軟體檔案的大小。
  3. 連線到裝置:使用Netmiko連線到Cisco裝置。

本章節將繼續介紹如何完成升級過程,包括設定啟動檔案和重新啟動裝置。

網路裝置軟體升級與告警收集實務

在網路管理中,軟體升級和告警收集是兩項重要的任務。本文將透過 Netmiko 工具展示如何實作這些功能。

使用 Netmiko 升級網路裝置軟體

步驟解析

  1. 連線設定:首先,我們需要設定裝置的連線資訊,包括主機 IP、使用者名稱、密碼和裝置型別。

  2. 檔案傳輸:使用 file_transfer 函式將新的軟體檔案上傳到裝置。

  3. 驗證檔案:執行 dir 命令來確認新軟體檔案的大小是否與本地檔案一致。

  4. 設定啟動檔案:使用 send_config_set 方法設定裝置的啟動檔案。

  5. 儲存設定:執行 wr 命令儲存設定變更。

  6. 重新載入裝置:如果所有條件滿足(檔案大小一致且啟動設定正確),則執行 reload 命令重新載入裝置。

程式碼範例

from netmiko import Netmiko, file_transfer
from re import findall
import os

# 裝置連線資訊
device = {
    "host": "10.10.10.1",
    "username": "admin",
    "password": "cisco",
    "device_type": "cisco_ios",
    "global_delay_factor": 0.1
}

filename = "universalk9.17.08.01.bin"
set_software = [f"boot system {filename}", "config-register 0x2102"]
local_filesize = os.path.getsize(filename)

# 建立連線並傳輸檔案
net_connect = Netmiko(**device)
file_transfer(net_connect, source_file=filename, dest_file=filename, direction="put")

# 驗證檔案大小
output = net_connect.send_command(f"dir | include {filename}")
remote_filesize = findall("\d+", output)

# 設定啟動檔案並儲存設定
net_connect.send_config_set(set_software)
output = net_connect.send_command(f"show run | include {filename}")
boot_set = findall(set_software[0], output)
net_connect.send_command(f"wr")

# 檢查條件並重新載入裝置
if str(local_filesize) == remote_filesize[1] and set_software[0] == boot_set[0]:
    print("File is uploaded and set to boot successfully")
    net_connect.send_command("reload", expect_string="Proceed with reload")
    net_connect.send_command_timing("\n", delay_factor=1)
else:
    print("File upload or setting software as boot is failed")
    net_connect.disconnect()

內容解密:

  • file_transfer 函式用於將本地檔案傳輸到遠端裝置。
  • send_command 方法用於向裝置傳送命令並接收輸出。
  • findall 函式用於從命令輸出中擷取特定的資訊,如檔案大小。
  • send_config_set 方法用於向裝置傳送組態命令。
  • 條件檢查確保檔案傳輸和啟動設定正確無誤後才重新載入裝置。

蒐集 Juniper 裝置告警資訊

步驟解析

  1. 匯入必要模組:匯入 Netmikorepandas 模組。

  2. 定義裝置清單:列出需要收集告警資訊的 Juniper 裝置 IP。

  3. 迴圈連線裝置:使用迴圈逐一連線到每個裝置,執行 show system alarms 命令。

  4. 解析告警資訊:使用 findall 函式從輸出中提取告警的相關資訊,如時間、嚴重性和描述。

  5. 儲存告警資訊:將提取的資訊儲存到列表中,並計算不同嚴重性告警的總數。

程式碼範例

from netmiko import Netmiko
from re import findall
from pandas import DataFrame

# 定義裝置清單
host = ["10.10.20.1", "10.10.20.2", "10.10.20.3"]
time_list, severity_list, description_list, ip_list = ([] for x in range(4))
total_minor = total_major = total_critical = 0

# 迴圈連線裝置並收集告警資訊
for ip in host:
    device = {"host": ip, "username": "admin", "password": "juniper", "device_type": "juniper", "global_delay_factor": 0.1}
    net_connect = Netmiko(**device)
    output = net_connect.send_command("show system alarms")
    
    # 解析告警資訊並儲存
    alarm_count = findall("(\d+) alarms currently active", output)
    alarms = output.split("\n")
    del alarms[0:4]
    total_alarms += len(alarms)
    minor_alarms = findall("Minor", output)
    major_alarms = findall("Major", output)
    critical_alarms = findall("Critical", output)
    total_minor += len(minor_alarms)
    total_major += len(major_alarms)
    total_critical += len(critical_alarms)

內容解密:

  • 使用 Netmiko 連線到 Juniper 裝置並執行 show system alarms 命令。
  • findall 函式用於從命令輸出中提取告警的相關資訊。
  • 將提取的資訊儲存到列表中,以便後續處理或儲存到 Excel 檔案中。

蒐集Juniper裝置告警資訊並匯總至Excel報表

在網路維運過程中,定期檢查裝置告警資訊是確保網路穩定執行的關鍵步驟。本文將介紹如何使用Python指令碼自動從多台Juniper裝置收集告警資訊,並將結果匯總到Excel報表中,以便於進一步的分析和存檔。

實作步驟

  1. 建立裝置連線:使用Netmiko函式庫建立與Juniper裝置的SSH連線。
  2. 執行告警查詢命令:透過Netmiko傳送show system alarms命令到裝置,並接收輸出結果。
  3. 解析告警資訊:使用正規表示式(Regular Expression)解析輸出結果,提取告警的時間、嚴重程度和描述等資訊。
  4. 匯總告警資料:將各裝置的告警資訊匯總到列表中,以便後續處理。
  5. 建立Excel報表:利用pandas函式庫的DataFrame和ExcelWriter功能,將告警資料寫入Excel檔案中的不同工作表。

程式碼範例

from netmiko import Netmiko
from re import findall, split
import pandas

# 定義裝置列表
host = ["10.10.20.1", "10.10.20.2", "10.10.20.3"]

# 初始化列表用於儲存告警資訊
time_list, severity_list, description_list, ip_list = ([] for _ in range(4))

# 初始化計數器
total_minor = total_major = total_critical = total_alarms = 0

for ip in host:
    # 建立裝置連線設定
    device = {
        "host": ip,
        "username": "admin",
        "password": "juniper",
        "device_type": "juniper",
        "global_delay_factor": 0.1
    }
    
    # 連線裝置並執行命令
    net_connect = Netmiko(**device)
    output = net_connect.send_command("show system alarms")
    
    # 解析告警數量
    alarm_count = findall("(\d+) alarms currently active", output)
    alarms = split("\n", output)
    del alarms[0:4]  # 移除輸出結果中的標題行
    
    # 更新告警計數器
    total_alarms += len(alarms)
    minor_alarms = findall("Minor", output)
    major_alarms = findall("Major", output)
    critical_alarms = findall("Critical", output)
    total_minor += len(minor_alarms)
    total_major += len(major_alarms)
    total_critical += len(critical_alarms)
    
    # 解析每條告警資訊
    for alarm_item in alarms:
        time = findall("\d+-\d+-\d+ \d+:\d+:\d+ UTC", alarm_item)
        severity = findall("Minor|Major|Critical", alarm_item)
        description = findall("\d+-\d+-\d+ \d+:\d+:\d+ UTC\s+\w+\s+(.*)", alarm_item)
        
        # 將解析結果加入列表
        ip_list.append(ip)
        time_list.append(time[0])
        severity_list.append(severity[0])
        description_list.append(description[0])

# 建立Excel報表
with pandas.ExcelWriter('Alarm List.xlsx') as writer:
    df1 = pandas.DataFrame({
        "Alarm Count": [total_alarms],
        "Minor": [total_minor],
        "Major": [total_major],
        "Critical": [total_critical]
    })
    df2 = pandas.DataFrame({
        "Device IP": ip_list,
        "Time": time_list,
        "Severity": severity_list,
        "Description": description_list
    })
    
    # 將DataFrame寫入Excel檔案的不同工作表
    df1.to_excel(writer, sheet_name="Summary", index=False)
    df2.to_excel(writer, sheet_name="Alarms", index=False)

#### 內容解密:
1. **程式碼解說**此指令碼首先透過Netmiko函式庫連線到指定的Juniper裝置執行`show system alarms`命令並解析輸出結果以提取告警的詳細資訊
2. **正規表示式應用**使用正規表示式來匹配和提取告警時間嚴重程度和描述等資訊
3. **資料匯總與報表生成**將各裝置的告警資訊匯總後利用pandas函式庫生成包含Summary和Alarms兩個工作表的Excel報表

### 結果展示

執行指令碼後會在同一目錄下生成名為`Alarm List.xlsx`的Excel檔案其中Summary工作表展示了告警總數不同嚴重程度的告警數量Alarms工作表則詳細列出了每條告警的時間嚴重程度描述以及對應的裝置IP

### 技術要點

- 使用Netmiko進行SSH連線和命令執行
- 利用正規表示式進行文字解析
- 運用pandas進行資料處理和Excel報表生成

此指令碼有效地自動化了Juniper裝置告警資訊的收集和匯總工作提高了網路維運的效率對於其他廠牌的網路裝置只需調整命令和正規表示式即可實作類別似的功能