Skip to content

Commit

Permalink
v1.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
joeyorlando authored Aug 15, 2024
2 parents 4696add + 67fc52d commit d8b4d10
Show file tree
Hide file tree
Showing 35 changed files with 867 additions and 62 deletions.
190 changes: 190 additions & 0 deletions docs/sources/oncall-api-reference/escalation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
---
canonical: https://grafana.com/docs/oncall/latest/oncall-api-reference/escalation/
title: Escalation HTTP API
weight: 1200
refs:
users:
- pattern: /docs/oncall/
destination: /docs/oncall/<ONCALL_VERSION>/oncall-api-reference/users
- pattern: /docs/grafana-cloud/
destination: /docs/grafana-cloud/alerting-and-irm/oncall/oncall-api-reference/users
teams:
- pattern: /docs/oncall/
destination: /docs/oncall/<ONCALL_VERSION>/oncall-api-reference/teams
- pattern: /docs/grafana-cloud/
destination: /docs/grafana-cloud/alerting-and-irm/oncall/oncall-api-reference/teams
manual-paging:
- pattern: /docs/oncall/
destination: /docs/oncall/<ONCALL_VERSION>/configure/integrations/references/manual
- pattern: /docs/grafana-cloud/
destination: /docs/grafana-cloud/configure/integrations/references/manual
---

# Escalation HTTP API

See [Manual paging integration](ref:manual-paging) for more background on how escalating to a team or user(s) works.

## Escalate to a set of users

For more details about how to fetch a user's Grafana OnCall ID, refer to the [Users](ref:users) public API documentation.

```shell
curl "{{API_URL}}/api/v1/escalation/" \
--request POST \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json" \
--data '{
"title": "We are seeing a network outage in the datacenter",
"message": "I need help investigating, can you join the investigation?",
"source_url": "https://github.com/myorg/myrepo/issues/123",
"users": [
{
"id": "U281SN24AVVJX",
"important": false
},
{
"id": "U5AKCVNDEDUE7",
"important": true
}
]
}'
```

The above command returns JSON structured in the following way:

```json
{
"id": "IZHCC4GTNPZ93",
"integration_id": "CC3GZYZNIIEH5",
"route_id": "RDN8LITALJXCJ",
"alerts_count": 1,
"state": "firing",
"created_at": "2024-08-15T18:05:36.801215Z",
"resolved_at": null,
"resolved_by": null,
"acknowledged_at": null,
"acknowledged_by": null,
"title": "We're seeing a network outage in the datacenter",
"permalinks": {
"slack": null,
"slack_app": null,
"telegram": null,
"web": "http://<my_grafana_url>/a/grafana-oncall-app/alert-groups/I5LAZ2MXGPUAH"
},
"silenced_at": null
}
```

## Escalate to a team

For more details about how to fetch a team's Grafana OnCall ID, refer to the [Teams](ref:teams) public API documentation.

```shell
curl "{{API_URL}}/api/v1/escalation/" \
--request POST \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json" \
--data '{
"title": "We are seeing a network outage in the datacenter",
"message": "I need help investigating, can you join the investigation?",
"source_url": "https://github.com/myorg/myrepo/issues/123",
"team": "TI73TDU19W48J"
}'
```

The above command returns JSON structured in the following way:

```json
{
"id": "IZHCC4GTNPZ93",
"integration_id": "CC3GZYZNIIEH5",
"route_id": "RDN8LITALJXCJ",
"alerts_count": 1,
"state": "firing",
"created_at": "2024-08-15T18:05:36.801215Z",
"resolved_at": null,
"resolved_by": null,
"acknowledged_at": null,
"acknowledged_by": null,
"title": "We're seeing a network outage in the datacenter",
"permalinks": {
"slack": null,
"slack_app": null,
"telegram": null,
"web": "http://<my_grafana_url>/a/grafana-oncall-app/alert-groups/I5LAZ2MXGPUAH"
},
"silenced_at": null
}
```

## Escalate to a set of user(s) for an existing Alert Group

The following shows how you can escalate to a set of user(s) for an existing Alert Group.

