DATAZONE Connect
DATAZONE Connect ist ein generischer Script-Runner fuer Integrationen mit Drittsystemen. Er laeuft als eigener Docker-Container und stellt eine REST-API bereit, ueber die Scripts mit Variablen ausgefuehrt werden koennen.
Konzept
Connect verfolgt einen Scripts-first-Ansatz: Jede Integration (DATAZONE ERP, Teams, Slack, Zammad, etc.) ist ein einfaches Shell-Script mit standardisierten Metadaten. Das bedeutet maximale Flexibilitaet bei minimalem Aufwand.
Architektur
DATAZONE Control DATAZONE Connect
+------------------+ +------------------+
| Playbook | Webhook-Step | Flask API (5002) |
| Step 1: Script | ----------> | /api/scripts/run |
| Step 2: Task | | |
| Step 3: Webhook| ------------> | /scripts/ |
+------------------+ | erp-billing.sh |
| teams-notify.sh|
+------------------+Wie es funktioniert
- Scripts werden im Ordner
connect/scripts/abgelegt - Connect liest automatisch die Metadaten aus den Script-Headern (
@name,@description,@var) - Variablen werden als Umgebungsvariablen an die Scripts uebergeben
- Zugangsdaten (Passwoerter, API-Keys) kommen aus den Container-Umgebungsvariablen, nicht aus den Scripts
- Scripts geben strukturierte Ergebnisse ueber die Konvention
#RESULT:{json}zurueck
REST-API
Health-Check
GET /api/healthGibt den Status des Containers und die Anzahl verfuegbarer Scripts zurueck.
Scripts auflisten
GET /api/scriptsGibt eine Liste aller verfuegbaren Scripts mit Metadaten zurueck:
[
{
"name": "ERP Billing",
"filename": "erp-billing.sh",
"description": "Erstellt einen Taetigkeitsnachweis (TimeEntry) im DATAZONE ERP.",
"vars": [
{"name": "CUSTOMER_NUMBER", "required": true, "description": "Kundennummer (z.B. 10001)"},
{"name": "CUSTOMER_NAME", "required": true, "description": "Kundenname"},
{"name": "TASK", "required": true, "description": "Beschreibung der Taetigkeit"}
]
}
]Script ausfuehren
POST /api/scripts/run
Content-Type: application/json
{
"script": "erp-billing.sh",
"vars": {
"CUSTOMER_NUMBER": "10001",
"CUSTOMER_NAME": "Beispiel GmbH",
"TASK": "OPNsense Firmware Update"
}
}Synchrone Ausfuehrung (Standard): Wartet auf das Ergebnis und gibt es direkt zurueck.
Asynchrone Ausfuehrung: Mit ?async=true wird ein Job erstellt, dessen Status abgefragt werden kann:
POST /api/scripts/run?async=true
→ {"job_id": "abc123", "status": "running"}
GET /api/jobs/abc123
→ {"status": "completed", "exit_code": 0, "result": {...}}Eingehende Webhooks
POST /api/webhooks/incoming/{name}Empfaengt externe Webhook-Aufrufe (z.B. von Zammad, GitLab, etc.) und fuehrt das zugehoerige Script aus. Der Webhook-Body wird als WEBHOOK_BODY-Umgebungsvariable uebergeben.
Ausfuehrungslog
GET /api/logs
GET /api/logs?limit=10Gibt die letzten Script-Ausfuehrungen mit Status und Ergebnis zurueck.
Scripts erstellen
Metadaten-Format
Jedes Script beginnt mit einem standardisierten Header:
#!/bin/bash
###############################################################################
# @name Mein Script
# @description Kurze Beschreibung was das Script macht.
#
# @var PFLICHT_VAR required Beschreibung der Pflicht-Variable
# @var OPTIONAL_VAR optional Beschreibung der optionalen Variable
###############################################################################| Feld | Pflicht | Beschreibung |
|---|---|---|
@name | Ja | Anzeigename des Scripts |
@description | Ja | Kurzbeschreibung |
@var | Nein | Variable mit Name, required/optional und Beschreibung |
Strukturierte Rueckgabe
Scripts koennen ein JSON-Ergebnis ueber die Konvention #RESULT:{json} zurueckgeben:
echo "#RESULT:{\"success\":true,\"id\":42,\"message\":\"Erstellt\"}"Connect parst die letzte Zeile die mit #RESULT: beginnt und gibt das JSON als result-Feld in der API-Antwort zurueck.
Zugangsdaten
Zugangsdaten werden niemals direkt in Scripts gespeichert. Stattdessen werden sie als Container-Umgebungsvariablen konfiguriert:
# Im Script: Umgebungsvariable nutzen
ERP_PASSWORD="${ERP_PASSWORD:?ERP_PASSWORD nicht gesetzt}"
# In docker-compose.yml: Variable definieren
# environment:
# - ERP_PASSWORD=${ERP_PASSWORD:-}
# In .env: Wert setzen
# ERP_PASSWORD=geheim123Mitgelieferte Scripts
ERP Billing
Datei: erp-billing.sh
Erstellt automatisch einen Taetigkeitsnachweis (TimeEntry) im DATAZONE ERP. Loest die alte Nuclos/Sema-Anbindung ab.
| Variable | Pflicht | Beschreibung |
|---|---|---|
CUSTOMER_NUMBER | Ja | Kundennummer (z.B. 10001) |
CUSTOMER_NAME | Ja | Kundenname |
TASK | Ja | Beschreibung der Taetigkeit |
DURATION_HOURS | Nein | Dauer in Stunden (Standard: 0.5) |
HOSTNAME | Nein | Hostname des betroffenen Systems |
MODULE | Nein | Modultyp (opnsense, linux, etc.) |
BILLABLE | Nein | "true" oder "false" (Standard: true) |
Workflow:
- Login per JWT an
${ERP_URL}/api/v1/auth/loginmit Service-User - Customer per Kundennummer aufloesen:
GET /api/v1/customers/resolve/{CUSTOMER_NUMBER}→customer_id(UUID) - TimeEntry erstellen:
POST /api/v1/tickets/time-entries/mit customer_id, Beschreibung, Dauer
Wird der Kunde nicht im ERP gefunden, schlaegt das Script mit HTTP 404 fehl - keine Fallback-Buchung wie bei Nuclos.
Service-User im ERP
Im ERP muss ein dedizierter Service-User existieren (ohne MFA!) mit folgenden Permissions:
customers:read(Kunden aufloesen)timeentries:create(TimeEntry anlegen)timeentries:read(optional, fuer Sync)
Umgebungsvariablen (in .env setzen):
| Variable | Beschreibung |
|---|---|
ERP_URL | ERP Server URL (z.B. https://erp.datazone.de) |
ERP_USER | E-Mail des Service-Users |
ERP_PASSWORD | Passwort des Service-Users |
ERP_TENANT_SLUG | Mandanten-Slug (Standard: default) |
Nuclos Billing (Legacy)
Datei: nuclos-billing.sh
Alte Nuclos/Sema-Anbindung. Bleibt fuer Rollback-Zwecke vorhanden, wird aber nicht mehr aktiv genutzt. Neue Playbooks bitte mit erp-billing.sh konfigurieren.
Teams Notification
Datei: teams-notify.sh
Sendet eine Nachricht an einen Microsoft Teams Webhook:
| Variable | Pflicht | Beschreibung |
|---|---|---|
MESSAGE | Ja | Nachricht (Text) |
TITLE | Nein | Titel der Nachricht (Standard: DATAZONE Connect) |
COLOR | Nein | Farbe als Hex-Wert (Standard: 0076D7) |
Umgebungsvariable: TEAMS_WEBHOOK_URL muss in .env gesetzt sein.
Integration mit Playbooks
Connect wird ueber den Webhook-Step-Typ in Playbooks angebunden. Damit koennen Integrationen direkt in Wartungs-Workflows eingebunden werden.
Beispiel: Wartung mit ERP-Buchung
| Step | Typ | Aktion | Bei Fehler |
|---|---|---|---|
| 1 | VM Snapshot | Snapshot erstellen | stop |
| 2 | Task | PVE_UPDATE | continue |
| 3 | Online pruefen | Warten bis online | stop |
| 4 | Webhook | ERP Billing (30 Min buchen) | continue |
| 5 | Webhook | Teams Benachrichtigung | continue |
Beispiel: Webhook-Step Konfiguration
Fuer den Webhook-Step im Playbook:
| Feld | Wert |
|---|---|
| URL | http://datazone-connect:5002/api/scripts/run |
| Methode | POST |
| Body | {"script":"erp-billing.sh","vars":{"CUSTOMER_NUMBER":"{customer_number}","CUSTOMER_NAME":"{customer_name}","TASK":"Wartung {hostname}","DURATION_HOURS":"0.5","HOSTNAME":"{hostname}","MODULE":"{module}"}} |
| Headers | Content-Type: application/json |
Die Platzhalter {customer_number}, {customer_name}, {hostname} und {module} werden automatisch mit den Daten des aktuellen Hosts ersetzt.
Docker-Konfiguration
Connect laeuft als eigener Container im Docker-Netzwerk:
connect:
build: ./connect
container_name: datazone-connect
environment:
- CONNECT_TOKEN=${CONNECT_TOKEN:-}
# DATAZONE ERP Integration
- ERP_URL=${ERP_URL:-}
- ERP_USER=${ERP_USER:-}
- ERP_PASSWORD=${ERP_PASSWORD:-}
- ERP_TENANT_SLUG=${ERP_TENANT_SLUG:-default}
# Webhook URLs
- TEAMS_WEBHOOK_URL=${TEAMS_WEBHOOK_URL:-}
volumes:
- ./connect/scripts:/scripts:ro
networks:
- datazone-net
restart: unless-stoppedEigene Scripts
Eigene Scripts einfach in den Ordner connect/scripts/ legen. Der Container bindet diesen Ordner als Read-Only-Volume ein. Nach dem Hinzufuegen neuer Scripts ist kein Neustart noetig — sie werden beim naechsten API-Aufruf automatisch erkannt.
Sicherheit
Connect ist nur im Docker-Netzwerk erreichbar und von aussen nicht zugaenglich. Fuer zusaetzliche Absicherung kann ein CONNECT_TOKEN konfiguriert werden.