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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zabbix_argus_glue-0.1.0.tar.gz (145.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zabbix_argus_glue-0.1.0-py3-none-any.whl (26.2 kB view details)

Uploaded Python 3

File details

Details for the file zabbix_argus_glue-0.1.0.tar.gz.

File metadata

  • Download URL: zabbix_argus_glue-0.1.0.tar.gz
  • Upload date:
  • Size: 145.3 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for zabbix_argus_glue-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6d4bc1a8fa6b744b1a9cd41da18b6faa3a724cdb966100dcce721bdcc0ea834a
MD5 e5ad94feed12f1ef44c586272378031b
BLAKE2b-256 0feee4b8ba0104273c152b5d19322735fd08a663ba9d5d30312ea7bfdcaec085

See more details on using hashes here.

File details

Details for the file zabbix_argus_glue-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: zabbix_argus_glue-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.2 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for zabbix_argus_glue-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0c57f889241ae8cd67da77a036db627119e3f4390c7efe3ecd8430f188fee909
MD5 34b86c3bbe43c0bce507249099226e62
BLAKE2b-256 b7406d413eaf116c6070f51bdd6b6d77db66638dfc1b4d54559e7a149e45c00b

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page