vRealize Orchestrator Configuration Elements leicht gemacht

Beim Verwenden eines älteren vRO-Workflows (vRealize Orchestrator) bin ich auf das Problem gestoßen, dass viele Informationen manuell eingegeben werden müssen. Hier schleicht sich gerne mal der Fehlerteufel ein und ich habe nach einer Möglichkeit gesucht, unnötige Eingaben zu vermeiden. Bei der Recherche bin ich hier auf Configuration Elements gestoßen. Anhand zweier Blog-Artikel (hier und hier) habe ich mich mit dem Thema beschäftigt und entsprechende Funktionen in meinem Homelab implementiert. Der Blog-Artikel erklärt das Vorgehen etwas ausführlicher als die von mir erwähnten Quellen.

Wozu das Ganze?

Ein Praxisbeispiel ist das Bereitstellen von virtuellen Maschinen. Hinsichtlich der Netzwerk-Konfiguration gilt es einige Parameter zu setzen - unter anderem:

  • IP-Adresse
  • Netzwerkmaske
  • Gateway
  • DNS-Server und Such-Domänen

Wenn man diese ganzen Eigenschaften im Presentation Layer eines Workflows angibt, leidet die Übersichtlichkeit darunter und man erhöht auch automatisch potenzielle Fehler, wenn viele Informationen manuell eingetragen werden müssen. Viel praktischer wäre es, diese Einstellungen in einer Konfiguration zu speichern. So kann man einfach eine fertige Vorlage auswählen und gängige Konfigurationen werden automatisch übernommen - die Übersichtlichkeit wird optimiert:

Vorgehensweise

Zuerst müssen die Netzwerk-Konfigurationen in vRO hinterlegt werden. Hierzu empfiehlt es sich, im Configuration-Reiter, einen entsprechenden Ordner für die eigenen Konfigurationen zu erstellen. Ich habe pro Netzwerk eine entsprechende Konfiguration mit den ganzen benötigten Attributen erstellt:

vRO-Konfigurationen

Ich habe meine Netzwerk-Konfigurationen in einem Unterordner NetworkConfigs gespeichert, da ich in Zukunft noch weitere Konfigurationen erstellen werde.

Anschließend werden zwei "Code-Schnippsel", Actions, benötigt, um die folgende Logik abzubilden:

  • getConfigurationElements - Auslesen aller Konfigurationsdateinamen innerhalb eines Ordners
  • getConfigurationElementValue - Auslesen eines Einstellungswerts einer Konfigurationsdatei

Die erste Funktion wird im Presentation Layer des Workflows verwendet, um die hinterlegten Konfigurationsdateien in einer Dropdown-Box auswählen zu können (siehe auch den zweiten Screenshot weiter oben). Die zweite Funktion kann später in einem Workflow dazu verwendet werden, um die einzelnen Einstellungen auszulesen und weiterzuverwenden - beispielsweise, um eine geklonte VM mit neuen Netzwerk-Informationen zu versehen.

Das erste Modul

Bevor die einzelnen Actions erstellt werden, muss zunächst ein Modul erstellt werden. Hierzu gibt eine Namensschema, welches in etwa so aussieht:

1tld.firma.name

Ich habe mich in diesem Beispiel für com.stdevel.generic entschieden - generic deswegen, weil es sich um ziemlich allgemeine Funktionen handelt, die in zahlreichen Workflows Verwendung finden könnten. Würde man später weitere Actions für beispielsweise Monitoring erstellen, würde es sich empfehlen, diese in ein anderes Modul - z. B. com.stdevel.monitoring - auszulagern. Um ein Modul zu erstellen, muss der Design-Reiter (Zahnrad-Symbol) ausgewählt werden. Ein Klick auf New module öffnet ein Fenster, in welchem der Name angegeben wird.

getConfigurationElements

Note

Der Übersichtlichkeit halber werde ich im Rest des Artikels Configuration Elements auch als Konfigurationsdateien bezeichnen.

Im neu erstellten Modul folgt ein Klick auf Add action um eine Action zu erstellen.

Die erste Action, getConfigurationElements, führt die folgenden Schritte aus:

  1. Auslesen der Konfigurationskategorie anhand des übergebenen Pfads (Stankowic/NetworkConfigs im oberen Beispiel)
  2. Beziehen aller Konfigurationsdateien innerhalb der Kategorie bzw. Abbruch falls Pfad inkorrekt
  3. Auslesen der Namen aller Konfigurationsdateien und Zwischenspeichern in einem Array
  4. Übergabe des Arrays

Der folgende Quellcode wird hinterlegt:

 1//get category
 2var category = Server.getConfigurationElementCategoryWithPath(categoryPath);
 3
 4//die in a fire if non-existent
 5if (category == null) {
 6    throw "Configuration element category '" + categoryPath + "' not found or empty!";
 7}
 8
 9//get _all_ the elements
10var elements = category.configurationElements;
11var result = [];
12
13//retrieve names
14for (i = 0; i < elements.length; i++) {
15    System.log("Found configuration element '" + elements[i].name + "'");
16    result.push(elements[i].name);
17}
18
19//return results
20return result

Den Quellcode der Action gibt es übrigens auch auf GitHub: [klick mich!]

Um die Funktion zu testen, habe ich einen Workflow erstellt, welcher ein Pfad abfragt und anschließend alle gefundenen Konfigurationsdateien in der Konsole ausgibt:

Beispiel

Den Workflow gibt es zum Download auf GitHub: [klick mich!]

getConfigurationElementValue

Das Auflisten aller Konfigurationsdateien funktioniert nun - der nächste Schritt ist es nun, eine bestimmte Einstellung einer bestimmen Konfigurationsdatei auszulesen. Die nächste Action bildet die folgenden Schritte ab:

  1. Auslesen der Konfigurationskategorie anhand des übergebenen Pfads
  2. Beziehen der Konfigurationsdateien, Auswählen anhand übergebenen Namen
  3. Auslesen der enthaltenen Einstellungen, Auswählen anhand übergebenen Namen
  4. Übergabe des Einstellungswertes

Der Quellcode sieht wie folgt aus:

 1//get category
 2var category = Server.getConfigurationElementCategoryWithPath(categoryPath);
 3
 4//die in a fire if non-existent
 5if (category == null) {
 6    throw "Configuration element category '" + categoryPath + "' not found or empty!";
 7}
 8
 9//get _all_ the elements
10var elements = category.configurationElements;
11var result = [];
12
13//retrieve names
14for (i = 0; i < elements.length; i++) {
15    if (elements[i].name == elementName) {
16        //found required element
17        var attribute = elements[i].getAttributeWithKey(attributeName);
18        if (attribute != null) {
19            System.log("Found attribute '" + attributeName + "' in '" + elementName + "' with value '" + attribute.value + "'");
20            return attribute.value;
21        }
22        else {
23            throw "Attribute '" + attributeName + "' not found!";
24        }
25    }
26}

Den Quellcode der Action gibt es auch auf GitHub: [klick mich!]

Zum Testen empfiehlt sich auch hier wieder ein simpler Workflow, der den Konfigurationspfad, die Konfigurationsdatei und eine Einstellung abfragt und den Wert anschließend in der Konsole ausgibt:

Beispiel

Auch diesen Workflow gibt es wieder auf GitHub: [klick mich!]

Ausblick

Wie am Anfang des Artikel erwähnt, ist das Bereitstellen virtueller Maschinen ein konkreter Anwendungsfall die implementierten Actions. In einem weiteren Artikel werde ich das Provisionieren von virtuellen Maschinen aufgreifen und erläutern. 🙂

Übersetzungen: