2022-09-09 12:42:40 +05:00
|
|
|
import math
|
2022-07-11 13:16:56 +01:00
|
|
|
import time
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
import typing
|
2022-07-11 13:16:56 +01:00
|
|
|
|
2022-06-13 16:29:08 +04:00
|
|
|
from django.conf import settings
|
2022-06-03 08:09:47 -06:00
|
|
|
from rest_framework import serializers
|
|
|
|
|
|
|
|
|
|
from apps.api.serializers.telegram import TelegramToUserConnectorSerializer
|
|
|
|
|
from apps.base.messaging import get_messaging_backends
|
|
|
|
|
from apps.base.models import UserNotificationPolicy
|
2022-06-13 16:29:08 +04:00
|
|
|
from apps.base.utils import live_settings
|
2024-01-12 15:11:22 +00:00
|
|
|
from apps.oss_installation.constants import CloudSyncStatus
|
2022-06-13 16:29:08 +04:00
|
|
|
from apps.oss_installation.utils import cloud_user_identity_status
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
from apps.schedules.ical_utils import SchedulesOnCallUsers
|
2022-06-03 08:09:47 -06:00
|
|
|
from apps.user_management.models import User
|
2023-07-21 21:35:19 +02:00
|
|
|
from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField, TimeZoneField
|
2022-06-03 08:09:47 -06:00
|
|
|
from common.api_helpers.mixins import EagerLoadingMixin
|
2023-05-24 14:27:48 +08:00
|
|
|
from common.api_helpers.utils import check_phone_number_is_valid
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
from .custom_serializers import DynamicFieldsModelSerializer
|
|
|
|
|
from .organization import FastOrganizationSerializer
|
|
|
|
|
from .slack_user_identity import SlackUserIdentitySerializer
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
from .team import FastTeamSerializer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserSerializerContext(typing.TypedDict):
|
|
|
|
|
schedules_with_oncall_users: SchedulesOnCallUsers
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
|
2023-07-21 17:38:58 +02:00
|
|
|
class UserPermissionSerializer(serializers.Serializer):
|
|
|
|
|
action = serializers.CharField(read_only=True)
|
|
|
|
|
|
|
|
|
|
|
2024-04-02 14:59:03 -04:00
|
|
|
class GoogleCalendarSettingsSerializer(serializers.Serializer):
|
|
|
|
|
# # TODO: figure out how to get OrganizationFilteredPrimaryKeyRelatedField to work with many=True
|
|
|
|
|
# oncall_schedules_to_consider_for_shift_swaps =
|
|
|
|
|
# oncall_schedules_to_consider_for_shift_swaps = serializers.ListField(
|
|
|
|
|
# child=OrganizationFilteredPrimaryKeyRelatedField(
|
|
|
|
|
# queryset=OnCallSchedule.objects,
|
|
|
|
|
# required=False,
|
|
|
|
|
# allow_null=True,
|
|
|
|
|
# ),
|
|
|
|
|
# required=False,
|
|
|
|
|
# allow_null=True,
|
|
|
|
|
# )
|
|
|
|
|
oncall_schedules_to_consider_for_shift_swaps = serializers.ListField(
|
|
|
|
|
child=serializers.CharField(),
|
|
|
|
|
required=False,
|
|
|
|
|
allow_null=True,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2024-01-12 15:11:22 +00:00
|
|
|
class NotificationChainVerbal(typing.TypedDict):
|
|
|
|
|
default: str
|
|
|
|
|
important: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WorkingHoursPeriodSerializer(serializers.Serializer):
|
|
|
|
|
start = serializers.CharField()
|
|
|
|
|
end = serializers.CharField()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WorkingHoursSerializer(serializers.Serializer):
|
|
|
|
|
monday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
tuesday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
wednesday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
thursday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
friday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
saturday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
sunday = serializers.ListField(child=WorkingHoursPeriodSerializer())
|
|
|
|
|
|
|
|
|
|
|
2024-01-29 14:41:20 -03:00
|
|
|
class ListUserSerializer(DynamicFieldsModelSerializer, EagerLoadingMixin):
|
2022-06-03 08:09:47 -06:00
|
|
|
pk = serializers.CharField(read_only=True, source="public_primary_key")
|
|
|
|
|
slack_user_identity = SlackUserIdentitySerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
telegram_configuration = TelegramToUserConnectorSerializer(source="telegram_connection", read_only=True)
|
|
|
|
|
|
|
|
|
|
messaging_backends = serializers.SerializerMethodField()
|
|
|
|
|
|
|
|
|
|
organization = FastOrganizationSerializer(read_only=True)
|
|
|
|
|
current_team = TeamPrimaryKeyRelatedField(allow_null=True, required=False)
|
|
|
|
|
|
2022-12-01 14:13:39 +01:00
|
|
|
timezone = TimeZoneField(allow_null=True, required=False)
|
2022-06-03 08:09:47 -06:00
|
|
|
avatar = serializers.URLField(source="avatar_url", read_only=True)
|
2024-08-15 16:20:55 +02:00
|
|
|
avatar_full = serializers.SerializerMethodField()
|
2022-06-03 08:09:47 -06:00
|
|
|
notification_chain_verbal = serializers.SerializerMethodField()
|
2022-06-13 16:29:08 +04:00
|
|
|
cloud_connection_status = serializers.SerializerMethodField()
|
2024-01-12 15:11:22 +00:00
|
|
|
working_hours = WorkingHoursSerializer(required=False)
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2024-04-11 16:49:47 +02:00
|
|
|
SELECT_RELATED = [
|
|
|
|
|
"telegram_verification_code",
|
|
|
|
|
"telegram_connection",
|
|
|
|
|
"organization",
|
|
|
|
|
"slack_user_identity",
|
|
|
|
|
"mobileappauthtoken",
|
|
|
|
|
"google_oauth2_user",
|
|
|
|
|
]
|
2024-08-15 16:20:55 +02:00
|
|
|
PREFETCH_RELATED = ["notification_policies"]
|
2022-06-03 08:09:47 -06:00
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = User
|
|
|
|
|
fields = [
|
|
|
|
|
"pk",
|
|
|
|
|
"organization",
|
|
|
|
|
"current_team",
|
|
|
|
|
"email",
|
|
|
|
|
"username",
|
2022-11-28 15:52:31 +00:00
|
|
|
"name",
|
2023-06-16 12:00:14 +02:00
|
|
|
"role",
|
2022-06-03 08:09:47 -06:00
|
|
|
"avatar",
|
2022-11-28 15:52:31 +00:00
|
|
|
"avatar_full",
|
2022-07-11 13:16:56 +01:00
|
|
|
"timezone",
|
|
|
|
|
"working_hours",
|
2022-06-03 08:09:47 -06:00
|
|
|
"unverified_phone_number",
|
|
|
|
|
"verified_phone_number",
|
|
|
|
|
"slack_user_identity",
|
|
|
|
|
"telegram_configuration",
|
|
|
|
|
"messaging_backends",
|
|
|
|
|
"notification_chain_verbal",
|
2022-06-13 16:29:08 +04:00
|
|
|
"cloud_connection_status",
|
2022-09-09 12:42:40 +05:00
|
|
|
"hide_phone_number",
|
2024-04-02 14:59:03 -04:00
|
|
|
"has_google_oauth2_connected",
|
2022-06-03 08:09:47 -06:00
|
|
|
]
|
|
|
|
|
read_only_fields = [
|
|
|
|
|
"email",
|
|
|
|
|
"username",
|
2022-11-28 15:52:31 +00:00
|
|
|
"name",
|
2023-06-16 12:00:14 +02:00
|
|
|
"role",
|
2022-06-03 08:09:47 -06:00
|
|
|
"verified_phone_number",
|
2024-04-02 14:59:03 -04:00
|
|
|
"has_google_oauth2_connected",
|
2022-06-03 08:09:47 -06:00
|
|
|
]
|
|
|
|
|
|
2022-07-11 13:16:56 +01:00
|
|
|
def validate_working_hours(self, working_hours):
|
|
|
|
|
for day in working_hours:
|
2024-01-12 15:11:22 +00:00
|
|
|
for period in working_hours[day]:
|
2022-07-11 13:16:56 +01:00
|
|
|
try:
|
|
|
|
|
start = time.strptime(period["start"], "%H:%M:%S")
|
|
|
|
|
end = time.strptime(period["end"], "%H:%M:%S")
|
|
|
|
|
except ValueError:
|
|
|
|
|
raise serializers.ValidationError("'start' and 'end' fields must be in '%H:%M:%S' format")
|
|
|
|
|
|
|
|
|
|
if start >= end:
|
|
|
|
|
raise serializers.ValidationError("'start' must be less than 'end'")
|
|
|
|
|
return working_hours
|
|
|
|
|
|
2022-06-03 08:09:47 -06:00
|
|
|
def validate_unverified_phone_number(self, value):
|
|
|
|
|
if value:
|
|
|
|
|
if check_phone_number_is_valid(value):
|
|
|
|
|
return value
|
|
|
|
|
else:
|
|
|
|
|
raise serializers.ValidationError(
|
|
|
|
|
"Phone number must be entered in the format: '+999999999'. From 8 to 15 digits allowed."
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
return None
|
|
|
|
|
|
2024-01-12 15:11:22 +00:00
|
|
|
def get_messaging_backends(self, obj: User) -> dict[str, dict]:
|
2022-06-03 08:09:47 -06:00
|
|
|
serialized_data = {}
|
|
|
|
|
supported_backends = get_messaging_backends()
|
|
|
|
|
for backend_id, backend in supported_backends:
|
|
|
|
|
serialized_data[backend_id] = backend.serialize_user(obj)
|
|
|
|
|
return serialized_data
|
|
|
|
|
|
2024-01-12 15:11:22 +00:00
|
|
|
def get_notification_chain_verbal(self, obj: User) -> NotificationChainVerbal:
|
2022-06-03 08:09:47 -06:00
|
|
|
default, important = UserNotificationPolicy.get_short_verbals_for_user(user=obj)
|
|
|
|
|
return {"default": " - ".join(default), "important": " - ".join(important)}
|
|
|
|
|
|
2024-08-15 16:20:55 +02:00
|
|
|
def get_avatar_full(self, obj):
|
|
|
|
|
organization = self.context["request"].auth.organization if self.context.get("request") else obj.organization
|
|
|
|
|
return obj.avatar_full_url(organization)
|
|
|
|
|
|
2024-01-12 15:11:22 +00:00
|
|
|
def get_cloud_connection_status(self, obj: User) -> CloudSyncStatus | None:
|
2024-04-11 16:49:47 +02:00
|
|
|
is_open_source_with_cloud_notifications = self.context.get("is_open_source_with_cloud_notifications", None)
|
|
|
|
|
is_open_source_with_cloud_notifications = (
|
|
|
|
|
is_open_source_with_cloud_notifications
|
|
|
|
|
if is_open_source_with_cloud_notifications is not None
|
|
|
|
|
else settings.IS_OPEN_SOURCE and live_settings.GRAFANA_CLOUD_NOTIFICATIONS_ENABLED
|
|
|
|
|
)
|
|
|
|
|
if is_open_source_with_cloud_notifications:
|
2022-06-13 16:29:08 +04:00
|
|
|
connector = self.context.get("connector", None)
|
|
|
|
|
identities = self.context.get("cloud_identities", {})
|
|
|
|
|
identity = identities.get(obj.email, None)
|
|
|
|
|
status, _ = cloud_user_identity_status(connector, identity)
|
|
|
|
|
return status
|
|
|
|
|
return None
|
|
|
|
|
|
2022-09-09 12:42:40 +05:00
|
|
|
def to_representation(self, instance):
|
|
|
|
|
result = super().to_representation(instance)
|
|
|
|
|
if instance.id != self.context["request"].user.id:
|
|
|
|
|
if instance.hide_phone_number:
|
|
|
|
|
if result["verified_phone_number"]:
|
|
|
|
|
result["verified_phone_number"] = self._hide_phone_number(result["verified_phone_number"])
|
|
|
|
|
if result["unverified_phone_number"]:
|
|
|
|
|
result["unverified_phone_number"] = self._hide_phone_number(result["unverified_phone_number"])
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _hide_phone_number(number: str):
|
|
|
|
|
HIDE_SYMBOL = "*"
|
|
|
|
|
SHOW_LAST_SYMBOLS = 4
|
|
|
|
|
if len(number) <= 4:
|
|
|
|
|
SHOW_LAST_SYMBOLS = math.ceil(len(number) / 2)
|
|
|
|
|
return f"{HIDE_SYMBOL * (len(number) - SHOW_LAST_SYMBOLS)}{number[-SHOW_LAST_SYMBOLS:]}"
|
|
|
|
|
|
2022-06-03 08:09:47 -06:00
|
|
|
|
2024-01-29 14:41:20 -03:00
|
|
|
class UserSerializer(ListUserSerializer):
|
|
|
|
|
context: UserSerializerContext
|
|
|
|
|
|
|
|
|
|
is_currently_oncall = serializers.SerializerMethodField()
|
2024-04-02 14:59:03 -04:00
|
|
|
google_calendar_settings = GoogleCalendarSettingsSerializer(required=False)
|
2024-01-29 14:41:20 -03:00
|
|
|
|
|
|
|
|
class Meta(ListUserSerializer.Meta):
|
|
|
|
|
fields = ListUserSerializer.Meta.fields + [
|
|
|
|
|
"is_currently_oncall",
|
2024-04-02 14:59:03 -04:00
|
|
|
"google_calendar_settings",
|
2024-01-29 14:41:20 -03:00
|
|
|
]
|
|
|
|
|
read_only_fields = ListUserSerializer.Meta.read_only_fields + [
|
|
|
|
|
"is_currently_oncall",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def get_is_currently_oncall(self, obj: User) -> bool:
|
|
|
|
|
# Serializer context is set here: apps.api.views.user.UserView.get_serializer_context.
|
|
|
|
|
return any(obj in users for users in self.context.get("schedules_with_oncall_users", {}).values())
|
|
|
|
|
|
|
|
|
|
|
2023-07-21 17:38:58 +02:00
|
|
|
class CurrentUserSerializer(UserSerializer):
|
|
|
|
|
rbac_permissions = UserPermissionSerializer(read_only=True, many=True, source="permissions")
|
|
|
|
|
|
2024-08-14 18:02:34 -04:00
|
|
|
class Meta(UserSerializer.Meta):
|
2023-07-21 17:38:58 +02:00
|
|
|
fields = UserSerializer.Meta.fields + [
|
|
|
|
|
"rbac_permissions",
|
2024-08-14 18:02:34 -04:00
|
|
|
"google_oauth2_token_is_missing_scopes",
|
|
|
|
|
]
|
|
|
|
|
read_only_fields = UserSerializer.Meta.read_only_fields + [
|
|
|
|
|
"google_oauth2_token_is_missing_scopes",
|
2023-07-21 17:38:58 +02:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
2024-01-29 14:41:20 -03:00
|
|
|
class UserHiddenFieldsSerializer(ListUserSerializer):
|
2022-11-29 09:41:56 +01:00
|
|
|
fields_available_for_all_users = [
|
2022-06-03 08:09:47 -06:00
|
|
|
"pk",
|
|
|
|
|
"organization",
|
|
|
|
|
"current_team",
|
|
|
|
|
"username",
|
|
|
|
|
"avatar",
|
2022-07-11 13:16:56 +01:00
|
|
|
"timezone",
|
|
|
|
|
"working_hours",
|
2022-06-03 08:09:47 -06:00
|
|
|
"notification_chain_verbal",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def to_representation(self, instance):
|
2024-01-31 10:13:08 -03:00
|
|
|
ret = super(ListUserSerializer, self).to_representation(instance)
|
2022-09-09 12:42:40 +05:00
|
|
|
if instance.id != self.context["request"].user.id:
|
|
|
|
|
for field in ret:
|
2022-11-29 09:41:56 +01:00
|
|
|
if field not in self.fields_available_for_all_users:
|
2022-09-09 12:42:40 +05:00
|
|
|
ret[field] = "******"
|
|
|
|
|
ret["hidden_fields"] = True
|
2022-06-03 08:09:47 -06:00
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
2024-01-29 14:41:20 -03:00
|
|
|
class ScheduleUserSerializer(ListUserSerializer):
|
2023-04-26 17:46:51 -03:00
|
|
|
fields_to_keep = [
|
|
|
|
|
"pk",
|
|
|
|
|
"organization",
|
|
|
|
|
"email",
|
|
|
|
|
"username",
|
|
|
|
|
"name",
|
|
|
|
|
"avatar",
|
|
|
|
|
"avatar_full",
|
|
|
|
|
"timezone",
|
|
|
|
|
"working_hours",
|
|
|
|
|
"slack_user_identity",
|
|
|
|
|
"telegram_configuration",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def to_representation(self, instance):
|
2024-01-29 14:41:20 -03:00
|
|
|
serialized = super(ListUserSerializer, self).to_representation(instance)
|
2023-04-26 17:46:51 -03:00
|
|
|
ret = {field: value for field, value in serialized.items() if field in self.fields_to_keep}
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
2022-06-03 08:09:47 -06:00
|
|
|
class FastUserSerializer(serializers.ModelSerializer):
|
|
|
|
|
pk = serializers.CharField(source="public_primary_key")
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = User
|
|
|
|
|
fields = [
|
|
|
|
|
"pk",
|
|
|
|
|
"username",
|
|
|
|
|
]
|
|
|
|
|
read_only_fields = [
|
|
|
|
|
"pk",
|
|
|
|
|
"username",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FilterUserSerializer(EagerLoadingMixin, serializers.ModelSerializer):
|
|
|
|
|
value = serializers.CharField(source="public_primary_key")
|
|
|
|
|
display_name = serializers.CharField(source="username")
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = User
|
|
|
|
|
fields = ["value", "display_name"]
|
|
|
|
|
read_only_fields = [
|
|
|
|
|
"pk",
|
|
|
|
|
"username",
|
|
|
|
|
]
|
2023-08-16 14:13:56 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class UserShortSerializer(serializers.ModelSerializer):
|
|
|
|
|
username = serializers.CharField()
|
|
|
|
|
pk = serializers.CharField(source="public_primary_key")
|
|
|
|
|
avatar = serializers.CharField(source="avatar_url")
|
2024-08-15 16:20:55 +02:00
|
|
|
avatar_full = serializers.SerializerMethodField()
|
2023-08-16 14:13:56 +08:00
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = User
|
|
|
|
|
fields = [
|
|
|
|
|
"username",
|
|
|
|
|
"pk",
|
|
|
|
|
"avatar",
|
|
|
|
|
"avatar_full",
|
|
|
|
|
]
|
|
|
|
|
read_only_fields = [
|
|
|
|
|
"username",
|
|
|
|
|
"pk",
|
|
|
|
|
"avatar",
|
|
|
|
|
"avatar_full",
|
|
|
|
|
]
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
|
2024-08-15 16:20:55 +02:00
|
|
|
def get_avatar_full(self, obj):
|
|
|
|
|
organization = self.context["request"].auth.organization if self.context.get("request") else obj.organization
|
|
|
|
|
return obj.avatar_full_url(organization)
|
|
|
|
|
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
|
2023-11-03 12:40:54 -04:00
|
|
|
class UserIsCurrentlyOnCallSerializer(UserShortSerializer, EagerLoadingMixin):
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
context: UserSerializerContext
|
|
|
|
|
|
|
|
|
|
teams = FastTeamSerializer(read_only=True, many=True)
|
|
|
|
|
is_currently_oncall = serializers.SerializerMethodField()
|
|
|
|
|
|
2023-11-03 12:40:54 -04:00
|
|
|
SELECT_RELATED = ["organization"]
|
|
|
|
|
PREFETCH_RELATED = ["teams"]
|
|
|
|
|
|
|
|
|
|
class Meta(UserShortSerializer.Meta):
|
|
|
|
|
fields = UserShortSerializer.Meta.fields + [
|
|
|
|
|
"name",
|
|
|
|
|
"timezone",
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
"teams",
|
|
|
|
|
"is_currently_oncall",
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
def get_is_currently_oncall(self, obj: User) -> bool:
|
|
|
|
|
# Serializer context is set here: apps.api.views.user.UserView.get_serializer_context.
|
2024-01-29 14:41:20 -03:00
|
|
|
return any(obj in users for users in self.context.get("schedules_with_oncall_users", {}).values())
|
Add responders improvements (#3128)
# What this PR does
https://www.loom.com/share/c5e10b5ec51343d0954c6f41cfd6a5fb
## Summary of backend changes
- Add `AlertReceiveChannel.get_orgs_direct_paging_integrations` method
and `AlertReceiveChannel.is_contactable` property. These are needed to
be able to (optionally) filter down teams, in the `GET /teams` internal
API endpoint
([here](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R63)),
to just teams that have a "contactable" Direct Paging integration
- `engine/apps/alerts/paging.py`
- update these functions to support new UX. In short `direct_paging` no
longer takes a list of `ScheduleNotifications` or an `EscalationChain`
object
- add `user_is_oncall` helper function
- add `_construct_title` helper function. In short if no `title` is
provided, which is the case for Direct Pages originating from OnCall
(either UI or Slack), then the format is `f"{from_user.username} is
paging <team.name (if team is specified> <comma separated list of
user.usernames> to join escalation"`
- `engine/apps/api/serializers/team.py` - add
`number_of_users_currently_oncall` attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-26af48f796c9e987a76447586dd0f92349783d6ea6a0b6039a2f0f28bd58c2ebR45-R52))
- `engine/apps/api/serializers/user.py` - add `is_currently_oncall`
attribute to response schema
([code](https://github.com/grafana/oncall/pull/3128/files#diff-6744b5544ebb120437af98a996da5ad7d48ee1139a6112c7e3904010ab98f232R157-R162))
- `engine/apps/api/views/team.py` - add support for two new optional
query params `only_include_notifiable_teams` and `include_no_team`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-a4bd76e557f7e11dafb28a52c1034c075028c693b3c12d702d53c07fc6f24c05R55-R70))
- `engine/apps/api/views/user.py`
- in the `GET /users` internal API endpoint, when specifying the
`search` query param now also search on `teams__name`
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R223);
this is a new UX requirement)
- add support for a new optional query param, `is_currently_oncall`, to
allow filtering users based on.. whether they are currently on call or
not
([code](https://github.com/grafana/oncall/pull/3128/files#diff-30309629484ad28e6fe09816e1bd226226d652ea977b6f3b6775976c729bf4b5R272-R282))
- remove `check_availability` endpoint (no longer used with new UX; also
removed references in frontend code)
- `engine/apps/slack/scenarios/paging.py` and
`engine/apps/slack/scenarios/manage_responders.py` - update Slack
workflows to support new UX. Schedules are no longer a concept here.
When creating a new alert group via `/escalate` the user either
specifies a team and/or user(s) (they must specify at least one of the
two and validation is done here to check this). When adding responders
to an existing alert group it's simply a list of users that they can
add, no more schedules.
- add `Organization.slack_is_configured` and
`Organization.telegram_is_configured` properties. These are needed to
support [this new functionality
](https://github.com/grafana/oncall/pull/3128/files#diff-9d96504027309f2bd1e95352bac1433b09b60eb4fafb611b52a6c15ed16cbc48R271-R272)
in the `AlertReceiveChannel` model.
## Summary of frontend changes
- Refactor/rename `EscalationVariants` component to `AddResponders` +
remove `grafana-plugin/src/containers/UserWarningModal` (no longer
needed with new UX)
- Remove `grafana-plugin/src/models/user.ts` as it seemed to be a
duplicate of `grafana-plugin/src/models/user/user.types.ts`
Related to https://github.com/grafana/incident/issues/4278
- Closes #3115
- Closes #3116
- Closes #3117
- Closes #3118
- Closes #3177
## TODO
- [x] make frontend changes
- [x] update Slack backend functionality
- [x] update public documentation
- [x] add/update e2e tests
## Post-deploy To-dos
- [ ] update dev/ops/production Slack bots to update `/escalate` command
description (should now say "Direct page a team or user(s)")
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
2023-10-27 12:12:07 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class PagedUserSerializer(serializers.Serializer):
|
|
|
|
|
class Meta:
|
|
|
|
|
fields = [
|
|
|
|
|
"username",
|
|
|
|
|
"pk",
|
|
|
|
|
"avatar",
|
|
|
|
|
"avatar_full",
|
|
|
|
|
"important",
|
|
|
|
|
]
|