首页 > 解决方案 > Python:从 csv 中提取数据作为变量并插入基本文件(NAPALM 配置)

问题描述

问题:我正在尝试使用具有每个设备的可变信息的基本模板,使用 NAPALM 对一些网络设备进行批量编码。当前的编码不能很好地扩展,特别是 .csv 中的变量分配以及在配置文件中用所述变量替换文本是当我开始查看 10 多个变量时看起来不必要的巨大部分。例如 (variable = row['column name']) 和 (data = data.replace('{variable}', variable))

从 .csv 中的每一列自动生成基本变量完全让我无法理解。有一些变量是生成变量的组合似乎没问题。对于替换部分,我考虑过将变量放在列表中并在列表中迭代,因为名称相同,但除了手动编码列表之外,我想不出办法。

我选择使用 pandas vs csv,因为我喜欢编码看起来多么简洁明了。我还做了一些测试,从 csv 中提取数据并写了大约 20 行左右一千次以进行比较,发现这两种方法之间存在大约 2 秒的差异。我没有看到一次将新配置推送到超过 25-50 个设备,数据帧与 csv 的读/写可以忽略不计,但我可能会弄错。

==================================================== ========================

作为参考,NAPALM 通过以下方式从文件中读取配置:

driver = get_network_driver("ios")
with driver(IP, Username, Password) as device:
   device.load_merge_candidate(filename='Config.cfg')

Config.cfg 文件只是一个加载了 ios 命令的文件,但为了对多个设备进行编程,我正在考虑循环一个 .csv 文件,其中填充了配置文件中需要替换的变量。

基本配置文件示例

Base_Config.cfg

hostname {hostname}
spanning-tree mode rapid-pvst
udld enable
interface vlan {managementVLAN}
ip address {managementIP} {managementSubnet}

.csv 示例文件

ios_switch_info.csv

Temp IP,Building,Room,Device Role,Management IP,Management Subnet
192.168.1.1,Main,001,Access,10.1.1.2,255.255.255.0
192.168.1.2,Main,101,Access,10.1.1.3,255.255.255.0
192.168.1.3,Branch,007,Access,10.1.2.2,255.255.255.0

临时配置文件示例

温度配置文件

hostname MainAcc001
spanning-tree mode rapid-pvst
udld enable
interface vlan 101
ip address 10.1.1.2 255.255.255.0

脚本示例

Base_IOS_Config.py

import os
import pandas as pd
from getpass import getpass
from napalm import get_network_driver

username = input("Username: ")
password = getpass()
driver = get_network_driver("ios")
df = pd.read_csv('ios_switch_info.csv')
for index, row in df.iterrows():

    # This section of variable assignment could get very long  
  
    tempIP = row['Temp IP']
    building = row['Building']
    room = row['Room']
    deviceRole= row['Device Role']
    managementIP = row['Management IP']
    managementSubnet= row['Management Subnet']
    hostname = row['Building'] + row['Device Role'][:3] + row['Room']
    managementVLAN = int(managementIP.split('.')[2]) + 100
    
    with open('Base_Config.cfg', 'r') as base_config:
        data = base_config.read()

    # This section of replacement could get very long depending on number of variables 

    data = data.replace('{hostname}', hostname)
    data = data.replace('{managementIP}', managementIP)
    data = data.replace('{managementSubnet}', managementSubnet)
    data = data.replace('{managementVLAN}', managementVLAN)

    with open('Temp.cfg', 'w') as temp_config:
        temp_config.write(data)

    with driver(tempIP,username,password) as device:
        print(f"Accessing {hostname}")
        device.load_merge_candidate(filename='Temp.cfg')
        ........other stuff..........
    device.close()
os.remove('Temp.cfg')

标签: pythoncsv

解决方案


我最终想出的是从 .csv(交换机特定变量)和导入 ios_creds *(跨多个交换机的变量,例如 NTP 服务器地址)分配变量,而不是手动分配它们:

device_info = row.to_dict() # creates dict of .csv variables {column:variable}
device_info.update(**globals) # adds all global variables to dict

为了将所述变量放入配置文件,而不是用 data.replace 逐行替换每个变量,我最终使用了以下内容:

for key, value in device_info.items():
    data = data.replace("{" + str(key) + "}", str(value))

这会解析配置文件以查找变量(例如 {Hostname})并将其替换为保存在字典中的相应变量(例如 Hostname:MainAcc001)


推荐阅读