//Cloudogu EcoSystem Docs

Upgrade des CES mit Blueprints

Ausprägungen des CES werden in einem sogenannten Blueprint (Englisch für Konstruktionszeichnung) festgehalten.

Ein Blueprint ist ein in JSON geschriebenes Dokument. Es beschreibt auf deklarative Weise den Zielzustand eines EcoSystems hinsichtlich:

  • seiner installierten Dogus
  • seiner weiteren Pakete, die zum Betrieb notwendig oder sinnvoll sind.

Aufbau eines Blueprints

In diesem Abschnitt werden Top-Level-Properties eines Blueprints erläutert.

Beispiel-Blueprint

Die Eigenschaften der hier aufgeführten Properties werden im folgenden Abschnitt "Aufbau eines Blueprints" erläutert.

{
  "blueprintApi": "v1",
  "blueprintId": "blueprint-id",
  "cesappVersion": "4.2.3",
  "dogus": [
    {
      "name": "official/redmine",
      "version": "4.2.3-10",
      "targetState": "present"
    },
    {
      "name": "official/postfix",
      "version": "3.2.4-1"
    }
  ],
  "packages": [
    {
      "name": "backup-watcher",
      "version": "1.0.0"
    }
  ],
  "registryConfig": {
    "nexus": {
      "successfulInitialConfiguration": "true"
    },
    "_global": {
      "domain": "ces.local"
    }
  },
  "registryConfigEncrypted": {
    "nexus": {
      "admin_password": "nAtK3WSvdlYzeNmQhBkCeaTEGPMCHTcJimdtkncE...=="
    }
  }
}

Property blueprintApi

Diese Property definiert die Version des Blueprints. Je Version sind unterschiedliche, mögliche Implementierungen denkbar, die den Funktionsumfang der cesapp anzeigen, welche dieses Blueprint interpretiert. So lassen sich auch in Zukunft mit Fortschritt der cesapp noch vorherige Blueprints auswerten und anwenden.

Diese Property darf nicht leer sein.

Aktuell ist der Wert v1 erlaubt.

Property blueprintId

Diese Property dient zur eindeutigen Identifikation über unterschiedliche Blueprints hinweg, hat jedoch nur beschreibenden Charakter. Der Rahmen, in der die Eindeutigkeit ausreicht, wird durch die Organisation festgelegt, die diese Blueprints für sich einsetzt. Es bietet sich an, ein Versionierungsschema zu verwenden.

Da Blueprints darauf abzielen, Systemzustände nachzuvollziehen, sollten Blueprints nicht modifiziert werden, nachdem sie wenigstens einmal auf ein oder mehrere EcoSystem-Instanzen angewendet wurden. Stattdessen sollte ein Folge-Identifizierer für ein neues Blueprint gewählt werden.

Beispiel für aufeinander folgenden Blueprint-IDs für fünf unterschiedliche Blueprints:

"1.0.0 RC2"
"1.0.0"
"2.0.0 RC1"
"2.0.1 RC1"
"2.0.1"

Die blueprintId darf nicht leer sein.

Property cesappVersion

Diese Property bezeichnet die genaue Version der cesapp, also dem Tool, das das CES maßgeblich orchestriert. Weicht diese Version von der bisher im CES installierten Version der cesapp ab, dann wird die im Blueprint definiert Version installiert und danach der Upgrade-Vorgang fortgesetzt.

Die Version der cesapp kann unmittelbar mit Funktionalitäten oder Bugfixständen korrespondieren und muss mit ins Gesamtbild der Dogus passen. Wie bei allen anderen Versionsangaben in einem Blueprint ist nur eine feste Versionsangabe und keine Mindestversion oder Versionsintervalle möglich, um eine auditfähige Nachvollziehbarkeit zu gewährleisten.

Diese Property darf nicht leer sein.

Property dogus

Diese Property definiert eine Menge von Dogus, die installiert bzw. verändert werden sollen, sofern sie:

  • noch nicht im EcoSystem vorhanden sind oder
  • im EcoSystem vorhanden sind, aber nicht in der richtigen Version

