de DevOps Software Gitlab Pipelines

Gitlab - yaml Dateien validieren innerhalb der pipeline

Hier werden wir uns anschauen wie wir lokale Dateien innerhalb einer Pipeline ausführen können. Hintergrund wäre z.B. eine bestimmte Art von Validierung einer Config-Datei oder das Testen von Code.

Hierfür setzten wir allerdings voraus, dass der Runner richtig konfiguriert wurde und wir Pipelines ausführen können. Innerhalb unseres Repositories lege ich mir nun also eine Datei an für unsere Pipeline. Ich nenne Sie validate.py mit der wir nachher prüfen möchten ob eine .yaml Datei korrekt ist oder nicht. Zusätzlich müssen wir natürlich noch unsere .gitlab-ci.yaml Datei anlegen. Wir erstellen außerdem noch zum Testen eine Datei mit dem Namen richtig.yaml und eine mit dem Namen falsch.yaml. Deren Inhalte liste ich hier auf:

1➜  pipeline-example git:(master) cat richtig.yaml 
2test: test1
3➜  pipeline-example git:(master) cat falsch.yaml 
4test = test1

der Inhalt von den beiden Dateien die wir prüfen möchten

Wir erstellen uns nun die Pipeline config. Das ganze läuft bei uns auf einem Docker-Runner mit dem python Image. Wir haben eine validate Stage und zwei Jobs darin, die Parallel ablaufen.

 1default:
 2  image: python:3.9.19-alpine3.19
 3
 4stages:
 5  - validate
 6
 7test_richtig:
 8  stage: validate
 9  script:
10
11test_falsch:
12  stage: validate
13  script:

Im Script können wir natürlich auch direkt festlegen wie wir das Script aufrufen wollen und uns eine Datei anlegen womit wir die Abhängigkeiten installieren, da natürlich in jedem Docker Job keine Abhängigkeiten mehr drin sind. Das ganze können wir umgehen, in dem wir ein Image benutzen mit den Abhängigkeiten oder aber einen lokalen Pipeline Runner benutzen und die Abhängigkeiten lokal installieren.

Wir bereiten also eine Datei mit dem Namen requirements.txt und schreiben darin alle Abhängigkeiten die wir benötigen. Wir brauchen in unserem Fall pyyaml und jsonschema.

Wir erstellen eine Datei mit dem Namen validate.yaml und können hierin jetzt anfangen alles zu definieren und unseren Code zu schreiben.

Die Validate Datei

Wir beginnen indem wir unsere imports definieren.

1import sys
2from jsonschema import validate
3import yaml

Hier ist sys für das einlesen für Kommandozeilen Parameter wie z.B. der Dateiname (brauchen wir, da wir ja zwei Dateien prüfen wollen und nicht für jede ein einzelnes Script haben wollen). yaml ist für das Laden von yaml Code und das umwandeln in eine python Map und zum Schluss jsonschema bzw. validate kann yaml gegen ein vorher definiertes Schema laufen lassen.

Das Schema definieren

Da wir hier ein ganz einfaches Beispiel haben wollen deren Inhalt lediglich nur ein property ist ist unser Schema natürlich auch recht simpel.

1schema = """
2type: object
3properties:
4  test:
5    type: string
6
7"""

Wir haben also ein Schema vom Typ object mit einem property mit dem Namen test, welches vom Typ string ist.

Kommandozeile abgreifen

Um nun unser Parameter von der Kommandozeile zu bekommen können wir auf die sys Bibliothek zurück greifen und schreiben einfach

1name = sys.argv[1]

Damit bekommen wir das erste Argument, welches mitgegeben wurde. Das soll uns auch reichen, da wir hier kein kompliziertes Parsing usw. machen wollen.

Das validieren

Um nun zu validieren öffnen wir die per Kommandozeile übergebene Datei und rufen die validate Funktion auf

1with open(name, 'r') as file:
2    validate()

Die validate Funktion bekommt nun einmal unsere Datei die wir prüfen wollen und unser Schema mit. Das ganze können wir mittels yaml.safe_load einlesen.

1validate(yaml.safe_load(file), yaml.safe_load(schema))

Unsere komplette Datei sieht nun also wie folgt aus:

 1import sys
 2import yaml
 3from jsonschema import validate
 4
 5
 6schema = """
 7type: object
 8properties:
 9  test:
10    type: string
11
12"""
13
14name = sys.argv[1]
15
16with open(name, 'r') as file:
17    validate(yaml.safe_load(file), yaml.safe_load(schema))
18

Die Pipeline

In unserem Script im Pipeline Teil kommt nun einmal das installieren der Abhängigkeiten und anschließend das ausführen des Scripts, so dass die komplette .gitlab-ci.yaml Datei wie folgt aussieht.

 1default:
 2  image: python:3.9.19-alpine3.19
 3
 4stages:
 5  - validate
 6
 7test_richtig:
 8  stage: validate
 9  script:
10    - pip install --no-cache-dir -r requirements.txt && \
11    - python3 validate.py richtig.yaml
12
13test_falsch:
14  stage: validate
15  script:
16    - pip install --no-cache-dir -r requirements.txt && \
17    - python3 validate.py falsch.yaml

Wenn man nun auf das Repository geht findet man im Menü Pipelines. Klickt man dort auf Stages wird man sehen, dass ein Job fehlgeschlagen ist.

Der Status der Pipeline