Netdata.cloud bot for Zulip
Python 82.3%
Shell 14.7%
Dockerfile 2.6%
Other 0.4%
1 1 0

Clone this repository

https://tangled.org/anil.recoil.org/zulip-netdata-bot
git@git.recoil.org:anil.recoil.org/zulip-netdata-bot

For self-hosted knots, clone URLs may differ based on your setup.

README.md

Netdata Zulip Bot#

100% vibe coded, use at your peril

A webhook service that receives notifications from Netdata Cloud and forwards them to Zulip channels. Features HTTPS with Let's Encrypt certificates and mutual TLS authentication for secure communication with Netdata Cloud.

Features#

  • 🔐 HTTPS with Let's Encrypt: Automatic SSL certificate management
  • 🤝 Mutual TLS: Secure authentication with Netdata Cloud
  • 📊 Rich Formatting: Beautiful Zulip messages with emojis and markdown
  • 🏷️ Topic Organization: Automatic topic routing by severity level
  • 📝 Structured Logging: JSON-structured logs for monitoring
  • High Performance: FastAPI-based webhook endpoint

Quick Start#

1. Install Dependencies#

# Using uv (recommended)
uv sync

# Or using pip
pip install -e .

2. Create Configuration#

# Generate sample configuration files
netdata-zulip-bot --create-config

# Copy and customize
cp .zuliprc.sample ~/.zuliprc

3. Configure Zulip Settings#

Edit ~/.zuliprc:

[api]
site=https://yourorg.zulipchat.com
email=netdata-bot@yourorg.zulipchat.com  
key=your-zulip-api-key
stream=netdata-alerts

4. Set Server Environment Variables#

export SERVER_DOMAIN=your-webhook-domain.com
export SERVER_PORT=8443
export SERVER_ENABLE_MTLS=true

5. Setup SSL Certificate#

# Install certbot and obtain certificate
sudo certbot certonly --standalone -d your-webhook-domain.com

# Ensure certificate files are accessible
sudo chown -R $USER:$USER /etc/letsencrypt/live/your-webhook-domain.com/

6. Run the Service#

netdata-zulip-bot

Configuration#

Zulip Configuration#

The bot supports two configuration methods:

Create ~/.zuliprc:

[api]
site=https://yourorg.zulipchat.com
email=netdata-bot@yourorg.zulipchat.com
key=your-zulip-api-key
stream=netdata-alerts

Method 2: Environment Variables#

export ZULIP_SITE=https://yourorg.zulipchat.com
export ZULIP_EMAIL=netdata-bot@yourorg.zulipchat.com
export ZULIP_API_KEY=your-api-key
export ZULIP_STREAM=netdata-alerts

Use --env-config flag to use environment variables instead of zuliprc.

Server Configuration#

Set these environment variables:

  • SERVER_DOMAIN: Your public domain (required for Let's Encrypt)
  • SERVER_HOST: Bind address (default: 0.0.0.0)
  • SERVER_PORT: HTTPS port (default: 8443)
  • SERVER_CERT_PATH: Certificate path (default: /etc/letsencrypt/live)
  • SERVER_ENABLE_MTLS: Enable mutual TLS (default: true)
  • SERVER_CLIENT_CA_PATH: Client CA certificate for mTLS validation

Message Format#

Alert Notifications#

Messages are posted to topics based on severity level:

  • Topic: critical, warning, or clear
  • Format: Rich markdown with alert details, timestamps, and links

Example:

🔴 **High CPU Usage**

**Space:** production
**Chart:** system.cpu
**Context:** cpu utilization
**Severity:** Critical
**Time:** 2024-01-15 14:30:00 UTC

**Details:** CPU usage has exceeded 90% for 5 minutes
**Summary:** Critical alert: High CPU usage detected

[View Alert](https://app.netdata.cloud/spaces/...)

Reachability Notifications#

Messages are posted to the reachability topic:

❌ **Host Unreachable**

**Host:** web-server-01
**Status:** ❌ Unreachable  
**Severity:** Critical

**Summary:** Host web-server-01 is no longer reachable

[View Host](https://app.netdata.cloud/...)

Deployment#

Systemd Service#

Create /etc/systemd/system/netdata-zulip-bot.service:

[Unit]
Description=Netdata Zulip Bot
After=network.target

[Service]
Type=simple
User=netdata-bot
WorkingDirectory=/opt/netdata-zulip-bot
Environment=SERVER_DOMAIN=your-domain.com
ExecStart=/opt/netdata-zulip-bot/venv/bin/netdata-zulip-bot
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable netdata-zulip-bot
sudo systemctl start netdata-zulip-bot

Docker#

FROM python:3.11-slim

WORKDIR /app
COPY . .
RUN pip install -e .

EXPOSE 8443

CMD ["netdata-zulip-bot"]

Security#

Mutual TLS Authentication#

The service supports mutual TLS to authenticate Netdata Cloud webhooks:

  1. Server Certificate: Automatically managed by Let's Encrypt
  2. Client Verification: Validates Netdata's client certificate
  3. CA Certificate: Configure SERVER_CLIENT_CA_PATH to validate client certs

Webhook Endpoint Security#

  • HTTPS-only communication
  • Request logging and monitoring
  • Payload validation and sanitization
  • Error handling without information disclosure

Monitoring#

The service provides structured JSON logging for easy monitoring:

{
  "timestamp": "2024-01-15T14:30:00.000Z",
  "level": "info",
  "event": "Message sent to Zulip",
  "stream": "netdata-alerts",
  "topic": "critical",
  "message_id": 12345
}

Health Check#

curl -k https://your-domain.com:8443/health

Response:

{
  "status": "healthy",
  "service": "netdata-zulip-bot"
}

Development#

Running Tests#

pytest

Code Formatting#

black .
ruff check .

Local Development#

For development, you can disable HTTPS and mTLS:

export SERVER_ENABLE_MTLS=false
# Use HTTP for testing (not recommended for production)

Troubleshooting#

Common Issues#

  1. Certificate Not Found

    • Ensure Let's Encrypt certificates exist at /etc/letsencrypt/live/your-domain.com/
    • Check file permissions
  2. Zulip Connection Failed

    • Verify API credentials in zuliprc
    • Test connection with Zulip's API
  3. Webhook Not Receiving Data

    • Check firewall settings for port 8443
    • Verify domain DNS resolution
    • Check Netdata Cloud webhook configuration

Logs#

View service logs:

sudo journalctl -u netdata-zulip-bot -f

License#

MIT License - see LICENSE file for details.