Python / Excel: Génération de fichiers de configuration

Comment procédez-vous lorsque vous avez besoin de générer des fichiers de configuration pour des switchs ? Une multitude de solution existe pour répondre à ce besoin. Par exemple:

  • Partir d’un fichier de configuration existant, le modifier via Notepad puis recommencer pour chaque fichier à créer,
  • Créer un template de configuration par type d’équipement sous Word, un fichier Excel par template contenant les variables et faire un publipostage,
  • Utiliser un script Python, qui à partir d’un template au format texte et d’un seul fichier Excel générera un fichier de configuration par équipement.

C’est cette dernière solution que j’utilise généralement et que je vais détailler ici. Elle possède de multiples avantages qui me permettent d’atteindre mon objectif rapidement et en limitant le risque d’erreur.

La solution s’appuie sur 3 éléments:

  • Un ou plusieurs template de configuration (format txt): modèle(s) de configuration. Les éléments variables (hostname, adresses IP, etc.) commencent par le symbole $.
  • Un fichier de configuration (format Excel): fichier Excel input.xlsx. Les colonnes représentent les variables à remplacer dans les templates. Seules les deux premières colonnes sont obligatoires. La première colonne indique le template à utiliser et la deuxième colonne le hostname qui servira à nommer le fichier de configuration.
  • Le script Python: Le script reliant l’ensemble et générant les fichiers de configuration en prenant en entrés les deux autres éléments. Il nécessite l’installation du paquet openpyxl permettant la manipulation de fichiers Excel avec Python. Vous trouverez en bas de page le script Python, également disponible sur mon espace Github avec un fichier Excel et deux templates d’exemple.

L’ajout et la suppression de variables ne nécessitent pas de modification du script. L’absence d’une variable du fichier Excel dans un template ne génère pas d’erreur non plus, autorisant à utiliser des variables dans certains templates et pas dans d’autre.

Le script s’exécute, comme tout autre script Python, depuis un terminal et sans argument. Les fichiers de configuration générés sont placés dans un répertoire output créé à l’emplacement du script:

En espérant que cela puisse vous être utile dans vos futurs projets 🙂

#! python3
# coding=utf-8
"""
Contexte: GENERAL
Génération de fichiers de configurations avec utilisation de template
"""
import openpyxl
import os
import shutil
import re
import ipaddress

if not os.path.exists("output"):
    os.makedirs("output")
else:
    shutil.rmtree("output")
    os.makedirs("output")

# le fichier Excel avec les infos
wb = openpyxl.load_workbook("input.xlsx")

# onglet du fichier Excel contenant la conf des switchs
# possibilité d'ajouter d'autres onglets sur le même modèle
onglet_info_sw = wb["CONF-SWITCH"]

nbre_sw = onglet_info_sw.max_row + 1
for i in range(2, nbre_sw):
    dico_variables = {
        "variables": {}
    }
    for j in range(1, onglet_info_sw.max_column + 1):        
        isIP = True
        try:
            ipaddress.ip_address(str(onglet_info_sw.cell(row=i, column=j).value))
            isIp = True
        except:
            isIP = False        
        if str(onglet_info_sw.cell(row=1, column=j).value) == "TEMPLATE":
            dico_variables["variables"][onglet_info_sw.cell(row=1, column=j).value] = \
                str(onglet_info_sw.cell(row=i, column=j).value)
        elif isIP:
            dico_variables["variables"][onglet_info_sw.cell(row=1, column=j).value] = \
                str(onglet_info_sw.cell(row=i, column=j).value)
        else:
            dico_variables["variables"][onglet_info_sw.cell(row=1, column=j).value] = \
                str(onglet_info_sw.cell(row=i, column=j).value).replace(".",",")

    # utilisation du template spécifié
    with open(dico_variables["variables"]["TEMPLATE"]) as f:
        s = f.read()
    with open("output\\" + dico_variables["variables"]["HOSTNAME"] + ".txt", "w") as f:
        # remplacement de chaque variable dans le fichier cible
        for var in dico_variables["variables"]:
            s = re.sub("\$" + var, dico_variables["variables"][var], s)
        f.write(s)

Laisser un commentaire