Skip to main content

zabbix-argus-glue

PyPI version Supported Python versions Tests License: Apache-2.0

A glue service that synchronizes Zabbix 7.2+ problems with Argus incidents. It translates Zabbix problem events into Argus incident state changes, keeping both systems in sync.

Status: Early development. The reconciliation poller and webhook receiver are functional; ack sync is planned but not yet implemented.

Architecture

Hybrid push + poll design:

┌─────────────┐   webhook POST    ┌──────────────────────┐   REST API   ┌───────────┐
│   Zabbix    │ ───────────────>  │  zabbix-argus-glue   │ ───────────> │   Argus   │
│   Server    │ <───────────────  │                      │ <─────────── │   Server  │
│             │   API polling     │  - HTTP receiver     │              │           │
└─────────────┘                   │  - Reconciliation    │              └───────────┘
                                  │  - Ack sync       *  │
                                  └──────────────────────┘
                                           * planned
  1. Webhook receiver — receives Zabbix webhook POSTs, creates/closes Argus incidents in near-real-time. (implemented)
  2. Reconciliation poller — periodically fetches open problems from Zabbix, compares against Argus state, fixes drift. Full sync on startup. (implemented)
  3. Ack sync — detect acknowledgements and closures made in Argus, write them back to Zabbix. (planned)

Installation

uv tool install zabbix-argus-glue

Or install the latest unreleased version directly from the repository:

uv tool install git+https://github.com/Uninett/zabbix-argus-glue.git

Configuration

Copy the example configuration and edit it:

cp zabbixargus.example.toml zabbixargus.toml

See zabbixargus.example.toml for all available options with comments.

The program searches for zabbixargus.toml in the following locations (first match wins):

  1. Current working directory
  2. $XDG_CONFIG_HOME/zabbixargus/ (typically ~/.config/zabbixargus/)
  3. System config directory (typically /etc/xdg/zabbixargus/)

You can override this with --config PATH.

API tokens can also be provided via the ARGUS_TOKEN and ZABBIX_TOKEN environment variables instead of storing them in the config file. The webhook shared secret can likewise be set via WEBHOOK_SECRET instead of [webhook] secret, so it can be sourced from a Kubernetes Secret or vault rather than a plaintext config file.

Incident detail links point back to the Zabbix problem page using relative URLs (e.g. tr_events.php?triggerid=...&eventid=...). The Argus source system's base_url must include the full path prefix to the Zabbix frontend — for Apache-based installs this is typically https://zabbix.example.com/zabbix/, while Nginx-based installs usually use https://zabbix.example.com/.

Usage

# Run the service (config auto-discovered)
zabbix-argus-glue

# Verify API connectivity before running
zabbix-argus-glue --verify

# Use an explicit config file
zabbix-argus-glue --config /etc/zabbixargus/zabbixargus.toml

# Enable debug logging
zabbix-argus-glue -v

Webhook setup

The webhook receiver listens for HTTP POSTs from Zabbix. To use it, you need to configure a webhook media type and a trigger action in Zabbix.

By default the receiver binds 0.0.0.0:8080; change the bind address and port with [webhook] listen and port, or turn the receiver off entirely with [webhook] enabled = false.

Requires Zabbix 7.2 or later (the setup uses the {EVENT.TIMESTAMP} macro, introduced after the 7.0 LTS).

1. Create a webhook media type

In Zabbix, go to Alerts → Media types → Create media type and configure:

  • Name: Argus

  • Type: Webhook

  • Parameters:

    Name Value
    glue_url http://glue-host:8080/webhook
    secret (same value as [webhook] secret in your config)
    eventid {EVENT.ID}
    value {EVENT.VALUE}
    severity {EVENT.NSEVERITY}
    hostname {HOST.NAME}
    name {EVENT.NAME}
    timestamp {EVENT.TIMESTAMP}
    triggerid {TRIGGER.ID}
    tags {EVENT.TAGSJSON}
    update_status {EVENT.UPDATE.STATUS}
    update_action {EVENT.UPDATE.ACTIONJSON}
    update_user {USER.FULLNAME}
  • Script:

    var params = JSON.parse(value),
        req = new HttpRequest(),
        payload = {};
    
    req.addHeader('Content-Type: application/json');
    req.addHeader('X-Webhook-Secret: ' + params.secret);
    
    payload.eventid = params.eventid;
    payload.value = params.value;
    payload.severity = params.severity;
    payload.hostname = params.hostname;
    payload.name = params.name;
    payload.timestamp = params.timestamp;
    payload.triggerid = params.triggerid;
    payload.tags = params.tags;
    payload.update_status = params.update_status;
    payload.update_action = params.update_action;
    payload.update_user = params.update_user;
    
    var resp = req.post(params.glue_url, JSON.stringify(payload));
    
    if (req.getStatus() < 200 || req.getStatus() >= 300) {
        throw 'Request failed with status ' + req.getStatus()
            + ': ' + resp;
    }
    
    return 'OK';
    

