Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
99f42fe
Implements the data model and versioning layer for Event Orchestration.
Aidaho12 Jul 19, 2026
6b6eb0f
Implements condition evaluation, variable extraction, and safe templa…
Aidaho12 Jul 20, 2026
7ae8d7b
Implements deterministic action execution, event mutation, routing,
Aidaho12 Jul 21, 2026
aca06d2
Fix/2.0 schema aware migrations (#29)
Aidaho12 Jul 21, 2026
53556ef
Implements suppress, drop and pause, secure webhook actions
Aidaho12 Jul 22, 2026
b16a2af
Fix test_event_orchestration_migration_upgrade_and_downgrade
Aidaho12 Jul 22, 2026
a9e3a4c
Implements simulator, replay, shadow mode and Explain
Aidaho12 Jul 23, 2026
5a94c0d
Fix orchestration simulator API test to require JWT or API token auth…
Aidaho12 Jul 23, 2026
17ce835
Fix escalation flow blocking and UI matcher format handling
Aidaho12 Jul 24, 2026
cee94a9
Update escalation policy test to validate alert group creation and as…
Aidaho12 Jul 24, 2026
caaa2ad
Implements UI rule builder and management
Aidaho12 Jul 25, 2026
54e1673
Fix #24 and #32
Aidaho12 Jul 26, 2026
dc92ae8
Implements API, documentation, localization and quality
Aidaho12 Jul 27, 2026
0a3e486
Add Uptime Kuma integration, tests, and documentation
Aidaho12 Jul 28, 2026
1177aa0
Document the Kubernetes/Helm installation (#36)
megative Jul 28, 2026
d3e10c5
Add Slack Socket Mode worker deployment to the Helm chart (#35)
megative Jul 28, 2026
06d94e7
Add fr locale
Aidaho12 Jul 29, 2026
b19e1c4
Add audit log UI with filters, pagination, and localization support
Aidaho12 Jul 29, 2026
df709f7
Add support for skipping alert message updates during resolution; imp…
Aidaho12 Jul 30, 2026
e34dfd1
Normalize timezone handling for silences and implement UTC conversion…
Aidaho12 Aug 1, 2026
34aff9b
Add retroactive silence support with API, UI, and tests
Aidaho12 Aug 2, 2026
0416706
Implement maintenance-based lifecycle suppression for alerts, expand …
Aidaho12 Aug 3, 2026
017a7ed
Add support for user locale and theme preferences
Aidaho12 Aug 5, 2026
293ab58
Add `reactivate_on_end` and `apply_to_existing` lifecycle options to …
Aidaho12 Aug 6, 2026
88ad998
Add tests and refactor SSO group mapping edit logic
Aidaho12 Aug 7, 2026
b9c97e0
Fix SSO group mapping edit modal (#56)
megative Aug 7, 2026
7f7af39
Add orchestration action configuration for regex extraction, JSON pat…
Aidaho12 Aug 8, 2026
08b3b47
Add tests for dependency graph, escalation policies, and release inte…
Aidaho12 Aug 8, 2026
4dc498d
Delete repeted functions
Aidaho12 Aug 9, 2026
5ca7b3f
fix(datetime): centralize UTC normalization helpers
Aidaho12 Aug 10, 2026
780ee44
normalize(datetime): introduce centralized rotation scheduling helper…
Aidaho12 Aug 10, 2026
4ccedd8
Introduce centralized API token scope definitions and validations
Aidaho12 Aug 11, 2026
84611ab
Add notification template architecture
Aidaho12 Aug 12, 2026
a6364e3
Merge branch 'main' into release/2.0
Aidaho12 Aug 12, 2026
c0c1c59
Potential fix for pull request finding 'CodeQL / Incomplete string es…
Aidaho12 Aug 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ It provides the core building blocks of an on-call system:
- access groups and RBAC-style group roles;
- teams and on-call rotations;
- alert intake routes with per-route tokens;
- Alertmanager, AWS SNS/Cloud watch, Grafana, Zabbix, Sentry, LibreNMS, Datalog, RMON and generic webhook/PagerDuty Event API v2 integrations;
- Alertmanager, AWS SNS/Cloud watch, Grafana, Zabbix, Sentry, LibreNMS, Datadog, RMON,
Uptime Kuma and generic webhook/PagerDuty Event API v2 integrations;
- Mattermost, Slack, Telegram, Discord, Microsoft Teams, email, webhook, and voice-call notifications;
- profile-level browser/PWA push notifications;
- profile notification rules for browser push, email, and voice-call follow-up;
Expand Down Expand Up @@ -111,12 +112,13 @@ IncidentRelay includes Swagger/OpenAPI documentation and personal API tokens wit
| Source | Endpoint |
|-----------------|--------------------------------------------|
| Alertmanager | `POST /api/integrations/alertmanager` |
| Datalog | `POST /api/integrations/datalog` |
| Datadog | `POST /api/integrations/datadog` |
| Grafana | `POST /api/integrations/grafana` |
| RMON | `POST /api/integrations/rmon` |
| Zabbix | `POST /api/integrations/zabbix` |
| Sentry | `POST /api/integrations/sentry/<route_id>` |
| LibreNMS | `POST /api/integrations/librenms` |
| Uptime Kuma | `POST /api/integrations/uptime-kuma` |
| Generic webhook | `POST /api/integrations/webhook` |

### Notification channels
Expand Down Expand Up @@ -163,7 +165,7 @@ Read more: [Docker installation](docs/getting-started/docker.md)

### Kubernetes (Helm)

A Helm chart lives in `helm/incidentrelay`. It deploys the web UI plus the scheduler and Telegram workers, renders the application config from values into a Secret, and wires up the `/healthz` and `/readyz` probes.
A Helm chart lives in `helm/incidentrelay`. It deploys the web UI plus the scheduler, Telegram and Slack workers, renders the application config from values into a Secret, and wires up the `/healthz` and `/readyz` probes.

```bash
helm install incidentrelay ./helm/incidentrelay \
Expand All @@ -187,6 +189,8 @@ helm upgrade --install incidentrelay ./helm/incidentrelay \

All settings from `incidentrelay.conf` are available under `config.*` in [values.yaml](helm/incidentrelay/values.yaml); you can also bring a pre-rendered config via `existingConfigSecret`.

Read more: [Kubernetes installation](docs/getting-started/kubernetes.md)

### RedHat-like distributions from RPM repository

Recommended for RHEL, Rocky Linux, AlmaLinux, and CentOS Stream.
Expand Down Expand Up @@ -402,12 +406,14 @@ More examples:

- [Alertmanager integration](docs/integrations/alertmanager.md)
- [AWS SNS/Cloud watch](integrations/aws-sns-cloudwatch.md)
- [Datadog integration](docs/integrations/datadog.md)
- [Grafana integration](docs/integrations/grafana.md)
- [Datalog integration](docs/integrations/datadog.md)
- [RMON integration](docs/integrations/rmon.md)
- [Sentry integration](docs/integrations/sentry.md)
- [LibreNMS integration](docs/integrations/librenms.md)
- [Zabbix integration](docs/integrations/zabbix.md)
- [Uptime Kuma integration](docs/integrations/uptime-kuma.md)
- [Generic webhook integration](docs/integrations/generic-webhook.md)

---
Expand Down
11 changes: 11 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from app.i18n import register_i18n
from app.middleware import enforce_api_authentication
from app.views.admin_users_view import admin_users_bp
from app.views.audit_logs_view import audit_logs_bp
from app.views.alerts_view import alerts_bp
from app.views.auth_view import auth_bp
from app.views.calendar_view import calendar_bp
Expand Down Expand Up @@ -41,6 +42,10 @@
from app.views.matchers_view import matchers_bp
from app.views.business_services.routes import business_services_bp
from app.views.heartbeats_view import heartbeats_bp
from app.views.orchestrations_view import (
orchestrations_bp,
orchestration_webhook_actions_bp,
)


def create_app(log_role=None):
Expand Down Expand Up @@ -107,6 +112,7 @@ def register_blueprints(flask_app):
flask_app.register_blueprint(teams_bp, url_prefix="/api/teams")
flask_app.register_blueprint(users_bp, url_prefix="/api/users")
flask_app.register_blueprint(admin_users_bp, url_prefix="/api/admin/users")
flask_app.register_blueprint(audit_logs_bp, url_prefix="/api/admin/audit-logs")
flask_app.register_blueprint(rotations_bp, url_prefix="/api/rotations")
flask_app.register_blueprint(oncall_health_bp, url_prefix="/api/oncall-health")
flask_app.register_blueprint(calendar_bp, url_prefix="/api/calendar")
Expand All @@ -130,3 +136,8 @@ def register_blueprints(flask_app):
flask_app.register_blueprint(priority_policies_bp, url_prefix="/api/priority-policies")
flask_app.register_blueprint(business_services_bp)
flask_app.register_blueprint(heartbeats_bp, url_prefix="/api/heartbeats")
flask_app.register_blueprint(orchestrations_bp, url_prefix="/api/event-orchestrations")
flask_app.register_blueprint(
orchestration_webhook_actions_bp,
url_prefix="/api/orchestration-webhook-actions",
)
160 changes: 0 additions & 160 deletions app/api/openapi/endpoints/alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -671,40 +671,6 @@ def alert_comment_schema():
}


def alert_comment_user_schema():
"""Build alert comment user schema."""
return {
"type": "object",
"nullable": True,
"properties": {
"id": {"type": "integer"},
"username": {"type": "string", "nullable": True},
"email": {"type": "string", "nullable": True},
"display_name": {"type": "string", "nullable": True},
},
}


def alert_comment_schema():
"""Build alert comment response schema."""
return {
"type": "object",
"properties": {
"id": {"type": "integer"},
"group_id": {"type": "integer", "nullable": True},
"alert_id": {"type": "integer", "nullable": True},
"user_id": {"type": "integer", "nullable": True},
"user": alert_comment_user_schema(),
"body": {"type": "string"},
"created_at": date_time_property("Comment creation timestamp in UTC."),
"updated_at": date_time_property("Comment update timestamp in UTC."),
"edited": {
"type": "boolean",
"description": "True when updated_at is later than created_at.",
},
},
"additionalProperties": True,
}


def alert_comment_create_request_schema():
Expand Down Expand Up @@ -750,132 +716,6 @@ def delete_alert_comment_response_schema():
}


ALERT_COMMENT_CREATE_SCHEMA = {
"type": "object",
"required": ["body"],
"properties": {
"body": {
"type": "string",
"minLength": 1,
"maxLength": 5000,
"description": "Comment text. Leading and trailing whitespace is trimmed.",
"example": "Investigating disk usage on host1.",
},
},
}


ALERT_COMMENT_UPDATE_SCHEMA = {
"type": "object",
"required": ["body"],
"properties": {
"body": {
"type": "string",
"minLength": 1,
"maxLength": 5000,
"description": "New comment text. Leading and trailing whitespace is trimmed.",
"example": "Root cause found: log rotation failed.",
},
},
}


ALERT_COMMENT_DELETE_SCHEMA = {
"type": "object",
"properties": {
"deleted": {"type": "boolean", "example": True},
"id": {"type": "integer", "example": 42},
},
}


ALERT_COMMENT_PATHS = {
"/api/alerts/{alert_id}/comments": {
"get": {
"tags": ["alerts"],
"summary": "List alert comments",
"description": (
"Returns comments attached to an alert group. "
"The alert_id path parameter is the alert group id used by the alert details endpoint."
),
"operationId": "listAlertComments",
"parameters": [path_param("alert_id", "Alert group id.")],
"responses": {
"200": response(
"List of alert comments.",
{"type": "array", "items": alert_comment_schema()},
),
"403": response("Access denied."),
"404": response("Alert group not found."),
},
},
"post": {
"tags": ["alerts"],
"summary": "Create alert comment",
"description": (
"Creates a human comment on an alert group and appends a commented event "
"to the alert event history. Requires team responder, team manager, or global admin access."
),
"operationId": "createAlertComment",
"parameters": [path_param("alert_id", "Alert group id.")],
"requestBody": json_body(
"Comment properties.",
ALERT_COMMENT_CREATE_SCHEMA,
),
"responses": {
"201": response("Alert comment created.", alert_comment_schema()),
"400": response("Validation error."),
"403": response("Access denied."),
"404": response("Alert group not found."),
},
},
},
"/api/alerts/{alert_id}/comments/{comment_id}": {
"put": {
"tags": ["alerts"],
"summary": "Update alert comment",
"description": (
"Updates an existing alert group comment and appends a comment_updated event "
"to the alert event history. Requires team responder, team manager, or global admin access."
),
"operationId": "updateAlertComment",
"parameters": [
path_param("alert_id", "Alert group id."),
path_param("comment_id", "Alert comment id."),
],
"requestBody": json_body(
"Updated comment properties.",
ALERT_COMMENT_UPDATE_SCHEMA,
),
"responses": {
"200": response("Alert comment updated.", alert_comment_schema()),
"400": response("Validation error."),
"403": response("Access denied."),
"404": response("Alert group or comment not found."),
},
},
"delete": {
"tags": ["alerts"],
"summary": "Delete alert comment",
"description": (
"Soft-deletes an alert group comment and appends a comment_deleted event "
"to the alert event history. Deleted comments are hidden from the list endpoint."
),
"operationId": "deleteAlertComment",
"parameters": [
path_param("alert_id", "Alert group id."),
path_param("comment_id", "Alert comment id."),
],
"responses": {
"200": response("Alert comment deleted.", ALERT_COMMENT_DELETE_SCHEMA),
"403": response("Access denied."),
"404": response("Alert group or comment not found."),
},
},
},
}


def tags():
"""Return OpenAPI tags."""

Expand Down
21 changes: 2 additions & 19 deletions app/api/openapi/endpoints/heartbeats.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
from app.api.openapi.common import json_body, path_param, query_param, response

def tags():
return [{"name": "Heartbeats", "description": "Dead-man-switch checks that page when expected pings stop."}]


def path_param(name, description):
return {"name": name, "in": "path", "required": True, "description": description, "schema": {"type": "integer", "minimum": 1}}


def query_param(name, description, schema=None):
return {"name": name, "in": "query", "required": False, "description": description, "schema": schema or {"type": "string"}}


def json_body(description, schema, required=True):
return {"required": required, "description": description, "content": {"application/json": {"schema": schema}}}


def response(description, schema=None):
item = {"description": description}
if schema:
item["content"] = {"application/json": {"schema": schema}}
return item


HEARTBEAT_INSTANCE_SCHEMA = {
"type": "object",
"properties": {
Expand Down
Loading
Loading