Umgang mit JSON-Abfragesprachen, Teil 2 JSON mit JMESPath filtern

Autor / Redakteur: Dipl. -Ing. Thomas Drilling / Stephan Augsten

Bei den Public-Cloud-Anbietern AWS und Azure geht die Kommunikation von REST-APIs mit dem JSON-Format einher. Daher ist es wichtig, mit den gängigen Abfrage-Tools für JSON vertraut zu sein.

Firma zum Thema

Mithilfe von Vereinfachung und passenden Filtern lassen sich JSON-Ausgaben mit JMESPath aufs Wesentliche reduzieren.
Mithilfe von Vereinfachung und passenden Filtern lassen sich JSON-Ausgaben mit JMESPath aufs Wesentliche reduzieren.
(Bild: Drilling)

Nahezu alle Kommandozeilen-Befehle, die in der Azure-CLI oder der AWS-CLI z. B. zum Provisionieren, Konfigurieren oder Verwalten von IaaS- oder PaaS-Ressourcen dienen, liefern ein JSON-Array oder Wörterbuch als Ausgabe zurück, sogar wenn nicht JSON als Ausgabeformat verwendet wird.

Die AWS-Kommandozeile unterstützt z. B. als alternative Ausgabeformate yaml, yaml-stream, text und table; die Azure-CLI yaml, table, tsv und jsonc (farbiges JSON). Trotz dessen behandelt beispielsweise die Azure-CLI Ausgaben von CLI-Befehlen für Abfragen zunächst als JSON. CLI-Ergebnisse werden also in der Regel in Form eines JSON-Arrays oder -Wörterbuchs zurückgegeben.

Unter einem Array versteht man bei JSON eine Sequenz von Objekten, die sich eindeutig indizieren lassen. Wörterbücher dagegen sind unsortierte Objekte, auf die aber mit Schlüsseln zugegriffen wird. Dabei geben grundsätzlich all jene Befehle, die mehr als ein Objekt zurückgeben „können“ auch immer ein Array zurück, während Befehle, die „immer“ ein einzelnes Objekt zurückliefern, dieses als Wörterbuch ausgeben.

Nachdem wir uns im ersten Teil dieser kleinen Workshop-Serie das eher einfach gestrickte JSONPath angesehen haben und der dritte Teil dem mächtige JQ vorbehalten bleibt, befasst sich dieser Beitrag mit JMESPath. Möchten Sie JSONPath oder JQ unter AWS oder Azure nutzen, müssten Sie beide Tools erst installieren. JMESPath hingegen ist sowohl in der Azure-CLI als auch in der AWS-CLI vorinstalliert. Die gewünschten Filter-Ausdrücke leiten Sie mit dem Parameter „-- query“ ein.

Server- und Client-seitige Filterung

Wichtig: JMESPath ist eine Abfragesprache für JSON, die es erlaubt, Daten aus der CLI-Ausgabe zu filtern und auch zu ändern. Dabei werden die Abfragen für die JSON-Ausgabe ausgeführt, „bevor“ die Anzeigeformatierung passiert. Man könnte auch von einer „Client-seitigen“ Filterung sprechen.

Bei der AWS-CLI steht aber alternativ auch der Parameter „--filter“ zur Verfügung, der eine Server-seitige Filterung ermöglicht. Die Server-seitige Filterung wird bei AWS durch die jeweilige API selbst ermöglicht, während die Client-seitige Filterung mittels „--query“ ein Feature der CLI ist.

Filtern in der Azure CLI

Der Login-Dialog von Azure.
Der Login-Dialog von Azure.
(Bild: Drilling / Microsoft)

Schauen wir exemplarisch auf die Azure-CLI. Diese stehen als Linux-, Windows- und macOS-Clients bei Microsoft bereit, um sie auf dem Client-Rechner installieren zu können. Möchten Sie von dort mit Azure interagieren, müssen Sie sich mit …

az login

… bei einem Azure-Account authentifizieren. Ohne Parameter abgesetzt, leitet das Kommando durch eine interaktive, Browser-basierte Authentifizierung.

Folgendes Beispiel aus dem ersten Teil dieses Workshops liefert eine Liste (Array) aller virtuellen Maschinen des aktiven (oder per Parameter angebbaren) Abonnements im JSON-Standardformat zurück, bzw. im farbigen JSON, wenn Sie das Ausgabeformat explizit angeben:

