Skip to content

[ResponseOps][Rules] Allow users to create a snooze schedule for rule via API#210584

Merged
js-jankisalvi merged 39 commits intoelastic:mainfrom
js-jankisalvi:recuuring-schema
Mar 13, 2025
Merged

[ResponseOps][Rules] Allow users to create a snooze schedule for rule via API#210584
js-jankisalvi merged 39 commits intoelastic:mainfrom
js-jankisalvi:recuuring-schema

Conversation

@js-jankisalvi
Copy link
Contributor

@js-jankisalvi js-jankisalvi commented Feb 11, 2025

Summary

Resolves first part of #198783 (snooze API)
Creates a public API for adding snooze schedule to rules.
For this purpose we created new schedule schema which will be used as standard schedule schema across rules and alerting framework.

Note
The code to be reviewed for public API is under common/routes/schedule and inside external folders.
Rest of the code is just moving existing internal API route and its code to /internal folders.

Checklist

How to test

  • Create a rule in kibana
  • Snooze that rule via new public API
Path: https://localhost:5601/api/alerting/rule/<rule_id>/snooze_schedule
Method: POST
Body: 
{
    "schedule": { 
       "custom": {
         "start": "2025-02-25T18:00:00.000Z",
         "duration": "15m",
         "recurring": {
            "every": "1w",
            "onWeekDay": ["TU", "FR"],
            "occurrences": 10
         }
       }
    }
}
  • Verify various snooze schedule scenarios are generated correctly

Flaky test runner:

https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8009

Release note

Allow users to create a snooze schedule for rule via API

@js-jankisalvi js-jankisalvi self-assigned this Feb 11, 2025
js-jankisalvi and others added 5 commits February 13, 2025 13:54
…t --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --include-path /api/dashboards --update'
@js-jankisalvi js-jankisalvi changed the title [ResponseOps][Rules] Recurring schedule schema Feb 18, 2025
js-jankisalvi and others added 4 commits February 19, 2025 16:55
…t --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --include-path /api/dashboards --update'
@js-jankisalvi js-jankisalvi changed the title [ResponseOps][Rules] Schedule schema Feb 21, 2025
@js-jankisalvi js-jankisalvi changed the title [ResponseOps][Rules] Public snooze schedule API to allow users to add snooze schedule to a rule Feb 21, 2025
@js-jankisalvi js-jankisalvi added v9.1.0 Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// Feature:Alerting/RulesManagement Issues related to the Rules Management UX backport:version Backport to applied version labels release_note:enhancement labels Feb 28, 2025
@js-jankisalvi js-jankisalvi changed the title [ResponseOps][Rules] Public snooze schedule API to add snooze schedule to a rule Feb 28, 2025
@js-jankisalvi js-jankisalvi changed the title [ResponseOps][Rules] Public API to add snooze schedule to a rule Feb 28, 2025
@js-jankisalvi js-jankisalvi marked this pull request as ready for review February 28, 2025 12:04
@js-jankisalvi js-jankisalvi requested a review from a team as a code owner February 28, 2025 12:04
@elasticmachine
Copy link
Contributor

Pinging @elastic/response-ops (Team:ResponseOps)

js-jankisalvi and others added 3 commits February 28, 2025 12:13
…t --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --include-path /api/dashboards --update'
Copy link
Member

@cnasikas cnasikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Very meticulous with great testing coverage. I left some minor comments, and I would like to discuss the following:

  • If the user puts 48h as a duration, we return 2d because of the transformation we do. As we do not persist with the initial request, I do not think there is anything we can do. I just wanted to call it out. I think it is fine as long as we are consistent and always return the same. Maybe we have to document it.
  • Users can define seconds in the duration field. This can lead to the following interesting scenario: I set the duration to 129600s, which will be converted to 1.5d. How do you think we should handle this? Is it okay to leave it as it is?
}
}

if (duration === '-1' && recurring) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cnasikas What do you think of having duration: undefined instead of duration: -1? Isn't that clearer?

An answer for the future (aside from the fact that we will not support it initially): I think it is better if we force users to be explicit when they want to schedule the rule indefinitely. Having undefined to mean indefinitely can easily lead to mistakes, where users forget to put the duration and accidentally snooze a critical rule forever.

import moment from 'moment';
import { DURATION_REGEX, INTERVAL_FREQUENCY_REGEXP } from '../../constants';