2. Assign the media type to a user

Zabbix sends alerts through users. Create a dedicated service account or use an existing user.

Go to Users → Users and create or edit a user:

  • Username: e.g. argus-glue
  • Role: a User-type role (with the problem-update actions enabled) is enough — the account only fires webhooks and, once acknowledgement sync lands, acts on problems. Avoid Super admin: a credential-bearing service account should not hold full configuration rights.
  • Groups: a user group with read access to the hosts you want to sync. (Acknowledgement sync back to Zabbix additionally needs read-write access to those host groups.)
  • Media tab → Add:
    • Type: Argus
    • Send to: argus (required by Zabbix but ignored by webhooks)
    • Enabled: checked

Resolving "Inaccessible user" in update notifications

Update notifications carry {USER.FULLNAME} — the person who acknowledged or commented on a problem. Zabbix only reveals a user's name to accounts that share at least one user group with them; otherwise the macro resolves to the literal string Inaccessible user (a privacy safeguard introduced by ZBX-12441). To make names resolve without widening the service account's access, create a user group with no permissions (e.g. argus-visibility) and add both the argus-glue account and every operator who acknowledges problems to it. Membership alone establishes visibility; the empty permission set keeps it least-privilege. Granting Super admin also works but over-privileges the account — don't.

3. Create a trigger action

Go to Alerts → Actions → Trigger actions → Create action:

  • Name: Send to Argus
  • Conditions: (adjust to match the problems you want to sync)
  • Operations → Add:
    • Send to users: select the user from step 2
    • Send only to: Argus
    • Check Custom message and set any non-empty subject and body (e.g. {EVENT.NAME} / {EVENT.ID}). Zabbix requires a message to be defined even though webhooks ignore it.
  • Recovery operations → Add:
    • Same settings as above, including a custom message
  • Update operations → Add:
    • Same settings as above (forwards acks, comments, and severity changes)

4. Test with curl

curl -X POST http://localhost:8080/webhook \
  -H 'Content-Type: application/json' \
  -H 'X-Webhook-Secret: your-secret' \
  -d '{
    "eventid": "12345",
    "value": "1",
    "severity": "4",
    "hostname": "web01.example.com",
    "name": "High CPU usage on web01",
    "timestamp": "1745326800",
    "triggerid": "678",
    "tags": "[{\"tag\": \"application\", \"value\": \"nginx\"}]"
  }'

Development

Requires Python 3.11+.

# Clone and install in editable mode
git clone https://github.com/Uninett/zabbix-argus-glue.git
cd zabbix-argus-glue
uv venv --python 3.13
uv sync --all-groups

# Set up pre-commit hooks
pre-commit install

# Run tests
pytest

# Lint and format
ruff check --fix src/
ruff format src/

Changelog

See CHANGELOG.md. We use towncrier to manage changelog fragments. Add a fragment to changelog.d/ with each PR.

License

Apache-2.0. See LICENSE.

Metadata

Release files for zabbix-argus-glue 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zabbix-argus-glue 0.1.0
File Size Uploaded
zabbix_argus_glue-0.1.0.tar.gz 145.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zabbix-argus-glue 0.1.0
File Interpreter ABI Platform
zabbix_argus_glue-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 171.6 kB

Release files / zabbix_argus_glue-0.1.0.tar.gz

Download URL zabbix_argus_glue-0.1.0.tar.gz
Size 145.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6d4bc1a8fa6b744b1a9cd41da18b6faa3a724cdb966100dcce721bdcc0ea834a
BLAKE2b-256 checksum
How to use checksums
0feee4b8ba0104273c152b5d19322735fd08a663ba9d5d30312ea7bfdcaec085
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / zabbix_argus_glue-0.1.0-py3-none-any.whl

Download URL zabbix_argus_glue-0.1.0-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c57f889241ae8cd67da77a036db627119e3f4390c7efe3ecd8430f188fee909
BLAKE2b-256 checksum
How to use checksums
b7406d413eaf116c6070f51bdd6b6d77db66638dfc1b4d54559e7a149e45c00b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page