JSON mit JMESPath filtern
Interagierst du bei den großen Public-Cloud-Anbietern AWS oder Azure in der einen oder anderen Weise mit den REST-APIs der jeweiligen Services, ist das JSON-Format bei der Kommunikation mit solchen APIs stets involviert. Daher ist es wichtig, mit den gängigen Abfrage-Tools für JSON vertraut zu sein.
Passende Schulungen
AZ-104 Microsoft Azure Administrator (AZ-104T00)
AZ-104 Microsoft Azure Administrator (AZ-104T00): Azure Administration für Profis
Architecting on AWS (AWSA)
Architecting on AWS (AWSA): Die Grundlagen der Erstellung einer IT-Infrastruktur auf AWS
Du benötigst mehr Know-how rund um MS Azure? Dann empfehlen wir dir unsere Microsoft Azure Schulungen!
So liefern beispielsweise nahezu alle Kommandozeilen-Befehle, die du in der Azure-CLI oder der AWS-CLI z. B. zum Provisionieren, Konfigurieren oder Verwalten von IaaS- oder PaaS-Ressourcen absetzt, ein JSON-Array oder Wörterbuch als Ausgabe zurück. Sogar wenn du nicht JSON als Ausgabeformat verwendest – die AWS-CLI unterstützt z. B. als alternative Ausgabeformate yaml, yaml-stream, text und table; die Azure-CLI yaml, table, tsv und jsonc (farbiges JSON) – behandelt z. B. die Azure-CLI Ausgaben von CLI-Befehlen für Abfragen zunächst als JSON, d. h. CLI-Ergebnisse werden 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 https://jmespath.org/ JMESPath. Möchtest du JSONPath oder JQ unter AWS oder Azure nutzen, müsstest du 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 leitest du mit dem Parameter „– query“ ein.
Server- und Clientseitige Filterung
Wichtig: JMESPath ist eine Abfragesprache für JSON, die es erlaubt, Daten aus der CLI-Ausgabe zu filtern „UND“ 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.
Passende Schulungen
Advanced Architecting on AWS
Advanced Architecting on AWS: Spezialisiertes Gestalten komplexer Lösungen in AWS
Filtern in der Azure CLI
Schauen wir exemplarisch auf die Azure-CLI. Diese kannst du für Linux-, Windows- und MacOS-Clients von Microsoft https://docs.microsoft.com/de-de/cli/azure/install-azure-cli herunterladen und auf einem beliebigen Client-Rechner installieren. Möchtest du von dort mit Azure interagieren, müsst du dich 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 du das Ausgabeformat explizit angibst:
az vm list --output jsonc
Die Ausgabe ist natürlich seitenlang, da noch keine Filter zum Einsatz kommen. Die Abbildung zeigt nur einen Ausschnitt der Eigenschaften und Attribute der ersten VM (Array-Index 0) mit dem Namen „ditdekalivm“.
Mit dem Zeichen „.“ kannst du 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 kannst du 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 kannst du übrigens „–resource-group“ durch „-g“, „–name“ durch „-g“ und „–output“ durch „-o“ abkürzen:
az vm show -g ditde-website-rg -n ditdewebsitevm0 --query \ osProfile.linuxConfiguration.ssh.publicKeys -o jsonc
Auf gleiche Weise kannst du 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
Beachte 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 du den ausgegebenen Wert (also „mit“ Anführungszeichen) beispielsweise einer Umgebungsvariablen zuweist, um diese weiterzuverarbeiten.
Da ein solches Verhalten bei jeglicher Form der Weiterverarbeitung nicht gewollt ist, solltest du in einem solchen Szenario besser „tsv“ (table separated values) als Ausgabeformat wählen.
Gib als weiteres Beispiel die aktuelle Maschine-Größe aus: Hierzu kannst du 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
Natürlich kannst du auch mehrere Attribute angeben. Diese gibst du dann mittels eckiger Klammern an:
az vm get-instance-view -g ditde-website-rg -n ditdewebsitevm0 --query 'storageProfile.imageReference.[offer, sku, exactVersion]'
Allerdings musst du jetzt den gesamten Filter-Ausdruck in Hochkommas schreiben, was du bei den vorherigen Beispielen streng genommen auch schon hättest tun müssen, was wir aber nur der einfacheren Schreibweise wegen weggelassen haben. Folgende Abbildung zeigt das ganze noch mal in korrekter -tsv-Ausgabe:
Ermittel nun auf gleiche 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 musst du den gesamten Filterausdruck in Anführungszeichen schreiben, damit das „im“ Filterausdruck auf code,’PowerState/’ „matcht“ oder anders herum, also „außen“ die Hochkommas und „innen“ die Anführungszeichen. Der Status ist übrigens „VM deallocated“; die Zuordnung der VM zum Hypervisor ist also aufgehoben und du zahlst nicht für „Compute“, allenfalls für Storage oder Snapshots. Würdest du hingegen das Gastsystem herunterfahren, bliebe die Zuordnung erhalten. Wenn du eine VM über das GUI „beendest“, wird die Zuordnung ebenfalls ausgehoben.
Folgendes Beispiel ermittelt die Größe des eingebundenen Blockspeicher-Gerätes für das Root-Dateisystem einschließlich der verwendeten Caching-Methode. Wenn du möchtest, kannst du 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
Zur Abwechselung hier noch Mal 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. Du kannst es aber indizieren. Demonstrieren lässt sich das mit bereits verwendetem Kommando „az vm list“. Allerdings ist beim Abrufen eines Arrays keineswegs garantiert, dass die CLI-Ausgabe sortiert ist. Du kannst also die Indizierung nur sinnvoll benutzen, wenn du die Reihenfolge kennst oder die Rückgabereihenfolge für dich nicht wichtig ist. Möchtest du gezielt auf Eigenschaften „von“ einzelnen Elementen „aus“ einem Array zugreifen, muss der von dir 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. Für das Filtern verwendest du dann nach dem Vereinfachen den JMESPath-Operator [?…]. Er akzeptiert ein so genanntes „Prädikat“ als Inhalt. Unter einem Prädikat verseht 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: Filterst du 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
Kontakt
„*“ zeigt erforderliche Felder an