{"id":24168637,"url":"https://github.com/madeofpendletonwool/alert-translator","last_synced_at":"2026-06-04T13:31:39.653Z","repository":{"id":260774032,"uuid":"882305358","full_name":"madeofpendletonwool/alert-translator","owner":"madeofpendletonwool","description":"A little middlewear container to translate kubernetes alerts to look nice in ntfy","archived":false,"fork":false,"pushed_at":"2024-11-03T23:45:28.000Z","size":4,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-26T05:03:32.772Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/madeofpendletonwool.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-02T13:19:06.000Z","updated_at":"2024-11-03T23:45:31.000Z","dependencies_parsed_at":"2024-11-02T14:34:48.602Z","dependency_job_id":null,"html_url":"https://github.com/madeofpendletonwool/alert-translator","commit_stats":null,"previous_names":["madeofpendletonwool/alert-translator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madeofpendletonwool%2Falert-translator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madeofpendletonwool%2Falert-translator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madeofpendletonwool%2Falert-translator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madeofpendletonwool%2Falert-translator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madeofpendletonwool","download_url":"https://codeload.github.com/madeofpendletonwool/alert-translator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241488198,"owners_count":19970829,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-12T22:15:35.221Z","updated_at":"2026-06-04T13:31:39.646Z","avatar_url":"https://github.com/madeofpendletonwool.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Alert Translator\n\nA lightweight Flask middleware service that translates Kubernetes alerts from Prometheus/Alertmanager into beautifully formatted notifications for NTFY servers. Perfect for getting clean, emoji-rich alerts on your mobile device or desktop.\n\n## Features\n\n- 🚀 **Multi-Server Support**: Send alerts to multiple NTFY servers simultaneously\n- 🔐 **Authentication Support**: Basic auth and token-based authentication per server\n- 🎨 **Rich Formatting**: Clean, emoji-enhanced notifications with proper severity levels\n- 🏷️ **Smart Labeling**: Automatically extracts and formats Kubernetes labels (namespace, pod, instance, job)\n- ⚡ **Multiple Severity Levels**: Critical, Warning, and Info alerts with appropriate priorities\n- 🔄 **Resolution Tracking**: Handles both firing and resolved alert states\n- 📊 **Health Monitoring**: Built-in health check and test endpoints\n- 🛡️ **Error Handling**: Robust error handling with detailed logging\n- 🐳 **Container Ready**: Lightweight Python-based Docker container\n- ⚙️ **Flexible Configuration**: YAML config files or environment variables\n\n## Quick Start\n\n### Docker Run (Environment Variables)\n\n```bash\ndocker run -d \\\n  --name alert-translator \\\n  -p 5000:5000 \\\n  -e NTFY_URLS='[\"http://ntfy.ntfy.svc.cluster.local\", \"https://ntfy.example.com\"]' \\\n  -e NTFY_TOPIC=\"k8s-alerts\" \\\n  your-registry/alert-translator:latest\n```\n\n### Docker Run (Config File)\n\n```bash\n# Create config file\ncat \u003e config.yaml \u003c\u003c EOF\ntopic: \"kubernetes-alerts\"\nservers:\n  - name: \"internal-ntfy\"\n    url: \"http://ntfy.ntfy.svc.cluster.local\"\n  - name: \"external-ntfy\"\n    url: \"https://ntfy.example.com\"\n    auth:\n      type: \"basic\"\n      username: \"myuser\"\n      password: \"mypass\"\nEOF\n\n# Run with config file\ndocker run -d \\\n  --name alert-translator \\\n  -p 5000:5000 \\\n  -v $(pwd)/config.yaml:/etc/alert-translator/config.yaml \\\n  -e CONFIG_FILE=\"/etc/alert-translator/config.yaml\" \\\n  your-registry/alert-translator:latest\n```\n\n## Configuration\n\n### Method 1: YAML Configuration File (Recommended)\n\nCreate a `config.yaml` file:\n\n```yaml\n# Global topic for all servers\ntopic: \"kubernetes-alerts\"\n\n# List of NTFY servers\nservers:\n  # Internal server (no authentication)\n  - name: \"internal-ntfy\"\n    url: \"http://ntfy.ntfy.svc.cluster.local\"\n\n  # External server with basic authentication\n  - name: \"external-ntfy\"\n    url: \"https://ntfy.example.com\"\n    auth:\n      type: \"basic\"\n      username: \"your-username\"\n      password: \"your-password\"\n\n  # Server with token authentication\n  - name: \"token-server\"\n    url: \"https://ntfy.another.com\"\n    auth:\n      type: \"token\"\n      token: \"tk_your_access_token_here\"\n```\n\nSet the config file location:\n```bash\nexport CONFIG_FILE=\"/path/to/config.yaml\"\n```\n\n### Method 2: Environment Variables (Legacy Support)\n\n| Variable | Description | Default | Example |\n|----------|-------------|---------|---------|\n| `CONFIG_FILE` | Path to YAML config file | `/etc/alert-translator/config.yaml` | `/app/config.yaml` |\n| `NTFY_URLS` | NTFY server URLs (JSON array or comma-separated) | `http://ntfy.ntfy.svc.cluster.local` | `[\"http://server1\", \"http://server2\"]` |\n| `NTFY_URL` | Legacy single URL support | `http://ntfy.ntfy.svc.cluster.local` | `http://ntfy.example.com` |\n| `NTFY_TOPIC` | NTFY topic name | `kubernetes-alerts` | `my-alerts` |\n\n### NTFY_URLS Format Options\n\n**JSON Array (Recommended):**\n```bash\nNTFY_URLS='[\"http://ntfy.ntfy.svc.cluster.local\", \"https://ntfy.example.com\"]'\n```\n\n**Comma-Separated:**\n```bash\nNTFY_URLS=\"http://ntfy.ntfy.svc.cluster.local,https://ntfy.example.com\"\n```\n\n**Single URL (Legacy):**\n```bash\nNTFY_URL=\"http://ntfy.ntfy.svc.cluster.local\"\n```\n\n## Authentication Types\n\n### Basic Authentication\n```yaml\nauth:\n  type: \"basic\"\n  username: \"your-username\"\n  password: \"your-password\"\n```\n\n### Token Authentication\n```yaml\nauth:\n  type: \"token\"\n  token: \"tk_your_access_token_here\"\n```\n\n### No Authentication\nSimply omit the `auth` section for servers that don't require authentication.\n\n## Kubernetes Deployment\n\n### ConfigMap and Secret Approach\n\n```yaml\n# ConfigMap for configuration\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: alert-translator-config\n  namespace: monitoring\ndata:\n  config.yaml: |\n    topic: \"kubernetes-alerts\"\n    servers:\n      - name: \"internal-ntfy\"\n        url: \"http://ntfy.ntfy.svc.cluster.local\"\n      - name: \"external-ntfy\"\n        url: \"https://ntfy.example.com\"\n        auth:\n          type: \"basic\"\n          username: \"${EXTERNAL_NTFY_USERNAME}\"\n          password: \"${EXTERNAL_NTFY_PASSWORD}\"\n\n---\n# Secret for credentials\napiVersion: v1\nkind: Secret\nmetadata:\n  name: alert-translator-secrets\n  namespace: monitoring\ntype: Opaque\ndata:\n  # Base64 encoded credentials\n  external-ntfy-username: bXl1c2VybmFtZQ==  # \"myusername\"\n  external-ntfy-password: bXlwYXNzd29yZA==  # \"mypassword\"\n\n---\n# Deployment\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: alert-translator\n  namespace: monitoring\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: alert-translator\n  template:\n    metadata:\n      labels:\n        app: alert-translator\n    spec:\n      containers:\n      - name: alert-translator\n        image: your-registry/alert-translator:latest\n        ports:\n        - containerPort: 5000\n        env:\n        - name: CONFIG_FILE\n          value: \"/etc/alert-translator/config.yaml\"\n        - name: EXTERNAL_NTFY_USERNAME\n          valueFrom:\n            secretKeyRef:\n              name: alert-translator-secrets\n              key: external-ntfy-username\n        - name: EXTERNAL_NTFY_PASSWORD\n          valueFrom:\n            secretKeyRef:\n              name: alert-translator-secrets\n              key: external-ntfy-password\n        volumeMounts:\n        - name: config-volume\n          mountPath: /etc/alert-translator\n          readOnly: true\n        livenessProbe:\n          httpGet:\n            path: /health\n            port: 5000\n          initialDelaySeconds: 30\n          periodSeconds: 30\n        readinessProbe:\n          httpGet:\n            path: /health\n            port: 5000\n          initialDelaySeconds: 5\n          periodSeconds: 10\n      volumes:\n      - name: config-volume\n        configMap:\n          name: alert-translator-config\n\n---\n# Service\napiVersion: v1\nkind: Service\nmetadata:\n  name: alert-translator\n  namespace: monitoring\nspec:\n  selector:\n    app: alert-translator\n  ports:\n  - port: 80\n    targetPort: 5000\n  type: ClusterIP\n```\n\n## Alertmanager Configuration\n\nConfigure Alertmanager to send webhooks to the alert-translator:\n\n```yaml\nglobal:\n  # ... other config\n\nroute:\n  # ... your routing rules\n\nreceivers:\n- name: 'ntfy-alerts'\n  webhook_configs:\n  - url: 'http://alert-translator.monitoring.svc.cluster.local/webhook'\n    send_resolved: true\n    http_config:\n      timeout: 10s\n```\n\n## API Endpoints\n\n### POST /webhook\n**Primary endpoint for receiving Alertmanager webhooks**\n\nExpected payload: Standard Alertmanager webhook format\n\nResponse:\n```json\n{\n  \"status\": \"success\",\n  \"alerts_processed\": 2,\n  \"notifications_sent\": 4,\n  \"servers_configured\": 2,\n  \"results\": [\n    {\"server\": \"internal-ntfy\", \"status\": \"success\", \"url\": \"http://ntfy.ntfy.svc.cluster.local\"},\n    {\"server\": \"external-ntfy\", \"status\": \"success\", \"url\": \"https://ntfy.example.com\"}\n  ]\n}\n```\n\n### GET /health\n**Health check endpoint**\n\nResponse:\n```json\n{\n  \"status\": \"healthy\",\n  \"servers_configured\": 2,\n  \"servers\": [\n    {\"name\": \"internal-ntfy\", \"url\": \"http://ntfy.ntfy.svc.cluster.local\", \"has_auth\": false},\n    {\"name\": \"external-ntfy\", \"url\": \"https://ntfy.example.com\", \"has_auth\": true}\n  ],\n  \"topic\": \"kubernetes-alerts\"\n}\n```\n\n### POST /test\n**Send a test notification to all configured servers**\n\nResponse:\n```json\n{\n  \"status\": \"success\",\n  \"message\": \"Test notification sent\",\n  \"sent_to_servers\": 2,\n  \"total_servers\": 2,\n  \"results\": [\n    {\"server\": \"internal-ntfy\", \"status\": \"success\", \"url\": \"http://ntfy.ntfy.svc.cluster.local\"},\n    {\"server\": \"external-ntfy\", \"status\": \"success\", \"url\": \"https://ntfy.example.com\"}\n  ]\n}\n```\n\n### GET /config\n**Get current configuration (without sensitive data)**\n\nResponse:\n```json\n{\n  \"topic\": \"kubernetes-alerts\",\n  \"servers\": [\n    {\"name\": \"internal-ntfy\", \"url\": \"http://ntfy.ntfy.svc.cluster.local\", \"has_auth\": false},\n    {\"name\": \"external-ntfy\", \"url\": \"https://ntfy.example.com\", \"has_auth\": true, \"auth_type\": \"basic\"}\n  ]\n}\n```\n\n## Alert Severity Levels\n\n| Severity | Priority | Tags | Prefix |\n|----------|----------|------|--------|\n| Critical | urgent | critical, skull | CRITICAL |\n| Warning | high | warning | WARNING |\n| Info | default | info | INFO |\n\n## Notification Format\n\n### Alert Structure\n```\n🔥 Status: FIRING\n📝 Summary: High CPU usage detected\n📋 Description: CPU usage is above 90% for 5 minutes\n🏷️ Labels:\n📍 Namespace: production\n📦 Pod: web-app-12345\n🖥️ Instance: worker-node-1\n⚙️ Job: kubernetes-pods\n⏱️ Duration: 5 minutes\n⏰ Started: 2025-05-23T10:30:00Z\n📚 Runbook: https://runbook.example.com/cpu-alerts\n```\n\n### Resolved Alerts\n```\n✅ Status: RESOLVED\n📝 Summary: High CPU usage resolved\n...\n✅ Resolved: 2025-05-23T10:35:00Z\n```\n\n## Building\n\n### Requirements\n```txt\nFlask==3.0.0\nrequests==2.31.0\nPyYAML==6.0.1\n```\n\n### Build Docker Image\n```bash\n# Create Dockerfile\ncat \u003e Dockerfile \u003c\u003c EOF\nFROM python:3.11-slim\n\nWORKDIR /app\n\nRUN apt-get update \u0026\u0026 apt-get install -y --no-install-recommends \\\n    curl \\\n    \u0026\u0026 rm -rf /var/lib/apt/lists/*\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY app.py .\n\nRUN useradd --create-home --shell /bin/bash app \u0026\u0026 \\\n    chown -R app:app /app\nUSER app\n\nHEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\\n    CMD curl -f http://localhost:5000/health || exit 1\n\nEXPOSE 5000\n\nCMD [\"python\", \"app.py\"]\nEOF\n\n# Build\ndocker build -t alert-translator:latest .\n```\n\n### Local Development\n```bash\npip install -r requirements.txt\nexport CONFIG_FILE=\"config.yaml\"\n# or\nexport NTFY_URLS='[\"http://localhost:8080\"]'\nexport NTFY_TOPIC=\"test-alerts\"\npython app.py\n```\n\n## Testing\n\n### Send Test Notification\n```bash\ncurl -X POST http://localhost:5000/test\n```\n\n### Check Health\n```bash\ncurl http://localhost:5000/health\n```\n\n### Check Configuration\n```bash\ncurl http://localhost:5000/config\n```\n\n### Simulate Alertmanager Webhook\n```bash\ncurl -X POST http://localhost:5000/webhook \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"alerts\": [{\n      \"status\": \"firing\",\n      \"labels\": {\n        \"alertname\": \"HighCPUUsage\",\n        \"severity\": \"warning\",\n        \"namespace\": \"production\",\n        \"pod\": \"web-app-12345\"\n      },\n      \"annotations\": {\n        \"summary\": \"High CPU usage detected\",\n        \"description\": \"CPU usage is above 90%\"\n      },\n      \"startsAt\": \"2025-05-23T10:30:00Z\"\n    }]\n  }'\n```\n\n## Troubleshooting\n\n### Common Issues\n\n**Notifications not appearing:**\n1. Check NTFY server accessibility: `curl http://your-ntfy-server/health`\n2. Verify topic name matches your NTFY subscription\n3. Check logs for connection errors\n4. Verify authentication credentials if using auth\n\n**Authentication errors:**\n1. Check username/password are correct\n2. Verify token is valid and has correct permissions\n3. Check if the NTFY server has auth enabled\n4. Review server logs for auth failures\n\n**Only some servers receiving notifications:**\n1. Review logs for individual server errors\n2. Verify all URLs are accessible from the container\n3. Check network policies if running in Kubernetes\n4. Test each server individually\n\n**Configuration errors:**\n1. Validate YAML syntax: `python -c \"import yaml; yaml.safe_load(open('config.yaml'))\"`\n2. Check environment variable substitution\n3. Verify file permissions for config file\n4. Check the `/config` endpoint for current configuration\n\n### Logs\n```bash\n# Docker\ndocker logs alert-translator\n\n# Kubernetes\nkubectl logs -f deployment/alert-translator -n monitoring\n```\n\n### Debug Mode\nSet log level to DEBUG by modifying the logging configuration in `app.py`:\n```python\nlogging.basicConfig(level=logging.DEBUG)\n```\n\n## Architecture\n\n```\n┌─────────────────┐    ┌──────────────────┐    ┌──────────────┐\n│   Alertmanager  │───▶│ Alert Translator │───▶│  NTFY Server │\n│                 │    │                  │    │      #1      │\n│  - Prometheus   │    │ - Format alerts  │    │  (No Auth)   │\n│  - Rules        │    │ - Multi-server   │    └──────────────┘\n│  - Routing      │    │ - Authentication │           │\n└─────────────────┘    │ - Error handling │    ┌──────────────┐\n                       │ - Health checks  │───▶│  NTFY Server │\n                       └──────────────────┘    │      #2      │\n                                               │ (With Auth)  │\n                                               └──────────────┘\n                                                      │\n                                               ┌──────────────┐\n                                               │   Mobile     │\n                                               │   Desktop    │\n                                               │   Clients    │\n                                               └──────────────┘\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests if applicable\n5. Submit a pull request\n\n## License\n\nThis project is open source. Feel free to use, modify, and distribute according to your needs.\n\n---\n\n**Made with ❤️ for better Kubernetes monitoring**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadeofpendletonwool%2Falert-translator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadeofpendletonwool%2Falert-translator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadeofpendletonwool%2Falert-translator/lists"}