export const validateSchedule = (schedule: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does the rrule library handles this scenario?

start: schema.string({
validate: validateStartDateV1,
meta: {
description: 'The start date and time of the schedule in ISO 8601 format.',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should we mention that it has to be in the UTC format (with the z in the end) and use the timezone field to specify the timezone?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use UTC timezone format and added example

import moment from 'moment';
import { DURATION_REGEX, INTERVAL_FREQUENCY_REGEXP } from '../../constants';

export const validateSchedule = (schedule: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How then do we validate the duration, does it have to match exactly the difference between the start and end date?

end is optional, it gets converted to the until property in RRULE, meaning "recur until this date." Maybe we should rename end to until to reduce confusion? Making it part of recurring.end is a little helpful but I think if @adcoelho is getting confused then the user might also.

It's possible for the duration to go on longer than the end date, the rrule library won't throw an error or anything, it just won't make the rule recur ever.

.asDays();

if (intervalInDays && interval && durationInDays >= intervalInDays) {
return `Recurrence every ${every} must be longer than the duration ${duration}.`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, excellent, we have absolutely had SDHs come up around this before. This would technically work but let's not let the user hurt themselves.

js-jankisalvi and others added 3 commits March 12, 2025 12:57
…t --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --include-path /api/dashboards --update'
@js-jankisalvi
Copy link
Contributor Author

  • If the user puts 48h as a duration, we return 2d because of the transformation we do. As we do not persist with the initial request, I do not think there is anything we can do. I just wanted to call it out. I think it is fine as long as we are consistent and always return the same. Maybe we have to document it.
  • Users can define seconds in the duration field. This can lead to the following interesting scenario: I set the duration to 129600s, which will be converted to 1.5d. How do you think we should handle this? Is it okay to leave it as it is?

I found a way to return same duration string passed by user in request. We pass request duration to our transform method transformRRuleToCustomSchedule from snooze rule route and use that as response duration

transformRRuleToCustomSchedule({
  snoozeSchedule: createdSchedule,
  originalDuration: customSchedule.duration,
 }) 
@cnasikas
Copy link
Member

  • If the user puts 48h as a duration, we return 2d because of the transformation we do. As we do not persist with the initial request, I do not think there is anything we can do. I just wanted to call it out. I think it is fine as long as we are consistent and always return the same. Maybe we have to document it.
  • Users can define seconds in the duration field. This can lead to the following interesting scenario: I set the duration to 129600s, which will be converted to 1.5d. How do you think we should handle this? Is it okay to leave it as it is?

I found a way to return same duration string passed by user in request. We pass request duration to our transform method transformRRuleToCustomSchedule from snooze rule route and use that as response duration

transformRRuleToCustomSchedule({
  snoozeSchedule: createdSchedule,
  originalDuration: customSchedule.duration,
 }) 

I like the idea, but instead of passing it to the transformRRuleToCustomSchedule I think it is better to move the responsibility to the router like:

const customScheduleRes = transformRRuleToCustomSchedule(createdSchedule);

const response: SnoozeResponse = {
            body: {
              schedule: {
                id: snoozeScheduleId,
                custom: { ...customScheduleRes, duration: customSchedule.duration <-- this is req.body.schedule?.custom }
              },
            },
          };

Also, could you please open an issue to persist the new format to ES along with the old rrule format?

@js-jankisalvi
Copy link
Contributor Author

I like the idea, but instead of passing it to the transformRRuleToCustomSchedule I think it is better to move the responsibility to the router like:

updated

Also, could you please open an issue to persist the new format to ES along with the old rrule format?

Created issue

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Unknown metric groups

ESLint disabled line counts

id before after diff
@kbn/test-suites-xpack 723 725 +2

Total ESLint disabled count

id before after diff
@kbn/test-suites-xpack 749 751 +2

History

cc @js-jankisalvi

Copy link
Member

@cnasikas cnasikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

Copy link
Contributor

@adcoelho adcoelho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ship it 🎉

@js-jankisalvi js-jankisalvi enabled auto-merge (squash) March 13, 2025 14:55
@js-jankisalvi js-jankisalvi merged commit 14871c3 into elastic:main Mar 13, 2025
9 checks passed
@js-jankisalvi js-jankisalvi deleted the recuuring-schema branch March 13, 2025 15:03
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.x

https://github.com/elastic/kibana/actions/runs/13837846074

@kibanamachine
Copy link
Contributor

💔 All backports failed

Status Branch Result
8.x Backport failed because of merge conflicts

Manual backport

To create the backport manually run:

node scripts/backport --pr 210584

Questions ?

Please refer to the Backport tool documentation

@js-jankisalvi
Copy link
Contributor Author

💚 All backports created successfully

Status Branch Result
8.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

js-jankisalvi added a commit to js-jankisalvi/kibana that referenced this pull request Mar 14, 2025
… via API (elastic#210584)

## Summary

Resolves first part of elastic#198783
(snooze API)
Creates a public API for adding snooze schedule to rules.
For this purpose we created new schedule schema which will be used as
standard schedule schema across rules and alerting framework.

**Note**
The code to be reviewed for public API is under `common/routes/schedule`
and inside `external` folders.
Rest of the code is just moving existing internal API route and its code
to `/internal` folders.

### Checklist

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### How to test
- Create a rule in kibana
- Snooze that rule via new public API
```typescript
Path: https://localhost:5601/api/alerting/rule/<rule_id>/snooze_schedule
Method: POST
Body:
{
    "schedule": {
       "custom": {
         "start": "2025-02-25T18:00:00.000Z",
         "duration": "15m",
         "recurring": {
            "every": "1w",
            "onWeekDay": ["TU", "FR"],
            "occurrences": 10
         }
       }
    }
}
```
- Verify various snooze schedule scenarios are generated correctly

#### Flaky test runner:
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8009

### Release note
Allow users to create a snooze schedule for rule via API

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: lcawl <lcawley@elastic.co>
(cherry picked from commit 14871c3)

# Conflicts:
#	x-pack/platform/plugins/shared/alerting/tsconfig.json
#	x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/snooze.ts
@js-jankisalvi
Copy link
Contributor Author

💚 All backports created successfully

Status Branch Result
8.x

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

js-jankisalvi added a commit that referenced this pull request Mar 14, 2025
…r rule via API (#210584) (#214566)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps][Rules] Allow users to create a snooze schedule for rule
via API (#210584)](#210584)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Janki
Salvi","email":"117571355+js-jankisalvi@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-03-13T15:03:11Z","message":"[ResponseOps][Rules]
Allow users to create a snooze schedule for rule via API (#210584)\n\n##
Summary\n\nResolves first part of
https://github.com/elastic/kibana/issues/198783\n(snooze API)\nCreates a
public API for adding snooze schedule to rules.\nFor this purpose we
created new schedule schema which will be used as\nstandard schedule
schema across rules and alerting framework.\n\n**Note** \nThe code to be
reviewed for public API is under `common/routes/schedule`\nand inside
`external` folders.\nRest of the code is just moving existing internal
API route and its code\nto `/internal` folders.\n\n\n### Checklist\n\n-
[x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas
added for features that require explanation or tutorials\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n\n### How to
test\n- Create a rule in kibana\n- Snooze that rule via new public
API\n```typescript\nPath:
https://localhost:5601/api/alerting/rule/<rule_id>/snooze_schedule\nMethod:
POST\nBody: \n{\n \"schedule\": { \n \"custom\": {\n \"start\":
\"2025-02-25T18:00:00.000Z\",\n \"duration\": \"15m\",\n \"recurring\":
{\n \"every\": \"1w\",\n \"onWeekDay\": [\"TU\", \"FR\"],\n
\"occurrences\": 10\n }\n }\n }\n}\n``` \n- Verify various snooze
schedule scenarios are generated correctly\n\n#### Flaky test
runner:\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8009\n\n###
Release note\nAllow users to create a snooze schedule for rule via
API\n\n---------\n\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: lcawl
<lcawley@elastic.co>","sha":"14871c31aaeaacef22b3498343ec0f23b3c7d79f","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:enhancement","Team:ResponseOps","Feature:Alerting/RulesManagement","backport:version","v9.1.0","v8.19.0"],"title":"[ResponseOps][Rules]
Allow users to create a snooze schedule for rule via
API","number":210584,"url":"https://github.com/elastic/kibana/pull/210584","mergeCommit":{"message":"[ResponseOps][Rules]
Allow users to create a snooze schedule for rule via API (#210584)\n\n##
Summary\n\nResolves first part of
https://github.com/elastic/kibana/issues/198783\n(snooze API)\nCreates a
public API for adding snooze schedule to rules.\nFor this purpose we
created new schedule schema which will be used as\nstandard schedule
schema across rules and alerting framework.\n\n**Note** \nThe code to be
reviewed for public API is under `common/routes/schedule`\nand inside
`external` folders.\nRest of the code is just moving existing internal
API route and its code\nto `/internal` folders.\n\n\n### Checklist\n\n-
[x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas
added for features that require explanation or tutorials\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n\n### How to
test\n- Create a rule in kibana\n- Snooze that rule via new public
API\n```typescript\nPath:
https://localhost:5601/api/alerting/rule/<rule_id>/snooze_schedule\nMethod:
POST\nBody: \n{\n \"schedule\": { \n \"custom\": {\n \"start\":
\"2025-02-25T18:00:00.000Z\",\n \"duration\": \"15m\",\n \"recurring\":
{\n \"every\": \"1w\",\n \"onWeekDay\": [\"TU\", \"FR\"],\n
\"occurrences\": 10\n }\n }\n }\n}\n``` \n- Verify various snooze
schedule scenarios are generated correctly\n\n#### Flaky test
runner:\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8009\n\n###
Release note\nAllow users to create a snooze schedule for rule via
API\n\n---------\n\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: lcawl
<lcawley@elastic.co>","sha":"14871c31aaeaacef22b3498343ec0f23b3c7d79f"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/210584","number":210584,"mergeCommit":{"message":"[ResponseOps][Rules]
Allow users to create a snooze schedule for rule via API (#210584)\n\n##
Summary\n\nResolves first part of
https://github.com/elastic/kibana/issues/198783\n(snooze API)\nCreates a
public API for adding snooze schedule to rules.\nFor this purpose we
created new schedule schema which will be used as\nstandard schedule
schema across rules and alerting framework.\n\n**Note** \nThe code to be
reviewed for public API is under `common/routes/schedule`\nand inside
`external` folders.\nRest of the code is just moving existing internal
API route and its code\nto `/internal` folders.\n\n\n### Checklist\n\n-
[x]\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\nwas
added for features that require explanation or tutorials\n- [x] [Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common scenarios\n\n### How to
test\n- Create a rule in kibana\n- Snooze that rule via new public
API\n```typescript\nPath:
https://localhost:5601/api/alerting/rule/<rule_id>/snooze_schedule\nMethod:
POST\nBody: \n{\n \"schedule\": { \n \"custom\": {\n \"start\":
\"2025-02-25T18:00:00.000Z\",\n \"duration\": \"15m\",\n \"recurring\":
{\n \"every\": \"1w\",\n \"onWeekDay\": [\"TU\", \"FR\"],\n
\"occurrences\": 10\n }\n }\n }\n}\n``` \n- Verify various snooze
schedule scenarios are generated correctly\n\n#### Flaky test
runner:\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8009\n\n###
Release note\nAllow users to create a snooze schedule for rule via
API\n\n---------\n\nCo-authored-by: kibanamachine
<42973632+kibanamachine@users.noreply.github.com>\nCo-authored-by: lcawl
<lcawley@elastic.co>","sha":"14871c31aaeaacef22b3498343ec0f23b3c7d79f"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
CAWilson94 pushed a commit to CAWilson94/kibana that referenced this pull request Mar 22, 2025
… via API (elastic#210584)

## Summary

Resolves first part of elastic#198783
(snooze API)
Creates a public API for adding snooze schedule to rules.
For this purpose we created new schedule schema which will be used as
standard schedule schema across rules and alerting framework.

**Note** 
The code to be reviewed for public API is under `common/routes/schedule`
and inside `external` folders.
Rest of the code is just moving existing internal API route and its code
to `/internal` folders.


### Checklist

- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### How to test
- Create a rule in kibana
- Snooze that rule via new public API
```typescript
Path: https://localhost:5601/api/alerting/rule/<rule_id>/snooze_schedule
Method: POST
Body: 
{
    "schedule": { 
       "custom": {
         "start": "2025-02-25T18:00:00.000Z",
         "duration": "15m",
         "recurring": {
            "every": "1w",
            "onWeekDay": ["TU", "FR"],
            "occurrences": 10
         }
       }
    }
}
``` 
- Verify various snooze schedule scenarios are generated correctly

#### Flaky test runner:
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8009

### Release note
Allow users to create a snooze schedule for rule via API

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: lcawl <lcawley@elastic.co>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels Feature:Alerting/RulesManagement Issues related to the Rules Management UX release_note:enhancement Team:ResponseOps Platform ResponseOps team (formerly the Cases and Alerting teams) t// v8.19.0 v9.1.0

7 participants