Skip to content
Merged
1 change: 1 addition & 0 deletions x-pack/plugins/security_solution/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ export const NEW_FEATURES_TOUR_STORAGE_KEYS = {
export const RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY =
'securitySolution.ruleDetails.ruleExecutionLog.showMetrics.v8.2';

// TODO: https://github.com/elastic/kibana/pull/142950
/**
* Error codes that can be thrown during _bulk_action API dry_run call and be processed and displayed to end user
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
*/

import { BulkAction, BulkActionEditType } from './request_schema';
import type { PerformBulkActionSchema } from './request_schema';
import type { PerformBulkActionRequestBody } from './request_schema';

export const getPerformBulkActionSchemaMock = (): PerformBulkActionSchema => ({
export const getPerformBulkActionSchemaMock = (): PerformBulkActionRequestBody => ({
query: '',
ids: undefined,
action: BulkAction.disable,
});

export const getPerformBulkActionEditSchemaMock = (): PerformBulkActionSchema => ({
export const getPerformBulkActionEditSchemaMock = (): PerformBulkActionRequestBody => ({
query: '',
ids: undefined,
action: BulkAction.edit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@

import { left } from 'fp-ts/lib/Either';
import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils';

import type { PerformBulkActionSchema } from './request_schema';
import { performBulkActionSchema, BulkAction, BulkActionEditType } from './request_schema';
import { PerformBulkActionRequestBody, BulkAction, BulkActionEditType } from './request_schema';

const retrieveValidationMessage = (payload: unknown) => {
const decoded = performBulkActionSchema.decode(payload);
const decoded = PerformBulkActionRequestBody.decode(payload);
const checked = exactCheck(payload, decoded);
return foldLeftRight(checked);
};
Expand All @@ -21,7 +19,7 @@ describe('Perform bulk action request schema', () => {
describe('cases common to every bulk action', () => {
// missing query means it will request for all rules
test('valid request: missing query', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: undefined,
action: BulkAction.enable,
};
Expand All @@ -32,7 +30,7 @@ describe('Perform bulk action request schema', () => {
});

test('invalid request: missing action', () => {
const payload: Omit<PerformBulkActionSchema, 'action'> = {
const payload: Omit<PerformBulkActionRequestBody, 'action'> = {
query: 'name: test',
};
const message = retrieveValidationMessage(payload);
Expand All @@ -45,7 +43,7 @@ describe('Perform bulk action request schema', () => {
});

test('invalid request: unknown action', () => {
const payload: Omit<PerformBulkActionSchema, 'action'> & { action: 'unknown' } = {
const payload: Omit<PerformBulkActionRequestBody, 'action'> & { action: 'unknown' } = {
query: 'name: test',
action: 'unknown',
};
Expand Down Expand Up @@ -84,7 +82,7 @@ describe('Perform bulk action request schema', () => {

describe('bulk enable', () => {
test('valid request', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.enable,
};
Expand All @@ -96,7 +94,7 @@ describe('Perform bulk action request schema', () => {

describe('bulk disable', () => {
test('valid request', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.disable,
};
Expand All @@ -108,7 +106,7 @@ describe('Perform bulk action request schema', () => {

describe('bulk export', () => {
test('valid request', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.export,
};
Expand All @@ -120,7 +118,7 @@ describe('Perform bulk action request schema', () => {

describe('bulk delete', () => {
test('valid request', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.delete,
};
Expand All @@ -132,7 +130,7 @@ describe('Perform bulk action request schema', () => {

describe('bulk duplicate', () => {
test('valid request', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.duplicate,
};
Expand Down Expand Up @@ -268,7 +266,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: set_index_patterns edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [{ type: BulkActionEditType.set_index_patterns, value: ['logs-*'] }],
Expand All @@ -281,7 +279,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: add_index_patterns edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [{ type: BulkActionEditType.add_index_patterns, value: ['logs-*'] }],
Expand All @@ -294,7 +292,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: delete_index_patterns edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [
Expand Down Expand Up @@ -353,7 +351,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: set_timeline edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [
Expand Down Expand Up @@ -405,7 +403,7 @@ describe('Perform bulk action request schema', () => {
},
},
],
} as PerformBulkActionSchema;
} as PerformBulkActionRequestBody;

const message = retrieveValidationMessage(payload);

Expand All @@ -431,7 +429,7 @@ describe('Perform bulk action request schema', () => {
},
},
],
} as PerformBulkActionSchema;
} as PerformBulkActionRequestBody;

const message = retrieveValidationMessage(payload);

Expand All @@ -457,7 +455,7 @@ describe('Perform bulk action request schema', () => {
},
},
],
} as PerformBulkActionSchema;
} as PerformBulkActionRequestBody;

const message = retrieveValidationMessage(payload);

Expand All @@ -472,7 +470,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: set_schedule edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [
Expand All @@ -484,7 +482,7 @@ describe('Perform bulk action request schema', () => {
},
},
],
} as PerformBulkActionSchema;
} as PerformBulkActionRequestBody;

const message = retrieveValidationMessage(payload);

Expand Down Expand Up @@ -587,7 +585,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: add_rule_actions edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [
Expand Down Expand Up @@ -618,7 +616,7 @@ describe('Perform bulk action request schema', () => {
});

test('valid request: set_rule_actions edit action', () => {
const payload: PerformBulkActionSchema = {
const payload: PerformBulkActionRequestBody = {
query: 'name: test',
action: BulkAction.edit,
[BulkAction.edit]: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export enum BulkActionEditType {
'set_schedule' = 'set_schedule',
}

export const throttleForBulkActions = t.union([
export type ThrottleForBulkActions = t.TypeOf<typeof ThrottleForBulkActions>;
export const ThrottleForBulkActions = t.union([
t.literal('rule'),
TimeDuration({
allowedDurations: [
Expand All @@ -56,9 +57,9 @@ export const throttleForBulkActions = t.union([
],
}),
]);
export type ThrottleForBulkActions = t.TypeOf<typeof throttleForBulkActions>;

const bulkActionEditPayloadTags = t.type({
type BulkActionEditPayloadTags = t.TypeOf<typeof BulkActionEditPayloadTags>;
const BulkActionEditPayloadTags = t.type({
type: t.union([
t.literal(BulkActionEditType.add_tags),
t.literal(BulkActionEditType.delete_tags),
Expand All @@ -67,9 +68,8 @@ const bulkActionEditPayloadTags = t.type({
value: RuleTagArray,
});

export type BulkActionEditPayloadTags = t.TypeOf<typeof bulkActionEditPayloadTags>;

const bulkActionEditPayloadIndexPatterns = t.intersection([
type BulkActionEditPayloadIndexPatterns = t.TypeOf<typeof BulkActionEditPayloadIndexPatterns>;
const BulkActionEditPayloadIndexPatterns = t.intersection([
t.type({
type: t.union([
t.literal(BulkActionEditType.add_index_patterns),
Expand All @@ -81,63 +81,57 @@ const bulkActionEditPayloadIndexPatterns = t.intersection([
t.exact(t.partial({ overwrite_data_views: t.boolean })),
]);

export type BulkActionEditPayloadIndexPatterns = t.TypeOf<
typeof bulkActionEditPayloadIndexPatterns
>;

const bulkActionEditPayloadTimeline = t.type({
type BulkActionEditPayloadTimeline = t.TypeOf<typeof BulkActionEditPayloadTimeline>;
const BulkActionEditPayloadTimeline = t.type({
type: t.literal(BulkActionEditType.set_timeline),
value: t.type({
timeline_id: TimelineTemplateId,
timeline_title: TimelineTemplateTitle,
}),
});

export type BulkActionEditPayloadTimeline = t.TypeOf<typeof bulkActionEditPayloadTimeline>;

/**
* per rulesClient.bulkEdit rules actions operation contract (x-pack/plugins/alerting/server/rules_client/rules_client.ts)
* normalized rule action object is expected (NormalizedAlertAction) as value for the edit operation
*/
const normalizedRuleAction = t.exact(
type NormalizedRuleAction = t.TypeOf<typeof NormalizedRuleAction>;
const NormalizedRuleAction = t.exact(
t.type({
group: RuleActionGroup,
id: RuleActionId,
params: RuleActionParams,
})
);

const bulkActionEditPayloadRuleActions = t.type({
export type BulkActionEditPayloadRuleActions = t.TypeOf<typeof BulkActionEditPayloadRuleActions>;
export const BulkActionEditPayloadRuleActions = t.type({
type: t.union([
t.literal(BulkActionEditType.add_rule_actions),
t.literal(BulkActionEditType.set_rule_actions),
]),
value: t.type({
throttle: throttleForBulkActions,
actions: t.array(normalizedRuleAction),
throttle: ThrottleForBulkActions,
actions: t.array(NormalizedRuleAction),
}),
});

export type BulkActionEditPayloadRuleActions = t.TypeOf<typeof bulkActionEditPayloadRuleActions>;

const bulkActionEditPayloadSchedule = t.type({
export type BulkActionEditPayloadSchedule = t.TypeOf<typeof BulkActionEditPayloadSchedule>;
export const BulkActionEditPayloadSchedule = t.type({
type: t.literal(BulkActionEditType.set_schedule),
value: t.type({
interval: TimeDuration({ allowedUnits: ['s', 'm', 'h'] }),
lookback: TimeDuration({ allowedUnits: ['s', 'm', 'h'] }),
}),
});
export type BulkActionEditPayloadSchedule = t.TypeOf<typeof bulkActionEditPayloadSchedule>;

export const bulkActionEditPayload = t.union([
bulkActionEditPayloadTags,
bulkActionEditPayloadIndexPatterns,
bulkActionEditPayloadTimeline,
bulkActionEditPayloadRuleActions,
bulkActionEditPayloadSchedule,
]);

export type BulkActionEditPayload = t.TypeOf<typeof bulkActionEditPayload>;
export type BulkActionEditPayload = t.TypeOf<typeof BulkActionEditPayload>;
export const BulkActionEditPayload = t.union([
BulkActionEditPayloadTags,
BulkActionEditPayloadIndexPatterns,
BulkActionEditPayloadTimeline,
BulkActionEditPayloadRuleActions,
BulkActionEditPayloadSchedule,
]);

/**
* actions that modify rules attributes
Expand All @@ -155,7 +149,11 @@ export type BulkActionEditForRuleParams =
| BulkActionEditPayloadTimeline
| BulkActionEditPayloadSchedule;

export const performBulkActionSchema = t.intersection([
/**
* Request body parameters of the API route.
*/
export type PerformBulkActionRequestBody = t.TypeOf<typeof PerformBulkActionRequestBody>;
export const PerformBulkActionRequestBody = t.intersection([
t.exact(
t.type({
query: t.union([RuleQuery, t.undefined]),
Expand All @@ -177,16 +175,18 @@ export const performBulkActionSchema = t.intersection([
t.exact(
t.type({
action: t.literal(BulkAction.edit),
[BulkAction.edit]: NonEmptyArray(bulkActionEditPayload),
[BulkAction.edit]: NonEmptyArray(BulkActionEditPayload),
})
),
]),
]);

export const performBulkActionQuerySchema = t.exact(
/**
* Query string parameters of the API route.
*/
export type PerformBulkActionRequestQuery = t.TypeOf<typeof PerformBulkActionRequestQuery>;
export const PerformBulkActionRequestQuery = t.exact(
t.partial({
dry_run: t.union([t.literal('true'), t.literal('false')]),
})
);

export type PerformBulkActionSchema = t.TypeOf<typeof performBulkActionSchema>;
Loading