az vm list --output jsonc

Die ungefilterte Ausgabe einer VM-Liste pro Abonnement.
Die ungefilterte Ausgabe einer VM-Liste pro Abonnement.
(Bild: Drilling)

Die Ausgabe ist natürlich seitenlang, da noch keine Filter zum Einsatz kommen. Die vorangestellte Abbildung zeigt nur einen Ausschnitt der Eigenschaften und Attribute der ersten VM (Array-Index 0) mit dem Namen „ditdekalivm“.

Mit dem Zeichen „.“ Können Sie auf Eigenschaften von geschachtelten Wörterbüchern zuzugreifen. Der Befehl …

vm show --resource-group <Resource-Group> --name <VM-Name>

… liefert zum Beispiel eine Wörterbuch-Ausgabe. Daher können Sie bei der Filterung mit --query durch Anfügen von Punkten, welche je eine Schachtelungs-Ebene markieren, explizit auf die gewünschten Schlüssel zugreifen. Folgender Befehl ermittelt z. B. den Namen des öffentlichen SSH-Schlüssels der in der angegebenen Ressourcen-Gruppe genannten VM. Dabei können Sie übrigens „--resource-group“ durch „-g“, „--name“ durch „-n“ und „--output“ durch „-o“ abkürzen:

az vm show -g ditde-website-rg -n ditdewebsitevm0 --query \ osProfile.linuxConfiguration.ssh.publicKeys -o jsonc

Das Ermitteln des für die angegebene VM konfigurierten admin-Users.
Das Ermitteln des für die angegebene VM konfigurierten admin-Users.
(Bild: Drilling)

Auf gleiche Weise könnten Sie z. B. eben auch den Namen des verwendeten Admin-Users ermitteln:

az vm show -g ditde-website-rg -n ditdewebsitevm0 --query \ osProfile.linuxConfiguration.ssh.publicKeys -o jsonc

Beachten Sie dabei aber in beiden Fällen die mit ausgebebenen Anführungszeichen. Daran ist zu erkennen, dass es sich bei dem Objekt um eine gültige JSON-Zeichenfolge handelt. Allerdings würden die Anführungszeichen von der Shell nicht interpretiert werden, wenn Sie den ausgegebenen Wert (also „mit“ Anführungszeichen) beispielsweise einer Umgebungsvariablen zuweisen, um diese weiterzuverarbeiten.

Eine als Table (tsv) formatierte Ausgabe.
Eine als Table (tsv) formatierte Ausgabe.
(Bild: Drilling)

Da ein solches Verhalten bei jeglicher Form der Weiterverarbeitung nicht gewollt ist, sollten Sie in einem solchen Szenario besser „tsv“ (table separated values) als Ausgabeformat wählen. Geben Sie als weiteres Beispiel die aktuelle Maschine-Größe aus: Hierzu können Sie zur Abwechselung das Kommando „az vm get-instance-view“ verwenden:

az vm get-instance-view -g ditde-website-rg -n ditdewebsitevm0 --query hardwareProfile.vmSize -o jsonc

Mehrere Attribute ausgeben.
Mehrere Attribute ausgeben.
(Bild: Drilling)

Natürlich können wir auch mehrere Attribute angeben, die dann mittels eckiger Klammern mitgegeben werden:

az vm get-instance-view -g ditde-website-rg -n ditdewebsitevm0 --query 'storageProfile.imageReference.[offer, sku, exactVersion]'

Die korrekte, weiterverarbeitbare Ausgabe im table-Format.
Die korrekte, weiterverarbeitbare Ausgabe im table-Format.
(Bild: Drilling)

Allerdings müssen Sie jetzt den gesamten Filter-Ausdruck in Hochkommata schreiben. Bei den vorherigen Beispielen hätte dies streng genommen auch schon so gehandhabt werden müssen, was wir aber nur der einfacheren Schreibweise wegen weggelassen haben. Die Abbildung zeigt das Ganze noch mal in korrekter tsv-Ausgabe.

Das Ermitteln des Power-Status.
Das Ermitteln des Power-Status.
(Bild: Drilling)

Ermitteln Sie nun auf gleicher Weise den Power-Status mit:

