Automatisation du script amtree.sh
Ce sujet fait suite à l'article qui se trouve ici!
Si vous ne l’avez pas encore lu, n’attendez pas et allez-y!
Introduction
Reminder :
Dans l'article précédent nous avons préparé les 2 fichiers yaml pour répondre à la problématique des données sensibles se trouvant dans les fichiers JSON (arbres exportés)
Nous allons donc dans cet article:
Supprimer les données sensibles qui se trouvent dans les fichiers JSON avant de les importer dans un repository git.
Ajouter les données manquantes dans les fichiers JSON avant de les exporter dans AM en les valorisant en fonction de l'environnement cible.
I) Supprimer les données sensibles des fichiers JSON
Avant d’importer les arbres dans un repository git, nous devons impérativement enlever les données sensibles des fichiers JSON pour éviter toute fuite de données.
Nous allons créer un script, qui grâce à la commande jq va filtrer toutes les informations des fichiers JSON qu’on aura décidé de supprimer.
Définition:
Jq a une utilité similaire à celle d'un filtre pour les fichiers JSON. Jq permet le découpage et le filtrage des fichiers JSON avec des lignes de commandes ou grâce à des scripts shell qui permettent une automatisation optimale.
Pour cela nous devons tout d'abord connaître le nom de toutes les clés à nettoyer.
Prenons l’exemple de l’arbre provenant de l’ancien article.
C’ est un arbre qui utilise un LDAP Decision Node:
"2c112cc9-10af-447d-90af-1dca389f844c": {
"_id": "2c112cc9-10af-447d-90af-1dca389f844c",
"heartbeatTimeUnit": "SECONDS",
"beheraEnabled": true,
"userCreationAttrs": [],
"userProfileAttribute": "uid",
"returnUserDn": true,
"minimumPasswordLength": 8,
"secondaryServers": [],
"heartbeatInterval": 10,
"adminDn": "uid=admin",
"adminPassword": null,
"accountSearchBaseDn": [
"dc=example,dc=com"
],
"searchScope": "SUBTREE",
"searchFilterAttributes": [
"uid"
],
"trustAllServerCertificates": false,
"ldapOperationsTimeout": 0,
"primaryServers": [
"localhost:2636"
],
Nous avons marqué en rouge les données sensibles.
Nous allons grâce au deuxième fichier yaml, supprimer selon l’arbre et le node les données des fichiers JSON.
Exemple du 2nd fichier yaml:
myTree:
LDAP:
primaryServers: ldapServer1
adminDn: amAdmin
adminPassword: amadminPassword
searchFilterAttributes: searchFilter
userProfileAttribute: userProfile
minimumPasswordLength: minPassword
accountSearchBaseDn: baseDn
Lorsque nous récupérons le nom de l’arbre nous devons vérifier s’il se trouve aussi dans le fichier yaml, nous allons boucler la valeur puis faire de même pour le node. Grâce à jq nous allons ensuite pouvoir remplacer les valeurs des attributs par null.
Voici le code du script:
#!/bin/bash
#1) retrieving command line arguments in variables
YAML2=$1
JSON=$2
#We need the parse_yaml.sh script wich contains the function that parses the yaml files
source /path/to/parse_yaml.sh
#2) check that the first yaml file exists
if [ ! -f $YAML2 ]; then
echo "File "$YAML2" does not exist"
fi
#3) check that the JSON repository exists
if [ ! -d $JSON ]; then
echo "Le répertoire n'existe pas"
fi
#4) Read the yaml file, the function is in the parse_yaml.sh script
eval "$(parse_yaml $YAML2 "CONF2_")"
#For each json file "_filename" found in the directory
cd "$JSON"
for _filename in $(ls *.json); do
#search if the file name "_filename" is listed in the yaml2 file
#get the name of the current file tree with the right jq command
currentTreeName=$(jq -r ".tree._id" ${_filename})
#search in the yaml2 if we find the name of the tree
isTreeInYaml=$(compgen -A variable | grep -c ^CONF2_${currentTreeName}_)
if [ $isTreeInYaml -gt 0 ]; then
#loop on CONF2_${currentTreeName}_ variables to get the node name
#get the node id in the current file with the right jq command
OLDIFS="$IFS"
IFS=$'\n' # bash specific
currentNodesNames=$(jq -r ".tree.nodes[].displayName" ${_filename})
for node in $currentNodesNames; do
isNodeinYaml=$(compgen -A variable | grep -c ^CONF2_${currentTreeName}_${node}_)
if [ $isNodeinYaml -gt 0 ]; then
#List all the variables of the tree
currentTreeNodes=$(compgen -A variable | grep ^CONF2_${currentTreeName}_${node}_)
#We loop on the variables of the tree in question
for key in $currentTreeNodes; do
#Cut the CONF2_${currentTreeName}_${node}_ part to access the attributes directly
keyName=$(echo $key | sed -e "s/^CONF2_${currentTreeName}_${node}_//")
#retrieves the node id
id=$(jq -rc --arg nodeName $node '.tree.nodes |to_entries[]| select(.value.displayName==$nodeName)| .key' $_filename)
#Delete the data of the JSON file
jq ".\"nodes\".\"$id\".\"$keyName\"=\"null\"" $_filename > ${_filename}.tmp && mv ${_filename}.tmp ${_filename}
IFS="$OLDIFS"
done
fi
done
fi
done
Voici la commande qui permet d'exécuter le script :
$ /path/to/deletejson.sh "/path/to/conf2.yaml" "/path/to/jsonfiles"
Le fichier JSON devrait ressembler à ceci après avoir exécuté le script:
#Afficher le node LDAP de l'arbre JSON
cat myTree.json | jq '.nodes."2c112cc9-10af-447d-90af-1dca389f844c"'
"2c112cc9-10af-447d-90af-1dca389f844c": {
"_id": "2c112cc9-10af-447d-90af-1dca389f844c",
"heartbeatTimeUnit": "SECONDS",
"beheraEnabled": true,
"userCreationAttrs": [],
"userProfileAttribute": "null",
"returnUserDn": true,
"minimumPasswordLength": "null",
"secondaryServers": [],
"heartbeatInterval": 10,
"adminDn": "null",
"adminPassword": "null",
"accountSearchBaseDn": "null",
"searchScope": "SUBTREE",
"searchFilterAttributes": "null",
"trustAllServerCertificates": false,
"ldapOperationsTimeout": 0,
"primaryServers": "null",
"ldapConnectionMode": "LDAPS",
"_type": {
"_id": "LdapDecisionNode",
"name": "LDAP Decision",
"collection": true
}
On s'assure ensuite que tous les fichiers json des arbres exportés ne contiennent plus aucune donnée sensible, si c'est le cas, il nous suffira de mettre à jour le contenu des fichiers yaml1 et yaml2 et de réexecuter le script de nettoyage ensuite.
Nous pouvons maintenant importer les fichiers JSON dans un repository git en sécurité (nous avons déjà traité cette partie dans l'ancien article, je vous laisse y retourner).
II) Ajout des données dans les fichiers JSON
Pour ajouter les données nous allons avoir besoin de 2 scripts:
Le premier script va parser le premier fichier yaml qui contient les données enlevées des fichiers JSON selon l’environnement.
#!/bin/bash
#1) retrieving command line arguments in variables
FILE=$1
ENV=$2
KEY=$3
#We need the parse_yaml.sh script wich contains the function that parses the yaml files
source /path/to/parse_yaml.sh
#2) check that there is the right number of arguments
if [ $# -ne 3 ]; then
echo "Incorrect number of arguments, syntax $0 "FILE" "ENV" "KEY""
exit
fi
#3) check that the file exists
if [! -f "$FILE" ]; then
echo "The file $FILE does not exist"
fi
#4) Reading the yaml file
eval "$(parse_yaml $FILE "CONF1_")"
#5) retrieve of the value of ENV.KEY
secretvalue=CONF1_${ENV}_$KEY
On va maintenant adapter le script que nous venons de voir (qui nous permet de supprimer les données des fichiers JSON) pour lui ajouter une nouvelle fonctionnalité permettant de modifier les attributs du fichier json en fonction du contenu des fichiers yaml. Nous allons donc ajouter un argument "mode d'exécution" qui permettra d'indiquer au script s'il faut supprimer ou ajouter les données dans les fichiers JSON (c'est-à-dire est-ce qu'on veut récupérer les données JSON pour les importer dans un repo GIT (mode "delete") ou les exporter dans un serveur AM (mode "add").
Nous allons donc ajouter et changer l'ordre des arguments:
MODE=$1
JSON=$2
YAML2=$3
YAML1=$4
ENV=$5
Dans le cas de l'exécution du mode ajout, nous allons changer les valeurs "null" par celles du second fichier yaml et ensuite nous faisons appel au premier script pour remplacer les "pointeurs" par les vraies valeurs dans les fichiers JSON.
#2) Determine to run the script as delete or update
if [ $# -le 3 ]; then
echo "This script is for deleting data in the JSON files"
elif [ $# -le 5 ]; then
echo "This script is for adding data in the JSON files"
else
exit
fi
#Choose between deleting the data and adding it
if [ "$MODE" == "delete" ]; then
#Delete the data of the JSON file
jq ".\"nodes\".\"$id\".\"$keyName\"=\"null\"" $_filename > ${_filename}.tmp && mv ${_filename}.tmp ${_filename}
elif [ "$MODE" == "add" ]; then
#Add the data
#Change the data of the JSON files with the secret values of the second yaml file
jq ".\"nodes\".\"$id\".\"$keyName\"=\"$currentkey\"" $_filename > ${_filename}.tmp && mv ${_filename}.tmp ${_filename}
#call the script getSecretValue and exchange currentkey with currentValue
currentValue=$($JSON/getScriptValue.sh "$YAML2" "$ENV" "${!currentKey}")
# TODO handle non string values
# for some attributes such as minimumPasswordLength we need to specify the value not enclosed in double quotes
if [ "$keyName" == "minimumPasswordLength" ]; then
jq ".\"nodes\".\"$id\".\"$keyName\"=$currentValue" $_filename > ${_filename}.tmp && mv ${_filename}.tmp ${_filename}
else
jq ".\"nodes\".\"$id\".\"$keyName\"=\"$currentValue\"" $_filename > ${_filename}.tmp && mv ${_filename}.tmp ${_filename}
fi
fi
Voici les commandes qui permettent d'éxecuter le script en mode "delete" ou en mode "add" :
#Delete the values of JSON files
/path/to/updatejson.sh "delete" "/path/to/jsonfiles" "/path/to/conf2.yaml"
#Add the values of JSON files
/path/to/updatejson.sh "add" "/path/to/jsonfiles" "/path/to/conf2.yaml" "/path/to/conf1.yaml" "dev"
Lorsque nous exécutons le script pour ajouter les données, le fichier JSON devrait reprendre ses valeurs originelles comme montrées plus haut.
Note : Notre commande jq ajoute des guillemets dans le fichier JSON lorsque nous l'exécutons. Nous en avons besoin pour les valeurs que nous voulons ajouter dans les fichiers JSON. Il existe des valeurs dans les fichiers JSON qui sont des integer (des entiers). Si nous ajoutons des double quotes cela ne marchera pas car ce ne sont pas des chaînes de caractères (string). Nous avons dans notre arbre qu'une seule valeure avec un chiffre, nous avons donc fait une condition qui permet de ne pas implémenter des doubles quotes pour cette valeure. Si dans le fichier JSON plusieurs valeurs sont des integer, il faudra alors créer un fichier de configuration spécialement pour les integer.
Récapitulatif :
Supprimer les données sensibles des fichiers JSON
Ajout des données dans les fichiers JSON
Note : Vous pouvez retrouver tous les scripts dans mon repository github
Dans le prochain article, nous allons exporter et importer les arbres d'authentification de Forgerock AM de façon automatisé.
Mayane Maman