Diese Property sowie deren Werte sind optional, die Reihenfolge der Einträge ist nicht relevant. Wenn ein Blueprint auf einem existierenden EcoSystem angewendet wird, in dem bereits bestimmte Dogus installiert sind, diese aber nicht genannt sind, dann wird die Behandlung dieser Dogus ignoriert und sie bleiben so bestehen, wie sie sind.

Dogu-Property innerhalb von dogus

Sofern vorhanden, müssen bzw. können einzelne Dogu-Einträge diese Properties enthalten:

  • name

    • besteht aus Dogu-Namespace und Dogu-Name
    • Beispiel: "official/redmine"
    • Pflichtangabe
  • version

    • die Version des Dogus, die installiert werden soll (abhängig vom Dogu)
    • Beispiel: "3.15.2-2
    • Bedingte Pflichtangabe, wenn mit "targetState": "present" dieses Teil installiert werden soll.
  • targetState

    • Kennzeichnet, ob das Dogu im Zielzustand vorhanden sein darf oder nicht

      • present: Das Dogu muss in der angegebenen Version vorhanden sein, bzw. eine bestehende Version wird aktualisiert
      • absent: Das Dogu darf nicht vorhanden sein, bzw. eine bestehende Version wird ersatzlos deinstalliert
    • Optionale Angabe. Wenn Diese Property nicht vorhanden ist, dann wird standardmäßig present angenommen.

Dogus dürfen nicht mehrfach im Blueprint genannt werden. Auch nicht, wenn sie aus verschiedenen Namespaces stammen.

Property packages

Diese Property definiert eine Menge von Systempaketen, die installiert bzw. verändert werden sollen, sofern sie:

  • noch nicht auf dem EcoSystem-Hostsystem vorhanden sind oder
  • auf dem EcoSystem-Hostsystem installiert sind, aber nicht in der richtigen Version

Diese Property sowie deren Werte sind optional, die Reihenfolge der Einträge ist nicht relevant. Wenn ein Blueprint auf einem existieren EcoSystem angewendet wird, in dem bereits bestimmte Packages installiert sind, diese aber nicht genannt sind, dann wird die Behandlung dieser Pakete ignoriert und sie bleiben so bestehen, wie sie sind.

Package-Properties innerhalb von packages

Sofern vorhanden, müssen bzw. können einzelne Package-Einträge diese Properties enthalten:

  • name

    • der Name des Pakets
    • Beispiel: "backup-watcher"
    • Pflichtangabe
  • version

    • die Version des Pakets, die installiert werden soll
    • Beispiel: "1.0.0
    • Bedingte Pflichtangabe, wenn mit "targetState": "present" dieses Teil installiert werden soll.
  • targetState

    • Kennzeichnet, ob das Paket im Zielzustand vorhanden sein darf oder nicht

      • present: Das Paket muss in der angegebenen Version vorhanden sein, bzw. eine bestehende Version wird aktualisiert
      • absent: Das Paket darf nicht vorhanden sein, bzw. eine bestehende Version wird ersatzlos deinstalliert
    • Optionale Angabe. Wenn Diese Property nicht vorhanden ist, dann wird standardmäßig present angenommen.

Wegen der besonderen Bedeutung, die der cesapp im CES-Kontext zukommt, darf diese nicht im packages-Bereich des Blueprints definiert sein, sondern ausschließlich in der cesappVersion-Property.

Verhalten des Wartungsmodus während eines Blueprint-Upgrades

Sobald ein Blueprint-Upgrade gestartet wird, wird der Wartungsmodus des CES aktiviert, um eine Nutzung der Dogus während des Vorgangs zu verhindern. Wenn der Vorgang abgeschlossen ist, wird der Wartungsmodus wieder deaktiviert und das CES kann wie gewohnt genutzt werden. Sollte der Wartungsmodus schon vor dem Start des Blueprint-Upgrades im CES aktiviert sein, wird er während des gesamten Vorgangs beibehalten und am Ende nicht deaktiviert.

Ausführung

Wird das oben beschriebene Blueprint mittels

cesapp upgrade blueprint Blueprint.json

angewendet, werden alle dort aufgelisteten Dogus in der angegebenen Version installiert. Downgrades werden generell nicht unterstützt, daher würde es zu Fehlern kommen, wenn die Dogus bereits in einer höheren Version installiert sind.

Registry-Keys setzen und entfernen

Setzen von etcd-Werten mittels Blueprint

Durch das Blueprint-Upgrade können Werte im etcd gesetzt werden. Der Aufbau des entsprechenden Bereiches der blueprint.json entspricht dabei dem Aufbau setup.json.

Es können globale und dogu-spezifische etcd-Werte gesetzt werden. Verschlüsselte etcd-Werte müssen nach dem gleichen Schema unter der Sektion registryConfigEncrypted angelegt werden.

Das Setzen der Keys findet bei dem blueprint-Upgrade als letzter Schritt statt. Zuerst werden dabei alle globalen Werte und anschließend alle dogu-spezifischen etcd-Werte gesetzt.

Manche Dogus müssen gegebenenfalls neu gestartet werden, damit die Änderungen an der Registry bei ihnen wirksam werden. Darauf wird beim Ausführen des Blueprint-Upgrades hingewiesen.

Es ist nicht möglich, globale etcd-Werte verschlüsselt zu speichern. Dasselbe gilt für etcd-Werte eines Dogus, welches nicht installiert ist. Wird es dennoch versucht, so scheitert das blueprint-Upgrade.

Die verschlüsselten Werte werden verschlüsselt in der Blueprint-Historie abgespeichert.

Beispiel: blueprint.json zum Setzen von etcd-Werten
    {
        "blueprintApi": "v1",
        "blueprintId": "BP-ID",
        "cesappVersion": "1.4.0",
        "registryConfig": {
          "doguName": {
            "doguConfig" : "doguConfigValue",
            "doguConfigGroup" : {
              "doguConfig2" : "doguConfigValue",
              "doguConfig3" : "doguConfigValue2"
            }
          },
          "_global": {
            "globalConfigKey": "globalConfigValue"
          }
        },
        "registryConfigEncrypted": {
          "backup": {
            "key1" : "val1",
            "key2" : {
              "v1" : "val2",
              "v2" : "val3"
            }
          }
        },
        "registryConfigAbsent": [
          "_global/dir",
          "_global/dir2/key1",
          "_global/dir2/key2",
          "cas/dir1/key1",
          "cas/dir1/key2",
          "cas/dir2",
          "cas/key2"
        ]
    }
Property registryConfig

Dieser Bereich entspricht der Struktur der Property registryConfig der setup.json. In geschachtelten JSON-Objekten können die Werte und Struktur des Bereiches config im etcd bearbeitet werden. Dabei ist zu beachten, dass hier die Werte im Klartext sowohl im Blueprint, als auch im etcd abgelegt werden.

Property registryConfigEncrypted

Dieser Abschnitt entspricht dem bereits erläuterten Bereich registryConfig. Der Unterschied jedoch liegt darin, dass die Werte vor dem Ablegen im etcd mittels der den Dogus zugehörigen Public Keys verschlüsselt werden. Vor der Historisierung des Blueprints werden die Werte außerdem durch ihre verschlüsselten Pendants ersetzt.

Property registryConfigAbsent

Dieser Abschnitt erfüllt die Funktion zum Löschen von Registry-Keys. Die Angegebenen Keys werden vor dem Setzen neuer Keys in der Registry gelöscht. Der Abschnitt unterscheidet sich von den Sektionen registryConfig und registryConfigEncrypted. Hier werden alle Keys oder alternativ auch Directories mit ihrem vollständigen Pfad angegeben. Die Verschachtelung von Keys wird hier mit einem / angegeben. Toplevel-Einträge können nicht gelöscht werden. Also z.B. der Eintrag "_global" oder "cas" würde zu einem Fehler führen.

Beispiel:

Setzen von Keys:

{
  "registryConfig": {
    "cas": {
      "keys": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  }
}

Löschen dieser Keys:

{
  "registryConfigAbsent": [
    "cas/keys/key1",
    "cas/keys/key2"
  ]
}

Oder alternativ:

{
  "registryConfigAbsent": [
    "cas/keys"
  ]
}

Blueprint-Upgrade-Anpassungen via Blueprint Mask

Ein angepasstes Upgrade einer CES-Instanz mittels Blueprint und Blueprint Mask lässt sich via

cesapp upgrade blueprint --blueprint-mask blueprintmask.json blueprint.json

anstoßen, wobei die blueprint.json die generellen Informationen enthält, welche durch die Informationen in der blueprintmask.json angepasst werden.

Aufbau einer Blueprint Mask

Eine Blueprint Mask wird wie ein Blueprint als JSON-formatierte Textdatei angelegt. Darin werden verschiedene Properties beschrieben. Beispiel:

{
  "blueprintMaskApi": "v1",
  "blueprintMaskId": "BeispielMask",
  "dogus": [
    {
      "name": "official/redmine",
      "targetState": "absent"
    },
    {
      "name": "postfix",
      "targetState": "absent"
    }
  ]
}
Property blueprintMaskApi

Diese Property definiert die Version der Blueprint Mask. Je Version sind unterschiedliche Implementierungen denkbar, die den Funktionsumfang der cesapp anzeigen, welche diese Blueprint Mask interpretiert. So lassen sich auch in Zukunft mit Fortschritt der cesapp noch vorherige Blueprint Masks auswerten und anwenden.

Diese Property darf nicht leer sein.

Aktuell ist der Wert v1 erlaubt.

Property blueprintMaskId

Diese Property dient zur eindeutigen Identifikation über unterschiedliche Blueprint Masks hinweg, hat jedoch nur beschreibenden Charakter. Der Rahmen, in der die Eindeutigkeit ausreicht, wird durch die Organisation festgelegt, die diese Blueprints für sich einsetzt. Es bietet sich an, ein Versionierungsschema zu verwenden.

Diese Property darf nicht fehlen oder leer sein.

Property dogus

Diese Property enthält ein JSON-Array, das aus Dogu-Objekten besteht. Diese Dogu-Objekte werden durch ihren Namen (inklusive Namespace; bspw. "name": "official/scm") und den gewünschten Installationsstatus (present oder absent; bspw. "targetState": "present") beschrieben. Es ist ebenfalls möglich, den Namen ohne Namespace anzugeben, da der Namespace in der blueprint.json ohnehin verpflichtend ist.

Einschränkungen

Generell verändert eine Blueprint Mask nicht die Blueprint-JSON-Datei, sondern nur die Informationen, die beim Upgrade-Vorgang genutzt werden.

Mit der Blueprint Mask können nur Objekte verändert werden, die sich im Blueprint befinden, auf das die Mask angewendet wird. So lassen sich bspw. keine neuen Dogu-Objekte über die Mask hinzufügen.

Der targetState einer Dogu-Definition in der Mask wird von der cesapp nicht inhaltlich validiert. Jeder targetState, der nicht "absent" ist, wird als "present" interpretiert. Auch ein fehlender targetState wird als "present" interpretiert.

Namespace-Wechsel durch den Blueprint-Mechanismus

Durch den Blueprint-Mechanismus kann der Namespace eines Dogus gewechselt werden. Dabei kann auch gleichzeitig ein Upgrade stattfinden, indem einfach bei dem zu installierenden Dogu eine neuere Version angegeben wird.

Beispiel: Es ist official/meinDogu in Version 1.0.0 installiert. In der auszuführenden blueprint.json ist meinDogu in der Version 1.0.1 und im Namespace premium eingetragen. Ein Namespace-Wechsel (inklusive Upgrade) wird demnach beim Ausführen der Blueprint durchgeführt.

Der Namespace-Wechsel muss explizit über den Blueprint-Befehl erlaubt werden. Dies geschieht über den allow-namespace-switch-Flag. Beispiel: cesapp upgrade blueprint --allow-namespace-switch myBlueprint.json. Das Installieren einer älteren Version ist grundsätzlich nicht möglich.

Blueprint Historie

Die Informationen über alle durchgeführten Blueprint-Upgrades werden im etcd gespeichert. Dabei werden grundsätzlich die folgenden Werte historisiert:

  1. Der Zeitpunkt, an dem das letzte erfolgreiche Blueprint-Upgrade gestartet wurde (wird bei jedem Blueprint-Upgrade überschrieben).
  2. Der Zeitpunkt, an dem ein Blueprint-Upgrade abgeschlossen wurde.
  3. Die effektive blueprint.json. Sollte eine Blueprint-Maske verwendet worden sein, so sind die Auswirkungen dieser hier sichtbar.

Dazu werden, für den Fall, dass während eines Blueprint-Upgrades die Blueprint-Maske verwendet wurde, die folgenden Werte historisiert:

  1. Die blueprintMask.json
  2. Die blueprintOriginal.json. Dies ist die Bueprint-Datei, ohne die Auswirkungen von der Blueprint-Maske.

Hinweis: Alle Timestamps sind im Format RFC3339.

Aufbau etcd

Die oben aufgelisteten Werte sind unter diesen Keys im etcd zu finden:

  1. /blueprint/current
  2. /blueprint/<Startzeitpunkt>/endTime
  3. /blueprint/<Startzeitpunkt>/blueprint.json
  4. ggf. /blueprint/<Startzeitpunkt>/blueprintOriginal.json
  5. ggf. /blueprint/<Startzeitpunkt>/blueprintMask.json

Ablauf

Zum Start des Blueprint-Upgrades wird die Zeit des Starts festgehalten. Nach Abschluss des Blueprint-Upgrades wird die blueprint.json, sowie ggf. die blueprintMask.json und die blueprintOriginal.json inklusive Startzeitpunkt direkt im etcd gespeichert.

Wird das Blueprint-Upgrade erfolgreich durchlaufen, so wird anschließend im etcd der Endzeitpunkt sowie der Startzeitpunkt dieses Blueprint-Upgrades gespeichert.

Besonderheiten

Enthält eine blueprint.json einen oder mehrere verschlüsselte Einträge, wird sie nicht in ihrer ursprünglichen Form in der Blueprint-Historie abgespeichert.

Die zu verschlüsselnden Werte werden mit den Public-Keys der entsprechenden Dogus verschlüsselt. In der blueprint.json werden die zu verschlüsselnden Werte durch die verschlüsselten ersetzt und die veränderte Version wird in die Blueprint-Historie gespeichert.

Hierbei können gegebenenfalls Informationen (Formatierungen oder Werte, die von der cesapp nicht erkannt werden) der blueprint.json verloren gehen, da diese von der cesapp auf die Klassenstruktur des Blueprints übertragen wird und daraus anschließend wieder eine .json-Datei erstellt wird.

Beispiel: Abfrage der Werte im etcd

Um Informationen über das letzte durchgeführte Blueprint-Upgrade zu bekommen, muss zuerst der Startzeitpunkt des aktuellen Blueprint-Upgrades mit etcdctl get /blueprint/current abgefragt werden. Der Wert könnte wie folgt aussehen: 2019-09-27T09:14:42+02:00

Die blueprint.json des letzten Blueprint-Upgrades wird durch den Befehl etcdctl get blueprint/2019-09-27T09:14:42+02:00/blueprint.json aufgerufen.

Der Endzeitpunkt kann über die Abfrage etcdctl get blueprint/2019-09-27T09:14:42+02:00/endTime ermittelt werden.

Die BlueprintId, des zuletzt erfolgreich ausgeführten Blueprint-Upgrades, kann über die Shell mithilfe des folgenden Befehls abgefragt werden: etcdctl get /blueprint/$(etcdctl get /blueprint/current)/blueprint.json | jq -r ".blueprintId"