az vm get-instance-view -g ditde-website-rg -n ditdewebsitevm0 --query "instanceView.statuses [?starts_with(code,'PowerState/')].displayStatus" -o jsonc

Hier müssen Sie den gesamten Filterausdruck in Anführungszeichen schreiben, das Sie „im“ Filterausdruck auf code,'PowerState/' „matchen“ – oder anders herum, also „außen“ die Hochkommas und „innen“ die Anführungszeichen. Der zurückgelieferte Status ist übrigens „VM deallocated“.

Die Zuordnung der VM zum Hypervisor ist also aufgehoben und Sie zahlen demzufolge nicht für „Compute“, allenfalls für Storage oder Snapshots. Würde Sie hingegen das Gastsystem herunterfahren, bliebe die Zuordnung erhalten. Wenn Sie eine VM über das GUI „beenden“ wird die Zuordnung ebenfalls aufgehoben.

Das Umbenennen von Ausgabewerten.
Das Umbenennen von Ausgabewerten.
(Bild: Drilling)

Folgendes Beispiel ermittelt die Größe des eingebundenen Blockspeicher-Geräts für das Root-Dateisystem einschließlich der verwendeten Caching-Methode. Wenn Sie möchten, können Sie die ermittelten Datenfelder auch „bei“ der Ausgabe umbenennen z. B. in „cachingverfahren“ und „groesse“, um eine aussagekräftigere Anzeige zu bekommen:

az vm get-instance-view -g ditde-website-rg -n ditdewebsitevm0 --query "storageProfile.osDisk.{cachingverfahren: caching, groesse: diskSizeGb}" --output jsonc

Das Umbenennen von Ausgabewerten vereinfacht die Lesbarkeit.
Das Umbenennen von Ausgabewerten vereinfacht die Lesbarkeit.
(Bild: Drilling)

Zur Abwechselung hier noch einmal das Umbenennen von Ausgabewerten beim Kommando „az vm show“:

az vm show -g ditde-website-rg -n ditdewebsitevm0--query '{VMName:name, adminUser:osProfile.adminUsername, sshSchluessel:osProfile.linuxConfiguration.ssh.publicKeys[0].keyData }' -o jsonc

Array versus Wörterbuch

Wie eingangs erwähnt, besitzt ein Array im Gegensatz zu einem Wörterbuch keine eigenen Eigenschaften. Es lässt sich aber indizieren, wie das eingangs verwendete Kommando „az vm list“ demonstriert. Allerdings ist beim Abrufen eines Arrays keineswegs garantiert, dass die CLI-Ausgabe sortiert ist. Sie können also die Indizierung nur sinnvoll benutzen, wenn Sie die Reihenfolge kennen oder die Rückgabereihenfolge nicht wichtig ist.

Möchten Sie gezielt auf Eigenschaften „von“ einzelnen Elementen „aus“ einem Array zugreifen, muss der von Ihnen verwendende Ausdruck die Ausgabe zuerst „vereinfachen“ und dann „filtern“. Für das Vereinfachen eines Arrays kommt beim Filtern mit „--query“ der JMESPath-Operator „[]“ zum Einsatz. Er bedeutet, dass alle Ausdrücke nach dem []-Operator auf „jedes“ Element „im“ aktuellen Array angewendet werden, wenn dieser am Anfang steht.

Das Filtern auf Arrays.
Das Filtern auf Arrays.
(Bild: Drilling)

Für das Filtern verwenden wir dann nach dem Vereinfachen den JMESPath-Operator, der ein so genanntes „Prädikat“ als Inhalt akzeptiert. Unter einem Prädikat versteht Azure eine beliebige Anweisung, die sich zu „true“ oder „false“ auswerten lässt. Dann sind alle Ausdrücke, bei denen das Prädikat zu true ausgewertet wird, Teil der Ausgabe: Filtern Sie nun beispielsweise die Ausgabe von „az vm list“ der angegebenen Ressourcen-Gruppe auf Name, OS-Typ und Admin-User-Name:

az vm list -g ditde-storage-insider-RG --query '[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}' -o jsonc

(ID:47381124)

Über den Autor

Dipl. -Ing. Thomas Drilling

Dipl. -Ing. Thomas Drilling

IT-Consultant, Trainer, Freier Journalist