Skip to content

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

  1. Scripts are placed in the connect/scripts/ directory
  2. Connect automatically reads metadata from script headers (@name, @description, @var)
  3. Variables are passed to scripts as environment variables
  4. Credentials (passwords, API keys) come from container environment variables, not from scripts
  5. Scripts return structured results via the #RESULT:{json} convention

REST API

Health Check

GET /api/health

Returns the container status and the number of available scripts.

List Scripts

GET /api/scripts

Returns a list of all available scripts with metadata:

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

Returns recent script executions with status and results.

Creating Scripts

Metadata Format

Each script begins with a standardized header:

bash
#!/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
###############################################################################
FieldRequiredDescription
@nameYesDisplay name of the script
@descriptionYesBrief description
@varNoVariable with name, required/optional, and description

Structured Return Values

Scripts can return a JSON result via the #RESULT:{json} convention:

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

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

Included Scripts

Nuclos Billing

File: nuclos-billing.sh

Automatically creates an activity report with position in Nuclos ERP:

VariableRequiredDescription
CUSTOMER_NUMBERYesCustomer number (e.g., K-10001)
CUSTOMER_NAMEYesCustomer name
TASKYesTask description
DURATION_HOURSNoDuration in hours (default: 0.5)
HOSTNAMENoHostname of the affected system
MODULENoModule 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):

VariableDescription
NUCLOS_URLNuclos server URL (e.g., https://nuclos.example.de)
NUCLOS_USERNuclos username
NUCLOS_PASSNuclos password
NUCLOS_ORGANISATIONNuclos organization
NUCLOS_MITARBEITEREmployee ID for time tracking
NUCLOS_DEFAULT_PROJEKTFallback project name (default: DATAZONE)

Teams Notification

File: teams-notify.sh

Sends a message to a Microsoft Teams webhook:

VariableRequiredDescription
MESSAGEYesMessage text
TITLENoMessage title (default: DATAZONE Connect)
COLORNoColor 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

StepTypeActionOn Error
1VM SnapshotCreate snapshotstop
2TaskPVE_UPDATEcontinue
3Check OnlineWait until onlinestop
4WebhookNuclos Billing (book 30 min)continue
5WebhookTeams notificationcontinue

Example: Webhook Step Configuration

For the webhook step in the playbook:

FieldValue
URLhttp://datazone-connect:5002/api/scripts/run
MethodPOST
Body{"script":"nuclos-billing.sh","vars":{"CUSTOMER_NUMBER":"{customer_number}","CUSTOMER_NAME":"{customer_name}","TASK":"Maintenance {hostname}","MODULE":"{module}"}}
HeadersContent-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:

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

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

DATAZONE Control Documentation