使用Pandas和Excel中的同一Jinja模板创建多个模板

2024-05-15 10:35:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用同一个Jinja模板为某些网络设备创建多个配置模板

因此,我使用Pandas阅读了一份Excel工作表,如下所示:

Excel Sheet

然后,我将数据帧转换为一个字典,并在这个字典上循环,为每个主机名创建一个模板。我的Python代码,main.py

#!usr/bin/env python3

import os
from jinja2 import Environment, FileSystemLoader
import pandas as pd
from pprint import pprint

# Read Excel file
df = pd.read_excel(os.path.join("./", "device-list.xlsx"), sheet_name="Test")
# Convert to dictionary
dict_data = df.to_dict(orient="dict")
# Replace blank space by underscore and convert key to lowercase
data = dict((key.replace(" ", "_").lower(), value) for key, value in dict_data.items())

# Print data
pprint(data) # check output below

# Handle Jinja template
env = Environment(loader=FileSystemLoader("./"), trim_blocks=True, lstrip_blocks=True)
template = env.get_template(os.path.join("./", "switch.j2"))

i = 0

# Create a template for each hostname
while i < len(data["hostname"]):
    config = template.render(data)
    with open(f'{data["hostname"][i]}.txt', "w") as cfg_file:
        cfg_file.write(config)

    i += 1

print("Done")
pprint(data): 
{'clock_timezone': {0: 'UTC +2', 1: 'UTC +2'},
 'default_gateway': {0: '192.168.1.1', 1: '192.168.1.1'},   
 'domain_name': {0: 'Cisco.local', 1: 'Cisco.local'},       
 'enable_password': {0: 'cisco', 1: 'cisco'},
 'hostname': {0: 'Device-1', 1: 'Device-2'},
 'mgmt_vlan_id': {0: 100, 1: 100},
 'mgmt_vlan_ip': {0: '192.168.1.254', 1: '192.168.1.254'},  
 'mgmt_vlan_mask': {0: '255.255.255.0', 1: '255.255.255.0'},
 'mgmt_vlan_name': {0: 'MGMT', 1: 'MGMT'},
 'password': {0: 'cisco', 1: 'cisco'},
 'stp_protocol': {0: 'rapid-pvst', 1: 'rapid-pvst'},        
 'username': {0: 'cisco', 1: 'cisco'},
 'vtp_mode': {0: 'transparent', 1: 'transparent'}}

还有我的Jinja2模板switch.j2

clock timezone {{ clock_timezone }}
!
hostname {{ hostname }}
!
ip domain name {{ domain_name }}
!
spanning-tree mode {{ stp_protocol }}
!
vtp mode {{ vtp_mode }}
!
username {{ username }} privilege 15 algorithm-type scrypt secret {{ password }}
!
enable algorithm-type scrypt secret {{ enable_password }}
!
vlan {{ mgmt_vlan_id }}
    name {{ mgmt_vlan_name }}
exit
!
interface vlan {{ mgmt_vlan_id }}
    ip address {{ mgmt_vlan_ip }} {{ mgmt_vlan_mask }}
    description *** {{mgmt_vlan_name }} ***
    no shutdown
exit
!
ip default-gateway {{ default_gateway }}

我得到的两个设备的输出如下所示:

clock timezone {0: 'UTC +2', 1: 'UTC +2'}
!
hostname {0: 'Device-1', 1: 'Device-2'}
!
ip domain name {0: 'Cisco.local', 1: 'Cisco.local'}
!
spanning-tree mode {0: 'rapid-pvst', 1: 'rapid-pvst'}
!
vtp mode {0: 'transparent', 1: 'transparent'}
!
username {0: 'cisco', 1: 'cisco'} privilege 15 algorithm-type scrypt secret {0: 'cisco', 1: 'cisco'}
!
enable algorithm-type scrypt secret {0: 'cisco', 1: 'cisco'}
!
vlan {0: 100, 1: 100}
    name {0: 'MGMT', 1: 'MGMT'}
exit
!
interface vlan {0: 100, 1: 100}
    ip address {0: '192.168.1.254', 1: '192.168.1.254'} {0: '255.255.255.0', 1: '255.255.255.0'}
    description *** {0: 'MGMT', 1: 'MGMT'} ***
    no shutdown
exit
!
ip default-gateway {0: '192.168.1.1', 1: '192.168.1.1'}

我缺少什么来生成Device-1.txt中的0 key值和Device-2.txt中的1 key值?要获得类似于:

clock timezone UTC +2
!
hostname Device-1
!
ip domain name Cisco.local
!
spanning-tree mode rapid-pvst
!
vtp mode transparent
!
username cisco privilege 15 algorithm-type scrypt secret cisco
!
enable algorithm-type scrypt secret cisco
!
vlan 100
    name MGMT
exit
!
interface vlan 100
    ip address 192.168.1.254 255.255.255.0
    description *** MGMT ***
    no shutdown
exit
!
ip default-gateway 192.168.1.1

Tags: nameipdatasecretmodedevicetypeexit
1条回答
网友
1楼 · 发布于 2024-05-15 10:35:57

只传入所需的值,而不是整个数据。尝试下面的代码替换while循环

for i in range(len(data["hostname"])):
    sub_data = {}
    for key,val in data.items():
        sub_data[key] = val[i]
    print(sub_data)
    config = template.render(sub_data)
    with open(f'{sub_data["hostname"]}.txt', "w") as cfg_file:
        cfg_file.write(config)

解释:这是通过创建一个名为sub_data的字典来实现的,方法是循环遍历数据中的值数(这等于Excel工作表中的行数),并将其作为jinja模板的输入传递

相关问题 更多 >