```shell
curl "{{API_URL}}/api/v1/escalation/" \
--request POST \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json" \
--data '{
"alert_group_id": "IZMRNNY8RFS94",
"users": [
{
"id": "U281SN24AVVJX",
"important": false
},
{
"id": "U5AKCVNDEDUE7",
"important": true
}
]
}'
```

The above command returns JSON structured in the following way:

```json
{
"id": "IZHCC4GTNPZ93",
"integration_id": "CC3GZYZNIIEH5",
"route_id": "RDN8LITALJXCJ",
"alerts_count": 1,
"state": "firing",
"created_at": "2024-08-15T18:05:36.801215Z",
"resolved_at": null,
"resolved_by": null,
"acknowledged_at": null,
"acknowledged_by": null,
"title": "We're seeing a network outage in the datacenter",
"permalinks": {
"slack": null,
"slack_app": null,
"telegram": null,
"web": "http://<my_grafana_url>/a/grafana-oncall-app/alert-groups/I5LAZ2MXGPUAH"
},
"silenced_at": null
}
```

| Parameter | Unique | Required | Description |
| -------------------- | :----: | :--------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title` | No | No | Name of the Alert Group that will be created |
| `message` | No | No | Content of the Alert Group that will be created |
| `source_url` | No | No | Value that will be added in the Alert's payload as `oncall.permalink`. This can be useful to have the source URL/button autopopulated with a URL of interest. |
| `team` | No | Yes (see [Things to Note](#things-to-note)) | Grafana OnCall team ID. If specified, will use the "Direct Paging" Integration associated with this Grafana OnCall team, to create the Alert Group. |
| `users` | No | Yes (see [Things to Note](#things-to-note)) | List of user(s) to escalate to. See above request example for object schema. `id` represents the Grafana OnCall user's ID. `important` is a boolean representing whether to escalate the Alert Group using this user's default or important personal notification policy. |
| `alert_group_id` | No | No | If specified, will escalate the specified users for this Alert Group. |

## Things to note

- `team` and `users` are mutually exclusive in the request payload. If you would like to escalate to a team AND user(s),
first escalate to a team, then using the Alert Group ID returned in the response payload, add the required users to the
existing Alert Group
- `alert_group_id` is mutually exclusive with `title`, `message`, and `source_url`. Practically speaking this means that
if you are trying to escalate to a set of users on an existing Alert Group, you cannot update the `title`, `message`, or
`source_url` of that Alert Group
- If escalating to a set of users for an existing Alert Group, the Alert Group cannot be in a resolved state

**HTTP request**

`POST {{API_URL}}/api/v1/escalation/`
73 changes: 73 additions & 0 deletions docs/sources/oncall-api-reference/organizations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
canonical: https://grafana.com/docs/oncall/latest/oncall-api-reference/organizations/
title: Grafana OnCall organizations HTTP API
weight: 1500
refs:
pagination:
- pattern: /docs/oncall/
destination: /docs/oncall/<ONCALL_VERSION>/oncall-api-reference/#pagination
- pattern: /docs/grafana-cloud/
destination: /docs/grafana-cloud/alerting-and-irm/oncall/oncall-api-reference/#pagination
---

# Grafana OnCall organizations HTTP API

## Get an organization

This endpoint retrieves the organization object.

```shell
curl "{{API_URL}}/api/v1/organizations/O53AAGWFBPE5W/" \
--request GET \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json"
````

The above command returns JSON structured in the following way:

```json
{
"id": "O53AAGWFBPE5W"
}
```

**HTTP request**

`GET {{API_URL}}/api/v1/organizations/<ORGANIZATION_ID>/`

| Parameter | Unique | Description |
| ---------- | :-----: | :----------------------------------------------------------------- |
| `id` | Yes | Organization ID |

## List Organizations

```shell
curl "{{API_URL}}/api/v1/organizations/" \
--request GET \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json"
```

The above command returns JSON structured in the following way:

```json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "O53AAGWFBPE5W"
}
],
"page_size": 25,
"current_page_number": 1,
"total_pages": 1
}
```

> **Note**: The response is [paginated](ref:pagination). You may need to make multiple requests to get all records.

**HTTP request**

