-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution][Detections] Add Bulk Scheduling for rules (#140166)
Addresses [#2127](https://github.com/elastic/security-team/issues/2172) (internal) ## Summary Adds feature to bulk edit schedule of rules (interval -runs every- and lookback time) https://user-images.githubusercontent.com/5354282/188846852-8bcb128a-db02-4a81-9fc8-3029a97965c2.mov ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [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 - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- Loading branch information
Showing
24 changed files
with
763 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
packages/kbn-securitysolution-io-ts-types/src/time_duration/index.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { pipe } from 'fp-ts/lib/pipeable'; | ||
import { left } from 'fp-ts/lib/Either'; | ||
import { TimeDuration } from '.'; | ||
import { foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; | ||
|
||
describe('time_unit', () => { | ||
test('it should validate a correctly formed TimeDuration with time unit of seconds', () => { | ||
const payload = '1s'; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([]); | ||
expect(message.schema).toEqual(payload); | ||
}); | ||
|
||
test('it should validate a correctly formed TimeDuration with time unit of minutes', () => { | ||
const payload = '100m'; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([]); | ||
expect(message.schema).toEqual(payload); | ||
}); | ||
|
||
test('it should validate a correctly formed TimeDuration with time unit of hours', () => { | ||
const payload = '10000000h'; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([]); | ||
expect(message.schema).toEqual(payload); | ||
}); | ||
|
||
test('it should NOT validate a negative TimeDuration', () => { | ||
const payload = '-10s'; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([ | ||
'Invalid value "-10s" supplied to "TimeDuration"', | ||
]); | ||
expect(message.schema).toEqual({}); | ||
}); | ||
|
||
test('it should NOT validate a TimeDuration with some other time unit', () => { | ||
const payload = '10000000w'; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([ | ||
'Invalid value "10000000w" supplied to "TimeDuration"', | ||
]); | ||
expect(message.schema).toEqual({}); | ||
}); | ||
|
||
test('it should NOT validate a TimeDuration with a time interval with incorrect format', () => { | ||
const payload = '100ff0000w'; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([ | ||
'Invalid value "100ff0000w" supplied to "TimeDuration"', | ||
]); | ||
expect(message.schema).toEqual({}); | ||
}); | ||
|
||
test('it should NOT validate an empty string', () => { | ||
const payload = ''; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "TimeDuration"']); | ||
expect(message.schema).toEqual({}); | ||
}); | ||
|
||
test('it should NOT validate an number', () => { | ||
const payload = 100; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([ | ||
'Invalid value "100" supplied to "TimeDuration"', | ||
]); | ||
expect(message.schema).toEqual({}); | ||
}); | ||
|
||
test('it should NOT validate an TimeDuration with a valid time unit but unsafe integer', () => { | ||
const payload = `${Math.pow(2, 53)}h`; | ||
const decoded = TimeDuration.decode(payload); | ||
const message = pipe(decoded, foldLeftRight); | ||
|
||
expect(getPaths(left(message.errors))).toEqual([ | ||
`Invalid value "${Math.pow(2, 53)}h" supplied to "TimeDuration"`, | ||
]); | ||
expect(message.schema).toEqual({}); | ||
}); | ||
}); |
45 changes: 45 additions & 0 deletions
45
packages/kbn-securitysolution-io-ts-types/src/time_duration/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import * as t from 'io-ts'; | ||
import { Either } from 'fp-ts/lib/Either'; | ||
|
||
/** | ||
* Types the TimeDuration as: | ||
* - A string that is not empty, and composed of a positive integer greater than 0 followed by a unit of time | ||
* - in the format {safe_integer}{timeUnit}, e.g. "30s", "1m", "2h" | ||
*/ | ||
export const TimeDuration = new t.Type<string, string, unknown>( | ||
'TimeDuration', | ||
t.string.is, | ||
(input, context): Either<t.Errors, string> => { | ||
if (typeof input === 'string' && input.trim() !== '') { | ||
try { | ||
const inputLength = input.length; | ||
const time = parseInt(input.trim().substring(0, inputLength - 1), 10); | ||
const unit = input.trim().at(-1); | ||
if ( | ||
time >= 1 && | ||
Number.isSafeInteger(time) && | ||
(unit === 's' || unit === 'm' || unit === 'h') | ||
) { | ||
return t.success(input); | ||
} else { | ||
return t.failure(input, context); | ||
} | ||
} catch (error) { | ||
return t.failure(input, context); | ||
} | ||
} else { | ||
return t.failure(input, context); | ||
} | ||
}, | ||
t.identity | ||
); | ||
|
||
export type TimeDurationC = typeof TimeDuration; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.