Skip to content

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

  1. Scripts werden im Ordner connect/scripts/ abgelegt
  2. Connect liest automatisch die Metadaten aus den Script-Headern (@name, @description, @var)
  3. Variablen werden als Umgebungsvariablen an die Scripts uebergeben
  4. Zugangsdaten (Passwoerter, API-Keys) kommen aus den Container-Umgebungsvariablen, nicht aus den Scripts
  5. Scripts geben strukturierte Ergebnisse ueber die Konvention #RESULT:{json} zurueck

REST-API

Health-Check

GET /api/health

Gibt den Status des Containers und die Anzahl verfuegbarer Scripts zurueck.

Scripts auflisten

GET /api/scripts

Gibt eine Liste aller verfuegbaren Scripts mit Metadaten zurueck:

json
[
  {
    "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=10

Gibt die letzten Script-Ausfuehrungen mit Status und Ergebnis zurueck.

Scripts erstellen

Metadaten-Format

Jedes Script beginnt mit einem standardisierten Header:

bash
#!/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
###############################################################################
FeldPflichtBeschreibung
@nameJaAnzeigename des Scripts
@descriptionJaKurzbeschreibung
@varNeinVariable mit Name, required/optional und Beschreibung

Strukturierte Rueckgabe

Scripts koennen ein JSON-Ergebnis ueber die Konvention #RESULT:{json} zurueckgeben:

bash
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:

bash
# 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=geheim123

Mitgelieferte Scripts

ERP Billing

Datei: erp-billing.sh

Erstellt automatisch einen Taetigkeitsnachweis (TimeEntry) im DATAZONE ERP. Loest die alte Nuclos/Sema-Anbindung ab.

VariablePflichtBeschreibung
CUSTOMER_NUMBERJaKundennummer (z.B. 10001)
CUSTOMER_NAMEJaKundenname
TASKJaBeschreibung der Taetigkeit
DURATION_HOURSNeinDauer in Stunden (Standard: 0.5)
HOSTNAMENeinHostname des betroffenen Systems
MODULENeinModultyp (opnsense, linux, etc.)
BILLABLENein"true" oder "false" (Standard: true)

Workflow:

  1. Login per JWT an ${ERP_URL}/api/v1/auth/login mit Service-User
  2. Customer per Kundennummer aufloesen: GET /api/v1/customers/resolve/{CUSTOMER_NUMBER}customer_id (UUID)
  3. 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):

VariableBeschreibung
ERP_URLERP Server URL (z.B. https://erp.datazone.de)
ERP_USERE-Mail des Service-Users
ERP_PASSWORDPasswort des Service-Users
ERP_TENANT_SLUGMandanten-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:

VariablePflichtBeschreibung
MESSAGEJaNachricht (Text)
TITLENeinTitel der Nachricht (Standard: DATAZONE Connect)
COLORNeinFarbe 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

StepTypAktionBei Fehler
1VM SnapshotSnapshot erstellenstop
2TaskPVE_UPDATEcontinue
3Online pruefenWarten bis onlinestop
4WebhookERP Billing (30 Min buchen)continue
5WebhookTeams Benachrichtigungcontinue

Beispiel: Webhook-Step Konfiguration

Fuer den Webhook-Step im Playbook:

FeldWert
URLhttp://datazone-connect:5002/api/scripts/run
MethodePOST
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}"}}
HeadersContent-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:

yaml
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-stopped

Eigene 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.

DATAZONE Control Documentation