diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a6e4cb4..2963a516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Docs for `/resolution_notes` public api endpoint [#222](https://github.com/grafana/oncall/issues/222) + ### Fixed - Change alerts order for `/alert` public api endpoint [#1031](https://github.com/grafana/oncall/issues/1031) +- Change resolution notes order for `/resolution_notes` public api endpoint to show notes for the newest alert group + on top ([#2404](https://github.com/grafana/oncall/pull/2404)) ## v1.3.2 (2023-06-29) diff --git a/docs/sources/oncall-api-reference/postmortems.md b/docs/sources/oncall-api-reference/postmortems.md deleted file mode 100644 index 41ae758c..00000000 --- a/docs/sources/oncall-api-reference/postmortems.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -canonical: https://grafana.com/docs/oncall/latest/oncall-api-reference/postmortems/ -draft: true -title: Postmortem HTTP API -weight: 1000 ---- - -# Create a postmortem - -```shell -curl "{{API_URL}}/api/v1/postmortems/" \ - --request POST \ - --header "Authorization: meowmeowmeow" \ - --header "Content-Type: application/json" \ - --data '{ - "alert_group_id": "I68T24C13IFW1", - "text": "Demo postmortem text" - }' -``` - -The above command returns JSON structured in the following way: - -```json -{ - "id": "P658FE5K87EWZ", - "alert_group_id": "I68T24C13IFW1", - "created_at": "2020-06-19T12:37:01.430444Z", - "text": "Demo postmortem text" -} -``` - -**HTTP request** - -`POST {{API_URL}}/api/v1/postmortems/` - -# Get a postmortem - -```shell -curl "{{API_URL}}/api/v1/postmortems/P658FE5K87EWZ/" \ - --request GET \ - --header "Authorization: meowmeowmeow" \ - --header "Content-Type: application/json" -``` - -The above command returns JSON structured in the following way: - -```json -{ - "id": "P658FE5K87EWZ", - "alert_group_id": "I68T24C13IFW1", - "created_at": "2020-06-19T12:37:01.430444Z", - "text": "Demo postmortem text", - "postmortem_messages": [ - { - "id": "M4BTQUS3PRHYQ", - "alert_group_id": "I68T24C13IFW1", - "author": "U4DNY931HHJS5", - "source": "web", - "created_at": "2020-06-19T12:40:01.429805Z", - "text": "Demo postmortem message" - } - ] -} -``` - -**HTTP request** - -`GET {{API_URL}}/api/v1/postmortems//` - -# List postmortems - -```shell -curl "{{API_URL}}/api/v1/postmortems/" \ - --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": "P658FE5K87EWZ", - "alert_group_id": "I68T24C13IFW1", - "created_at": "2020-06-19T12:37:01.430444Z", - "text": "Demo postmortem text", - "postmortem_messages": [ - { - "id": "M4BTQUS3PRHYQ", - "alert_group_id": "I68T24C13IFW1", - "author": "U4DNY931HHJS5", - "source": "web", - "created_at": "2020-06-19T12:40:01.429805Z", - "text": "Demo postmortem message" - } - ] - } - ] -} -``` - -The following available filter parameter should be provided with a `GET` argument: - -- `alert_group_id` - -**HTTP request** - -`GET {{API_URL}}/api/v1/postmortems/` - -# Update a postmortem - -```shell -curl "{{API_URL}}/api/v1/postmortems/P658FE5K87EWZ/" \ - --request PUT \ - --header "Authorization: meowmeowmeow" \ - --header "Content-Type: application/json" \ - --data '{ - "text": "Demo postmortem text" - }' -``` - -The above command returns JSON structured in the following way: - -```json -{ - "id": "P658FE5K87EWZ", - "alert_group_id": "I68T24C13IFW1", - "created_at": "2020-06-19T12:37:01.430444Z", - "text": "Demo postmortem text" -} -``` - -**HTTP request** - -`PUT {{API_URL}}/api/v1/postmortems//` - -# Delete a postmortem - -```shell -curl "{{API_URL}}/api/v1/postmortems/P658FE5K87EWZ/" \ - --request DELETE \ - --header "Authorization: meowmeowmeow" -``` - -**HTTP request** - -`DELETE {{API_URL}}/api/v1/postmortems//` diff --git a/docs/sources/oncall-api-reference/postmortem_messages.md b/docs/sources/oncall-api-reference/resolution_notes.md similarity index 53% rename from docs/sources/oncall-api-reference/postmortem_messages.md rename to docs/sources/oncall-api-reference/resolution_notes.md index 237b7bff..b5d8cc77 100644 --- a/docs/sources/oncall-api-reference/postmortem_messages.md +++ b/docs/sources/oncall-api-reference/resolution_notes.md @@ -1,20 +1,19 @@ --- -canonical: https://grafana.com/docs/oncall/latest/oncall-api-reference/postmortem_messages/ -draft: true -title: Postmortem Messages HTTP API +canonical: https://grafana.com/docs/oncall/latest/oncall-api-reference/resolution_notes/ +title: Resolution Notes HTTP API weight: 900 --- -# Create a postmortem message +# Create a resolution note ```shell -curl "{{API_URL}}/api/v1/postmortem_messages/" \ +curl "{{API_URL}}/api/v1/resolution_notes/" \ --request POST \ --header "Authorization: meowmeowmeow" \ --header "Content-Type: application/json" \ --data '{ "alert_group_id": "I68T24C13IFW1", - "text": "Demo postmortem message" + "text": "Demo resolution note" }' ``` @@ -27,18 +26,23 @@ The above command returns JSON structured in the following way: "author": "U4DNY931HHJS5", "source": "web", "created_at": "2020-06-19T12:40:01.429805Z", - "text": "Demo postmortem message" + "text": "Demo resolution note" } ``` +| Parameter | Required | Description | +| --------------- | :------: | :--------------------- | +| `alert_group_id`| Yes | Alert group ID | | +| `text` | Yes | Resolution note text | + **HTTP request** -`POST {{API_URL}}/api/v1/postmortem_messages/` +`POST {{API_URL}}/api/v1/resolution_notes/` -# Get a postmortem message +# Get a resolution note ```shell -curl "{{API_URL}}/api/v1/postmortem_messages/M4BTQUS3PRHYQ/" \ +curl "{{API_URL}}/api/v1/resolution_notes/M4BTQUS3PRHYQ/" \ --request GET \ --header "Authorization: meowmeowmeow" \ --header "Content-Type: application/json" @@ -53,18 +57,18 @@ The above command returns JSON structured in the following way: "author": "U4DNY931HHJS5", "source": "web", "created_at": "2020-06-19T12:40:01.429805Z", - "text": "Demo postmortem message" + "text": "Demo resolution note" } ``` **HTTP request** -`GET {{API_URL}}/api/v1/postmortem_messages//` +`GET {{API_URL}}/api/v1/resolution_notes//` -# List postmortem messages +# List resolution notes ```shell -curl "{{API_URL}}/api/v1/postmortem_messages/" \ +curl "{{API_URL}}/api/v1/resolution_notes/" \ --request GET \ --header "Authorization: meowmeowmeow" \ --header "Content-Type: application/json" @@ -84,7 +88,7 @@ The above command returns JSON structured in the following way: "author": "U4DNY931HHJS5", "source": "web", "created_at": "2020-06-19T12:40:01.429805Z", - "text": "Demo postmortem message" + "text": "Demo resolution note" } ] } @@ -96,17 +100,17 @@ The following available filter parameter should be provided as a `GET` argument: **HTTP request** -`GET {{API_URL}}/api/v1/postmortem_messages/` +`GET {{API_URL}}/api/v1/resolution_notes/` -# Update a postmortem message +# Update a resolution note ```shell -curl "{{API_URL}}/api/v1/postmortem_messages/M4BTQUS3PRHYQ/" \ +curl "{{API_URL}}/api/v1/resolution_notes/M4BTQUS3PRHYQ/" \ --request PUT \ --header "Authorization: meowmeowmeow" \ --header "Content-Type: application/json" \ --data '{ - "text": "Demo postmortem message" + "text": "Demo resolution note updated" }' ``` @@ -119,22 +123,22 @@ The above command returns JSON structured in the following way: "author": "U4DNY931HHJS5", "source": "web", "created_at": "2020-06-19T12:40:01.429805Z", - "text": "Demo postmortem message" + "text": "Demo resolution note updated" } ``` **HTTP request** -`PUT {{API_URL}}/api/v1/postmortem_messages//` +`PUT {{API_URL}}/api/v1/resolution_notes//` -# Delete a postmortem message +# Delete a resolution note ```shell -curl "{{API_URL}}/api/v1/postmortem_messages/M4BTQUS3PRHYQ/" \ +curl "{{API_URL}}/api/v1/resolution_notes/M4BTQUS3PRHYQ/" \ --request DELETE \ --header "Authorization: meowmeowmeow" ``` **HTTP request** -`DELETE {{API_URL}}/api/v1/postmortem_messages//` +`DELETE {{API_URL}}/api/v1/resolution_notes//` diff --git a/engine/apps/public_api/tests/test_resolution_notes.py b/engine/apps/public_api/tests/test_resolution_notes.py index c7d5b11d..f976ef05 100644 --- a/engine/apps/public_api/tests/test_resolution_notes.py +++ b/engine/apps/public_api/tests/test_resolution_notes.py @@ -6,6 +6,63 @@ from rest_framework.test import APIClient from apps.alerts.models import ResolutionNote +@pytest.mark.django_db +def test_get_resolution_notes( + make_organization_and_user_with_token, + make_alert_receive_channel, + make_alert_group, + make_resolution_note, +): + organization, user, token = make_organization_and_user_with_token() + client = APIClient() + + alert_receive_channel = make_alert_receive_channel(organization) + alert_group_1 = make_alert_group(alert_receive_channel) + alert_group_2 = make_alert_group(alert_receive_channel) + + resolution_note_1 = make_resolution_note( + alert_group=alert_group_1, + source=ResolutionNote.Source.WEB, + author=user, + ) + resolution_note_2 = make_resolution_note( + alert_group=alert_group_2, + source=ResolutionNote.Source.WEB, + author=user, + ) + + url = reverse("api-public:resolution_notes-list") + + response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token}") + + expected_response = { + "count": 2, + "next": None, + "previous": None, + "results": [ + { + "id": resolution_note_2.public_primary_key, + "alert_group_id": alert_group_2.public_primary_key, + "author": user.public_primary_key, + "source": resolution_note_2.get_source_display(), + "created_at": resolution_note_2.created_at.isoformat().replace("+00:00", "Z"), + "text": resolution_note_2.text, + }, + { + "id": resolution_note_1.public_primary_key, + "alert_group_id": alert_group_1.public_primary_key, + "author": user.public_primary_key, + "source": resolution_note_1.get_source_display(), + "created_at": resolution_note_1.created_at.isoformat().replace("+00:00", "Z"), + "text": resolution_note_1.text, + }, + ], + } + + assert response.status_code == status.HTTP_200_OK + assert response.json() == expected_response + + @pytest.mark.django_db def test_get_resolution_note( make_organization_and_user_with_token, diff --git a/engine/apps/public_api/views/resolution_notes.py b/engine/apps/public_api/views/resolution_notes.py index 7d07ca1f..f4886efa 100644 --- a/engine/apps/public_api/views/resolution_notes.py +++ b/engine/apps/public_api/views/resolution_notes.py @@ -35,7 +35,7 @@ class ResolutionNoteView(RateLimitHeadersMixin, UpdateSerializerMixin, ModelView queryset = self.serializer_class.setup_eager_loading(queryset) if alert_group_id: queryset = queryset.filter(alert_group__public_primary_key=alert_group_id) - return queryset.order_by("alert_group__started_at") + return queryset.order_by("-alert_group__started_at") def get_object(self): public_primary_key = self.kwargs["pk"]