`GET {{API_URL}}/api/v1/organizations/`
86 changes: 86 additions & 0 deletions docs/sources/oncall-api-reference/teams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
canonical: https://grafana.com/docs/oncall/latest/oncall-api-reference/teams/
title: Grafana OnCall teams HTTP API
weight: 1500
refs:
pagination:
- pattern: /docs/oncall/
destination: /docs/oncall/<ONCALL_VERSION>/oncall-api-reference/#pagination
- pattern: /docs/grafana-cloud/
destination: /docs/grafana-cloud/alerting-and-irm/oncall/oncall-api-reference/#pagination
---

# Grafana OnCall teams HTTP API

## Get a team

This endpoint retrieves the team object.

```shell
curl "{{API_URL}}/api/v1/teams/TI73TDU19W48J/" \
--request GET \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json"
````

The above command returns JSON structured in the following way:

```json
{
"id": "TI73TDU19W48J",
"name": "my test team",
"email": "",
"avatar_url": "/avatar/3f49c15916554246daa714b9bd0ee398"
}
```

**HTTP request**

`GET {{API_URL}}/api/v1/teams/<TEAM_ID>/`

| Parameter | Unique | Description |
| ---------- | :-----: | :----------------------------------------------------------------- |
| `id` | Yes/org | Team ID |
| `name` | Yes/org | Team name |
| `email` | Yes/org | Team e-mail |
| `avatar_url` | Yes | Avatar URL of the Grafana team |

## List Teams

```shell
curl "{{API_URL}}/api/v1/teams/" \
--request GET \
--header "Authorization: meowmeowmeow" \
--header "Content-Type: application/json"
```

The above command returns JSON structured in the following way:

```json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "TI73TDU19W48J",
"name": "my test team",
"email": "",
"avatar_url": "/avatar/3f49c15916554246daa714b9bd0ee398"
}
],
"page_size": 50,
"current_page_number": 1,
"total_pages": 1
}
```

> **Note**: The response is [paginated](ref:pagination). You may need to make multiple requests to get all records.

The following available filter parameter should be provided as a `GET` argument:

- `name` (Exact match)

**HTTP request**

`GET {{API_URL}}/api/v1/teams/`
3 changes: 2 additions & 1 deletion engine/apps/alerts/models/alert_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ def get_paged_users(self) -> typing.List[PagedUser]:

user_ids: typing.Set[str] = set()
users: typing.Dict[str, PagedUser] = {}
organization = self.channel.organization

log_records = self.log_records.filter(
type__in=(AlertGroupLogRecord.TYPE_DIRECT_PAGING, AlertGroupLogRecord.TYPE_UNPAGE_USER)
Expand Down Expand Up @@ -594,7 +595,7 @@ def get_paged_users(self) -> typing.List[PagedUser]:
"name": user.name,
"username": user.username,
"avatar": user.avatar_url,
"avatar_full": user.avatar_full_url,
"avatar_full": user.avatar_full_url(organization),
"important": important,
"teams": [{"pk": t.public_primary_key, "name": t.name} for t in user.teams.all()],
}
Expand Down
5 changes: 3 additions & 2 deletions engine/apps/alerts/models/alert_group_log_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,10 @@ class AlertGroupLogRecord(models.Model):
def render_log_line_json(self):
time = humanize.naturaldelta(self.alert_group.started_at - self.created_at)
created_at = DateTimeField().to_representation(self.created_at)
author = self.author.short() if self.author is not None else None
organization = self.alert_group.channel.organization
author = self.author.short(organization) if self.author is not None else None

sf = SlackFormatter(self.alert_group.channel.organization)
sf = SlackFormatter(organization)
action = sf.format(self.rendered_log_line_action(substitute_author_with_tag=True))
action = clean_markup(action)

Expand Down
5 changes: 3 additions & 2 deletions engine/apps/alerts/models/resolution_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@ def recreate(self):
def render_log_line_json(self):
time = humanize.naturaldelta(self.alert_group.started_at - self.created_at)
created_at = DateTimeField().to_representation(self.created_at)
author = self.author.short() if self.author is not None else None
organization = self.alert_group.channel.organization
author = self.author.short(organization) if self.author is not None else None

sf = SlackFormatter(self.alert_group.channel.organization)
sf = SlackFormatter(organization)
action = sf.format(self.text)
action = clean_markup(action)

Expand Down
Loading

0 comments on commit d8b4d10

Please sign in to comment.