DATAZONE Connect
DATAZONE Connect is a generic script runner for third-party system integrations. It runs as a separate Docker container and provides a REST API through which scripts can be executed with variables.
Concept
Connect follows a scripts-first approach: Every integration (Nuclos, Teams, Slack, Zammad, etc.) is a simple shell script with standardized metadata. This means maximum flexibility with minimum effort.
Architecture
DATAZONE Control DATAZONE Connect
+------------------+ +------------------+
| Playbook | Webhook Step | Flask API (5002) |
| Step 1: Script | ----------> | /api/scripts/run |
| Step 2: Task | | |
| Step 3: Webhook| ------------> | /scripts/ |
+------------------+ | nuclos.sh |
| teams.sh |
| slack.sh |
+------------------+How It Works
- Scripts are placed in the
connect/scripts/directory - Connect automatically reads metadata from script headers (
@name,@description,@var) - Variables are passed to scripts as environment variables
- Credentials (passwords, API keys) come from container environment variables, not from scripts
- Scripts return structured results via the
#RESULT:{json}convention
REST API
Health Check
GET /api/healthReturns the container status and the number of available scripts.
List Scripts
GET /api/scriptsReturns a list of all available scripts with metadata:
[
{
"name": "Nuclos Billing",
"filename": "nuclos-billing.sh",
"description": "Creates activity report with position in Nuclos.",
"vars": [
{"name": "CUSTOMER_NUMBER", "required": true, "description": "Customer number (e.g., K-10001)"},
{"name": "CUSTOMER_NAME", "required": true, "description": "Customer name"},
{"name": "TASK", "required": true, "description": "Task description"}
]
}
]Execute Script
POST /api/scripts/run
Content-Type: application/json
{
"script": "nuclos-billing.sh",
"vars": {
"CUSTOMER_NUMBER": "K-10001",
"CUSTOMER_NAME": "Bell & Schmidt",
"TASK": "OPNsense Firmware Update"
}
}Synchronous execution (default): Waits for the result and returns it directly.
Asynchronous execution: With ?async=true, a job is created whose status can be queried:
POST /api/scripts/run?async=true
-> {"job_id": "abc123", "status": "running"}
GET /api/jobs/abc123
-> {"status": "completed", "exit_code": 0, "result": {...}}Incoming Webhooks
POST /api/webhooks/incoming/{name}Receives external webhook calls (e.g., from Zammad, GitLab, etc.) and executes the associated script. The webhook body is passed as a WEBHOOK_BODY environment variable.
Execution Log
GET /api/logs
GET /api/logs?limit=10Returns recent script executions with status and results.
Creating Scripts
Metadata Format
Each script begins with a standardized header:
#!/bin/bash
###############################################################################
# @name My Script
# @description Brief description of what the script does.
#
# @var REQUIRED_VAR required Description of the required variable
# @var OPTIONAL_VAR optional Description of the optional variable
###############################################################################| Field | Required | Description |
|---|---|---|
@name | Yes | Display name of the script |
@description | Yes | Brief description |
@var | No | Variable with name, required/optional, and description |
Structured Return Values
Scripts can return a JSON result via the #RESULT:{json} convention:
echo "#RESULT:{\"success\":true,\"id\":42,\"message\":\"Created\"}"Connect parses the last line starting with #RESULT: and returns the JSON as the result field in the API response.
Credentials
Credentials are never stored directly in scripts. Instead, they are configured as container environment variables:
# In script: use environment variable
NUCLOS_PASS="${NUCLOS_PASS:?NUCLOS_PASS not set}"
# In docker-compose.yml: define variable
# environment:
# - NUCLOS_PASS=${NUCLOS_PASS:-}
# In .env: set value
# NUCLOS_PASS=secret123Included Scripts
Nuclos Billing
File: nuclos-billing.sh
Automatically creates an activity report with position in Nuclos ERP:
| Variable | Required | Description |
|---|---|---|
CUSTOMER_NUMBER | Yes | Customer number (e.g., K-10001) |
CUSTOMER_NAME | Yes | Customer name |
TASK | Yes | Task description |
DURATION_HOURS | No | Duration in hours (default: 0.5) |
HOSTNAME | No | Hostname of the affected system |
MODULE | No | Module type (opnsense, linux, etc.) |
Dynamic project lookup: The script automatically searches for the matching Nuclos project based on the customer number. If no project is found, it falls back to the default project (DATAZONE) and prepends the customer name in the billing text.
Environment variables (set in .env):
| Variable | Description |
|---|---|
NUCLOS_URL | Nuclos server URL (e.g., https://nuclos.example.de) |
NUCLOS_USER | Nuclos username |
NUCLOS_PASS | Nuclos password |
NUCLOS_ORGANISATION | Nuclos organization |
NUCLOS_MITARBEITER | Employee ID for time tracking |
NUCLOS_DEFAULT_PROJEKT | Fallback project name (default: DATAZONE) |
Teams Notification
File: teams-notify.sh
Sends a message to a Microsoft Teams webhook:
| Variable | Required | Description |
|---|---|---|
MESSAGE | Yes | Message text |
TITLE | No | Message title (default: DATAZONE Connect) |
COLOR | No | Color as hex value (default: 0076D7) |
Environment variable: TEAMS_WEBHOOK_URL must be set in .env.
Playbook Integration
Connect is integrated via the Webhook step type in playbooks. This allows integrations to be embedded directly in maintenance workflows.
Example: Maintenance with Nuclos Billing
| Step | Type | Action | On Error |
|---|---|---|---|
| 1 | VM Snapshot | Create snapshot | stop |
| 2 | Task | PVE_UPDATE | continue |
| 3 | Check Online | Wait until online | stop |
| 4 | Webhook | Nuclos Billing (book 30 min) | continue |
| 5 | Webhook | Teams notification | continue |
Example: Webhook Step Configuration
For the webhook step in the playbook:
| Field | Value |
|---|---|
| URL | http://datazone-connect:5002/api/scripts/run |
| Method | POST |
| Body | {"script":"nuclos-billing.sh","vars":{"CUSTOMER_NUMBER":"{customer_number}","CUSTOMER_NAME":"{customer_name}","TASK":"Maintenance {hostname}","MODULE":"{module}"}} |
| Headers | Content-Type: application/json |
The placeholders {customer_number}, {customer_name}, {hostname}, and {module} are automatically replaced with data from the current host.
Docker Configuration
Connect runs as a separate container in the Docker network:
connect:
build: ./connect
container_name: datazone-connect
environment:
- CONNECT_TOKEN=${CONNECT_TOKEN:-}
- NUCLOS_URL=${NUCLOS_URL:-}
- NUCLOS_USER=${NUCLOS_USER:-}
- NUCLOS_PASS=${NUCLOS_PASS:-}
- NUCLOS_ORGANISATION=${NUCLOS_ORGANISATION:-}
- NUCLOS_MITARBEITER=${NUCLOS_MITARBEITER:-}
- NUCLOS_DEFAULT_PROJEKT=${NUCLOS_DEFAULT_PROJEKT:-DATAZONE}
- TEAMS_WEBHOOK_URL=${TEAMS_WEBHOOK_URL:-}
volumes:
- ./connect/scripts:/scripts:ro
networks:
- datazone-net
restart: unless-stoppedCustom Scripts
Simply place custom scripts in the connect/scripts/ directory. The container mounts this directory as a read-only volume. After adding new scripts, no restart is needed — they are automatically detected on the next API call.
Security
Connect is only accessible within the Docker network and not reachable from outside. For additional security, a CONNECT_TOKEN can be configured.