Skip to content

Commit

Permalink
Public API: allow null escalation chain when creating routes (#1557)
Browse files Browse the repository at this point in the history
# What this PR does
Allows passing `null` as a value for `escalation_chain` when creating
routes via the public API.

## Which issue(s) this PR fixes
This is needed to unblock #1555 +
creating a route without an escalation chain is possible in the web UI,
so this PR makes the public API more consistent with the web UI.

## Checklist

- [x] Tests updated
- [x] Documentation added
- [x] `CHANGELOG.md` updated
  • Loading branch information
vstpme authored Mar 16, 2023
1 parent 4bb6397 commit bd12d38
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Changed

- Allow passing `null` as a value for `escalation_chain` when creating routes via the public API ([1557](https://github.com/grafana/oncall/pull/1557))

## v1.1.39 (2023-03-16)

### Added
Expand Down
2 changes: 1 addition & 1 deletion docs/sources/oncall-api-reference/routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Routes allow you to direct different alerts to different messenger channels and
| Parameter | Unique | Required | Description |
|-----------------------| :----: |:--------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `integration_id` | No | Yes | Each route is assigned to a specific integration. |
| `escalation_chain_id` | No | Yes | Each route is assigned a specific escalation chain. |
| `escalation_chain_id` | No | Yes | Each route is assigned a specific escalation chain. Explicitly pass `null` to create a route without an escalation chain assigned. |
| `routing_type` | Yes | No | Routing type that can be either `jinja2` or `regex`(default value) |
| `routing_regex` | Yes | Yes | Jinja2 template or Python Regex query (use <https://regex101.com/> for debugging). OnCall chooses the route for an alert in case there is a match inside the whole alert payload. |
| `position` | Yes | Optional | Route matching is performed one after another starting from position=`0`. Position=`-1` will put the route to the end of the list before `is_the_last_route`. A new route created with a position of an existing route will move the old route (and all following routes) down in the list. |
Expand Down
1 change: 1 addition & 0 deletions engine/apps/public_api/serializers/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class ChannelFilterSerializer(BaseChannelFilterSerializer):
escalation_chain_id = OrganizationFilteredPrimaryKeyRelatedField(
queryset=EscalationChain.objects,
source="escalation_chain",
allow_null=True,
)

is_the_last_route = serializers.BooleanField(read_only=True, source="is_default")
Expand Down
31 changes: 31 additions & 0 deletions engine/apps/public_api/tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,37 @@ def test_create_route(
assert response.json() == expected_response


@pytest.mark.django_db
def test_create_route_without_escalation_chain(route_public_api_setup):
_, _, token, alert_receive_channel, escalation_chain, _ = route_public_api_setup

client = APIClient()
url = reverse("api-public:routes-list")

data = {
"integration_id": alert_receive_channel.public_primary_key,
"routing_regex": "testreg",
"escalation_chain_id": None,
}
response = client.post(url, format="json", HTTP_AUTHORIZATION=token, data=data)

expected_response = {
"id": response.data["id"],
"integration_id": alert_receive_channel.public_primary_key,
"escalation_chain_id": None,
"routing_type": "regex",
"routing_regex": data["routing_regex"],
"position": 0,
"is_the_last_route": False,
"slack": {"channel_id": None, "enabled": True},
"telegram": {"id": None, "enabled": False},
TEST_MESSAGING_BACKEND_FIELD: {"id": None, "enabled": False},
}

assert response.status_code == status.HTTP_201_CREATED
assert response.json() == expected_response


@pytest.mark.django_db
def test_invalid_route_data(
route_public_api_setup,
Expand Down

0 comments on commit bd12d38

Please sign in to comment.