Skip to content

Commit

Permalink
Merge branch 'system_actions_mvp' of github.com:elastic/kibana into s…
Browse files Browse the repository at this point in the history
…ystem_actions_mvp
  • Loading branch information
guskovaue committed Nov 14, 2023
2 parents 825bcc6 + aadd675 commit 6105ee6
Show file tree
Hide file tree
Showing 7 changed files with 365 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import {
enabledRuleForBulkOps1,
enabledRuleForBulkOps2,
enabledRuleForBulkOps3,
returnedRuleForBulkDelete1,
returnedRuleForBulkDelete2,
returnedRuleForBulkDelete3,
returnedRuleForBulkOps1,
returnedRuleForBulkOps2,
returnedRuleForBulkOps3,
siemRuleForBulkOps1,
} from '../../../../rules_client/tests/test_helpers';
import { migrateLegacyActions } from '../../../../rules_client/lib';
Expand Down Expand Up @@ -81,6 +81,7 @@ const rulesClientParams: jest.Mocked<ConstructorOptions> = {
isAuthenticationTypeAPIKey: jest.fn(),
getAuthenticationAPIKey: jest.fn(),
connectorAdapterRegistry: new ConnectorAdapterRegistry(),
isSystemAction: jest.fn(),
getAlertIndicesAlias: jest.fn(),
alertsService: null,
};
Expand Down Expand Up @@ -192,7 +193,7 @@ describe('bulkDelete', () => {
expect.anything()
);
expect(result).toStrictEqual({
rules: [returnedRuleForBulkDelete1, returnedRuleForBulkDelete3],
rules: [returnedRuleForBulkOps1, returnedRuleForBulkOps3],
errors: [{ message: 'UPS', rule: { id: 'id2', name: 'fakeName' }, status: 500 }],
total: 2,
taskIdsFailedToBeDeleted: [],
Expand Down Expand Up @@ -256,7 +257,7 @@ describe('bulkDelete', () => {
expect.anything()
);
expect(result).toStrictEqual({
rules: [returnedRuleForBulkDelete1],
rules: [returnedRuleForBulkOps1],
errors: [{ message: 'UPS', rule: { id: 'id2', name: 'fakeName' }, status: 409 }],
total: 2,
taskIdsFailedToBeDeleted: [],
Expand Down Expand Up @@ -314,7 +315,7 @@ describe('bulkDelete', () => {
expect.anything()
);
expect(result).toStrictEqual({
rules: [returnedRuleForBulkDelete1, returnedRuleForBulkDelete2],
rules: [returnedRuleForBulkOps1, returnedRuleForBulkOps2],
errors: [],
total: 2,
taskIdsFailedToBeDeleted: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ export interface RRuleAttributes {
byweekday?: Array<string | number>;
bymonth?: number[];
bysetpos?: number[];
bymonthday: number[];
byyearday: number[];
byweekno: number[];
byhour: number[];
byminute: number[];
bysecond: number[];
bymonthday?: number[];
byyearday?: number[];
byweekno?: number[];
byhour?: number[];
byminute?: number[];
bysecond?: number[];
}

export interface RuleSnoozeScheduleAttributes {
Expand Down
120 changes: 119 additions & 1 deletion x-pack/plugins/alerting/server/routes/bulk_enable_rules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
*/

import { httpServiceMock } from '@kbn/core/server/mocks';

import { actionsClientMock } from '@kbn/actions-plugin/server/mocks';
import { bulkEnableRulesRoute } from './bulk_enable_rules';
import { licenseStateMock } from '../lib/license_state.mock';
import { mockHandlerArguments } from './_mock_handler_arguments';
import { rulesClientMock } from '../rules_client.mock';
import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled';
import { verifyApiAccess } from '../lib/license_api_access';
import { RuleActionTypes, RuleDefaultAction, RuleSystemAction, SanitizedRule } from '../types';

const rulesClient = rulesClientMock.create();

Expand Down Expand Up @@ -123,4 +124,121 @@ describe('bulkEnableRulesRoute', () => {

expect(res.forbidden).toHaveBeenCalledWith({ body: { message: 'Fail' } });
});

describe('actions', () => {
const mockedRule: SanitizedRule<{}> = {
id: '1',
alertTypeId: '1',
schedule: { interval: '10s' },
params: {
bar: true,
},
createdAt: new Date(),
updatedAt: new Date(),
actions: [
{
group: 'default',
id: '2',
actionTypeId: 'test',
params: {
foo: true,
},
uuid: '123-456',
type: RuleActionTypes.DEFAULT,
},
],
consumer: 'bar',
name: 'abc',
tags: ['foo'],
enabled: true,
muteAll: false,
notifyWhen: 'onActionGroupChange',
createdBy: '',
updatedBy: '',
apiKeyOwner: '',
throttle: '30s',
mutedInstanceIds: [],
executionStatus: {
status: 'unknown',
lastExecutionDate: new Date('2020-08-20T19:23:38Z'),
},
revision: 0,
};

const action: RuleDefaultAction = {
actionTypeId: 'test',
group: 'default',
id: '2',
params: {
foo: true,
},
uuid: '123-456',
type: RuleActionTypes.DEFAULT,
};

const systemAction: RuleSystemAction = {
actionTypeId: 'test-2',
id: 'system_action-id',
params: {
foo: true,
},
uuid: '123-456',
type: RuleActionTypes.SYSTEM,
};

const mockedRules: Array<SanitizedRule<{}>> = [
{ ...mockedRule, actions: [action, systemAction] },
];

const bulkEnableActionsResult = {
rules: mockedRules,
errors: [],
total: 1,
taskIdsFailedToBeEnabled: [],
};

it('removes the type from the actions correctly before sending the response', async () => {
const licenseState = licenseStateMock.create();
const router = httpServiceMock.createRouter();
const actionsClient = actionsClientMock.create();
actionsClient.isSystemAction.mockImplementation((id: string) => id === 'system_action-id');

bulkEnableRulesRoute({ router, licenseState });
const [_, handler] = router.patch.mock.calls[0];

// rulesClient.bulkDisableRules.mockResolvedValueOnce(bulkDisableActionsResult);
rulesClient.bulkEnableRules.mockResolvedValueOnce(bulkEnableActionsResult);

const [context, req, res] = mockHandlerArguments(
{ rulesClient, actionsClient },
{
body: bulkEnableRequest,
},
['ok']
);

const routeRes = await handler(context, req, res);

// @ts-expect-error: body exists
expect(routeRes.body.rules[0].actions).toEqual([
{
connector_type_id: 'test',
group: 'default',
id: '2',
params: {
foo: true,
},
uuid: '123-456',
},
{
connector_type_id: 'test-2',
id: 'system_action-id',
params: {
foo: true,
},
uuid: '123-456',
},
]);
});
});
});
18 changes: 16 additions & 2 deletions x-pack/plugins/alerting/server/routes/bulk_enable_rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { IRouter } from '@kbn/core/server';
import { verifyAccessAndContext, handleDisabledApiKeysError } from './lib';
import { ILicenseState, RuleTypeDisabledError } from '../lib';
import { AlertingRequestHandlerContext, INTERNAL_BASE_ALERTING_API_PATH } from '../types';
import { transformRuleToRuleResponseV1 } from './rule/transforms';
import { Rule } from '../application/rule/types';

export const bulkEnableRulesRoute = ({
router,
Expand All @@ -35,8 +37,20 @@ export const bulkEnableRulesRoute = ({
const { filter, ids } = req.body;

try {
const result = await rulesClient.bulkEnableRules({ filter, ids });
return res.ok({ body: result });
const bulkEnableResults = await rulesClient.bulkEnableRules({ filter, ids });

const resultBody = {
body: {
...bulkEnableResults,
rules: bulkEnableResults.rules.map((rule) => {
// TODO (http-versioning): Remove this cast, this enables us to move forward
// without fixing all of other solution types
return transformRuleToRuleResponseV1(rule as Rule);
}),
},
};

return res.ok(resultBody);
} catch (e) {
if (e instanceof RuleTypeDisabledError) {
return e.sendResponse(res);
Expand Down
45 changes: 34 additions & 11 deletions x-pack/plugins/alerting/server/rules_client/methods/bulk_enable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { getRuleCircuitBreakerErrorMessage } from '../../../common';
import {
getAuthorizationFilter,
checkAuthorizationAndGetTotal,
getAlertFromRaw,
scheduleTask,
updateMeta,
createNewAPIKeySet,
Expand All @@ -32,6 +31,12 @@ import {
import { RulesClientContext, BulkOperationError, BulkOptions } from '../types';
import { validateScheduleLimit } from '../../application/rule/methods/get_schedule_frequency';
import { RuleAttributes } from '../../data/rule/types';
import {
transformRuleAttributesToRuleDomain,
transformRuleDomainToRule,
} from '../../application/rule/transforms';
import type { RuleParams } from '../../application/rule/types';
import { ruleDomainSchema } from '../../application/rule/schemas';

const getShouldScheduleTask = async (
context: RulesClientContext,
Expand All @@ -57,8 +62,12 @@ const getShouldScheduleTask = async (
}
};

export const bulkEnableRules = async (context: RulesClientContext, options: BulkOptions) => {
export const bulkEnableRules = async <Params extends RuleParams>(
context: RulesClientContext,
options: BulkOptions
) => {
const { ids, filter } = getAndValidateCommonBulkOptions(options);
const actionsClient = await context.getActionsClient();

const kueryNodeFilter = ids ? convertRuleIdsToKueryNode(ids) : buildKueryNodeFilter(filter);
const authorizationFilter = await getAuthorizationFilter(context, { action: 'ENABLE' });
Expand Down Expand Up @@ -89,18 +98,32 @@ export const bulkEnableRules = async (context: RulesClientContext, options: Bulk
taskManager: context.taskManager,
});

const updatedRules = rules.map(({ id, attributes, references }) => {
return getAlertFromRaw(
context,
id,
attributes.alertTypeId as string,
attributes as RawRule,
references,
false
const enabledRules = rules.map(({ id, attributes, references }) => {
// TODO (http-versioning): alertTypeId should never be null, but we need to
// fix the type cast from SavedObjectsBulkUpdateObject to SavedObjectsBulkUpdateObject
// when we are doing the bulk disable and this should fix itself
const ruleType = context.ruleTypeRegistry.get(attributes.alertTypeId!);
const ruleDomain = transformRuleAttributesToRuleDomain<Params>(
attributes as RuleAttributes,
{
id,
logger: context.logger,
ruleType,
references,
omitGeneratedValues: false,
},
(connectorId: string) => actionsClient.isSystemAction(connectorId)
);

try {
ruleDomainSchema.validate(ruleDomain);
} catch (e) {
context.logger.warn(`Error validating bulk enabled rule domain object for id: ${id}, ${e}`);
}
return transformRuleDomainToRule(ruleDomain);
});

return { errors, rules: updatedRules, total, taskIdsFailedToBeEnabled };
return { errors, rules: enabledRules, total, taskIdsFailedToBeEnabled };
};

const bulkEnableRulesWithOCC = async (
Expand Down
Loading

0 comments on commit 6105ee6

Please sign in to comment.