mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution][Bulk actions]- Fix bulk actions data views behavior (#138448)
## Summary Addresses [bug](https://github.com/elastic/kibana/issues/138383) found where even when `overwrite_data_views` was false, the rule's `index` property was being modified. Please see added integration tests to understand desired behavior of changes. There is one edge case which is a bit weird, but I think too late to address in 8.4. If a user uses bulk delete on a rule with a data view and _no_ index patterns defined and `overwrite_data_views = true`, both data view and index will be set to `undefined`. Per our current behavior, a rule with no data source defaults to using the default index patterns. Not sure this is ideal, but it is in line with the behavior that already exists for a rule.
This commit is contained in:
parent
f41fbcda3f
commit
9e8b5b9784
3 changed files with 305 additions and 72 deletions
|
@ -127,6 +127,36 @@ describe('ruleParamsModifier', () => {
|
|||
expect(editedRuleParams).toHaveProperty('dataViewId', undefined);
|
||||
});
|
||||
|
||||
test('should set dataViewId to undefined if overwrite_data_views=true on delete_index_patterns action', () => {
|
||||
const editedRuleParams = ruleParamsModifier(
|
||||
{ dataViewId: 'test-data-view', index: ['test-*', 'index'] } as RuleAlertType['params'],
|
||||
[
|
||||
{
|
||||
type: BulkActionEditType.delete_index_patterns,
|
||||
value: ['index'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
]
|
||||
);
|
||||
expect(editedRuleParams).toHaveProperty('dataViewId', undefined);
|
||||
expect(editedRuleParams).toHaveProperty('index', ['test-*']);
|
||||
});
|
||||
|
||||
test('should set dataViewId to undefined and index to undefined if overwrite_data_views=true on delete_index_patterns action and rule had no index patterns to begin with', () => {
|
||||
const editedRuleParams = ruleParamsModifier(
|
||||
{ dataViewId: 'test-data-view', index: undefined } as RuleAlertType['params'],
|
||||
[
|
||||
{
|
||||
type: BulkActionEditType.delete_index_patterns,
|
||||
value: ['index'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
]
|
||||
);
|
||||
expect(editedRuleParams).toHaveProperty('dataViewId', undefined);
|
||||
expect(editedRuleParams).toHaveProperty('index', undefined);
|
||||
});
|
||||
|
||||
test('should throw error on adding index pattern if rule is of machine learning type', () => {
|
||||
expect(() =>
|
||||
ruleParamsModifier({ type: 'machine_learning' } as RuleAlertType['params'], [
|
||||
|
|
|
@ -35,6 +35,10 @@ const applyBulkActionEditToRuleParams = (
|
|||
"Index patterns can't be added. Machine learning rule doesn't have index patterns property"
|
||||
);
|
||||
|
||||
if (ruleParams.dataViewId != null && !action.overwrite_data_views) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (action.overwrite_data_views) {
|
||||
ruleParams.dataViewId = undefined;
|
||||
}
|
||||
|
@ -48,6 +52,14 @@ const applyBulkActionEditToRuleParams = (
|
|||
"Index patterns can't be deleted. Machine learning rule doesn't have index patterns property"
|
||||
);
|
||||
|
||||
if (ruleParams.dataViewId != null && !action.overwrite_data_views) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (action.overwrite_data_views) {
|
||||
ruleParams.dataViewId = undefined;
|
||||
}
|
||||
|
||||
if (ruleParams.index) {
|
||||
ruleParams.index = deleteItemsFromArray(ruleParams.index, action.value);
|
||||
}
|
||||
|
@ -59,6 +71,10 @@ const applyBulkActionEditToRuleParams = (
|
|||
"Index patterns can't be overwritten. Machine learning rule doesn't have index patterns property"
|
||||
);
|
||||
|
||||
if (ruleParams.dataViewId != null && !action.overwrite_data_views) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (action.overwrite_data_views) {
|
||||
ruleParams.dataViewId = undefined;
|
||||
}
|
||||
|
|
|
@ -562,78 +562,6 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
expect(deleteIndexRule.index).to.eql(['initial-index-*', 'index2-*']);
|
||||
});
|
||||
|
||||
it('should add an index pattern to a rule and overwrite the data view', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const dataViewId = 'index1-*';
|
||||
const simpleRule = {
|
||||
...getSimpleRule(ruleId),
|
||||
index: undefined,
|
||||
data_view_id: dataViewId,
|
||||
};
|
||||
await createRule(supertest, log, simpleRule);
|
||||
|
||||
const { body: setIndexBody } = await postBulkAction()
|
||||
.send({
|
||||
query: '',
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.add_index_patterns,
|
||||
value: ['initial-index-*'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(setIndexBody.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(setIndexBody.attributes.results.updated[0].index).to.eql(['initial-index-*']);
|
||||
expect(setIndexBody.attributes.results.updated[0].data_view_id).to.eql(undefined);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(['initial-index-*']);
|
||||
});
|
||||
|
||||
it('should not delete data view in a rule when delete index pattern action applied', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const dataViewId = 'index1-*';
|
||||
const simpleRule = {
|
||||
...getSimpleRule(ruleId),
|
||||
index: undefined,
|
||||
data_view_id: dataViewId,
|
||||
};
|
||||
await createRule(supertest, log, simpleRule);
|
||||
|
||||
const { body: bulkActionResponse } = await postBulkAction()
|
||||
.send({
|
||||
query: '',
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.delete_index_patterns,
|
||||
value: ['initial-index-*'],
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(bulkActionResponse.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(bulkActionResponse.attributes.results.updated[0].data_view_id).to.be(dataViewId);
|
||||
expect(bulkActionResponse.attributes.results.updated[0].index).to.be(undefined);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: updatedRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(updatedRule.data_view_id).to.be(dataViewId);
|
||||
expect(updatedRule.index).to.be(undefined);
|
||||
});
|
||||
|
||||
it('should set timeline values in rule', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const timelineId = '91832785-286d-4ebe-b884-1a208d111a70';
|
||||
|
@ -835,6 +763,265 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('overwrite_data_views', () => {
|
||||
it('should add an index pattern to a rule and overwrite the data view when overwrite_data_views is true', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const dataViewId = 'index1-*';
|
||||
const simpleRule = {
|
||||
...getSimpleRule(ruleId),
|
||||
index: undefined,
|
||||
data_view_id: dataViewId,
|
||||
};
|
||||
await createRule(supertest, log, simpleRule);
|
||||
|
||||
const { body: setIndexBody } = await postBulkAction()
|
||||
.send({
|
||||
query: '',
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.add_index_patterns,
|
||||
value: ['initial-index-*'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(setIndexBody.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(setIndexBody.attributes.results.updated[0].index).to.eql(['initial-index-*']);
|
||||
expect(setIndexBody.attributes.results.updated[0].data_view_id).to.eql(undefined);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(['initial-index-*']);
|
||||
});
|
||||
|
||||
it('should NOT add an index pattern to a rule and overwrite the data view when overwrite_data_views is false', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const dataViewId = 'index1-*';
|
||||
const simpleRule = {
|
||||
...getSimpleRule(ruleId),
|
||||
index: undefined,
|
||||
data_view_id: dataViewId,
|
||||
};
|
||||
await createRule(supertest, log, simpleRule);
|
||||
|
||||
const { body: setIndexBody } = await postBulkAction()
|
||||
.send({
|
||||
query: '',
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.add_index_patterns,
|
||||
value: ['initial-index-*'],
|
||||
overwrite_data_views: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(setIndexBody.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(setIndexBody.attributes.results.updated[0].index).to.eql(undefined);
|
||||
expect(setIndexBody.attributes.results.updated[0].data_view_id).to.eql(dataViewId);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(undefined);
|
||||
expect(setIndexRule.data_view_id).to.eql(dataViewId);
|
||||
});
|
||||
|
||||
it('should set an index pattern to a rule and overwrite the data view when overwrite_data_views is true', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const dataViewId = 'index1-*';
|
||||
const simpleRule = {
|
||||
...getSimpleRule(ruleId),
|
||||
index: undefined,
|
||||
data_view_id: dataViewId,
|
||||
};
|
||||
await createRule(supertest, log, simpleRule);
|
||||
|
||||
const { body: setIndexBody } = await postBulkAction()
|
||||
.send({
|
||||
query: '',
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.set_index_patterns,
|
||||
value: ['initial-index-*'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(setIndexBody.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(setIndexBody.attributes.results.updated[0].index).to.eql(['initial-index-*']);
|
||||
expect(setIndexBody.attributes.results.updated[0].data_view_id).to.eql(undefined);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(['initial-index-*']);
|
||||
expect(setIndexRule.data_view_id).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('should NOT set an index pattern to a rule and overwrite the data view when overwrite_data_views is false', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const dataViewId = 'index1-*';
|
||||
const simpleRule = {
|
||||
...getSimpleRule(ruleId),
|
||||
index: undefined,
|
||||
data_view_id: dataViewId,
|
||||
};
|
||||
await createRule(supertest, log, simpleRule);
|
||||
|
||||
const { body: setIndexBody } = await postBulkAction()
|
||||
.send({
|
||||
query: '',
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.set_index_patterns,
|
||||
value: ['initial-index-*'],
|
||||
overwrite_data_views: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(setIndexBody.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(setIndexBody.attributes.results.updated[0].index).to.eql(undefined);
|
||||
expect(setIndexBody.attributes.results.updated[0].data_view_id).to.eql(dataViewId);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(undefined);
|
||||
expect(setIndexRule.data_view_id).to.eql(dataViewId);
|
||||
});
|
||||
|
||||
// This rule will now not have a source defined - as has been the behavior of rules since the beginning
|
||||
// this rule will use the default index patterns on rule run
|
||||
it('should NOT error if all index patterns removed from a rule with data views when no index patterns exist on the rule and overwrite_data_views is true', async () => {
|
||||
const dataViewId = 'index1-*';
|
||||
const ruleId = 'ruleId';
|
||||
const rule = await createRule(supertest, log, {
|
||||
...getSimpleRule(ruleId),
|
||||
data_view_id: dataViewId,
|
||||
index: undefined,
|
||||
});
|
||||
|
||||
const { body } = await postBulkAction()
|
||||
.send({
|
||||
ids: [rule.id],
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.delete_index_patterns,
|
||||
value: ['simple-index-*'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(body.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(body.attributes.results.updated[0].index).to.eql(undefined);
|
||||
expect(body.attributes.results.updated[0].data_view_id).to.eql(undefined);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(undefined);
|
||||
expect(setIndexRule.data_view_id).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('should return error if all index patterns removed from a rule with data views and overwrite_data_views is true', async () => {
|
||||
const dataViewId = 'index1-*';
|
||||
const ruleId = 'ruleId';
|
||||
const rule = await createRule(supertest, log, {
|
||||
...getSimpleRule(ruleId),
|
||||
data_view_id: dataViewId,
|
||||
index: ['simple-index-*'],
|
||||
});
|
||||
|
||||
const { body } = await postBulkAction()
|
||||
.send({
|
||||
ids: [rule.id],
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.delete_index_patterns,
|
||||
value: ['simple-index-*'],
|
||||
overwrite_data_views: true,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(500);
|
||||
|
||||
expect(body.attributes.summary).to.eql({ failed: 1, succeeded: 0, total: 1 });
|
||||
expect(body.attributes.errors[0]).to.eql({
|
||||
message: "Mutated params invalid: Index patterns can't be empty",
|
||||
status_code: 500,
|
||||
rules: [
|
||||
{
|
||||
id: rule.id,
|
||||
name: rule.name,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should NOT return error if all index patterns removed from a rule with data views and overwrite_data_views is false', async () => {
|
||||
const dataViewId = 'index1-*';
|
||||
const ruleId = 'ruleId';
|
||||
const rule = await createRule(supertest, log, {
|
||||
...getSimpleRule(ruleId),
|
||||
data_view_id: dataViewId,
|
||||
index: ['simple-index-*'],
|
||||
});
|
||||
|
||||
const { body } = await postBulkAction()
|
||||
.send({
|
||||
ids: [rule.id],
|
||||
action: BulkAction.edit,
|
||||
[BulkAction.edit]: [
|
||||
{
|
||||
type: BulkActionEditType.delete_index_patterns,
|
||||
value: ['simple-index-*'],
|
||||
overwrite_data_views: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(body.attributes.summary).to.eql({ failed: 0, succeeded: 1, total: 1 });
|
||||
|
||||
// Check that the updated rule is returned with the response
|
||||
expect(body.attributes.results.updated[0].index).to.eql(['simple-index-*']);
|
||||
expect(body.attributes.results.updated[0].data_view_id).to.eql(dataViewId);
|
||||
|
||||
// Check that the updates have been persisted
|
||||
const { body: setIndexRule } = await fetchRule(ruleId).expect(200);
|
||||
|
||||
expect(setIndexRule.index).to.eql(['simple-index-*']);
|
||||
expect(setIndexRule.data_view_id).to.eql(dataViewId);
|
||||
});
|
||||
});
|
||||
|
||||
it('should limit concurrent requests to 5', async () => {
|
||||
const ruleId = 'ruleId';
|
||||
const timelineId = '91832785-286d-4ebe-b884-1a208d111a70';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue