[PYTHON] Créer automatiquement un fichier de configuration Ansible (vars) à partir d'Excel (Ansible)

Ceux qui seraient heureux si vous pouviez le lire

・ Ceux qui construisent des serveurs ou introduisent MW avec Ansible dans le département infrastructure ・ Ceux qui trouvent difficile de créer des fichiers d'inventaire et des playbooks

Environnement d'exécution

 Vagrant.configure(2) do |config|
  config.vm.box = "bento/centos-6.7"
 
  config.vm.define "dev" do |node|
    node.vm.network "private_network", ip: "192.168.10.10"
    node.vm.synced_folder "/Users/takahirono7/projects/", "/root/project"
  end
end

Synchroniser les fichiers entre le système d'exploitation invité fonctionnant sur Vagrant et Mac

introduction

・ Je suis une personne du département infrastructure qui vérifie souvent les exigences autour des MW, les construit, les teste et les livre en fonction des exigences du côté métier.

・ Dans mon département, j'obtiens les exigences du développement, et sur cette base, je dépose les informations d'instance dans un fichier vars et je le construis avec Ansible. -C'est une image pour déployer les informations pour chaque instance avec un fichier vars comme indiqué ci-dessous.

スクリーンショット 2017-06-10 15.42.54.png

Le fichier vars ressemble à ceci:

yaml


apache_instance:
  instance_name: 'SAMPLE_InstanceA'
  server_name: 'sample.jp'
  instance_user:
    name: 'apache_user'
  instance_settings:
    chkconfig: false
    add_encodings:
      - 'x-compress Z'
      - 'x-gzip gz'
    add_languages:
      - 'ja .ja'
      - 'en .en'
      - 'fr .fr'
    start_servers: '5'
    min_spare_servers: '5'
    max_spare_servers: '10'
    server_limit: '512'
    max_request_workers: '150'
    max_connections_perchild: '0'

Comme mentionné ci-dessus, les fichiers ci-dessus sont préparés pour chaque instance.

Ce fichier est créé sur la base de la ** "fiche des exigences" ** (Excel) transmise par le développeur au format suivant.

スクリーンショット 2017-06-10 16.11.16.png

Mis à part le fait qu'il est inefficace, n'est-ce pas une certaine façon de construire des infrastructures?

Le fichier réel est plus long et plus complexe, donc créer des Vars à partir de celui-ci peut être une tâche ardue.

J'ai créé une application Python qui ** automatise cela **.

Méthode de montage

Le principe est qu'Excel est une fois remplacé par un fichier texte, qui est chargé dans l'application et converti au format vars yaml.

En python, il existe un module xlrd en tant que module qui touche Excel. Au début, j'essayais de l'implémenter, mais j'avais un problème interne tel que l'augmentation du nombre de colonnes et de lignes dans Excel chez le demandeur, j'ai donc choisi de l'implémenter une fois en le convertissant en texte.

Si la méthode d'application est que la feuille Excel est fixe et que le nombre de lignes et de colonnes n'augmente pas, je pense que ce sera plus facile à mettre en œuvre en utilisant le module ci-dessus.

** Fondamentalement, il s'agit d'une méthode de stockage d'un fichier texte (à l'origine Excel) en python avec un module fractionné etc. pour chaque paramètre dans un dictionnaire, et enfin de le rendre dans un modèle jinja2 et de le sortir **

Puisque les informations internes sont supprimées du script, il est impossible de l'exécuter tel quel, mais je pense que vous ne pouvez vous référer qu'à l'essence m (_ _) m Je suis désolé que python soit toujours en train d'écrire, donc c'est sale.

Configuration des outils

Structure du répertoire

/root/project/convert_hearing_sheet_into_vars
|--README.md
|--hearing_sheets  #Placez le fichier texte converti par la macro(Voir ci-dessous)
|  |--Apache.txt #Fichier texte converti en Excel
|--main.py #Démarrez chaque module
|--scripts
|  |--__init__.py
|  |--create_dict_from_apache_sheet.py
|  |--common_method.py #Décrire le traitement courant
|--config.json
|--output
|  |--apache_hogehoge_instance.yml #Le fichier vars converti à partir de txt est placé

|--vars_template
|  |--[template]apache_vars.j2

main.py Appeler chaque module

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- mode: python;Encoding: utf8n -*-

### import
#-----------------------------------------------
import sys
import os
from scripts.create_dict_from_apache_sheet import CreateDictFromApacheSheet
from scripts.common_method import CommonMethod

#-----------------------------------------------
###Traitement des arguments de ligne de commande
#-----------------------------------------------
# $1 = run.py
# $2 =Nom du fichier d'exécution
argvs = sys.argv
argc = len(argvs)
if (argc != 2):
    print(
        'Usage: # python %s filename {dest file name}' % argvs[0])
    sys.exit(1)

excelfile = argvs[1]

#===============================================
#Chemin de fichier, définition de variable commune
#===============================================
script_dir = os.path.abspath(os.path.dirname(__file__))

#Lire un fichier texte converti par une macro
apache_file = os.path.join(
    script_dir, "hearing_sheets", excelfile)

#Instanciez une classe de méthode pour un traitement commun
method = CommonMethod()
config_lines = method.open_file(apache_file)

#Obtenez la ligne contenant le nom de l'instance et créez une liste d'instances
inst_list_apache = []
for i in config_lines:
    if i.find("Nom de l'instance") >= 0:
        inst_list_apache.append(i)
        target_instances = method.split_by_tab(inst_list_apache)
print("Nombre d'instances")
print(len(target_instances) - 1)

print("Exécute le processus pour les instances suivantes")
for instance in target_instances[1:]:
    print(instance)
#Effectuer le traitement pour chaque instance
#Obtenez également le numéro d'index en utilisant enumerate
print("Commencer le traitement")
for index, target_instance_name in enumerate(target_instances[1:]):
    print(index, target_instance_name)
    apache_dict = CreateDictFromApacheSheet(script_dir)
    apache_dict.exec(config_lines, index, target_instance_name)
print("Sortie de traitement")

create_dict_from_apache_sheet.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- mode: python;Encoding: utf8n -*-
### importfile
#-------------------------------------------------------
import sys, os, copy, platform, codecs, re, traceback, json  # @UnusedImport
from collections import defaultdict
from os.path import join, dirname, abspath, isfile
from jinja2 import Environment, FileSystemLoader
from scripts.common_method import CommonMethod


class CreateDictFromApacheSheet(CommonMethod):

    def __init__(self, script_dir):
        self.script_dir = script_dir

    def exec(self, config_lines, index, target_instance_name):
        ###############Chemin de fichier, définition de variable commune#############

        #Extraire les paramètres d'instance
        main_dict_apache = self.extract_instance_params(
            config_lines,
            index,
            target_instance_name)

        #Fichier vars de sortie
        self.output_vars_files(
            index, target_instance_name, main_dict_apache)

    def extract_instance_params(self,
                                config_lines,
                                index,
                                target_instance_name):

        apache_dict = defaultdict(dict)
        json_file = os.path.join(self.script_dir, "config.json")
        #Lire le fichier json
        with open(json_file) as f:
            json_dict = json.load(f)
        apache_dict["instance_name"] = target_instance_name

        # config.Stocker le dictionnaire stocké dans json pour chaque paramètre
        for parameter in json_dict["apache"]["APACHE_INSTANCE"]:
            version_list = []
            parameter_key = list(parameter.keys())
            parameter_value = list(parameter.values())
            #Convertir en str.Si vous essayez de l'utiliser comme liste, vous pouvez'Une erreur de conversion se produit
            parameter_key_str = parameter_key[0]
            parameter_value_str = parameter_value[0]

            for i in config_lines:
                if i.find(parameter_key_str) >= 0:
                    version_list.append(i)
                    version_params = self.split_by_tab(version_list)
            apache_dict[parameter_value_str] = version_params[index + 1]

        return apache_dict

#Obtenez le modèle jinja2 et apache_Rendre et afficher le contenu de dict
    def output_vars_files(self, index, target_instance_name, main_dict_apache):

        template_dir = os.path.join(
            self.script_dir, "vars_template", site)

        jinja_env = Environment(
            trim_blocks=True, loader=FileSystemLoader(template_dir))
        vars_file = os.path.join(self.script_dir, "output", "instance_%s_%s.yml" %(target_instance_name))
        tmpl = jinja_env.get_template("[template]apache_vars.j2")
        with open(vars_file, "wb") as f:
            f.write(tmpl.render(main_dict_apache).encode("utf-8"))



[template]apache_vars.j2 Cela devient un modèle pour les vars. La valeur du dictionnaire créé par create_dict_from_apache_sheet.py peut être appliquée à ce modèle.

