Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RAM] Window Maintenance Client/Saved Object and Mapping/REST APIs #153411

Merged
merged 26 commits into from
Apr 13, 2023

Conversation

JiaweiWu
Copy link
Contributor

@JiaweiWu JiaweiWu commented Mar 21, 2023

Summary

Resolves: #152270
Specs: https://docs.google.com/document/u/1/d/1-QblF6P19W9o5-10Us3bfgN80GRfjSIhybHrvJS_ObA/edit

This PR implements the following:

  • New maintenance window SO
  • New maintenance window client in the alerting plugin (generates and queries maintenance window events, and other CRUD functionality around the SO)
  • New maintenance window REST APIs
  • Kibana privileges for reading/writing maintenance window

This PR does not include integration with task runner, a new PR will be created to do that work.

APIs:

Find all maintenance windows in current space
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/_find`
body: {}
Create maintenance window:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window`
body: {
  title: string,
  duration: number,
  r_rule: RRule
}
Update maintenance window by ID:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}`,
body: {
  title?: string,
  duration?: number,
  enabled?: boolean,
  r_rule?: RRule,
}
Get maintenance window by ID:
GET `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}`,
Delete maintenance window by ID:
DELETE `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}`,
Archive maintenance window by ID:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}/_archive`,
body: {
  archive: boolean
}
Finish maintenance window by ID:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}/_finish`,

Maintenance window response schema:

{
  id: string;
  title: string;
  enabled: boolean;
  duration: number;
  expirationDate: string;
  events: DateRange[];
  rRule: RRuleParams;
  status: 'running' | 'upcoming' | 'finished' | 'archived';
  startDate: string | null;
  endDate: string | null;
  createdBy: string | null;
  updatedBy: string | null;
  createdAt: string;
  updatedAt: string;
}

@JiaweiWu JiaweiWu changed the title Issue 152270 window maintenance so/mapping/API [RAM] Window Maintenance SO/mapping/REST API Mar 22, 2023
@JiaweiWu JiaweiWu changed the title [RAM] Window Maintenance SO/mapping/REST API [RAM] Window Maintenance client/saved object/mapping/REST APIs Mar 27, 2023
@JiaweiWu JiaweiWu changed the title [RAM] Window Maintenance client/saved object/mapping/REST APIs [RAM] Window Maintenance Client/Saved Object and Mapping/REST APIs Mar 27, 2023
@JiaweiWu JiaweiWu added release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) Feature:Alerting/RulesManagement Issues related to the Rules Management UX v8.8.0 labels Mar 27, 2023
@JiaweiWu JiaweiWu marked this pull request as ready for review March 27, 2023 17:23
@JiaweiWu JiaweiWu requested review from a team as code owners March 27, 2023 17:23
@elasticmachine
Copy link
Contributor

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

@JiaweiWu
Copy link
Contributor Author

@elasticmachine merge upstream

Copy link
Contributor

@doakalexi doakalexi left a comment

Choose a reason for hiding this comment

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

LGTM!

Comment on lines 44 to 45
startDate: string | null;
endDate: string | null;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have these start and end dates that map to:
image

The dates indicate the start and end date of the current or upcoming EVENT, not the start and end date of the entire maintenance window schedule, should I name these something like eventStartDate instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

eventStartDate sounds good to me, I agree that start and end date could be confusing

@JiaweiWu JiaweiWu requested a review from a team as a code owner April 3, 2023 22:03
@JiaweiWu
Copy link
Contributor Author

JiaweiWu commented Apr 3, 2023

@elasticmachine merge upstream

Copy link
Contributor

@jeramysoucy jeramysoucy left a comment

Choose a reason for hiding this comment

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

Looks good from our perspective! Thanks for making the SO namespace type change!

savedObjects.registerType({
name: MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE,
hidden: true,
namespaceType: 'multiple-isolated',
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@JiaweiWu
Copy link
Contributor Author

@elasticmachine merge upstream

@JiaweiWu
Copy link
Contributor Author

@elasticmachine merge upstream

}

// Returns the most recent/relevant event and the status for a maintenance window
export const getMaintenanceWindowDateAndStatus = ({
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like this function is not used any where, is that correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's being used in getMaintenanceWindowFromRaw, basically we use this helper to decorate the maintenance window SO with the current status, the event_start/end_dates when returned by the API, kind of similar to getAlertFromRaw

});

if (!shouldRegenerateEvents({ maintenanceWindow: attributes, rRule, duration })) {
events = mergeEvents({ oldEvents: attributes.events, newEvents: events });
Copy link
Contributor

@XavierM XavierM Apr 13, 2023

Choose a reason for hiding this comment

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

am I thinking about it to simplistic here? but why can we just trust the new events and delete the old events. I imagine that the new events will have duplicate.

Copy link
Contributor Author

@JiaweiWu JiaweiWu Apr 13, 2023

Choose a reason for hiding this comment

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

The main reason is to make sure we do not overwrite events that have been finished early. When we finish an event, we modify that event entry's end date to be now, but if we edit the rule and just regenerate everything, it would overwrite that finished event and would go back to being running.

The more robust way of doing this is to keep another array of modified events (I think google calendar does this). But obviously, it's more work, modifying 1 event works fine for now, we just need to be careful when we regenerate the event array.

Copy link
Contributor Author

@JiaweiWu JiaweiWu Apr 13, 2023

Choose a reason for hiding this comment

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

Like discussed, I will do a filter for modified events in the old event array, and replace the new event array with the modified old event.

import { SavedObjectsTypeMappingDefinition } from '@kbn/core/server';
import { rRuleMappingsField } from './rrule_mappings_field';

export const maintenanceWindowMappings: SavedObjectsTypeMappingDefinition = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's go over together but I do not think that we need add this attributes to be indexed, only the one we are going to have sort/filter/search on it. Since we are going to do all this feature in memory of the UI, I do not think that we need anything. what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea sounds good to me, I'm not sure how indexing works behind the scenes, but if we need to index it again, can we add it back to the mapping?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will remove the explicit mappings for all fields except for events and enabled since we filter on those.

MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE,
} from '../common';

export const maintenanceWindowFeature: KibanaFeatureConfig = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nicely done!

import { createValidateRruleBy } from '../../lib/validate_rrule_by';
import { validateSnoozeStartDate, validateSnoozeEndDate } from '../../lib/validate_snooze_date';

export const rRuleSchema = schema.object({
Copy link
Contributor

Choose a reason for hiding this comment

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

That's great to have!

context: MaintenanceWindowClientContext,
params: ArchiveParams
): Promise<MaintenanceWindow> {
return await retryIfConflicts(
Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering if we really need to do that or just use the saved object options retryOnConflict. They already doing it for us what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we can specify retryOnConflict for update calls on the savedObjectClient when version is defined.

@JiaweiWu
Copy link
Contributor Author

In the last commit d65b6a9, I made the following changes:

  • Remove 'filter' parameter for the find endpoint, changed the HTTP route from a POST to GET
  • Modified mergeEvent function to merge only modified events
  • Changed maintenance window mapping by removing most of the properties that we do not sort/filter on
  • Move maintenance window routes to its own folder
  • Update any associated tests

Copy link
Contributor

@XavierM XavierM left a comment

Choose a reason for hiding this comment

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

Code looks good and working as expected. Please create an issue tech debt to bring back all the maintenance window files under one folder alerting/server/maintenance_window

Awesome work here!!!

@JiaweiWu
Copy link
Contributor Author

@elasticmachine merge upstream

@JiaweiWu JiaweiWu enabled auto-merge (squash) April 13, 2023 18:14
@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] x-pack/test/functional/apps/lens/group3/config.ts / lens app - group 3 lens no data adds a new data view when no data views
  • [job] [logs] x-pack/test/functional/apps/lens/group3/config.ts / lens app - group 3 lens no data when no data opens integrations
  • [job] [logs] x-pack/test/functional/apps/lens/group3/config.ts / lens app - group 3 lens reporting "after all" hook for "should not cause PDF reports to fail"
  • [job] [logs] x-pack/test/functional/apps/lens/group3/config.ts / lens app - group 3 lens rollup tests should allow creation of lens xy chart
  • [job] [logs] x-pack/test/functional/apps/lens/group3/config.ts / lens app - group 3 lens rollup tests should allow seamless transition to and from table view
  • [job] [logs] x-pack/test/functional/apps/lens/group3/config.ts / lens app - group 3 lens rollup tests should allow to switch from regular index to rollup index retaining config

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
alerting 35 37 +2

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
alerting 550 579 +29

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
alerting 41 42 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
alerting 44.6KB 45.1KB +535.0B

Saved Objects .kibana field count

Every field in each saved object type adds overhead to Elasticsearch. Kibana needs to keep the total field count below Elasticsearch's default limit of 1000 fields. Only specify field mappings for the fields you wish to search on or query. See https://www.elastic.co/guide/en/kibana/master/saved-objects-service.html#_mappings

id before after diff
maintenance-window - 3 +3
Unknown metric groups

API count

id before after diff
alerting 571 600 +29

ESLint disabled line counts

id before after diff
securitySolution 432 435 +3

Total ESLint disabled count

id before after diff
securitySolution 512 515 +3

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@JiaweiWu JiaweiWu merged commit 3b07f96 into elastic:main Apr 13, 2023
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Apr 13, 2023
saarikabhasi pushed a commit to saarikabhasi/kibana that referenced this pull request Apr 19, 2023
…lastic#153411)

## Summary
Resolves: elastic#152270
Specs:
https://docs.google.com/document/u/1/d/1-QblF6P19W9o5-10Us3bfgN80GRfjSIhybHrvJS_ObA/edit

This PR implements the following:
- New maintenance window SO
- New maintenance window client in the alerting plugin (generates and
queries maintenance window events, and other CRUD functionality around
the SO)
- New maintenance window REST APIs 
- Kibana privileges for reading/writing maintenance window

This PR does not include integration with task runner, a new PR will be
created to do that work.
 
## APIs:

```
Find all maintenance windows in current space
GET `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/_find`
body: {}
```

```
Create maintenance window:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window`
body: {
  title: string,
  duration: number,
  r_rule: RRule
}
```

```
Update maintenance window by ID:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}`,
body: {
  title?: string,
  duration?: number,
  enabled?: boolean,
  r_rule?: RRule,
}
```

```
Get maintenance window by ID:
GET `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}`,
```

```
Delete maintenance window by ID:
DELETE `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}`,
```

```
Archive maintenance window by ID:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}/_archive`,
body: {
  archive: boolean
}
```

```
Finish maintenance window by ID:
POST `${INTERNAL_BASE_ALERTING_API_PATH}/rules/maintenance_window/{id}/_finish`,
```


## Maintenance window response schema:
```
{
  id: string;
  title: string;
  enabled: boolean;
  duration: number;
  expirationDate: string;
  events: DateRange[];
  rRule: RRuleParams;
  status: 'running' | 'upcoming' | 'finished' | 'archived';
  startDate: string | null;
  endDate: string | null;
  createdBy: string | null;
  updatedBy: string | null;
  createdAt: string;
  updatedAt: string;
}
```

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
JiaweiWu added a commit that referenced this pull request Apr 19, 2023
…Fields (#154761)

## Summary

Resolves: #153468
Maintenance window API PR: #153411

This PR does the following: 
- Skip alert notifications for rules in maintenance
- Add `maintenance_window_ids` field to alert events in the event log
- Add `maintenance_window_ids` attribute to AAD

### Checklist
- [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

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
nikitaindik pushed a commit to nikitaindik/kibana that referenced this pull request Apr 25, 2023
…Fields (elastic#154761)

## Summary

Resolves: elastic#153468
Maintenance window API PR: elastic#153411

This PR does the following: 
- Skip alert notifications for rules in maintenance
- Add `maintenance_window_ids` field to alert events in the event log
- Add `maintenance_window_ids` attribute to AAD

### Checklist
- [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

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Alerting/RulesManagement Issues related to the Rules Management UX release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RAM] Window Maintenance - Create alerting client and saved object mapping
9 participants