mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[RAM] Fix case conversion of frequency.notify_when in API (#148838)
## Summary Closes #148572 Fixes an issue where rules APIs required `frequency.notifyWhen` to be sent/received instead of `frequency.notify_when` ### 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: Julia <iuliia.guskova@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
2228086ae6
commit
cb2f07b570
15 changed files with 84 additions and 45 deletions
|
@ -12,7 +12,9 @@ type RenameActionToConnector<K extends string> = K extends `actionTypeId`
|
|||
: K;
|
||||
|
||||
export type AsApiContract<T> = {
|
||||
[K in keyof T as CamelToSnake<RenameActionToConnector<Extract<K, string>>>]: T[K];
|
||||
[K in keyof T as CamelToSnake<RenameActionToConnector<Extract<K, string>>>]: K extends 'frequency'
|
||||
? AsApiContract<T[K]>
|
||||
: T[K];
|
||||
};
|
||||
|
||||
export type RewriteRequestCase<T> = (requested: AsApiContract<T>) => T;
|
||||
|
|
|
@ -15,8 +15,20 @@ import {
|
|||
} from '../../common';
|
||||
|
||||
function transformAction(input: AsApiContract<RuleAction>): RuleAction {
|
||||
const { connector_type_id: actionTypeId, ...rest } = input;
|
||||
return { actionTypeId, ...rest };
|
||||
const { connector_type_id: actionTypeId, frequency, ...rest } = input;
|
||||
return {
|
||||
actionTypeId,
|
||||
...(frequency
|
||||
? {
|
||||
frequency: {
|
||||
summary: frequency.summary,
|
||||
throttle: frequency.throttle,
|
||||
notifyWhen: frequency.notify_when,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...rest,
|
||||
};
|
||||
}
|
||||
|
||||
// AsApiContract does not deal with object properties that are dates - the
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
RewriteResponseCase,
|
||||
handleDisabledApiKeysError,
|
||||
rewriteRuleLastRun,
|
||||
rewriteActionsRes,
|
||||
} from './lib';
|
||||
import {
|
||||
RuleTypeParams,
|
||||
|
@ -69,13 +70,7 @@ const rewriteBodyRes: RewriteResponseCase<PartialRule<RuleTypeParams>> = ({
|
|||
: {}),
|
||||
...(actions
|
||||
? {
|
||||
actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({
|
||||
group,
|
||||
id,
|
||||
params,
|
||||
connector_type_id: actionTypeId,
|
||||
frequency,
|
||||
})),
|
||||
actions: rewriteActionsRes(actions),
|
||||
}
|
||||
: {}),
|
||||
...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}),
|
||||
|
|
|
@ -11,7 +11,8 @@ import { CreateOptions } from '../rules_client';
|
|||
import {
|
||||
RewriteRequestCase,
|
||||
RewriteResponseCase,
|
||||
rewriteActions,
|
||||
rewriteActionsReq,
|
||||
rewriteActionsRes,
|
||||
handleDisabledApiKeysError,
|
||||
verifyAccessAndContext,
|
||||
countUsageOfPredefinedIds,
|
||||
|
@ -45,11 +46,13 @@ export const bodySchema = schema.object({
|
|||
const rewriteBodyReq: RewriteRequestCase<CreateOptions<RuleTypeParams>['data']> = ({
|
||||
rule_type_id: alertTypeId,
|
||||
notify_when: notifyWhen,
|
||||
actions,
|
||||
...rest
|
||||
}) => ({
|
||||
...rest,
|
||||
alertTypeId,
|
||||
notifyWhen,
|
||||
actions: rewriteActionsReq(actions),
|
||||
});
|
||||
|
||||
const rewriteBodyRes: RewriteResponseCase<SanitizedRule<RuleTypeParams>> = ({
|
||||
|
@ -87,12 +90,7 @@ const rewriteBodyRes: RewriteResponseCase<SanitizedRule<RuleTypeParams>> = ({
|
|||
last_execution_date: lastExecutionDate,
|
||||
last_duration: lastDuration,
|
||||
},
|
||||
actions: actions.map(({ group, id, actionTypeId, params }) => ({
|
||||
group,
|
||||
id,
|
||||
params,
|
||||
connector_type_id: actionTypeId,
|
||||
})),
|
||||
actions: rewriteActionsRes(actions),
|
||||
...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}),
|
||||
...(nextRun ? { next_run: nextRun } : {}),
|
||||
});
|
||||
|
@ -128,7 +126,6 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt
|
|||
await rulesClient.create<RuleTypeParams>({
|
||||
data: rewriteBodyReq({
|
||||
...rule,
|
||||
actions: rewriteActions(rule.actions),
|
||||
notify_when: rule.notify_when as RuleNotifyWhenType,
|
||||
}),
|
||||
options: { id: params?.id },
|
||||
|
|
|
@ -64,7 +64,13 @@ const rewriteBodyRes: RewriteResponseCase<SanitizedRule<RuleTypeParams>> = ({
|
|||
id,
|
||||
params,
|
||||
connector_type_id: actionTypeId,
|
||||
frequency,
|
||||
frequency: frequency
|
||||
? {
|
||||
summary: frequency.summary,
|
||||
notify_when: frequency.notifyWhen,
|
||||
throttle: frequency.throttle,
|
||||
}
|
||||
: undefined,
|
||||
})),
|
||||
...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}),
|
||||
...(nextRun ? { next_run: nextRun } : {}),
|
||||
|
|
|
@ -18,7 +18,7 @@ export type {
|
|||
} from './rewrite_request_case';
|
||||
export { verifyAccessAndContext } from './verify_access_and_context';
|
||||
export { countUsageOfPredefinedIds } from './count_usage_of_predefined_ids';
|
||||
export { rewriteActions } from './rewrite_actions';
|
||||
export { rewriteActionsReq, rewriteActionsRes } from './rewrite_actions';
|
||||
export { actionsSchema } from './actions_schema';
|
||||
export { rewriteRule, rewriteRuleLastRun } from './rewrite_rule';
|
||||
export { rewriteNamespaces } from './rewrite_namespaces';
|
||||
|
|
|
@ -14,7 +14,7 @@ type ReqRuleAction = Omit<RuleAction, 'actionTypeId' | 'frequency'> & {
|
|||
>[K];
|
||||
};
|
||||
};
|
||||
export const rewriteActions: (
|
||||
export const rewriteActionsReq: (
|
||||
actions?: ReqRuleAction[]
|
||||
) => Array<Omit<RuleAction, 'actionTypeId'>> = (actions) => {
|
||||
const rewriteFrequency: RewriteRequestCase<NonNullable<RuleAction['frequency']>> = ({
|
||||
|
@ -30,3 +30,16 @@ export const rewriteActions: (
|
|||
} as RuleAction)
|
||||
);
|
||||
};
|
||||
|
||||
export const rewriteActionsRes = (actions?: RuleAction[]) => {
|
||||
const rewriteFrequency = ({ notifyWhen, ...rest }: NonNullable<RuleAction['frequency']>) => ({
|
||||
...rest,
|
||||
notify_when: notifyWhen,
|
||||
});
|
||||
if (!actions) return [];
|
||||
return actions.map(({ actionTypeId, frequency, ...action }) => ({
|
||||
...action,
|
||||
connector_type_id: actionTypeId,
|
||||
...(frequency ? { frequency: rewriteFrequency(frequency) } : {}),
|
||||
}));
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ type RenameAlertToRule<K extends string> = K extends `alertTypeId`
|
|||
|
||||
export type AsApiContract<
|
||||
T,
|
||||
ComplexPropertyKeys = `actions` | `executionStatus` | 'lastRun',
|
||||
ComplexPropertyKeys = 'actions' | 'executionStatus' | 'lastRun' | 'frequency',
|
||||
OpaquePropertyKeys = `params`
|
||||
> = T extends Array<infer I>
|
||||
? Array<AsApiContract<I>>
|
||||
|
@ -32,7 +32,7 @@ export type AsApiContract<
|
|||
[K in keyof T as CamelToSnake<
|
||||
RenameAlertToRule<Extract<K, string>>
|
||||
>]: K extends OpaquePropertyKeys
|
||||
? // don't convert explciitly opaque types which we treat as a black box
|
||||
? // don't convert explcitly opaque types which we treat as a black box
|
||||
T[K]
|
||||
: T[K] extends undefined
|
||||
? AsApiContract<Exclude<T[K], undefined>> | undefined
|
||||
|
|
|
@ -63,7 +63,9 @@ export const rewriteRule = ({
|
|||
connector_type_id: actionTypeId,
|
||||
...(frequency
|
||||
? {
|
||||
frequency,
|
||||
summary: frequency.summary,
|
||||
notify_when: frequency.notifyWhen,
|
||||
throttle: frequency.throttle,
|
||||
}
|
||||
: {}),
|
||||
})),
|
||||
|
|
|
@ -9,7 +9,12 @@ import { omit } from 'lodash';
|
|||
import { schema } from '@kbn/config-schema';
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { verifyAccessAndContext, RewriteResponseCase, rewriteRuleLastRun } from './lib';
|
||||
import {
|
||||
verifyAccessAndContext,
|
||||
RewriteResponseCase,
|
||||
rewriteRuleLastRun,
|
||||
rewriteActionsRes,
|
||||
} from './lib';
|
||||
import {
|
||||
RuleTypeParams,
|
||||
AlertingRequestHandlerContext,
|
||||
|
@ -54,13 +59,7 @@ const rewriteBodyRes: RewriteResponseCase<ResolvedSanitizedRule<RuleTypeParams>>
|
|||
last_execution_date: executionStatus.lastExecutionDate,
|
||||
last_duration: executionStatus.lastDuration,
|
||||
},
|
||||
actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({
|
||||
group,
|
||||
id,
|
||||
params,
|
||||
connector_type_id: actionTypeId,
|
||||
frequency,
|
||||
})),
|
||||
actions: rewriteActionsRes(actions),
|
||||
...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}),
|
||||
...(nextRun ? { next_run: nextRun } : {}),
|
||||
});
|
||||
|
|
|
@ -15,7 +15,8 @@ import {
|
|||
RewriteResponseCase,
|
||||
RewriteRequestCase,
|
||||
handleDisabledApiKeysError,
|
||||
rewriteActions,
|
||||
rewriteActionsReq,
|
||||
rewriteActionsRes,
|
||||
actionsSchema,
|
||||
rewriteRuleLastRun,
|
||||
} from './lib';
|
||||
|
@ -44,12 +45,13 @@ const bodySchema = schema.object({
|
|||
});
|
||||
|
||||
const rewriteBodyReq: RewriteRequestCase<UpdateOptions<RuleTypeParams>> = (result) => {
|
||||
const { notify_when: notifyWhen, ...rest } = result.data;
|
||||
const { notify_when: notifyWhen, actions, ...rest } = result.data;
|
||||
return {
|
||||
...result,
|
||||
data: {
|
||||
...rest,
|
||||
notifyWhen,
|
||||
actions: rewriteActionsReq(actions),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
@ -96,13 +98,7 @@ const rewriteBodyRes: RewriteResponseCase<PartialRule<RuleTypeParams>> = ({
|
|||
: {}),
|
||||
...(actions
|
||||
? {
|
||||
actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({
|
||||
group,
|
||||
id,
|
||||
params,
|
||||
connector_type_id: actionTypeId,
|
||||
frequency,
|
||||
})),
|
||||
actions: rewriteActionsRes(actions),
|
||||
}
|
||||
: {}),
|
||||
...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}),
|
||||
|
@ -133,7 +129,6 @@ export const updateRuleRoute = (
|
|||
id,
|
||||
data: {
|
||||
...rule,
|
||||
actions: rewriteActions(rule.actions),
|
||||
notify_when: rule.notify_when as RuleNotifyWhenType,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -38,7 +38,7 @@ describe('cloneRule', () => {
|
|||
message: 'alert ',
|
||||
},
|
||||
frequency: {
|
||||
notifyWhen: 'onActionGroupChange',
|
||||
notify_when: 'onActionGroupChange',
|
||||
throttle: null,
|
||||
summary: false,
|
||||
},
|
||||
|
|
|
@ -19,7 +19,15 @@ const transformAction: RewriteRequestCase<RuleAction> = ({
|
|||
id,
|
||||
params,
|
||||
actionTypeId,
|
||||
frequency,
|
||||
...(frequency
|
||||
? {
|
||||
frequency: {
|
||||
summary: frequency.summary,
|
||||
notifyWhen: frequency.notify_when,
|
||||
throttle: frequency.throttle,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
const transformExecutionStatus: RewriteRequestCase<RuleExecutionStatus> = ({
|
||||
|
|
|
@ -42,7 +42,7 @@ describe('createRule', () => {
|
|||
},
|
||||
connector_type_id: '.server-log',
|
||||
frequency: {
|
||||
notifyWhen: 'onActionGroupChange',
|
||||
notify_when: 'onActionGroupChange',
|
||||
throttle: null,
|
||||
summary: false,
|
||||
},
|
||||
|
|
|
@ -51,6 +51,11 @@ describe('resolveRule', () => {
|
|||
id: '1',
|
||||
params: { documents: [{ dsfsdf: 1212 }] },
|
||||
connector_type_id: '.index',
|
||||
frequency: {
|
||||
summary: null,
|
||||
notify_when: 'onActiveAlert',
|
||||
throttle: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
outcome: 'aliasMatch',
|
||||
|
@ -95,6 +100,11 @@ describe('resolveRule', () => {
|
|||
id: '1',
|
||||
params: { documents: [{ dsfsdf: 1212 }] },
|
||||
actionTypeId: '.index',
|
||||
frequency: {
|
||||
summary: null,
|
||||
notifyWhen: 'onActiveAlert',
|
||||
throttle: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
outcome: 'aliasMatch',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue