Dokumentation
Flows und Automatisierung
Ein Flow ist eine Zeichnung, die läuft. Sie setzen Knoten auf eine Arbeitsfläche, ziehen Drähte dazwischen, und die Plattform geht diese Zeichnung jedes Mal ab, wenn der von Ihnen gewählte Moment eintritt. Diese Seite sagt, was ein Flow kann, was jeder Knoten bedeutet und wo genau seine Grenzen liegen.
Was ein Flow ist
Ein Flow ist ein gerichteter Graph: Knoten mit Drähten dazwischen, abgelaufen von einem einzigen Startpunkt aus. Er ist bewusst kein Skript mit einer Schleife. Vier Regeln legen die Form fest, und der Editor verweigert die Veröffentlichung einer Zeichnung, die eine davon bricht, und nennt dabei den Knoten, der nicht stimmt.
- Genau ein Auslöser. Der Auslöserknoten ist der einzige Eingang, und er entscheidet, welche Variablen im Rest der Zeichnung existieren.
- Keine Zyklen. Ein Draht, der zu einem Knoten zurückführt, aus dem er kam, wird abgelehnt, denn ein Flow kann nicht warten: eine Schleife würde schlicht nie enden.
- Jeder Knoten muss vom Auslöser aus erreichbar sein. Ein Knoten, der lose hängt, ist ein Fehler, den man auf einem Bildschirmfoto nicht sieht, also ist es ein Fehler beim Veröffentlichen.
- Zweige werden nacheinander abgelaufen, nie nebeneinander. Zwei Zweige gleichzeitig würden gleichzeitig in state schreiben, und das Ergebnis hinge am zeitlichen Zufall.
Die Arbeitsfläche
Der Editor ist eine Arbeitsfläche, und einen zweiten gibt es nicht. Ein neuer Flow öffnet sich sofort darauf, und ein Flow, der eine gerade Liste von Schritten war, öffnet sich als gerade Kette von Knoten.
- Die Palette enthält die zwölf Knotenarten. Klicken Sie eine an, um sie auf die Fläche zu setzen, oder ziehen Sie sie an die gewünschte Stelle.
- Ziehen Sie einen Knoten an seiner Kopfzeile, um ihn zu verschieben. Alles andere auf dem Knoten ist ein Bedienelement und beginnt deshalb keine Ziehbewegung.
- Ein Draht läuft von einem Ausgangspunkt zu einem Eingangspunkt. Ziehen Sie vom einen zum anderen, oder klicken Sie erst den Ausgang und dann den Eingang an. Beides tut dasselbe, und das Zweite ist der Weg über die Tastatur.
- Lassen Sie einen Draht im Leeren los, passiert nichts. Zum Entfernen wählen Sie ihn aus und drücken Entfernen, oder Sie nehmen das Kreuz, das darauf sitzt.
- Zoomen Sie zwischen 50 und 200 Prozent, sehen Sie mit Einpassen die ganze Zeichnung, und ziehen Sie den Hintergrund, um zu schwenken. Eine Übersichtskarte gibt es nicht.
Die Knoten
Zwölf Arten, und diese Liste ist mit Absicht kurz. Jede Art ist ein Bedienbereich, neun Übersetzungen, ein Zweig im Ausführer und eine Zeile in der Wahrheitstabelle, also ist eine Art, die ihr Gewicht trägt, mehr wert als eine, die es fast tut.
| Knoten | Ausgänge | Was er tut und wo er aufhört |
|---|---|---|
trigger | out | Der einzige Eingang. Sein Ereignis entscheidet, welche Variablen existieren. Ein manueller Auslöser trägt außerdem das JSON, das Sie einspeisen: höchstens 2048 Zeichen, 40 Schlüssel und 512 Zeichen pro Wert. |
script | ok · error | Rendert eine Skriptvorlage gegen ein Ziel. Er verlässt den Knoten über ok, oder über error, wenn das Rendern scheitert. Setzen Sie den Haken für Weiterlaufen bei einem Fehler, läuft es trotzdem weiter. |
switch | rule-0 … · otherwise | Sieht sich einen Wert an und nimmt die erste Regel, die passt; alles andere geht über otherwise. Höchstens zwölf Regeln und ein Vergleichswert von höchstens 512 Zeichen. |
if | true · false | Eine Bedingung, zwei Ausgänge. Dieselben Operatoren und dieselbe Auswertung wie eine switch-Regel, gezeichnet als das Ja oder Nein, das es wirklich ist. |
set | out | Schreibt in state, wo ein späterer Knoten oder ein Skript es wieder ausliest. Höchstens zwölf Zuweisungen pro Knoten und 4096 Zeichen pro Wert. Die Namen wählen Sie selbst; http ist reserviert. |
http | ok · error | Ruft eine URL auf und legt die Antwort in state.http ab. GET oder POST, höchstens acht Kopfzeilen, eine Zeitgrenze zwischen 0,5 und 10 Sekunden und eine Antwortgrenze zwischen 256 Byte und 256 KiB, standardmäßig 64 KiB. Höchstens drei Weiterleitungen, jede erneut geprüft. |
notify | out | Schreibt eine Meldung im Bereich dieses Kontos, auf der Stufe Info oder Warnung. Titel höchstens 120 Zeichen, Text höchstens 1000. Setzen Sie den Haken bei Auch per E-Mail senden, geht sie zusätzlich als E-Mail hinaus, an alle mit Zugriff auf Skripte, die Flow-Meldungen unter E-Mail-Benachrichtigungen nicht abgeschaltet haben. Ein Testlauf verschickt nie E-Mail. |
action | ok · error | Startet, stoppt, fährt herunter, setzt aus oder nimmt den Server dieser Ausführung wieder auf und wartet bis zu 300 Sekunden auf den Abschluss des Befehls. Null bedeutet nicht warten: angenommen ist nicht dasselbe wie laufend. |
delay | out | Pausiert den Lauf. Bis 30 Sekunden innerhalb der Anfrage, die ihn gestartet hat; länger, und der Lauf wird zurückgestellt und später fortgesetzt, höchstens 30 Tage. |
approval | approved · rejected | Hält den Lauf an, bis eine Person genehmigt oder ablehnt, mit einer Frist und einem gewählten Ausgang, falls niemand antwortet. |
foreach | loop · done | Durchläuft den Schleifenausgang einmal je Element einer Liste, gelesen als JSON, eins pro Zeile oder durch Kommas getrennt. |
repeat | loop · done | Durchläuft den Schleifenausgang, solange eine Bedingung zutrifft, und liest diese Bedingung vor jeder Runde neu. |
break | — | Verlässt die Schleife, in der er steht. Der Lauf macht am Ausgang Fertig dieser Schleife weiter. |
subflow | ok · error | Führt einen anderen Flow dieses Kontos aus und wartet auf das Ergebnis. Das Kind erhält seine Eingabe als input.*. |
log | out | Schreibt eine Zeile in die Ausführung, so wie der Debug-Knoten es in Node-RED tut. Das Feld fasst 1000 Zeichen; in der Ausführung landen die ersten 200. |
note | — | Text auf der Arbeitsfläche. Er hat keine Anschlüsse und wird nie abgelaufen, taucht also auch nie in einer Ausführung auf. |
end | — | Beendet diesen Zweig und sagt, wie die Ausführung ausging: erfolgreich, gescheitert, oder übersprungen für einen Server, für den dieser Flow nicht gedacht war. Dazu gehört eine Nachricht von höchstens 280 Zeichen. |
Auslöser
Fünf Momente, und welchen Sie wählen, ist nicht nur, wann der Flow läuft. Es ist auch, welche Variablen existieren, welche die Auswahl Ihnen anbietet und welche die Plattform zu speichern verweigert. Ein Pfad, der in diesem Moment nicht existieren kann, ist ein Fehler beim Speichern und kein leerer Text mitten in einer Ausführung.
| Auslöser | Wann er läuft | Was da ist und was nicht |
|---|---|---|
server.provisioned | Einmal, direkt nachdem eine Bestellung die Maschine hervorgebracht hat. | Alles. Dies ist der einzige Moment, in dem jede Gruppe existiert. |
server.reinstalled | Nachdem eine Neuinstallation einer bestehenden Maschine geglückt ist. | Dieselbe Maschine, ein anderes Abbild. Die Adresse bleibt unverändert und das Anlagedatum ist weiterhin das ursprüngliche. Heute feuert er nur für Container; die Neuinstallation einer virtuellen Maschine schließt ein Bauteil ab, das nicht rendern kann. |
server.deleted | Sobald eine Löschung angenommen wurde, solange die Zeile noch lesbar ist. | Alles außer dem Abbild. Es gibt nichts mehr, woraus ein Abbild zu lesen wäre, und die Plattform erfindet keines, also fehlt os schlicht. |
manual | Nie von selbst. Sie starten ihn im Editor mit Inject. | Eine bestehende Maschine, die Sie auswählen, dazu Ihr eigenes JSON als input. Auch hier gibt es kein Abbild: was auf einer Maschine liegt, kann die Plattform im Nachhinein nicht nachschlagen. |
webhook | Sobald ein Fremder an eine eigene URL sendet. | Überhaupt keine Maschine, also kein Tarif, keine Adresse, keine Verbindung und kein Agent. Übrig bleiben das Konto, der Flow, der gesendete Rumpf als input und die Anfrage selbst als webhook. |
Variablen
Jeder Wert, den ein Flow lesen kann, stammt aus einer dieser Gruppen. Die Auswahl im Editor zeigt die Gruppen, die bei Ihrem Auslöser existieren, und sonst nichts. Einen unbekannten Pfad zu lesen ist ein Fehler und nie ein Leerwert: eine falsche Annahme gehört laut.
| Gruppe | Existiert bei | Was darin steht |
|---|---|---|
org.* | Jedem Auslöser | Das Konto: id, Name und Kurzname. |
user.* | Den vier Serverauslösern | Die Person, für die die Ausführung handelt: id, Name und E-Mail-Adresse. |
flow.* | Jedem Auslöser | Dieser Flow und diese Ausführung: Name, Ausführungs-id, Schrittnummer und Anzahl, Auslöser und Startzeitpunkt. |
server.* | Den vier Serverauslösern | Die Maschine: Name, Hostname, Art, Status, externe id, Knoten, Kerne, Arbeitsspeicher, Festplatte und Anlagedatum. |
server.compute.* | Den vier Serverauslösern | Welche Art Gast es ist und was diese Art wirklich kann: Art, Vorlage, unprivileged, Speicher, Einhängepunkte, capabilities und unsupported. Alle sieben sind optional, und Fehlen bedeutet nicht festgestellt und nicht nein. |
plan.* | Den vier Serverauslösern | Der Tarif hinter der Bestellung: Name, Kerne, Arbeitsspeicher, Festplatte und Brücke. |
os.* | Angelegt und neu installiert | Das Abbild: Name, Kurzname und Kategorie. Es gibt keine Familie und keine Version, denn der Katalog hat diese Spalten nicht, und sie zu raten wählt die falsche Paketverwaltung. |
ip.* | Den vier Serverauslösern | Die vergebene Adresse und ob sie Version 4 oder 6 ist. |
network.* | Den vier Serverauslösern | Alles rund um diese Adresse: cidr, Gateway, Netzmaske, Netz, Broadcast und die Namensauflöser. |
prefix.* | Den vier Serverauslösern | Der Adressbereich, aus dem sie stammt, mit seiner Spanne und seinem Elternbereich. |
integration.* | Den vier Serverauslösern | Die Verbindung, die die Maschine trägt: Name, Art, Knoten, Speicher, Brücke und der vmid-Bereich. |
agent.* | Den vier Serverauslösern | Der Agent, der die Arbeit gemacht hat: Name, Status, Version, Hostname, Betriebssystem, Kernel und Kerne. |
input.* | Manuell und Webhook | Was Sie eingespeist haben oder was der Webhook gesendet hat. Die Schlüssel gehören Ihnen, und die Auswahl folgt ihnen. |
webhook.* | Nur Webhook | Die Anfrage selbst: welcher Endpunkt, wann sie eintraf und von welcher Adresse. |
state.* | Nach einem set-Knoten | Was ein set-Knoten in diesem Flow geschrieben hat. Die Namen gehören Ihnen, und sie existieren nur unterhalb des Knotens, der sie schreibt. |
state.http.<node>.* | Nach einem http-Knoten | Pro http-Knoten: status, ok, body, json, error und url. Alle sechs existieren immer, auf dem guten Weg wie auf dem schlechten. |
device.* | Noch nirgends | Für Netzwerkgeräte entworfen. Es gibt keinen Anbieter, der sie füllen kann, also kann heute kein Flow sie verwenden. |
Ausdrücke
Ein set-Knoten schreibt in state. Sein Wert ist wörtlicher Text, es sei denn, Sie setzen den Haken für Ausdrücke; dann wird er als Vorlage gelesen, mit den Variablen dieser Ausführung eingesetzt.
- Dieser Haken ist eine bewusste Entscheidung. Ein Wert, der zufällig zwei geschweifte Klammern enthält, ein Stück Ansible oder ein Helm-Fragment, bedeutet weiterhin, was dort stand. Nichts ändert seine Bedeutung durch eine Änderung, um die niemand gebeten hat.
- Die Sprache ist reine Ausgabe. Zwei Klammern und ein Pfad, sonst nichts: kein assign, kein capture, keine Schleife, kein include. Was auf der Fläche steht, ist das, was herauskommt, mit eingesetzten Werten.
- Es gibt 46 Filter: Text, Zahlen, Datumsangaben, die wenigen Listenfilter, die Text ergeben, und die eigenen quote, ini und ipoctet. Die Auswahl im Editor zählt sie auf. Zwei Familien fehlen mit Absicht, jene die würfeln und jene die ein Objekt zurückgeben, wo Sie ein Wort wollten.
- Geheimnisse stehen hier nicht zur Verfügung, Bausteine ebenso wenig. Was ein set-Knoten schreibt, landet im Protokoll der Ausführung, und dort hat ein Geheimnis nichts verloren.
Genehmigungen und Schleifen
Ein Ablauf kann anhalten und auf eine Person warten, und er kann dieselben Knoten mehrfach durchlaufen. Beides ging nicht, solange ein Lauf nicht angehalten und später geweckt werden konnte. Diese Warteschlange gibt es jetzt.
- Ein Genehmigungsknoten hält den Lauf an, schreibt eine Anfrage und meldet sie dem Konto. Das Beantworten erfordert ein eigenes Recht, damit wer den Ablauf geschrieben hat nicht automatisch derjenige ist, der ihn abzeichnet.
- Jede Anfrage trägt eine Frist und das, was ohne Antwort geschieht: als genehmigt fortfahren, als abgelehnt fortfahren oder den Lauf als nicht zutreffend beenden. Eine vierte Wahl gibt es nicht, denn ein Lauf, der ewig wartet, ist ein Lauf, von dem niemand je wieder hört.
- Für jedes durchläuft seinen Schleifenausgang einmal je Element einer Liste. In der Schleife enthält state.loop das aktuelle Element, seine Position und die Gesamtzahl.
- An den Knoten innerhalb einer Schleife darf nichts von außen hängen. Diese Knoten laufen in jeder Runde erneut, und eine Meldung, die an beiden hängt, würde pro Runde eine Nachricht schreiben.
- Ein Genehmigungsschritt kann auch E-Mail senden. Diese geht nur an die Mitglieder, die über Genehmigungen entscheiden dürfen, und nicht an alle, die Flows sehen können; die Panel-Benachrichtigung wird ohnehin geschrieben.
Warten, und Flows, die Flows aufrufen
Ein Lauf, der stillsteht, ist kein fehlgeschlagener Lauf. Drei Dinge können ihn zurückstellen, und alle drei nutzen dieselbe Warteschlange: eine Genehmigung, eine lange Pause und ein Subflow, dessen Kind selbst wartet.
- Eine Pause von einer halben Minute oder weniger wartet einfach innerhalb der Anfrage, die sie gestartet hat, und genau das möchten Sie, wenn Sie einem Agenten kurz Zeit geben. Alles Längere stellt den Lauf zurück, sodass die auslösende Bestellung sofort fertig ist und der Rest des Flows später folgt.
- Ein Subflow führt einen anderen Flow dieses Kontos als einen Schritt aus. Sein Ergebnis bestimmt den Ausgang: Ein Kind, das erfolgreich war oder nichts zu tun fand, geht über OK weiter, ein fehlgeschlagenes über Fehler. Status, Lauf und Flow-Name stehen in state.subflow.
- Ein Flow darf sich nie selbst erreichen, weder direkt noch über einen anderen Flow. Das wird beim Deployen geprüft, und die Meldung nennt die gefundene Kette.
- Flows dürfen sich höchstens drei Ebenen tief aufrufen. Da Flows unabhängig voneinander bearbeitet werden, wird diese Grenze zweimal geprüft: einmal beim Deployen und einmal, während der Lauf tatsächlich läuft.
Webhooks
Ein Webhook-Endpunkt gibt einem System von außen eine eigene URL. Es sendet JSON, der Flow hinter der URL läuft, und die Antwort ist ein nackter Statuscode. Endpunkte stehen unter Skripte auf dem Reiter Webhooks und sind eigene Objekte: derselbe Endpunkt kann auf einen anderen Flow zeigen, ohne dass der Absender etwas merkt.
- Legen Sie den Endpunkt an und geben Sie ihm einen Namen, den Sie später wiedererkennen. Die URL wird für Sie erzeugt und ist nicht wählbar: 32 zufällige Zeichen, also 160 Bit, damit ist Raten keine Strategie.
- Wählen Sie, wie der Absender sich ausweist, und kopieren Sie das Geheimnis. Es wird einmal gezeigt und danach nie wieder; ist es verloren, erzeugen Sie es neu, und dann bekommen Sie auch eine neue URL.
- Richten Sie den Endpunkt auf einen Flow, dessen Auslöser ein Webhook ist. Der Endpunkt darf früher existieren als der Flow, und bis dahin wird eine Anfrage angenommen und mit einer 202 beantwortet, die nichts startet. So bauen Menschen das tatsächlich, deshalb gilt es nicht als Fehler.
| Verfahren | Was es tut |
|---|---|
none | Überhaupt kein Nachweis: wer die URL kennt, kann den Flow starten. Vertretbar mit einer Adressliste daneben und schwer vertretbar ohne. |
hmac_sha256 | Der Absender signiert den rohen Rumpf zusammen mit einem Zeitstempel. Das ist die Wahl: sie bindet die Anfrage an ihren eigenen Rumpf, also lässt sich eine abgefangene Anfrage nicht bearbeiten und weiterschicken. |
bearer | Der Absender setzt das geteilte Token in die Authorization-Kopfzeile. Einfach, und es sagt nichts über den Rumpf aus, der daran hing. |
Die Signatur ist das Wort sha256, ein Gleichheitszeichen und der HMAC-SHA256 über genau die Bytes aus Zeitstempel, Punkt und Rumpf, in kleinen Hexadezimalziffern. Sie gehört in X-Provibr-Signature, und der Zeitstempel selbst gehört in X-Provibr-Timestamp, als ganze Sekunden seit der Epoche.
Eine Anfrage, deren Zeitstempel mehr als 300 Sekunden alt ist oder in der Zukunft liegt, wird mit einer 401 abgelehnt. Dieses Fenster ist eine echte Regel und keine Zierde, denn der Zeitstempel steckt im signierten Material: eine abgefangene Anfrage lässt sich morgen nicht erneut senden, indem man einen frischen Zeitstempel darüberklebt.
Eine Anfrage zu signieren ist eine Zeile openssl. Dieses Beispiel sendet ein kleines Objekt; der Text für die Kommandozeile bleibt absichtlich englisch, damit er dem entspricht, was Ihr Terminal zeigt.
# Sign the raw body together with the timestamp, then post it.
SECRET="$PROVIBR_WEBHOOK_SECRET"
BODY='{"reason":"maintenance","attempt":1}'
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -r | cut -d' ' -f1)
curl -sS -X POST 'https://app.provibr.com/api/hooks/flows/<your-slug>' \
-H 'Content-Type: application/json' \
-H "X-Provibr-Timestamp: $TS" \
-H "X-Provibr-Signature: sha256=$SIG" \
--data "$BODY"| Grenze | Einzelheiten |
|---|---|
body | Standardmäßig 64 KiB, einstellbar zwischen 1 KiB und 256 KiB. Eine größere Anfrage wird abgeschnitten, während sie noch eintrifft, und nicht erst vollständig gelesen und dann abgelehnt. |
rate | Standardmäßig 60 Anfragen pro Minute, einstellbar zwischen 1 und 600. Gezählt wird pro Endpunkt und nicht pro Absender, denn eine echte Quelle hat eine Adresse und ein Angreifer tausend. |
payload | Ein JSON-Objekt einer Ebene. Jeder Schlüssel wird zu input gefolgt von diesem Schlüssel; ein verschachteltes Objekt wird abgelehnt und nicht flachgeklopft. |
allowlist | Höchstens 20 Adressen oder Bereiche, in v4 oder v6. Leer bedeutet überhaupt keine Einschränkung. |
endpoints | Höchstens 50 Endpunkte pro Konto. |
| Code | Bedeutung |
|---|---|
202 | Angenommen. Entweder ist eine Ausführung gestartet, oder es gab nichts zu starten: noch kein Flow verknüpft, der Flow ist abgeschaltet, oder die Ausführung selbst ist umgefallen. In allen vier Fällen hat der Absender nichts falsch gemacht, und ein Beleg sagt, welcher der vier es war. |
401 | Die Signatur oder das Token fehlt oder stimmt nicht, oder die Signatur stimmt und ihr Zeitstempel liegt außerhalb des Fensters. |
403 | Der Endpunkt ist abgeschaltet, oder die Quelladresse steht nicht auf der Adressliste. |
404 | Es gibt keinen Endpunkt mit diesem Kürzel. |
410 | Der Endpunkt wurde zurückgezogen. Das Kürzel bleibt für immer belegt, und diese Antwort sagt einer ehrlichen Quelle, dass sie eine neue URL braucht, was eine 404 nicht täte. |
413 | Der Rumpf ist größer, als dieser Endpunkt annimmt. |
422 | Der Rumpf ist kein JSON-Objekt einer Ebene. |
429 | Über der Durchsatzgrenze dieses Endpunkts. |
Jede Anfrage hinterlässt einen Beleg, angenommen oder nicht: das Ergebnis, den zurückgegebenen Status, die Quelladresse vollständig und wie viele Bytes wirklich gelesen wurden. Der Rumpf wird nie aufbewahrt. Belege verschwinden nach 90 Tagen, früher als die Ausführungen selbst, denn eine Quelladresse ist ein personenbezogenes Datum von jemandem, der nicht unser Kunde ist.
Fassungen und Ausführungen
Zwei Fragen, die einander ähneln, haben hier zwei verschiedene Antworten. Wer wann was geändert hat, ist eine Fassung. Was diese eine Ausführung tatsächlich abgelaufen ist, ist eine Kopie, die an der Ausführung selbst hängt. Eine Momentaufnahme kann die erste Frage nicht beantworten und eine Fassung die zweite nicht, deshalb gibt es beide.
- Jede Veröffentlichung schreibt eine Fassung, auch eine, die nichts geändert hat. Die Nummer zählt pro Flow hoch und wird nie wiederverwendet.
- Der Unterschied zwischen zwei Fassungen ist eine lesbare Liste und kein rohes JSON: ein Knoten hinzugefügt, entfernt oder geändert mit den genannten Feldern, ein Draht hinzugefügt oder entfernt. Wo ein Knoten auf der Fläche liegt, ist keine Änderung.
- Wiederherstellen dreht nichts zurück. Es schreibt die alte Zeichnung als neue Fassung obenauf, mit einer Notiz, woher sie stammt.
- Jede Ausführung bewahrt die Zeichnung, die sie abgelaufen ist. Ein Flow, der sich danach ändert, schreibt nie um, was eine ältere Ausführung getan hat.
- Eine Ausführung enthält eine Zeile pro besuchtem Knoten, mit dem Ergebnis und dem Ausgang, über den sie ihn verließ, und eine Zeile pro nicht besuchtem Knoten mit dem Grund. Nicht besucht ist eine Tatsache, die des Aufschreibens wert ist, und keine Leerstelle.
- Die Ausführungsliste filtert nach Auslöser, Status und Fassung und lässt sich als CSV ausgeben. Die Ausgabe endet bei 5000 Zeilen und sagt das in der Datei, statt still aufzuhören.
Skriptvorlagen führen daneben eine eigene Geschichte: jede gespeicherte Fassung des Inhalts und einen zeilenweisen Unterschied zwischen zweien davon.