Maîtriser le moteur de Templates GO
De plus en plus de logiciels sont codés en langage GO, que ce soit Kubernetes, Docker, Helm, Grafana etc... Maîtriser son moteur de templates est donc un réel gage de qualité.
Il faut savoir que le langage GO embarque un moteur de templates très puissant, et souvent utile pour les logiciels précédemment cités. Regardons comment manipuler le moteur de templates GO pour générer un JSON.
Parser un JSON
Il existe énormément de cas d'usage nous amenant à manipuler le moteur de templates du langage GO. Un cas courant est celui de la commande docker inspect
utilisée avec l'argument -f
.
Voici un exemple avec la commande docker inspect
qui affiche uniquement l'adresse IP du conteneur :
docker inspect --format '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' NOM DU CONTENEUR
La fonction range
du moteur de templates Go permet d'itérer sur une séquence de données. On peut la considérer comme l'équivalent d'une boucle for
.
À l'intérieur de la boucle range
, vous pouvez accéder à chaque élément de la séquence avec le point .
.
Générer un JSON
Dans certains cas, il est nécessaire de générer un JSON à partir d'un template GO.
Par exemple avec l'outil Trivy qui permet de scanner les CVE d'une machine, il est possible de formater la sortie directement en JSON.
Sauf que le JSON qui est généré contient beaucoup d'informations qui ne sont pas forcément utiles, cela rend également le fichier très long, et réduit les performances lorsqu'il faut le parser.
C'est pour cela que générer un JSON avec un template GO peut s'avérer très intéressant afin de ne garder uniquement les informations qui sont pertinentes.
Pour ce faire, il faut utiliser la fonction toJson
et l'afficher avec printf
. Voici un exemple de template GO :
{{- range . }}{{- range .MyKey }}
{{- $json := dict "Key1" .Myvalue1 "Key2" .Myvalue2 | toJson }}
{{- printf "%s\n" $json }}
{{- end }}{{- end }}
Key1
et Myvalue1
par vos clés et valeurs JSON.Ce template GO vient générer un JSON qui ressemble à ceci :
{"Key1": Myvalue1,"Key2": Myvalue2}
La comparaison
Il est possible de comparer des éléments dans un template GO, pour notamment vérifier si deux chaînes de caractères sont identiques, vérifier un booléen etc...
Certains opérateurs vont vous paraître familier car ils ressemblent beaucoup au langage Bash et au moteur de templates Jinja2.
Utilisons les opérateurs eq
et not
pour nos comparaisons :
{{ if eq .Car "BMW" }}
La voiture est une BMW.
{{ else if not eq .Car "Mercedes" }}
La voiture est ni une BMW ni une Mercedes
{{ else }}
La voiture est une Mercedes.
{{ end }}
Dans cet exemple, nous testons avec un if
si la clé .Car
est égale à la valeur "BMW"
. Si c'est le cas, le template GO affiche "La voitures est une BMW."
.
Sinon, le test else if
vérifie si la clé .Car
n'est pas égale à la chaîne "Mercedes"
. Si c'est le cas, le template GO affiche "La voiture est ni une BMW ni une Mercedes"
.
Sinon, dans le else
nous affichons "La voiture est une Mercedes."
.
Il est possible d'utiliser la négation avec l'opérateur not
comme dans cet exemple :
{{ $car := "Audi" }}
{{ if not (eq $car "BMW") }}
Ma voiture est {{ $car }}!
{{ end }}
Les listes
Pour déclarer une liste dans un template GO, il faut utiliser la fonction slice
. Voici un exemple avec la déclaration d'une variable nommée car
qui stocke cette liste :
{{ $car := slice "BMW" "Mercedes" "Audi" }}
Pour itérer dans cette liste slice
, nous allons utiliser la fonction range
comme ceci :
{{ range $index, $element := $car }}
L'élément numéro {{ $index }} est {{ $element }}
{{ end }}
Les dictionnaires
Il est possible d'utiliser les dictionnaires dans un template GO afin d'y stocker clés et valeurs. Pour ce faire, il faut utiliser la fonction dict
comme dans l'exemple suivant :
{{ $car := dict "Marque" "BMW" "Classe" "Berline" "Année" 2022 }}
Il est possible d'accéder aux valeurs de ce dictionnaire de cette manière :
{{$car.Marque}} // affiche "BMW"
{{$car.Classe}} // affiche "Berline"
{{$car.Année}} // affiche 2022
Conclusion
Nous avons pu voir dans cet article que le moteur de templates du langage GO est très puissant, et sera amené à être de plus en plus utilisé avec la démocratisation du langage GO.
A titre de comparaison avec le moteur de templates Jinja2, les fonctions comme toJson
, toYaml
, block
et bien d'autres fonctions ne sont pas présentes en Jinja2. Cela rend la manipulation et la génération de fichiers plus simple en GO.