apache_instance:
  instance_name: '{{ instance_name }}'
  server_name: '{{ server_name }}'
  instance_user:
    name: '{{ instance_user }}'
  instance_settings:
    chkconfig: false
    add_encodings:
      - 'x-compress Z'
      - 'x-gzip gz'
    add_languages:
      - 'ja .ja'
      - 'en .en'
      - 'fr .fr'
    start_servers: '{{ start_servers }}'
    min_spare_servers: '{{ min_spare_servers }}'
    max_spare_servers: '{{ max_spare_servers }}'
    server_limit: '{{ server_limit }}'
    max_request_workers: '{{ max_request_workers }}'
    max_connections_perchild: '{{ max_connections_perchild }}'

config.json

Ce fichier relie la feuille d'audience Excel à la clé du dictionnaire dans le script.

json


{
	"apache" : {
		"APACHE_INSTANCE": [
			{"ServerName"					: "server_name"},
			{"User"						: "instance_user"},
			{"AddEncoding" 					: "add_encodings"},
			{"AddLanguage"			: "add_languages"},
			{"StartServers"					: "start_servers"},
			{"MinSpareServers"				: "min_spare_servers"},
			{"MaxSpareServers"				: "max_spare_servers"},
			{"ServerLimit"					: "server_limit"},
			{"MaxClients (MaxRequestWorkers)" : "max_request_workers"},
			{"MaxRequestsPerChild(MaxConnectionsPerChild)" : "max_connections_perchild"}
		]
	}

}

Étapes de l'outil

La procédure spécifique est la suivante.

  1. Convertissez la feuille d'audience Excel en fichier texte à l'aide d'une macro
  2. Placez le fichier texte créé dans le répertoire hear_sheets
  3. Exécution de l'outil Le fichier vars est craché dans le répertoire de sortie Ce sera le flux

Convertir la feuille d'audition Excel en fichier texte à l'aide d'une macro

Tout d'abord, exécutez la macro suivante pour convertir le fichier Excel en texte pour chaque feuille. Veuillez noter qu'il y a un endroit dans la macro qui décrit le chemin du répertoire local.

La macro cite l'article suivant. Merci m (_ _) m http://d.hatena.ne.jp/minamijoyo/20080124/p1

vba


Sub OutputTEXT()
'Enregistrer toutes les feuilles de classeur actives sous forme de texte délimité par des tabulations
    Dim name As String
    Dim outdir As String
    Dim sheet As Worksheet
      
    'Veuillez spécifier le dossier de destination de la sortie
    outdir = "D:\Users\hogehoge\Documents\"
     
    'Masquer l'avertissement d'écrasement si des données existent déjà
    Application.DisplayAlerts = False
     
    For Each sheet In Worksheets
        sheet.Select
        name = outdir & ActiveSheet.name & ".txt"
        ActiveWorkbook.SaveAs Filename:=name, FileFormat:=xlText, CreateBackup:=False
    Next sheet
     
    'Affichage d'avertissement de retour
    Application.DisplayAlerts = True
End Sub 

Lorsque vous faites cela, le texte sera craché dans le dossier de destination comme ci-dessous

Apache.txt


Nom de l'instance SAMPLE_InstanceA	SAMPLE_InstanceB	SAMPLE_InstanceC
Réglage de démarrage automatique Non Non Non Non
ServerName	sample.jp sample.jp_B	sample.jp_C
User	apache_user		apache_user		apache_user
StartServers									5	5	5
MinSpareServers									5	5	5
MaxSpareServers									10	10	10
ServerLimit									512	512	512
MaxClients (MaxRequestWorkers)				150	150	150
MaxRequestsPerChild(MaxConnectionsPerChild)			0	0	0

Placez le fichier texte créé dans le répertoire hear_sheets

Placez le fichier ci-dessus dans le répertoire hear_sheets de l'outil

Exécution de l'outil

 [root@localhost convert_hearing_sheet_into_vars]# ./main.py apache
Nombre d'instances Apache
3
Exécute le processus pour les instances Apache suivantes
SAMPLE_InstanceA
SAMPLE_InstanceB
SAMPLE_InstanceC

les variables sont crachées dans le répertoire de sortie

Recommended Posts

Créer automatiquement un fichier de configuration Ansible (vars) à partir d'Excel (Ansible)
Créer un bloc de données à partir d'Excel à l'aide de pandas
Modifier Excel à partir de Python pour créer un tableau croisé dynamique
Créer un tableau C à partir d'une feuille Python> Excel
Créez automatiquement des rapports Word et Excel avec Python
Manipuler des fichiers Excel à partir de python avec xlrd (mémo personnel)
Une histoire qui a permis de créer automatiquement une liste de lecture Anison à partir de vos fichiers musicaux