Skip to content

Commit

Permalink
Merge pull request #5206 from grafana/dev
Browse files Browse the repository at this point in the history
v1.11.4
  • Loading branch information
matiasb authored Oct 24, 2024
2 parents c49cef7 + 9a929e2 commit 1b8eddd
Show file tree
Hide file tree
Showing 23 changed files with 418 additions and 280 deletions.
32 changes: 16 additions & 16 deletions docs/sources/oncall-api-reference/escalation_policies.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,22 @@ The above command returns JSON structured in the following way:
}
```

| Parameter | Required | Description |
| ---------------------------------- | :--------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `escalation_chain_id` | Yes | Each escalation policy is assigned to a specific escalation chain. |
| `position` | Optional | Escalation policies execute one after another starting from `position=0`. `Position=-1` will put the escalation policy to the end of the list. A new escalation policy created with a position of an existing escalation policy will move the old one (and all following) down in the list. |
| `type` | Yes | One of: `wait`, `notify_persons`, `notify_person_next_each_time`, `notify_on_call_from_schedule`, `notify_user_group`, `trigger_webhook`, `resolve`, `notify_whole_channel`, `notify_if_time_from_to`, `declare_incident`. |
| `important` | Optional | Default is `false`. Will assign "important" to personal notification rules if `true`. This can be used to distinguish alerts on which you want to be notified immediately by phone. Applicable for types `notify_persons`, `notify_team_members`, `notify_on_call_from_schedule`, and `notify_user_group`. |
| `duration` | If type = `wait` | The duration, in seconds, when type `wait` is chosen. Valid values are: `60`, `300`, `900`, `1800`, `3600`. |
| `action_to_trigger` | If type = `trigger_webhook` | ID of a webhook. |
| `group_to_notify` | If type = `notify_user_group` | ID of a `User Group`. |
| `persons_to_notify` | If type = `notify_persons` | List of user IDs. |
| `persons_to_notify_next_each_time` | If type = `notify_person_next_each_time` | List of user IDs. |
| `notify_on_call _from_schedule` | If type = `notify_on_call_from_schedule` | ID of a Schedule. |
| `notify_if_time_from` | If type = `notify_if_time_from_to` | UTC time represents the beginning of the time period, for example `09:00:00Z`. |
| `notify_if_time_to` | If type = `notify_if_time_from_to` | UTC time represents the end of the time period, for example `18:00:00Z`. |
| `team_to_notify` | If type = `notify_team_members` | ID of a team. |
| `severity` | If type = `declare_incident` | Severity of the incident. |
| Parameter | Required | Description |
| ---------------------------------- |:----------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `escalation_chain_id` | Yes | Each escalation policy is assigned to a specific escalation chain. |
| `position` | Optional | Escalation policies execute one after another starting from `position=0`. `Position=-1` will put the escalation policy to the end of the list. A new escalation policy created with a position of an existing escalation policy will move the old one (and all following) down in the list. |
| `type` | Yes | One of: `wait`, `notify_persons`, `notify_person_next_each_time`, `notify_on_call_from_schedule`, `notify_user_group`, `trigger_webhook`, `resolve`, `notify_whole_channel`, `notify_if_time_from_to`, `declare_incident`. |
| `important` | Optional | Default is `false`. Will assign "important" to personal notification rules if `true`. This can be used to distinguish alerts on which you want to be notified immediately by phone. Applicable for types `notify_persons`, `notify_team_members`, `notify_on_call_from_schedule`, and `notify_user_group`. |
| `duration` | If type = `wait` | The duration, in seconds, when type `wait` is chosen. Valid values are any number of seconds in the inclusive range `60 to 86400`. |
| `action_to_trigger` | If type = `trigger_webhook` | ID of a webhook. |
| `group_to_notify` | If type = `notify_user_group` | ID of a `User Group`. |
| `persons_to_notify` | If type = `notify_persons` | List of user IDs. |
| `persons_to_notify_next_each_time` | If type = `notify_person_next_each_time` | List of user IDs. |
| `notify_on_call _from_schedule` | If type = `notify_on_call_from_schedule` | ID of a Schedule. |
| `notify_if_time_from` | If type = `notify_if_time_from_to` | UTC time represents the beginning of the time period, for example `09:00:00Z`. |
| `notify_if_time_to` | If type = `notify_if_time_from_to` | UTC time represents the end of the time period, for example `18:00:00Z`. |
| `team_to_notify` | If type = `notify_team_members` | ID of a team. |
| `severity` | If type = `declare_incident` | Severity of the incident. |

**HTTP request**

Expand Down
2 changes: 1 addition & 1 deletion engine/apps/alerts/models/escalation_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ def sorted_users_queue(self):
return sorted(self.notify_to_users_queue.all(), key=lambda user: (user.username or "", user.pk))

@property
def slack_integration_required(self):
def slack_integration_required(self) -> bool:
if self.step in self.SLACK_INTEGRATION_REQUIRED_STEPS:
return True
else:
Expand Down
14 changes: 10 additions & 4 deletions engine/apps/alerts/tasks/notify_ical_schedule_shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,17 @@ def notify_ical_schedule_shift(schedule_pk):
prev_shifts = convert_prev_shifts_to_new_format(prev_shifts, schedule)
prev_shifts_updated = True

# convert datetimes which was dumped to str back to datetime to calculate shift diff correct
str_format = "%Y-%m-%d %X%z"
def _parse_timestamp(timestamp: str) -> datetime.datetime:
# convert datetimes which was dumped to str back to datetime to calculate shift diff correct
try:
dt = datetime.datetime.strptime(timestamp, "%Y-%m-%d %X%z")
except ValueError:
dt = datetime.datetime.strptime(timestamp, "%Y-%m-%d %X.%f%z")
return dt

for prev_shift in prev_shifts:
prev_shift["start"] = datetime.datetime.strptime(prev_shift["start"], str_format)
prev_shift["end"] = datetime.datetime.strptime(prev_shift["end"], str_format)
prev_shift["start"] = _parse_timestamp(prev_shift["start"])
prev_shift["end"] = _parse_timestamp(prev_shift["end"])

# get shifts in progress now
now = datetime.datetime.now(datetime.timezone.utc)
Expand Down
39 changes: 39 additions & 0 deletions engine/apps/alerts/tests/test_notify_ical_schedule_shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,45 @@ def test_next_shift_changes_no_triggering_notification(
assert not mock_slack_api_call.called


@pytest.mark.django_db
def test_current_shifts_using_microseconds(
make_organization_and_user_with_slack_identities,
make_user,
make_schedule,
):
organization, _, _, _ = make_organization_and_user_with_slack_identities()
user1 = make_user(organization=organization, username="user1")
schedule = make_schedule(
organization,
schedule_class=OnCallScheduleCalendar,
name="test_schedule",
channel="channel",
prev_ical_file_overrides=None,
cached_ical_file_overrides=None,
)
schedule.refresh_ical_file()
schedule.current_shifts = json.dumps(
{
"test_shift_uid": {
"users": [user1.pk],
"start": timezone.now().replace(microsecond=123456),
"end": timezone.now().replace(microsecond=654321) + timezone.timedelta(days=1),
"all_day": False,
"priority": 1,
"priority_increased_by": 0,
}
},
default=str,
)
schedule.empty_oncall = False
schedule.save()

with patch("apps.slack.client.SlackClient.chat_postMessage") as mock_slack_api_call:
notify_ical_schedule_shift(schedule.pk)

assert mock_slack_api_call.called


@pytest.mark.django_db
def test_lower_priority_changes_no_triggering_notification(
make_organization_and_user_with_slack_identities,
Expand Down
16 changes: 8 additions & 8 deletions engine/apps/api/serializers/alert_group_escalation_snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ class Meta(EscalationPolicySerializer.Meta):
class AlertGroupEscalationSnapshotAPISerializer(serializers.Serializer):
"""Serializes AlertGroup escalation snapshot for API endpoint"""

escalation_chain = serializers.SerializerMethodField()
channel_filter = serializers.SerializerMethodField()
class EscalationChainSnapshotAPISerializer(serializers.Serializer):
name = serializers.CharField()

class ChannelFilterSnapshotAPISerializer(serializers.Serializer):
name = serializers.CharField(source="str_for_clients")

escalation_chain = EscalationChainSnapshotAPISerializer(read_only=True, source="escalation_chain_snapshot")
channel_filter = ChannelFilterSnapshotAPISerializer(read_only=True, source="channel_filter_snapshot")
escalation_policies = EscalationPolicySnapshotAPISerializer(
source="escalation_policies_snapshots", many=True, read_only=True
)

class Meta:
fields = ["escalation_chain", "channel_filter", "escalation_policies"]

def get_escalation_chain(self, obj):
return {"name": obj.escalation_chain_snapshot.name}

def get_channel_filter(self, obj):
return {"name": obj.channel_filter_snapshot.str_for_clients}
Loading

0 comments on commit 1b8eddd

Please sign in to comment.