[Alerting] Renaming AlertType to RuleType and updating Alerting Task Runner (#120661)

* Renaming AlertType to RuleType and updating Alerting Task Runner

* Fixing types

* Fixing types

* holy cannoli

* Fixing types

* Fixing types and tests

* Fixing types and tests

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
ymao1 2021-12-09 09:21:38 -05:00 committed by GitHub
parent f14540ff63
commit 7c27163d6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
82 changed files with 1163 additions and 1202 deletions

View file

@ -15,7 +15,7 @@ Rules and connectors log to the Kibana logger with tags of [alerting] and [actio
[source, txt]
--------------------------------------------------
server log [11:39:40.389] [error][alerting][alerting][plugins][plugins] Executing Alert "5b6237b0-c6f6-11eb-b0ff-a1a0cbcf29b6" has resulted in Error: Saved object [action/fdbc8610-c6f5-11eb-b0ff-a1a0cbcf29b6] not found
server log [11:39:40.389] [error][alerting][alerting][plugins][plugins] Executing Rule "5b6237b0-c6f6-11eb-b0ff-a1a0cbcf29b6" has resulted in Error: Saved object [action/fdbc8610-c6f5-11eb-b0ff-a1a0cbcf29b6] not found
--------------------------------------------------
Some of the resources, such as saved objects and API keys, may no longer be available or valid, yielding error messages about those missing resources.

View file

@ -170,7 +170,7 @@ And see the errors for the rules you might provide the next search query:
}
],
},
"message": "alert executed: .index-threshold:30d856c0-b14b-11eb-9a7c-9df284da9f99: 'test'",
"message": "rule executed: .index-threshold:30d856c0-b14b-11eb-9a7c-9df284da9f99: 'test'",
"error" : {
"message" : "Saved object [action/ef0e2530-b14a-11eb-9a7c-9df284da9f99] not found"
},

View file

@ -1020,7 +1020,7 @@ This log message tells us that when Task Manager was running one of our rules, i
For example, in this case, wed expect to see a corresponding log line from the Alerting framework itself, saying that the rule failed. You should look in the Kibana log for a line similar to the log line below (probably shortly before the Task Manager log line):
Executing Alert "27559295-44e4-4983-aa1b-94fe043ab4f9" has resulted in Error: Unable to load resource /api/something
Executing Rule "27559295-44e4-4983-aa1b-94fe043ab4f9" has resulted in Error: Unable to load resource /api/something
This would confirm that the error did in fact happen in the rule itself (rather than the Task Manager) and it would help us pin-point the specific ID of the rule which failed: 27559295-44e4-4983-aa1b-94fe043ab4f9

View file

@ -24,7 +24,7 @@ import { isEmpty } from 'lodash';
import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
import {
Alert,
AlertTaskState,
RuleTaskState,
LEGACY_BASE_ALERT_API_PATH,
} from '../../../../plugins/alerting/common';
@ -34,7 +34,7 @@ type Props = RouteComponentProps & {
};
export const ViewAlertPage = withRouter(({ http, id }: Props) => {
const [alert, setAlert] = useState<Alert | null>(null);
const [alertState, setAlertState] = useState<AlertTaskState | null>(null);
const [alertState, setAlertState] = useState<RuleTaskState | null>(null);
useEffect(() => {
if (!alert) {
@ -42,7 +42,7 @@ export const ViewAlertPage = withRouter(({ http, id }: Props) => {
}
if (!alertState) {
http
.get<AlertTaskState | null>(`${LEGACY_BASE_ALERT_API_PATH}/alert/${id}/state`)
.get<RuleTaskState | null>(`${LEGACY_BASE_ALERT_API_PATH}/alert/${id}/state`)
.then(setAlertState);
}
}, [alert, alertState, http, id]);

View file

@ -26,7 +26,7 @@ import { isEmpty } from 'lodash';
import { ALERTING_EXAMPLE_APP_ID, AlwaysFiringParams } from '../../common/constants';
import {
Alert,
AlertTaskState,
RuleTaskState,
LEGACY_BASE_ALERT_API_PATH,
} from '../../../../plugins/alerting/common';
@ -40,7 +40,7 @@ function hasCraft(state: any): state is { craft: string } {
}
export const ViewPeopleInSpaceAlertPage = withRouter(({ http, id }: Props) => {
const [alert, setAlert] = useState<Alert<AlwaysFiringParams> | null>(null);
const [alertState, setAlertState] = useState<AlertTaskState | null>(null);
const [alertState, setAlertState] = useState<RuleTaskState | null>(null);
useEffect(() => {
if (!alert) {
@ -50,7 +50,7 @@ export const ViewPeopleInSpaceAlertPage = withRouter(({ http, id }: Props) => {
}
if (!alertState) {
http
.get<AlertTaskState | null>(`${LEGACY_BASE_ALERT_API_PATH}/alert/${id}/state`)
.get<RuleTaskState | null>(`${LEGACY_BASE_ALERT_API_PATH}/alert/${id}/state`)
.then(setAlertState);
}
}, [alert, alertState, http, id]);

View file

@ -7,7 +7,7 @@
import uuid from 'uuid';
import { range } from 'lodash';
import { AlertType } from '../../../../plugins/alerting/server';
import { RuleType } from '../../../../plugins/alerting/server';
import {
DEFAULT_INSTANCES_TO_GENERATE,
ALERTING_EXAMPLE_APP_ID,
@ -37,7 +37,7 @@ function getTShirtSizeByIdAndThreshold(
return DEFAULT_ACTION_GROUP;
}
export const alertType: AlertType<
export const alertType: RuleType<
AlwaysFiringParams,
never,
{ count?: number },

View file

@ -6,7 +6,7 @@
*/
import axios from 'axios';
import { AlertType } from '../../../../plugins/alerting/server';
import { RuleType } from '../../../../plugins/alerting/server';
import { Operator, Craft, ALERTING_EXAMPLE_APP_ID } from '../../common/constants';
interface PeopleInSpace {
@ -39,7 +39,7 @@ function getCraftFilter(craft: string) {
craft === Craft.OuterSpace ? true : craft === person.craft;
}
export const alertType: AlertType<
export const alertType: RuleType<
{ outerSpaceCapacity: number; craft: string; op: string },
never,
{ peopleInSpace: number },

View file

@ -230,7 +230,7 @@ interface MyRuleTypeAlertContext extends AlertInstanceContext {
type MyRuleTypeActionGroups = 'default' | 'warning';
const myRuleType: AlertType<
const myRuleType: RuleType<
MyRuleTypeParams,
MyRuleTypeExtractedParams,
MyRuleTypeState,

View file

@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
import { ActionGroup } from './alert_type';
import { ActionGroup } from './rule_type';
export type DefaultActionGroupId = 'default';

View file

@ -11,9 +11,9 @@
import { AlertsHealth } from './alert';
export * from './alert';
export * from './alert_type';
export * from './rule_type';
export * from './alert_instance';
export * from './alert_task_instance';
export * from './rule_task_instance';
export * from './alert_navigation';
export * from './alert_summary';
export * from './builtin_action_groups';

View file

@ -9,15 +9,15 @@ import * as t from 'io-ts';
import { rawAlertInstance } from './alert_instance';
import { DateFromString } from './date_from_string';
export const alertStateSchema = t.partial({
export const ruleStateSchema = t.partial({
alertTypeState: t.record(t.string, t.unknown),
alertInstances: t.record(t.string, rawAlertInstance),
previousStartedAt: t.union([t.null, DateFromString]),
});
export type AlertTaskState = t.TypeOf<typeof alertStateSchema>;
export type RuleTaskState = t.TypeOf<typeof ruleStateSchema>;
export const alertParamsSchema = t.intersection([
export const ruleParamsSchema = t.intersection([
t.type({
alertId: t.string,
}),
@ -25,4 +25,4 @@ export const alertParamsSchema = t.intersection([
spaceId: t.string,
}),
]);
export type AlertTaskParams = t.TypeOf<typeof alertParamsSchema>;
export type RuleTaskParams = t.TypeOf<typeof ruleParamsSchema>;

View file

@ -8,7 +8,7 @@
import { LicenseType } from '../../licensing/common/types';
import { RecoveredActionGroupId, DefaultActionGroupId } from './builtin_action_groups';
export interface AlertType<
export interface RuleType<
ActionGroupIds extends Exclude<string, RecoveredActionGroupId> = DefaultActionGroupId,
RecoveryActionGroupId extends string = RecoveredActionGroupId
> {

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { AlertType, RecoveredActionGroup } from '../common';
import { RuleType, RecoveredActionGroup } from '../common';
import { httpServiceMock } from '../../../../src/core/public/mocks';
import { loadAlert, loadAlertType, loadAlertTypes } from './alert_api';
import uuid from 'uuid';
@ -16,7 +16,7 @@ beforeEach(() => jest.resetAllMocks());
describe('loadAlertTypes', () => {
test('should call get alert types API', async () => {
const resolvedValue: AlertType[] = [
const resolvedValue: RuleType[] = [
{
id: 'test',
name: 'Test',
@ -43,7 +43,7 @@ describe('loadAlertTypes', () => {
describe('loadAlertType', () => {
test('should call get alert types API', async () => {
const alertType: AlertType = {
const alertType: RuleType = {
id: 'test',
name: 'Test',
actionVariables: ['var1'],
@ -66,7 +66,7 @@ describe('loadAlertType', () => {
});
test('should find the required alertType', async () => {
const alertType: AlertType = {
const alertType: RuleType = {
id: 'test-another',
name: 'Test Another',
actionVariables: [],

View file

@ -7,9 +7,9 @@
import { HttpSetup } from 'kibana/public';
import { LEGACY_BASE_ALERT_API_PATH } from '../common';
import type { Alert, AlertType } from '../common';
import type { Alert, RuleType } from '../common';
export async function loadAlertTypes({ http }: { http: HttpSetup }): Promise<AlertType[]> {
export async function loadAlertTypes({ http }: { http: HttpSetup }): Promise<RuleType[]> {
return await http.get(`${LEGACY_BASE_ALERT_API_PATH}/list_alert_types`);
}
@ -18,11 +18,11 @@ export async function loadAlertType({
id,
}: {
http: HttpSetup;
id: AlertType['id'];
}): Promise<AlertType | undefined> {
id: RuleType['id'];
}): Promise<RuleType | undefined> {
const alertTypes = (await http.get(
`${LEGACY_BASE_ALERT_API_PATH}/list_alert_types`
)) as AlertType[];
)) as RuleType[];
return alertTypes.find((type) => type.id === id);
}

View file

@ -6,12 +6,12 @@
*/
import { AlertNavigationRegistry } from './alert_navigation_registry';
import { AlertType, RecoveredActionGroup, SanitizedAlert } from '../../common';
import { RuleType, RecoveredActionGroup, SanitizedAlert } from '../../common';
import uuid from 'uuid';
beforeEach(() => jest.resetAllMocks());
const mockAlertType = (id: string): AlertType => ({
const mockAlertType = (id: string): RuleType => ({
id,
name: id,
actionGroups: [],

View file

@ -6,7 +6,7 @@
*/
import { i18n } from '@kbn/i18n';
import { AlertType } from '../../common';
import { RuleType } from '../../common';
import { AlertNavigationHandler } from './types';
const DEFAULT_HANDLER = Symbol('*');
@ -14,7 +14,7 @@ export class AlertNavigationRegistry {
private readonly alertNavigations: Map<string, Map<string | symbol, AlertNavigationHandler>> =
new Map();
public has(consumer: string, alertType: AlertType) {
public has(consumer: string, alertType: RuleType) {
return this.hasTypedHandler(consumer, alertType.id) || this.hasDefaultHandler(consumer);
}
@ -70,7 +70,7 @@ export class AlertNavigationRegistry {
consumerNavigations.set(ruleTypeId, handler);
}
public get(consumer: string, alertType: AlertType): AlertNavigationHandler {
public get(consumer: string, alertType: RuleType): AlertNavigationHandler {
if (this.has(consumer, alertType)) {
const consumerHandlers = this.alertNavigations.get(consumer)!;
return (consumerHandlers.get(alertType.id) ?? consumerHandlers.get(DEFAULT_HANDLER))!;

View file

@ -6,7 +6,7 @@
*/
import { ISavedObjectsRepository, SavedObjectsServiceStart } from 'src/core/server';
import { AlertsHealth, HealthStatus, RawAlert, AlertExecutionStatusErrorReasons } from '../types';
import { AlertsHealth, HealthStatus, RawRule, AlertExecutionStatusErrorReasons } from '../types';
export const getHealth = async (
internalSavedObjectsRepository: ISavedObjectsRepository
@ -26,7 +26,7 @@ export const getHealth = async (
},
};
const { saved_objects: decryptErrorData } = await internalSavedObjectsRepository.find<RawAlert>({
const { saved_objects: decryptErrorData } = await internalSavedObjectsRepository.find<RawRule>({
filter: `alert.attributes.executionStatus.status:error and alert.attributes.executionStatus.error.reason:${AlertExecutionStatusErrorReasons.Decrypt}`,
fields: ['executionStatus'],
type: 'alert',
@ -44,7 +44,7 @@ export const getHealth = async (
};
}
const { saved_objects: executeErrorData } = await internalSavedObjectsRepository.find<RawAlert>({
const { saved_objects: executeErrorData } = await internalSavedObjectsRepository.find<RawRule>({
filter: `alert.attributes.executionStatus.status:error and alert.attributes.executionStatus.error.reason:${AlertExecutionStatusErrorReasons.Execute}`,
fields: ['executionStatus'],
type: 'alert',
@ -62,7 +62,7 @@ export const getHealth = async (
};
}
const { saved_objects: readErrorData } = await internalSavedObjectsRepository.find<RawAlert>({
const { saved_objects: readErrorData } = await internalSavedObjectsRepository.find<RawRule>({
filter: `alert.attributes.executionStatus.status:error and alert.attributes.executionStatus.error.reason:${AlertExecutionStatusErrorReasons.Read}`,
fields: ['executionStatus'],
type: 'alert',
@ -80,7 +80,7 @@ export const getHealth = async (
};
}
const { saved_objects: noErrorData } = await internalSavedObjectsRepository.find<RawAlert>({
const { saved_objects: noErrorData } = await internalSavedObjectsRepository.find<RawRule>({
filter: 'not alert.attributes.executionStatus.status:error',
fields: ['executionStatus'],
type: 'alert',

View file

@ -14,7 +14,7 @@ import { AlertsConfigType } from './types';
export type RulesClient = PublicMethodsOf<RulesClientClass>;
export type {
AlertType,
RuleType,
ActionGroup,
ActionGroupIdsOf,
AlertingPlugin,

View file

@ -6,11 +6,11 @@
*/
import { createAlertEventLogRecordObject } from './create_alert_event_log_record_object';
import { UntypedNormalizedAlertType } from '../rule_type_registry';
import { UntypedNormalizedRuleType } from '../rule_type_registry';
import { RecoveredActionGroup } from '../types';
describe('createAlertEventLogRecordObject', () => {
const ruleType: jest.Mocked<UntypedNormalizedAlertType> = {
const ruleType: jest.Mocked<UntypedNormalizedRuleType> = {
id: 'test',
name: 'My test alert',
actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup],

View file

@ -7,13 +7,13 @@
import { AlertInstanceState } from '../types';
import { IEvent } from '../../../event_log/server';
import { UntypedNormalizedAlertType } from '../rule_type_registry';
import { UntypedNormalizedRuleType } from '../rule_type_registry';
export type Event = Exclude<IEvent, undefined>;
interface CreateAlertEventLogRecordParams {
ruleId: string;
ruleType: UntypedNormalizedAlertType;
ruleType: UntypedNormalizedRuleType;
action: string;
ruleName?: string;
instanceId?: string;

View file

@ -5,6 +5,6 @@
* 2.0.
*/
export function getAlertTypeFeatureUsageName(alertTypeName: string) {
return `Alert: ${alertTypeName}`;
export function getRuleTypeFeatureUsageName(ruleTypeName: string) {
return `Rule: ${ruleTypeName}`;
}

View file

@ -8,7 +8,7 @@
export { parseDuration, validateDurationSchema } from '../../common/parse_duration';
export type { ILicenseState } from './license_state';
export { LicenseState } from './license_state';
export { validateAlertTypeParams } from './validate_alert_type_params';
export { validateRuleTypeParams } from './validate_rule_type_params';
export { getAlertNotifyWhenType } from './get_alert_notify_when_type';
export { verifyApiAccess } from './license_api_access';
export { ErrorWithReason, getReasonFromError, isErrorWithReason } from './error_with_reason';
@ -21,6 +21,6 @@ export { AlertTypeDisabledError, isErrorThatHandlesItsOwnResponse } from './erro
export {
executionStatusFromState,
executionStatusFromError,
alertExecutionStatusToRaw,
alertExecutionStatusFromRaw,
} from './alert_execution_status';
ruleExecutionStatusToRaw,
ruleExecutionStatusFromRaw,
} from './rule_execution_status';

View file

@ -11,8 +11,8 @@ export const createLicenseStateMock = () => {
const licenseState: jest.Mocked<ILicenseState> = {
clean: jest.fn(),
getLicenseInformation: jest.fn(),
ensureLicenseForAlertType: jest.fn(),
getLicenseCheckForAlertType: jest.fn().mockResolvedValue({
ensureLicenseForRuleType: jest.fn(),
getLicenseCheckForRuleType: jest.fn().mockResolvedValue({
isValid: true,
}),
checkLicense: jest.fn().mockResolvedValue({

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { AlertType } from '../types';
import { RuleType } from '../types';
import { Subject } from 'rxjs';
import { LicenseState, ILicenseState } from './license_state';
import { licensingMock } from '../../../licensing/server/mocks';
@ -53,11 +53,11 @@ describe('checkLicense()', () => {
});
});
describe('getLicenseCheckForAlertType', () => {
describe('getLicenseCheckForRuleType', () => {
let license: Subject<ILicense>;
let licenseState: ILicenseState;
const mockNotifyUsage = jest.fn();
const alertType: AlertType<never, never, never, never, never, 'default', 'recovered'> = {
const ruleType: RuleType<never, never, never, never, never, 'default', 'recovered'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -82,10 +82,10 @@ describe('getLicenseCheckForAlertType', () => {
test('should return false when license not defined', () => {
expect(
licenseState.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired
licenseState.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired
)
).toEqual({
isValid: false,
@ -96,10 +96,10 @@ describe('getLicenseCheckForAlertType', () => {
test('should return false when license not available', () => {
license.next(createUnavailableLicense());
expect(
licenseState.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired
licenseState.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired
)
).toEqual({
isValid: false,
@ -111,10 +111,10 @@ describe('getLicenseCheckForAlertType', () => {
const expiredLicense = licensingMock.createLicense({ license: { status: 'expired' } });
license.next(expiredLicense);
expect(
licenseState.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired
licenseState.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired
)
).toEqual({
isValid: false,
@ -128,10 +128,10 @@ describe('getLicenseCheckForAlertType', () => {
});
license.next(basicLicense);
expect(
licenseState.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired
licenseState.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired
)
).toEqual({
isValid: false,
@ -145,10 +145,10 @@ describe('getLicenseCheckForAlertType', () => {
});
license.next(goldLicense);
expect(
licenseState.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired
licenseState.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired
)
).toEqual({
isValid: true,
@ -160,7 +160,7 @@ describe('getLicenseCheckForAlertType', () => {
license: { status: 'active', type: 'gold' },
});
license.next(goldLicense);
licenseState.getLicenseCheckForAlertType(alertType.id, alertType.name, 'gold');
licenseState.getLicenseCheckForRuleType(ruleType.id, ruleType.name, 'gold');
expect(mockNotifyUsage).not.toHaveBeenCalled();
});
@ -169,7 +169,7 @@ describe('getLicenseCheckForAlertType', () => {
license: { status: 'active', type: 'basic' },
});
license.next(basicLicense);
licenseState.getLicenseCheckForAlertType(alertType.id, alertType.name, 'basic');
licenseState.getLicenseCheckForRuleType(ruleType.id, ruleType.name, 'basic');
expect(mockNotifyUsage).not.toHaveBeenCalled();
});
@ -178,21 +178,21 @@ describe('getLicenseCheckForAlertType', () => {
license: { status: 'active', type: 'gold' },
});
license.next(goldLicense);
licenseState.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired,
licenseState.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired,
{ notifyUsage: true }
);
expect(mockNotifyUsage).toHaveBeenCalledWith('Alert: Test');
expect(mockNotifyUsage).toHaveBeenCalledWith('Rule: Test');
});
});
describe('ensureLicenseForAlertType()', () => {
describe('ensureLicenseForRuleType()', () => {
let license: Subject<ILicense>;
let licenseState: ILicenseState;
const mockNotifyUsage = jest.fn();
const alertType: AlertType<never, never, never, never, never, string, string> = {
const ruleType: RuleType<never, never, never, never, never, string, string> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -217,18 +217,18 @@ describe('ensureLicenseForAlertType()', () => {
test('should throw when license not defined', () => {
expect(() =>
licenseState.ensureLicenseForAlertType(alertType)
licenseState.ensureLicenseForRuleType(ruleType)
).toThrowErrorMatchingInlineSnapshot(
`"Alert type test is disabled because license information is not available at this time."`
`"Rule type test is disabled because license information is not available at this time."`
);
});
test('should throw when license not available', () => {
license.next(createUnavailableLicense());
expect(() =>
licenseState.ensureLicenseForAlertType(alertType)
licenseState.ensureLicenseForRuleType(ruleType)
).toThrowErrorMatchingInlineSnapshot(
`"Alert type test is disabled because license information is not available at this time."`
`"Rule type test is disabled because license information is not available at this time."`
);
});
@ -236,9 +236,9 @@ describe('ensureLicenseForAlertType()', () => {
const expiredLicense = licensingMock.createLicense({ license: { status: 'expired' } });
license.next(expiredLicense);
expect(() =>
licenseState.ensureLicenseForAlertType(alertType)
licenseState.ensureLicenseForRuleType(ruleType)
).toThrowErrorMatchingInlineSnapshot(
`"Alert type test is disabled because your basic license has expired."`
`"Rule type test is disabled because your basic license has expired."`
);
});
@ -248,9 +248,9 @@ describe('ensureLicenseForAlertType()', () => {
});
license.next(basicLicense);
expect(() =>
licenseState.ensureLicenseForAlertType(alertType)
licenseState.ensureLicenseForRuleType(ruleType)
).toThrowErrorMatchingInlineSnapshot(
`"Alert test is disabled because it requires a Gold license. Go to License Management to view upgrade options."`
`"Rule test is disabled because it requires a Gold license. Go to License Management to view upgrade options."`
);
});
@ -259,7 +259,7 @@ describe('ensureLicenseForAlertType()', () => {
license: { status: 'active', type: 'gold' },
});
license.next(goldLicense);
licenseState.ensureLicenseForAlertType(alertType);
licenseState.ensureLicenseForRuleType(ruleType);
});
test('should call notifyUsage', () => {
@ -267,8 +267,8 @@ describe('ensureLicenseForAlertType()', () => {
license: { status: 'active', type: 'gold' },
});
license.next(goldLicense);
licenseState.ensureLicenseForAlertType(alertType);
expect(mockNotifyUsage).toHaveBeenCalledWith('Alert: Test');
licenseState.ensureLicenseForRuleType(ruleType);
expect(mockNotifyUsage).toHaveBeenCalledWith('Rule: Test');
});
});

View file

@ -14,9 +14,9 @@ import { Observable, Subscription } from 'rxjs';
import { LicensingPluginStart } from '../../../licensing/server';
import { ILicense, LicenseType } from '../../../licensing/common/types';
import { PLUGIN } from '../constants/plugin';
import { getAlertTypeFeatureUsageName } from './get_alert_type_feature_usage_name';
import { getRuleTypeFeatureUsageName } from './get_rule_type_feature_usage_name';
import {
AlertType,
RuleType,
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
@ -68,21 +68,21 @@ export class LicenseState {
this._notifyUsage = notifyUsage;
}
public getLicenseCheckForAlertType(
alertTypeId: string,
alertTypeName: string,
public getLicenseCheckForRuleType(
ruleTypeId: string,
ruleTypeName: string,
minimumLicenseRequired: LicenseType,
{ notifyUsage }: { notifyUsage: boolean } = { notifyUsage: false }
): { isValid: true } | { isValid: false; reason: 'unavailable' | 'expired' | 'invalid' } {
if (notifyUsage) {
this.notifyUsage(alertTypeName, minimumLicenseRequired);
this.notifyUsage(ruleTypeName, minimumLicenseRequired);
}
if (!this.license?.isAvailable) {
return { isValid: false, reason: 'unavailable' };
}
const check = this.license.check(alertTypeId, minimumLicenseRequired);
const check = this.license.check(ruleTypeId, minimumLicenseRequired);
switch (check.state) {
case 'expired':
@ -98,10 +98,10 @@ export class LicenseState {
}
}
private notifyUsage(alertTypeName: string, minimumLicenseRequired: LicenseType) {
private notifyUsage(ruleTypeName: string, minimumLicenseRequired: LicenseType) {
// No need to notify usage on basic alert types
if (this._notifyUsage && minimumLicenseRequired !== 'basic') {
this._notifyUsage(getAlertTypeFeatureUsageName(alertTypeName));
this._notifyUsage(getRuleTypeFeatureUsageName(ruleTypeName));
}
}
@ -147,7 +147,7 @@ export class LicenseState {
}
}
public ensureLicenseForAlertType<
public ensureLicenseForRuleType<
Params extends AlertTypeParams,
ExtractedParams extends AlertTypeParams,
State extends AlertTypeState,
@ -156,7 +156,7 @@ export class LicenseState {
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: AlertType<
ruleType: RuleType<
Params,
ExtractedParams,
State,
@ -166,12 +166,12 @@ export class LicenseState {
RecoveryActionGroupId
>
) {
this.notifyUsage(alertType.name, alertType.minimumLicenseRequired);
this.notifyUsage(ruleType.name, ruleType.minimumLicenseRequired);
const check = this.getLicenseCheckForAlertType(
alertType.id,
alertType.name,
alertType.minimumLicenseRequired
const check = this.getLicenseCheckForRuleType(
ruleType.id,
ruleType.name,
ruleType.minimumLicenseRequired
);
if (check.isValid) {
@ -182,9 +182,9 @@ export class LicenseState {
throw new AlertTypeDisabledError(
i18n.translate('xpack.alerting.serverSideErrors.unavailableLicenseErrorMessage', {
defaultMessage:
'Alert type {alertTypeId} is disabled because license information is not available at this time.',
'Rule type {ruleTypeId} is disabled because license information is not available at this time.',
values: {
alertTypeId: alertType.id,
ruleTypeId: ruleType.id,
},
}),
'license_unavailable'
@ -193,8 +193,8 @@ export class LicenseState {
throw new AlertTypeDisabledError(
i18n.translate('xpack.alerting.serverSideErrors.expirerdLicenseErrorMessage', {
defaultMessage:
'Alert type {alertTypeId} is disabled because your {licenseType} license has expired.',
values: { alertTypeId: alertType.id, licenseType: this.license!.type },
'Rule type {ruleTypeId} is disabled because your {licenseType} license has expired.',
values: { ruleTypeId: ruleType.id, licenseType: this.license!.type },
}),
'license_expired'
);
@ -202,10 +202,10 @@ export class LicenseState {
throw new AlertTypeDisabledError(
i18n.translate('xpack.alerting.serverSideErrors.invalidLicenseErrorMessage', {
defaultMessage:
'Alert {alertTypeId} is disabled because it requires a {licenseType} license. Go to License Management to view upgrade options.',
'Rule {ruleTypeId} is disabled because it requires a {licenseType} license. Go to License Management to view upgrade options.',
values: {
alertTypeId: alertType.id,
licenseType: capitalize(alertType.minimumLicenseRequired),
ruleTypeId: ruleType.id,
licenseType: capitalize(ruleType.minimumLicenseRequired),
},
}),
'license_invalid'

View file

@ -10,14 +10,14 @@ import { AlertExecutionStatusErrorReasons } from '../types';
import {
executionStatusFromState,
executionStatusFromError,
alertExecutionStatusToRaw,
alertExecutionStatusFromRaw,
} from './alert_execution_status';
ruleExecutionStatusToRaw,
ruleExecutionStatusFromRaw,
} from './rule_execution_status';
import { ErrorWithReason } from './error_with_reason';
const MockLogger = loggingSystemMock.create().get();
describe('AlertExecutionStatus', () => {
describe('RuleExecutionStatus', () => {
beforeEach(() => {
jest.resetAllMocks();
});
@ -71,14 +71,14 @@ describe('AlertExecutionStatus', () => {
});
});
describe('alertExecutionStatusToRaw()', () => {
describe('ruleExecutionStatusToRaw()', () => {
const date = new Date('2020-09-03T16:26:58Z');
const status = 'ok';
const reason = AlertExecutionStatusErrorReasons.Decrypt;
const error = { reason, message: 'wops' };
test('status without an error', () => {
expect(alertExecutionStatusToRaw({ lastExecutionDate: date, status })).toMatchInlineSnapshot(`
expect(ruleExecutionStatusToRaw({ lastExecutionDate: date, status })).toMatchInlineSnapshot(`
Object {
"error": null,
"lastDuration": 0,
@ -89,7 +89,7 @@ describe('AlertExecutionStatus', () => {
});
test('status with an error', () => {
expect(alertExecutionStatusToRaw({ lastExecutionDate: date, status, error }))
expect(ruleExecutionStatusToRaw({ lastExecutionDate: date, status, error }))
.toMatchInlineSnapshot(`
Object {
"error": Object {
@ -104,7 +104,7 @@ describe('AlertExecutionStatus', () => {
});
test('status with a duration', () => {
expect(alertExecutionStatusToRaw({ lastExecutionDate: date, status, lastDuration: 1234 }))
expect(ruleExecutionStatusToRaw({ lastExecutionDate: date, status, lastDuration: 1234 }))
.toMatchInlineSnapshot(`
Object {
"error": null,
@ -116,41 +116,41 @@ describe('AlertExecutionStatus', () => {
});
});
describe('alertExecutionStatusFromRaw()', () => {
describe('ruleExecutionStatusFromRaw()', () => {
const date = new Date('2020-09-03T16:26:58Z').toISOString();
const status = 'active';
const reason = AlertExecutionStatusErrorReasons.Execute;
const error = { reason, message: 'wops' };
test('no input', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id');
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id');
expect(result).toBe(undefined);
});
test('undefined input', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', undefined);
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', undefined);
expect(result).toBe(undefined);
});
test('null input', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', null);
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', null);
expect(result).toBe(undefined);
});
test('invalid date', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', {
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', {
lastExecutionDate: 'an invalid date',
})!;
checkDateIsNearNow(result.lastExecutionDate);
expect(result.status).toBe('unknown');
expect(result.error).toBe(undefined);
expect(MockLogger.debug).toBeCalledWith(
'invalid alertExecutionStatus lastExecutionDate "an invalid date" in raw alert alert-id'
'invalid ruleExecutionStatus lastExecutionDate "an invalid date" in raw rule rule-id'
);
});
test('valid date', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', {
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', {
lastExecutionDate: date,
});
expect(result).toMatchInlineSnapshot(`
@ -162,7 +162,7 @@ describe('AlertExecutionStatus', () => {
});
test('valid status and date', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', {
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', {
status,
lastExecutionDate: date,
});
@ -175,7 +175,7 @@ describe('AlertExecutionStatus', () => {
});
test('valid status, date and error', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', {
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', {
status,
lastExecutionDate: date,
error,
@ -193,7 +193,7 @@ describe('AlertExecutionStatus', () => {
});
test('valid status, date and duration', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', {
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', {
status,
lastExecutionDate: date,
lastDuration: 1234,
@ -208,7 +208,7 @@ describe('AlertExecutionStatus', () => {
});
test('valid status, date, error and duration', () => {
const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', {
const result = ruleExecutionStatusFromRaw(MockLogger, 'rule-id', {
status,
lastExecutionDate: date,
error,

View file

@ -6,16 +6,16 @@
*/
import { Logger } from 'src/core/server';
import { AlertTaskState, AlertExecutionStatus, RawAlertExecutionStatus } from '../types';
import { RuleTaskState, AlertExecutionStatus, RawRuleExecutionStatus } from '../types';
import { getReasonFromError } from './error_with_reason';
import { getEsErrorMessage } from './errors';
import { AlertExecutionStatuses } from '../../common';
export function executionStatusFromState(state: AlertTaskState): AlertExecutionStatus {
const instanceIds = Object.keys(state.alertInstances ?? {});
export function executionStatusFromState(state: RuleTaskState): AlertExecutionStatus {
const alertIds = Object.keys(state.alertInstances ?? {});
return {
lastExecutionDate: new Date(),
status: instanceIds.length === 0 ? 'ok' : 'active',
status: alertIds.length === 0 ? 'ok' : 'active',
};
}
@ -30,12 +30,12 @@ export function executionStatusFromError(error: Error): AlertExecutionStatus {
};
}
export function alertExecutionStatusToRaw({
export function ruleExecutionStatusToRaw({
lastExecutionDate,
lastDuration,
status,
error,
}: AlertExecutionStatus): RawAlertExecutionStatus {
}: AlertExecutionStatus): RawRuleExecutionStatus {
return {
lastExecutionDate: lastExecutionDate.toISOString(),
lastDuration: lastDuration ?? 0,
@ -45,19 +45,19 @@ export function alertExecutionStatusToRaw({
};
}
export function alertExecutionStatusFromRaw(
export function ruleExecutionStatusFromRaw(
logger: Logger,
alertId: string,
rawAlertExecutionStatus?: Partial<RawAlertExecutionStatus> | null | undefined
ruleId: string,
rawRuleExecutionStatus?: Partial<RawRuleExecutionStatus> | null | undefined
): AlertExecutionStatus | undefined {
if (!rawAlertExecutionStatus) return undefined;
if (!rawRuleExecutionStatus) return undefined;
const { lastExecutionDate, lastDuration, status = 'unknown', error } = rawAlertExecutionStatus;
const { lastExecutionDate, lastDuration, status = 'unknown', error } = rawRuleExecutionStatus;
let parsedDateMillis = lastExecutionDate ? Date.parse(lastExecutionDate) : Date.now();
if (isNaN(parsedDateMillis)) {
logger.debug(
`invalid alertExecutionStatus lastExecutionDate "${lastExecutionDate}" in raw alert ${alertId}`
`invalid ruleExecutionStatus lastExecutionDate "${lastExecutionDate}" in raw rule ${ruleId}`
);
parsedDateMillis = Date.now();
}
@ -78,7 +78,7 @@ export function alertExecutionStatusFromRaw(
return executionStatus;
}
export const getAlertExecutionStatusPending = (lastExecutionDate: string) => ({
export const getRuleExecutionStatusPending = (lastExecutionDate: string) => ({
status: 'pending' as AlertExecutionStatuses,
lastExecutionDate,
error: null,

View file

@ -6,17 +6,17 @@
*/
import { schema } from '@kbn/config-schema';
import { validateAlertTypeParams } from './validate_alert_type_params';
import { validateRuleTypeParams } from './validate_rule_type_params';
test('should return passed in params when validation not defined', () => {
const result = validateAlertTypeParams({
const result = validateRuleTypeParams({
foo: true,
});
expect(result).toEqual({ foo: true });
});
test('should validate and apply defaults when params is valid', () => {
const result = validateAlertTypeParams(
const result = validateRuleTypeParams(
{ param1: 'value' },
schema.object({
param1: schema.string(),
@ -31,7 +31,7 @@ test('should validate and apply defaults when params is valid', () => {
test('should validate and throw error when params is invalid', () => {
expect(() =>
validateAlertTypeParams(
validateRuleTypeParams(
{},
schema.object({
param1: schema.string(),

View file

@ -8,7 +8,7 @@
import Boom from '@hapi/boom';
import { AlertTypeParams, AlertTypeParamsValidator } from '../types';
export function validateAlertTypeParams<Params extends AlertTypeParams>(
export function validateRuleTypeParams<Params extends AlertTypeParams>(
params: Record<string, unknown>,
validator?: AlertTypeParamsValidator<Params>
): Params {

View file

@ -16,7 +16,7 @@ import { KibanaRequest } from 'kibana/server';
import { featuresPluginMock } from '../../features/server/mocks';
import { KibanaFeature } from '../../features/server';
import { AlertsConfig } from './config';
import { AlertType } from './types';
import { RuleType } from './types';
import { eventLogMock } from '../../event_log/server/mocks';
import { actionsMock } from '../../actions/server/mocks';
@ -99,7 +99,7 @@ describe('Alerting Plugin', () => {
describe('registerType()', () => {
let setup: PluginSetupContract;
const sampleAlertType: AlertType<never, never, never, never, never, 'default'> = {
const sampleRuleType: RuleType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'test',
minimumLicenseRequired: 'basic',
@ -126,7 +126,7 @@ describe('Alerting Plugin', () => {
it('should throw error when license type is invalid', async () => {
expect(() =>
setup.registerType({
...sampleAlertType,
...sampleRuleType,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
minimumLicenseRequired: 'foo' as any,
})
@ -135,52 +135,52 @@ describe('Alerting Plugin', () => {
it('should not throw when license type is gold', async () => {
setup.registerType({
...sampleAlertType,
...sampleRuleType,
minimumLicenseRequired: 'gold',
});
});
it('should not throw when license type is basic', async () => {
setup.registerType({
...sampleAlertType,
...sampleRuleType,
minimumLicenseRequired: 'basic',
});
});
it('should apply default config value for ruleTaskTimeout if no value is specified', async () => {
const ruleType = {
...sampleAlertType,
...sampleRuleType,
minimumLicenseRequired: 'basic',
} as AlertType<never, never, never, never, never, 'default', never>;
} as RuleType<never, never, never, never, never, 'default', never>;
await setup.registerType(ruleType);
expect(ruleType.ruleTaskTimeout).toBe('5m');
});
it('should apply value for ruleTaskTimeout if specified', async () => {
const ruleType = {
...sampleAlertType,
...sampleRuleType,
minimumLicenseRequired: 'basic',
ruleTaskTimeout: '20h',
} as AlertType<never, never, never, never, never, 'default', never>;
} as RuleType<never, never, never, never, never, 'default', never>;
await setup.registerType(ruleType);
expect(ruleType.ruleTaskTimeout).toBe('20h');
});
it('should apply default config value for cancelAlertsOnRuleTimeout if no value is specified', async () => {
const ruleType = {
...sampleAlertType,
...sampleRuleType,
minimumLicenseRequired: 'basic',
} as AlertType<never, never, never, never, never, 'default', never>;
} as RuleType<never, never, never, never, never, 'default', never>;
await setup.registerType(ruleType);
expect(ruleType.cancelAlertsOnRuleTimeout).toBe(true);
});
it('should apply value for cancelAlertsOnRuleTimeout if specified', async () => {
const ruleType = {
...sampleAlertType,
...sampleRuleType,
minimumLicenseRequired: 'basic',
cancelAlertsOnRuleTimeout: false,
} as AlertType<never, never, never, never, never, 'default', never>;
} as RuleType<never, never, never, never, never, 'default', never>;
await setup.registerType(ruleType);
expect(ruleType.cancelAlertsOnRuleTimeout).toBe(false);
});

View file

@ -46,7 +46,7 @@ import {
AlertInstanceContext,
AlertInstanceState,
AlertsHealth,
AlertType,
RuleType,
AlertTypeParams,
AlertTypeState,
Services,
@ -91,7 +91,7 @@ export interface PluginSetupContract {
ActionGroupIds extends string = never,
RecoveryActionGroupId extends string = never
>(
alertType: AlertType<
ruleType: RuleType<
Params,
ExtractedParams,
State,
@ -273,7 +273,7 @@ export class AlertingPlugin {
ActionGroupIds extends string = never,
RecoveryActionGroupId extends string = never
>(
alertType: AlertType<
ruleType: RuleType<
Params,
ExtractedParams,
State,
@ -283,15 +283,15 @@ export class AlertingPlugin {
RecoveryActionGroupId
>
) {
if (!(alertType.minimumLicenseRequired in LICENSE_TYPE)) {
throw new Error(`"${alertType.minimumLicenseRequired}" is not a valid license type`);
if (!(ruleType.minimumLicenseRequired in LICENSE_TYPE)) {
throw new Error(`"${ruleType.minimumLicenseRequired}" is not a valid license type`);
}
alertingConfig.then((config) => {
alertType.ruleTaskTimeout = alertType.ruleTaskTimeout ?? config.defaultRuleTaskTimeout;
alertType.cancelAlertsOnRuleTimeout =
alertType.cancelAlertsOnRuleTimeout ?? config.cancelAlertsOnRuleTimeout;
ruleTypeRegistry.register(alertType);
ruleType.ruleTaskTimeout = ruleType.ruleTaskTimeout ?? config.defaultRuleTaskTimeout;
ruleType.cancelAlertsOnRuleTimeout =
ruleType.cancelAlertsOnRuleTimeout ?? config.cancelAlertsOnRuleTimeout;
ruleTypeRegistry.register(ruleType);
});
},
getSecurityHealth: async () => {
@ -390,7 +390,7 @@ export class AlertingPlugin {
ruleTypeRegistry: this.ruleTypeRegistry!,
kibanaBaseUrl: this.kibanaBaseUrl,
supportsEphemeralTasks: plugins.taskManager.supportsEphemeralTasks(),
maxEphemeralActionsPerAlert: config.maxEphemeralActionsPerAlert,
maxEphemeralActionsPerRule: config.maxEphemeralActionsPerAlert,
cancelAlertsOnRuleTimeout: config.cancelAlertsOnRuleTimeout,
});
});

View file

@ -10,7 +10,7 @@ import { identity } from 'lodash';
import type { MethodKeysOf } from '@kbn/utility-types';
import { httpServerMock } from '../../../../../src/core/server/mocks';
import { rulesClientMock, RulesClientMock } from '../rules_client.mock';
import { AlertsHealth, AlertType } from '../../common';
import { AlertsHealth, RuleType } from '../../common';
import type { AlertingRequestHandlerContext } from '../types';
export function mockHandlerArguments(
@ -21,7 +21,7 @@ export function mockHandlerArguments(
areApiKeysEnabled,
}: {
rulesClient?: RulesClientMock;
listTypes?: AlertType[];
listTypes?: RuleType[];
getFrameworkHealth?: jest.MockInstance<Promise<AlertsHealth>, []> &
(() => Promise<AlertsHealth>);
areApiKeysEnabled?: () => Promise<boolean>;

View file

@ -12,14 +12,14 @@ import { RewriteResponseCase, verifyAccessAndContext } from './lib';
import {
AlertingRequestHandlerContext,
INTERNAL_BASE_ALERTING_API_PATH,
AlertTaskState,
RuleTaskState,
} from '../types';
const paramSchema = schema.object({
id: schema.string(),
});
const rewriteBodyRes: RewriteResponseCase<AlertTaskState> = ({
const rewriteBodyRes: RewriteResponseCase<RuleTaskState> = ({
alertTypeState,
alertInstances,
previousStartedAt,

View file

@ -7,7 +7,7 @@
import { TaskRunnerFactory } from './task_runner';
import { RuleTypeRegistry, ConstructorOptions } from './rule_type_registry';
import { ActionGroup, AlertType } from './types';
import { ActionGroup, RuleType } from './types';
import { taskManagerMock } from '../../task_manager/server/mocks';
import { ILicenseState } from './lib/license_state';
import { licenseStateMock } from './lib/license_state.mock';
@ -56,8 +56,8 @@ describe('has()', () => {
});
describe('register()', () => {
test('throws if AlertType Id contains invalid characters', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
test('throws if RuleType Id contains invalid characters', () => {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -76,21 +76,21 @@ describe('register()', () => {
const invalidCharacters = [' ', ':', '*', '*', '/'];
for (const char of invalidCharacters) {
expect(() => registry.register({ ...alertType, id: `${alertType.id}${char}` })).toThrowError(
new Error(`expected AlertType Id not to include invalid character: ${char}`)
expect(() => registry.register({ ...ruleType, id: `${ruleType.id}${char}` })).toThrowError(
new Error(`expected RuleType Id not to include invalid character: ${char}`)
);
}
const [first, second] = invalidCharacters;
expect(() =>
registry.register({ ...alertType, id: `${first}${alertType.id}${second}` })
registry.register({ ...ruleType, id: `${first}${ruleType.id}${second}` })
).toThrowError(
new Error(`expected AlertType Id not to include invalid characters: ${first}, ${second}`)
new Error(`expected RuleType Id not to include invalid characters: ${first}, ${second}`)
);
});
test('throws if AlertType Id isnt a string', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
test('throws if RuleType Id isnt a string', () => {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: 123 as unknown as string,
name: 'Test',
actionGroups: [
@ -107,13 +107,13 @@ describe('register()', () => {
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
expect(() => registry.register(alertType)).toThrowError(
expect(() => registry.register(ruleType)).toThrowError(
new Error(`expected value of type [string] but got [number]`)
);
});
test('throws if AlertType ruleTaskTimeout is not a valid duration', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
test('throws if RuleType ruleTaskTimeout is not a valid duration', () => {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: '123',
name: 'Test',
actionGroups: [
@ -131,7 +131,7 @@ describe('register()', () => {
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
expect(() => registry.register(alertType)).toThrowError(
expect(() => registry.register(ruleType)).toThrowError(
new Error(
`Rule type \"123\" has invalid timeout: string is not a valid duration: 23 milisec.`
)
@ -139,7 +139,7 @@ describe('register()', () => {
});
test('throws if defaultScheduleInterval isnt valid', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: '123',
name: 'Test',
actionGroups: [
@ -158,7 +158,7 @@ describe('register()', () => {
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
expect(() => registry.register(alertType)).toThrowError(
expect(() => registry.register(ruleType)).toThrowError(
new Error(
`Rule type \"123\" has invalid default interval: string is not a valid duration: foobar.`
)
@ -166,7 +166,7 @@ describe('register()', () => {
});
test('throws if minimumScheduleInterval isnt valid', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: '123',
name: 'Test',
actionGroups: [
@ -184,7 +184,7 @@ describe('register()', () => {
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
expect(() => registry.register(alertType)).toThrowError(
expect(() => registry.register(ruleType)).toThrowError(
new Error(
`Rule type \"123\" has invalid minimum interval: string is not a valid duration: foobar.`
)
@ -192,7 +192,7 @@ describe('register()', () => {
});
test('throws if RuleType action groups contains reserved group id', () => {
const alertType: AlertType<never, never, never, never, never, 'default' | 'NotReserved'> = {
const ruleType: RuleType<never, never, never, never, never, 'default' | 'NotReserved'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -217,15 +217,15 @@ describe('register()', () => {
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
expect(() => registry.register(alertType)).toThrowError(
expect(() => registry.register(ruleType)).toThrowError(
new Error(
`Rule type [id="${alertType.id}"] cannot be registered. Action groups [recovered] are reserved by the framework.`
`Rule type [id="${ruleType.id}"] cannot be registered. Action groups [recovered] are reserved by the framework.`
)
);
});
test('allows an AlertType to specify a custom recovery group', () => {
const alertType: AlertType<never, never, never, never, never, 'default', 'backToAwesome'> = {
test('allows an RuleType to specify a custom recovery group', () => {
const ruleType: RuleType<never, never, never, never, never, 'default', 'backToAwesome'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -245,7 +245,7 @@ describe('register()', () => {
isExportable: true,
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
registry.register(alertType);
registry.register(ruleType);
expect(registry.get('test').actionGroups).toMatchInlineSnapshot(`
Array [
Object {
@ -260,8 +260,8 @@ describe('register()', () => {
`);
});
test('allows an AlertType to specify a custom rule task timeout', () => {
const alertType: AlertType<never, never, never, never, never, 'default', 'backToAwesome'> = {
test('allows an RuleType to specify a custom rule task timeout', () => {
const ruleType: RuleType<never, never, never, never, never, 'default', 'backToAwesome'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -278,12 +278,12 @@ describe('register()', () => {
isExportable: true,
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
registry.register(alertType);
registry.register(ruleType);
expect(registry.get('test').ruleTaskTimeout).toBe('13m');
});
test('throws if the custom recovery group is contained in the AlertType action groups', () => {
const alertType: AlertType<
test('throws if the custom recovery group is contained in the RuleType action groups', () => {
const ruleType: RuleType<
never,
never,
never,
@ -316,15 +316,15 @@ describe('register()', () => {
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
expect(() => registry.register(alertType)).toThrowError(
expect(() => registry.register(ruleType)).toThrowError(
new Error(
`Rule type [id="${alertType.id}"] cannot be registered. Action group [backToAwesome] cannot be used as both a recovery and an active action group.`
`Rule type [id="${ruleType.id}"] cannot be registered. Action group [backToAwesome] cannot be used as both a recovery and an active action group.`
)
);
});
test('registers the executor with the task manager', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -341,7 +341,7 @@ describe('register()', () => {
ruleTaskTimeout: '20m',
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
registry.register(alertType);
registry.register(ruleType);
expect(taskManager.registerTaskDefinitions).toHaveBeenCalledTimes(1);
expect(taskManager.registerTaskDefinitions.mock.calls[0]).toMatchInlineSnapshot(`
Array [
@ -357,7 +357,7 @@ describe('register()', () => {
});
test('shallow clones the given rule type', () => {
const alertType: AlertType<never, never, never, never, never, 'default'> = {
const ruleType: RuleType<never, never, never, never, never, 'default'> = {
id: 'test',
name: 'Test',
actionGroups: [
@ -373,8 +373,8 @@ describe('register()', () => {
producer: 'alerts',
};
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
registry.register(alertType);
alertType.name = 'Changed';
registry.register(ruleType);
ruleType.name = 'Changed';
expect(registry.get('test').name).toEqual('Test');
});
@ -433,8 +433,8 @@ describe('get()', () => {
executor: jest.fn(),
producer: 'alerts',
});
const alertType = registry.get('test');
expect(alertType).toMatchInlineSnapshot(`
const ruleType = registry.get('test');
expect(ruleType).toMatchInlineSnapshot(`
Object {
"actionGroups": Array [
Object {
@ -539,12 +539,12 @@ describe('list()', () => {
test('should return action variables state and empty context', () => {
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
registry.register(alertTypeWithVariables('x', '', 's'));
const alertType = registry.get('x');
expect(alertType.actionVariables).toBeTruthy();
registry.register(ruleTypeWithVariables('x', '', 's'));
const ruleType = registry.get('x');
expect(ruleType.actionVariables).toBeTruthy();
const context = alertType.actionVariables!.context;
const state = alertType.actionVariables!.state;
const context = ruleType.actionVariables!.context;
const state = ruleType.actionVariables!.state;
expect(context).toBeTruthy();
expect(context!.length).toBe(0);
@ -556,12 +556,12 @@ describe('list()', () => {
test('should return action variables context and empty state', () => {
const registry = new RuleTypeRegistry(ruleTypeRegistryParams);
registry.register(alertTypeWithVariables('x', 'c', ''));
const alertType = registry.get('x');
expect(alertType.actionVariables).toBeTruthy();
registry.register(ruleTypeWithVariables('x', 'c', ''));
const ruleType = registry.get('x');
expect(ruleType.actionVariables).toBeTruthy();
const context = alertType.actionVariables!.context;
const state = alertType.actionVariables!.state;
const context = ruleType.actionVariables!.context;
const state = ruleType.actionVariables!.state;
expect(state).toBeTruthy();
expect(state!.length).toBe(0);
@ -597,11 +597,11 @@ describe('ensureRuleTypeEnabled', () => {
test('should call ensureLicenseForAlertType on the license state', async () => {
ruleTypeRegistry.ensureRuleTypeEnabled('test');
expect(mockedLicenseState.ensureLicenseForAlertType).toHaveBeenCalled();
expect(mockedLicenseState.ensureLicenseForRuleType).toHaveBeenCalled();
});
test('should throw when ensureLicenseForAlertType throws', async () => {
mockedLicenseState.ensureLicenseForAlertType.mockImplementation(() => {
mockedLicenseState.ensureLicenseForRuleType.mockImplementation(() => {
throw new Error('Fail');
});
expect(() => ruleTypeRegistry.ensureRuleTypeEnabled('test')).toThrowErrorMatchingInlineSnapshot(
@ -610,12 +610,12 @@ describe('ensureRuleTypeEnabled', () => {
});
});
function alertTypeWithVariables<ActionGroupIds extends string>(
function ruleTypeWithVariables<ActionGroupIds extends string>(
id: ActionGroupIds,
context: string,
state: string
): AlertType<never, never, never, never, never, ActionGroupIds> {
const baseAlert: AlertType<never, never, never, never, never, ActionGroupIds> = {
): RuleType<never, never, never, never, never, ActionGroupIds> {
const baseAlert: RuleType<never, never, never, never, never, ActionGroupIds> = {
id,
name: `${id}-name`,
actionGroups: [],

View file

@ -14,7 +14,7 @@ import { LicensingPluginSetup } from '../../licensing/server';
import { RunContext, TaskManagerSetupContract } from '../../task_manager/server';
import { TaskRunnerFactory } from './task_runner';
import {
AlertType,
RuleType,
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
@ -28,7 +28,7 @@ import {
validateDurationSchema,
} from '../common';
import { ILicenseState } from './lib/license_state';
import { getAlertTypeFeatureUsageName } from './lib/get_alert_type_feature_usage_name';
import { getRuleTypeFeatureUsageName } from './lib/get_rule_type_feature_usage_name';
export interface ConstructorOptions {
taskManager: TaskManagerSetupContract;
@ -39,7 +39,7 @@ export interface ConstructorOptions {
export interface RegistryRuleType
extends Pick<
UntypedNormalizedAlertType,
UntypedNormalizedRuleType,
| 'name'
| 'actionGroups'
| 'recoveryActionGroup'
@ -57,26 +57,26 @@ export interface RegistryRuleType
}
/**
* AlertType IDs are used as part of the authorization strings used to
* RuleType IDs are used as part of the authorization strings used to
* grant users privileged operations. There is a limited range of characters
* we can use in these auth strings, so we apply these same limitations to
* the AlertType Ids.
* the RuleType Ids.
* If you wish to change this, please confer with the Kibana security team.
*/
const alertIdSchema = schema.string({
const ruleTypeIdSchema = schema.string({
validate(value: string): string | void {
if (typeof value !== 'string') {
return `expected AlertType Id of type [string] but got [${typeDetect(value)}]`;
return `expected RuleType Id of type [string] but got [${typeDetect(value)}]`;
} else if (!value.match(/^[a-zA-Z0-9_\-\.]*$/)) {
const invalid = value.match(/[^a-zA-Z0-9_\-\.]+/g)!;
return `expected AlertType Id not to include invalid character${
return `expected RuleType Id not to include invalid character${
invalid.length > 1 ? `s` : ``
}: ${invalid?.join(`, `)}`;
}
},
});
export type NormalizedAlertType<
export type NormalizedRuleType<
Params extends AlertTypeParams,
ExtractedParams extends AlertTypeParams,
State extends AlertTypeState,
@ -87,7 +87,7 @@ export type NormalizedAlertType<
> = {
actionGroups: Array<ActionGroup<ActionGroupIds | RecoveryActionGroupId>>;
} & Omit<
AlertType<
RuleType<
Params,
ExtractedParams,
State,
@ -100,7 +100,7 @@ export type NormalizedAlertType<
> &
Pick<
Required<
AlertType<
RuleType<
Params,
ExtractedParams,
State,
@ -113,7 +113,7 @@ export type NormalizedAlertType<
'recoveryActionGroup'
>;
export type UntypedNormalizedAlertType = NormalizedAlertType<
export type UntypedNormalizedRuleType = NormalizedRuleType<
AlertTypeParams,
AlertTypeParams,
AlertTypeState,
@ -125,7 +125,7 @@ export type UntypedNormalizedAlertType = NormalizedAlertType<
export class RuleTypeRegistry {
private readonly taskManager: TaskManagerSetupContract;
private readonly ruleTypes: Map<string, UntypedNormalizedAlertType> = new Map();
private readonly ruleTypes: Map<string, UntypedNormalizedRuleType> = new Map();
private readonly taskRunnerFactory: TaskRunnerFactory;
private readonly licenseState: ILicenseState;
private readonly licensing: LicensingPluginSetup;
@ -142,7 +142,7 @@ export class RuleTypeRegistry {
}
public ensureRuleTypeEnabled(id: string) {
this.licenseState.ensureLicenseForAlertType(this.get(id));
this.licenseState.ensureLicenseForRuleType(this.get(id));
}
public register<
@ -154,7 +154,7 @@ export class RuleTypeRegistry {
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: AlertType<
ruleType: RuleType<
Params,
ExtractedParams,
State,
@ -164,44 +164,44 @@ export class RuleTypeRegistry {
RecoveryActionGroupId
>
) {
if (this.has(alertType.id)) {
if (this.has(ruleType.id)) {
throw new Error(
i18n.translate('xpack.alerting.ruleTypeRegistry.register.duplicateAlertTypeError', {
i18n.translate('xpack.alerting.ruleTypeRegistry.register.duplicateRuleTypeError', {
defaultMessage: 'Rule type "{id}" is already registered.',
values: {
id: alertType.id,
id: ruleType.id,
},
})
);
}
// validate ruleTypeTimeout here
if (alertType.ruleTaskTimeout) {
const invalidTimeout = validateDurationSchema(alertType.ruleTaskTimeout);
if (ruleType.ruleTaskTimeout) {
const invalidTimeout = validateDurationSchema(ruleType.ruleTaskTimeout);
if (invalidTimeout) {
throw new Error(
i18n.translate('xpack.alerting.ruleTypeRegistry.register.invalidTimeoutAlertTypeError', {
i18n.translate('xpack.alerting.ruleTypeRegistry.register.invalidTimeoutRuleTypeError', {
defaultMessage: 'Rule type "{id}" has invalid timeout: {errorMessage}.',
values: {
id: alertType.id,
id: ruleType.id,
errorMessage: invalidTimeout,
},
})
);
}
}
alertType.actionVariables = normalizedActionVariables(alertType.actionVariables);
ruleType.actionVariables = normalizedActionVariables(ruleType.actionVariables);
// validate defaultScheduleInterval here
if (alertType.defaultScheduleInterval) {
const invalidDefaultTimeout = validateDurationSchema(alertType.defaultScheduleInterval);
if (ruleType.defaultScheduleInterval) {
const invalidDefaultTimeout = validateDurationSchema(ruleType.defaultScheduleInterval);
if (invalidDefaultTimeout) {
throw new Error(
i18n.translate(
'xpack.alerting.ruleTypeRegistry.register.invalidDefaultTimeoutAlertTypeError',
'xpack.alerting.ruleTypeRegistry.register.invalidDefaultTimeoutRuleTypeError',
{
defaultMessage: 'Rule type "{id}" has invalid default interval: {errorMessage}.',
values: {
id: alertType.id,
id: ruleType.id,
errorMessage: invalidDefaultTimeout,
},
}
@ -211,16 +211,16 @@ export class RuleTypeRegistry {
}
// validate minimumScheduleInterval here
if (alertType.minimumScheduleInterval) {
const invalidMinimumTimeout = validateDurationSchema(alertType.minimumScheduleInterval);
if (ruleType.minimumScheduleInterval) {
const invalidMinimumTimeout = validateDurationSchema(ruleType.minimumScheduleInterval);
if (invalidMinimumTimeout) {
throw new Error(
i18n.translate(
'xpack.alerting.ruleTypeRegistry.register.invalidMinimumTimeoutAlertTypeError',
'xpack.alerting.ruleTypeRegistry.register.invalidMinimumTimeoutRuleTypeError',
{
defaultMessage: 'Rule type "{id}" has invalid minimum interval: {errorMessage}.',
values: {
id: alertType.id,
id: ruleType.id,
errorMessage: invalidMinimumTimeout,
},
}
@ -229,7 +229,7 @@ export class RuleTypeRegistry {
}
}
const normalizedAlertType = augmentActionGroupsWithReserved<
const normalizedRuleType = augmentActionGroupsWithReserved<
Params,
ExtractedParams,
State,
@ -237,17 +237,17 @@ export class RuleTypeRegistry {
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>(alertType);
>(ruleType);
this.ruleTypes.set(
alertIdSchema.validate(alertType.id),
/** stripping the typing is required in order to store the AlertTypes in a Map */
normalizedAlertType as unknown as UntypedNormalizedAlertType
ruleTypeIdSchema.validate(ruleType.id),
/** stripping the typing is required in order to store the RuleTypes in a Map */
normalizedRuleType as unknown as UntypedNormalizedRuleType
);
this.taskManager.registerTaskDefinitions({
[`alerting:${alertType.id}`]: {
title: alertType.name,
timeout: alertType.ruleTaskTimeout,
[`alerting:${ruleType.id}`]: {
title: ruleType.name,
timeout: ruleType.ruleTaskTimeout,
createTaskRunner: (context: RunContext) =>
this.taskRunnerFactory.create<
Params,
@ -257,14 +257,14 @@ export class RuleTypeRegistry {
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId | RecoveredActionGroupId
>(normalizedAlertType, context),
>(normalizedRuleType, context),
},
});
// No need to notify usage on basic alert types
if (alertType.minimumLicenseRequired !== 'basic') {
if (ruleType.minimumLicenseRequired !== 'basic') {
this.licensing.featureUsage.register(
getAlertTypeFeatureUsageName(alertType.name),
alertType.minimumLicenseRequired
getRuleTypeFeatureUsageName(ruleType.name),
ruleType.minimumLicenseRequired
);
}
}
@ -279,7 +279,7 @@ export class RuleTypeRegistry {
RecoveryActionGroupId extends string = string
>(
id: string
): NormalizedAlertType<
): NormalizedRuleType<
Params,
ExtractedParams,
State,
@ -290,7 +290,7 @@ export class RuleTypeRegistry {
> {
if (!this.has(id)) {
throw Boom.badRequest(
i18n.translate('xpack.alerting.ruleTypeRegistry.get.missingAlertTypeError', {
i18n.translate('xpack.alerting.ruleTypeRegistry.get.missingRuleTypeError', {
defaultMessage: 'Rule type "{id}" is not registered.',
values: {
id,
@ -299,11 +299,11 @@ export class RuleTypeRegistry {
);
}
/**
* When we store the AlertTypes in the Map we strip the typing.
* This means that returning a typed AlertType in `get` is an inherently
* When we store the RuleTypes in the Map we strip the typing.
* This means that returning a typed RuleType in `get` is an inherently
* unsafe operation. Down casting to `unknown` is the only way to achieve this.
*/
return this.ruleTypes.get(id)! as unknown as NormalizedAlertType<
return this.ruleTypes.get(id)! as unknown as NormalizedRuleType<
Params,
ExtractedParams,
State,
@ -332,7 +332,7 @@ export class RuleTypeRegistry {
minimumScheduleInterval,
defaultScheduleInterval,
},
]: [string, UntypedNormalizedAlertType]) => ({
]: [string, UntypedNormalizedRuleType]) => ({
id,
name,
actionGroups,
@ -345,7 +345,7 @@ export class RuleTypeRegistry {
ruleTaskTimeout,
minimumScheduleInterval,
defaultScheduleInterval,
enabledInLicense: !!this.licenseState.getLicenseCheckForAlertType(
enabledInLicense: !!this.licenseState.getLicenseCheckForRuleType(
id,
name,
minimumLicenseRequired
@ -356,7 +356,7 @@ export class RuleTypeRegistry {
}
}
function normalizedActionVariables(actionVariables: AlertType['actionVariables']) {
function normalizedActionVariables(actionVariables: RuleType['actionVariables']) {
return {
context: actionVariables?.context ?? [],
state: actionVariables?.state ?? [],
@ -373,7 +373,7 @@ function augmentActionGroupsWithReserved<
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: AlertType<
ruleType: RuleType<
Params,
ExtractedParams,
State,
@ -382,7 +382,7 @@ function augmentActionGroupsWithReserved<
ActionGroupIds,
RecoveryActionGroupId
>
): NormalizedAlertType<
): NormalizedRuleType<
Params,
ExtractedParams,
State,
@ -391,8 +391,8 @@ function augmentActionGroupsWithReserved<
ActionGroupIds,
RecoveredActionGroupId | RecoveryActionGroupId
> {
const reservedActionGroups = getBuiltinActionGroups(alertType.recoveryActionGroup);
const { id, actionGroups, recoveryActionGroup } = alertType;
const reservedActionGroups = getBuiltinActionGroups(ruleType.recoveryActionGroup);
const { id, actionGroups, recoveryActionGroup } = ruleType;
const activeActionGroups = new Set<string>(actionGroups.map((item) => item.id));
const intersectingReservedActionGroups = intersection<string>(
@ -427,7 +427,7 @@ function augmentActionGroupsWithReserved<
}
return {
...alertType,
...ruleType,
actionGroups: [...actionGroups, ...reservedActionGroups],
recoveryActionGroup: recoveryActionGroup ?? RecoveredActionGroup,
};

View file

@ -24,27 +24,23 @@ import { ActionsClient, ActionsAuthorization } from '../../../actions/server';
import {
Alert,
PartialAlert,
RawAlert,
RawRule,
RuleTypeRegistry,
AlertAction,
IntervalSchedule,
SanitizedAlert,
AlertTaskState,
RuleTaskState,
AlertSummary,
AlertExecutionStatusValues,
AlertNotifyWhenType,
AlertTypeParams,
ResolvedSanitizedRule,
AlertWithLegacyId,
SanitizedAlertWithLegacyId,
SanitizedRuleWithLegacyId,
PartialAlertWithLegacyId,
RawAlertInstance,
} from '../types';
import {
validateAlertTypeParams,
alertExecutionStatusFromRaw,
getAlertNotifyWhenType,
} from '../lib';
import { validateRuleTypeParams, ruleExecutionStatusFromRaw, getAlertNotifyWhenType } from '../lib';
import {
GrantAPIKeyResult as SecurityPluginGrantAPIKeyResult,
InvalidateAPIKeyResult as SecurityPluginInvalidateAPIKeyResult,
@ -52,7 +48,7 @@ import {
import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server';
import { TaskManagerStartContract } from '../../../task_manager/server';
import { taskInstanceToAlertTaskInstance } from '../task_runner/alert_task_instance';
import { RegistryRuleType, UntypedNormalizedAlertType } from '../rule_type_registry';
import { RegistryRuleType, UntypedNormalizedRuleType } from '../rule_type_registry';
import {
AlertingAuthorization,
WriteOperations,
@ -77,7 +73,7 @@ import { markApiKeyForInvalidation } from '../invalidate_pending_api_keys/mark_a
import { ruleAuditEvent, RuleAuditAction } from './audit_events';
import { KueryNode, nodeBuilder } from '../../../../../src/plugins/data/common';
import { mapSortField } from './lib';
import { getAlertExecutionStatusPending } from '../lib/alert_execution_status';
import { getRuleExecutionStatusPending } from '../lib/rule_execution_status';
import { AlertInstance } from '../alert_instance';
import { EVENT_LOG_ACTIONS } from '../plugin';
import { createAlertEventLogRecordObject } from '../lib/create_alert_event_log_record_object';
@ -316,10 +312,7 @@ export class RulesClient {
// Throws an error if alert type isn't registered
const ruleType = this.ruleTypeRegistry.get(data.alertTypeId);
const validatedAlertTypeParams = validateAlertTypeParams(
data.params,
ruleType.validate?.params
);
const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params);
const username = await this.getUserName();
let createdAPIKey = null;
@ -355,7 +348,7 @@ export class RulesClient {
const legacyId = Semver.lt(this.kibanaVersion, '8.0.0') ? id : null;
const notifyWhen = getAlertNotifyWhenType(data.notifyWhen, data.throttle);
const rawAlert: RawAlert = {
const rawRule: RawRule = {
...data,
...this.apiKeyAsAlertAttributes(createdAPIKey, username),
legacyId,
@ -364,11 +357,11 @@ export class RulesClient {
updatedBy: username,
createdAt: new Date(createTime).toISOString(),
updatedAt: new Date(createTime).toISOString(),
params: updatedParams as RawAlert['params'],
params: updatedParams as RawRule['params'],
muteAll: false,
mutedInstanceIds: [],
notifyWhen,
executionStatus: getAlertExecutionStatusPending(new Date().toISOString()),
executionStatus: getRuleExecutionStatusPending(new Date().toISOString()),
};
this.auditLogger?.log(
@ -379,11 +372,11 @@ export class RulesClient {
})
);
let createdAlert: SavedObject<RawAlert>;
let createdAlert: SavedObject<RawRule>;
try {
createdAlert = await this.unsecuredSavedObjectsClient.create(
'alert',
this.updateMeta(rawAlert),
this.updateMeta(rawRule),
{
...options,
references,
@ -393,7 +386,7 @@ export class RulesClient {
} catch (e) {
// Avoid unused API key
markApiKeyForInvalidation(
{ apiKey: rawAlert.apiKey },
{ apiKey: rawRule.apiKey },
this.logger,
this.unsecuredSavedObjectsClient
);
@ -404,7 +397,7 @@ export class RulesClient {
try {
scheduledTask = await this.scheduleRule(
createdAlert.id,
rawAlert.alertTypeId,
rawRule.alertTypeId,
data.schedule,
true
);
@ -420,7 +413,7 @@ export class RulesClient {
}
throw e;
}
await this.unsecuredSavedObjectsClient.update<RawAlert>('alert', createdAlert.id, {
await this.unsecuredSavedObjectsClient.update<RawRule>('alert', createdAlert.id, {
scheduledTaskId: scheduledTask.id,
});
createdAlert.attributes.scheduledTaskId = scheduledTask.id;
@ -439,8 +432,8 @@ export class RulesClient {
}: {
id: string;
includeLegacyId?: boolean;
}): Promise<SanitizedAlert<Params> | SanitizedAlertWithLegacyId<Params>> {
const result = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
}): Promise<SanitizedAlert<Params> | SanitizedRuleWithLegacyId<Params>> {
const result = await this.unsecuredSavedObjectsClient.get<RawRule>('alert', id);
try {
await this.authorization.ensureAuthorized({
ruleTypeId: result.attributes.alertTypeId,
@ -481,7 +474,7 @@ export class RulesClient {
includeLegacyId?: boolean;
}): Promise<ResolvedSanitizedRule<Params>> {
const { saved_object: result, ...resolveResponse } =
await this.unsecuredSavedObjectsClient.resolve<RawAlert>('alert', id);
await this.unsecuredSavedObjectsClient.resolve<RawRule>('alert', id);
try {
await this.authorization.ensureAuthorized({
ruleTypeId: result.attributes.alertTypeId,
@ -520,7 +513,7 @@ export class RulesClient {
};
}
public async getAlertState({ id }: { id: string }): Promise<AlertTaskState | void> {
public async getAlertState({ id }: { id: string }): Promise<RuleTaskState | void> {
const alert = await this.get({ id });
await this.authorization.ensureAuthorized({
ruleTypeId: alert.alertTypeId,
@ -539,7 +532,7 @@ export class RulesClient {
public async getAlertSummary({ id, dateStart }: GetAlertSummaryParams): Promise<AlertSummary> {
this.logger.debug(`getAlertSummary(): getting alert ${id}`);
const rule = (await this.get({ id, includeLegacyId: true })) as SanitizedAlertWithLegacyId;
const rule = (await this.get({ id, includeLegacyId: true })) as SanitizedRuleWithLegacyId;
await this.authorization.ensureAuthorized({
ruleTypeId: rule.alertTypeId,
@ -612,7 +605,7 @@ export class RulesClient {
per_page: perPage,
total,
saved_objects: data,
} = await this.unsecuredSavedObjectsClient.find<RawAlert>({
} = await this.unsecuredSavedObjectsClient.find<RawRule>({
...options,
sortField: mapSortField(options.sortField),
filter:
@ -646,7 +639,7 @@ export class RulesClient {
return this.getAlertFromRaw<Params>(
id,
attributes.alertTypeId,
fields ? (pick(attributes, fields) as RawAlert) : attributes,
fields ? (pick(attributes, fields) as RawRule) : attributes,
references
);
});
@ -687,7 +680,7 @@ export class RulesClient {
throw error;
}
const { filter: authorizationFilter } = authorizationTuple;
const resp = await this.unsecuredSavedObjectsClient.find<RawAlert, RuleAggregation>({
const resp = await this.unsecuredSavedObjectsClient.find<RawRule, RuleAggregation>({
...options,
filter:
(authorizationFilter && filter
@ -776,11 +769,11 @@ export class RulesClient {
private async deleteWithOCC({ id }: { id: string }) {
let taskIdToRemove: string | undefined | null;
let apiKeyToInvalidate: string | null = null;
let attributes: RawAlert;
let attributes: RawRule;
try {
const decryptedAlert =
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawAlert>('alert', id, {
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawRule>('alert', id, {
namespace: this.namespace,
});
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@ -792,7 +785,7 @@ export class RulesClient {
`delete(): Failed to load API key to invalidate on alert ${id}: ${e.message}`
);
// Still attempt to load the scheduledTaskId using SOC
const alert = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
const alert = await this.unsecuredSavedObjectsClient.get<RawRule>('alert', id);
taskIdToRemove = alert.attributes.scheduledTaskId;
attributes = alert.attributes;
}
@ -854,20 +847,23 @@ export class RulesClient {
id,
data,
}: UpdateOptions<Params>): Promise<PartialAlert<Params>> {
let alertSavedObject: SavedObject<RawAlert>;
let alertSavedObject: SavedObject<RawRule>;
try {
alertSavedObject =
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawAlert>('alert', id, {
alertSavedObject = await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawRule>(
'alert',
id,
{
namespace: this.namespace,
});
}
);
} catch (e) {
// We'll skip invalidating the API key since we failed to load the decrypted saved object
this.logger.error(
`update(): Failed to load API key to invalidate on alert ${id}: ${e.message}`
);
// Still attempt to load the object using SOC
alertSavedObject = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
alertSavedObject = await this.unsecuredSavedObjectsClient.get<RawRule>('alert', id);
}
try {
@ -934,15 +930,12 @@ export class RulesClient {
private async updateAlert<Params extends AlertTypeParams>(
{ id, data }: UpdateOptions<Params>,
{ attributes, version }: SavedObject<RawAlert>
{ attributes, version }: SavedObject<RawRule>
): Promise<PartialAlert<Params>> {
const ruleType = this.ruleTypeRegistry.get(attributes.alertTypeId);
// Validate
const validatedAlertTypeParams = validateAlertTypeParams(
data.params,
ruleType.validate?.params
);
const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params);
await this.validateActions(ruleType, data.actions);
// Validate intervals, if configured
@ -977,19 +970,19 @@ export class RulesClient {
const apiKeyAttributes = this.apiKeyAsAlertAttributes(createdAPIKey, username);
const notifyWhen = getAlertNotifyWhenType(data.notifyWhen, data.throttle);
let updatedObject: SavedObject<RawAlert>;
let updatedObject: SavedObject<RawRule>;
const createAttributes = this.updateMeta({
...attributes,
...data,
...apiKeyAttributes,
params: updatedParams as RawAlert['params'],
params: updatedParams as RawRule['params'],
actions,
notifyWhen,
updatedBy: username,
updatedAt: new Date().toISOString(),
});
try {
updatedObject = await this.unsecuredSavedObjectsClient.create<RawAlert>(
updatedObject = await this.unsecuredSavedObjectsClient.create<RawRule>(
'alert',
createAttributes,
{
@ -1020,7 +1013,7 @@ export class RulesClient {
private apiKeyAsAlertAttributes(
apiKey: CreateAPIKeyResult | null,
username: string | null
): Pick<RawAlert, 'apiKey' | 'apiKeyOwner'> {
): Pick<RawRule, 'apiKey' | 'apiKeyOwner'> {
return apiKey && apiKey.apiKeysEnabled
? {
apiKeyOwner: username,
@ -1042,12 +1035,12 @@ export class RulesClient {
private async updateApiKeyWithOCC({ id }: { id: string }) {
let apiKeyToInvalidate: string | null = null;
let attributes: RawAlert;
let attributes: RawRule;
let version: string | undefined;
try {
const decryptedAlert =
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawAlert>('alert', id, {
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawRule>('alert', id, {
namespace: this.namespace,
});
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@ -1059,7 +1052,7 @@ export class RulesClient {
`updateApiKey(): Failed to load API key to invalidate on alert ${id}: ${e.message}`
);
// Still attempt to load the attributes and version using SOC
const alert = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
const alert = await this.unsecuredSavedObjectsClient.get<RawRule>('alert', id);
attributes = alert.attributes;
version = alert.version;
}
@ -1146,12 +1139,12 @@ export class RulesClient {
private async enableWithOCC({ id }: { id: string }) {
let apiKeyToInvalidate: string | null = null;
let attributes: RawAlert;
let attributes: RawRule;
let version: string | undefined;
try {
const decryptedAlert =
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawAlert>('alert', id, {
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawRule>('alert', id, {
namespace: this.namespace,
});
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@ -1163,7 +1156,7 @@ export class RulesClient {
`enable(): Failed to load API key to invalidate on alert ${id}: ${e.message}`
);
// Still attempt to load the attributes and version using SOC
const alert = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
const alert = await this.unsecuredSavedObjectsClient.get<RawRule>('alert', id);
attributes = alert.attributes;
version = alert.version;
}
@ -1265,12 +1258,12 @@ export class RulesClient {
private async disableWithOCC({ id }: { id: string }) {
let apiKeyToInvalidate: string | null = null;
let attributes: RawAlert;
let attributes: RawRule;
let version: string | undefined;
try {
const decryptedAlert =
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawAlert>('alert', id, {
await this.encryptedSavedObjectsClient.getDecryptedAsInternalUser<RawRule>('alert', id, {
namespace: this.namespace,
});
apiKeyToInvalidate = decryptedAlert.attributes.apiKey;
@ -1282,7 +1275,7 @@ export class RulesClient {
`disable(): Failed to load API key to invalidate on alert ${id}: ${e.message}`
);
// Still attempt to load the attributes and version using SOC
const alert = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
const alert = await this.unsecuredSavedObjectsClient.get<RawRule>('alert', id);
attributes = alert.attributes;
version = alert.version;
}
@ -1403,7 +1396,7 @@ export class RulesClient {
}
private async muteAllWithOCC({ id }: { id: string }) {
const { attributes, version } = await this.unsecuredSavedObjectsClient.get<RawAlert>(
const { attributes, version } = await this.unsecuredSavedObjectsClient.get<RawRule>(
'alert',
id
);
@ -1465,7 +1458,7 @@ export class RulesClient {
}
private async unmuteAllWithOCC({ id }: { id: string }) {
const { attributes, version } = await this.unsecuredSavedObjectsClient.get<RawAlert>(
const { attributes, version } = await this.unsecuredSavedObjectsClient.get<RawRule>(
'alert',
id
);
@ -1633,7 +1626,7 @@ export class RulesClient {
const mutedInstanceIds = attributes.mutedInstanceIds || [];
if (!attributes.muteAll && mutedInstanceIds.includes(alertInstanceId)) {
await this.unsecuredSavedObjectsClient.update<RawAlert>(
await this.unsecuredSavedObjectsClient.update<RawRule>(
'alert',
alertId,
this.updateMeta({
@ -1691,7 +1684,7 @@ export class RulesClient {
private injectReferencesIntoActions(
alertId: string,
actions: RawAlert['actions'],
actions: RawRule['actions'],
references: SavedObjectReference[]
) {
return actions.map((action) => {
@ -1716,18 +1709,18 @@ export class RulesClient {
private getAlertFromRaw<Params extends AlertTypeParams>(
id: string,
ruleTypeId: string,
rawAlert: RawAlert,
rawRule: RawRule,
references: SavedObjectReference[] | undefined,
includeLegacyId: boolean = false
): Alert | AlertWithLegacyId {
const ruleType = this.ruleTypeRegistry.get(ruleTypeId);
// In order to support the partial update API of Saved Objects we have to support
// partial updates of an Alert, but when we receive an actual RawAlert, it is safe
// partial updates of an Alert, but when we receive an actual RawRule, it is safe
// to cast the result to an Alert
const res = this.getPartialAlertFromRaw<Params>(
id,
ruleType,
rawAlert,
rawRule,
references,
includeLegacyId
);
@ -1741,7 +1734,7 @@ export class RulesClient {
private getPartialAlertFromRaw<Params extends AlertTypeParams>(
id: string,
ruleType: UntypedNormalizedAlertType,
ruleType: UntypedNormalizedRuleType,
{
createdAt,
updatedAt,
@ -1753,15 +1746,15 @@ export class RulesClient {
executionStatus,
schedule,
actions,
...partialRawAlert
}: Partial<RawAlert>,
...partialRawRule
}: Partial<RawRule>,
references: SavedObjectReference[] | undefined,
includeLegacyId: boolean = false
): PartialAlert<Params> | PartialAlertWithLegacyId<Params> {
const rule = {
id,
notifyWhen,
...partialRawAlert,
...partialRawRule,
// we currently only support the Interval Schedule type
// Once we support additional types, this type signature will likely change
schedule: schedule as IntervalSchedule,
@ -1771,7 +1764,7 @@ export class RulesClient {
...(createdAt ? { createdAt: new Date(createdAt) } : {}),
...(scheduledTaskId ? { scheduledTaskId } : {}),
...(executionStatus
? { executionStatus: alertExecutionStatusFromRaw(this.logger, id, executionStatus) }
? { executionStatus: ruleExecutionStatusFromRaw(this.logger, id, executionStatus) }
: {}),
};
return includeLegacyId
@ -1780,7 +1773,7 @@ export class RulesClient {
}
private async validateActions(
alertType: UntypedNormalizedAlertType,
alertType: UntypedNormalizedRuleType,
actions: NormalizedAlertAction[]
): Promise<void> {
if (actions.length === 0) {
@ -1831,11 +1824,11 @@ export class RulesClient {
Params extends AlertTypeParams,
ExtractedParams extends AlertTypeParams
>(
ruleType: UntypedNormalizedAlertType,
ruleType: UntypedNormalizedRuleType,
ruleActions: NormalizedAlertAction[],
ruleParams: Params
): Promise<{
actions: RawAlert['actions'];
actions: RawRule['actions'];
params: ExtractedParams;
references: SavedObjectReference[];
}> {
@ -1868,7 +1861,7 @@ export class RulesClient {
ExtractedParams extends AlertTypeParams
>(
ruleId: string,
ruleType: UntypedNormalizedAlertType,
ruleType: UntypedNormalizedRuleType,
ruleParams: SavedObjectAttributes | undefined,
references: SavedObjectReference[]
): Params {
@ -1896,9 +1889,9 @@ export class RulesClient {
private async denormalizeActions(
alertActions: NormalizedAlertAction[]
): Promise<{ actions: RawAlert['actions']; references: SavedObjectReference[] }> {
): Promise<{ actions: RawRule['actions']; references: SavedObjectReference[] }> {
const references: SavedObjectReference[] = [];
const actions: RawAlert['actions'] = [];
const actions: RawRule['actions'] = [];
if (alertActions.length) {
const actionsClient = await this.getActionsClient();
const actionIds = [...new Set(alertActions.map((alertAction) => alertAction.id))];
@ -1953,7 +1946,7 @@ export class RulesClient {
return truncate(`Alerting: ${alertTypeId}/${trim(alertName)}`, { length: 256 });
}
private updateMeta<T extends Partial<RawAlert>>(alertAttributes: T): T {
private updateMeta<T extends Partial<RawRule>>(alertAttributes: T): T {
if (alertAttributes.hasOwnProperty('apiKey') || alertAttributes.hasOwnProperty('apiKeyOwner')) {
alertAttributes.meta = alertAttributes.meta ?? {};
alertAttributes.meta.versionApiKeyLastmodified = this.kibanaVersion;

View file

@ -19,7 +19,7 @@ import { eventLogClientMock } from '../../../../event_log/server/mocks';
import { QueryEventsBySavedObjectResult } from '../../../../event_log/server';
import { SavedObject } from 'kibana/server';
import { EventsFactory } from '../../lib/alert_summary_from_event_log.test';
import { RawAlert } from '../../types';
import { RawRule } from '../../types';
import { getBeforeSetup, mockedDateString, setGlobalDate } from './lib';
const taskManager = taskManagerMock.createStart();
@ -64,7 +64,7 @@ const AlertSummaryFindEventsResult: QueryEventsBySavedObjectResult = {
const RuleIntervalSeconds = 1;
const BaseRuleSavedObject: SavedObject<RawAlert> = {
const BaseRuleSavedObject: SavedObject<RawRule> = {
id: '1',
type: 'alert',
attributes: {
@ -96,7 +96,7 @@ const BaseRuleSavedObject: SavedObject<RawAlert> = {
references: [],
};
function getRuleSavedObject(attributes: Partial<RawAlert> = {}): SavedObject<RawAlert> {
function getRuleSavedObject(attributes: Partial<RawRule> = {}): SavedObject<RawRule> {
return {
...BaseRuleSavedObject,
attributes: { ...BaseRuleSavedObject.attributes, ...attributes },

View file

@ -12,7 +12,7 @@ import {
} from 'kibana/server';
import { AlertTypeParams } from '../../index';
import { Query } from '../../../../../../src/plugins/data/common/query';
import { RawAlert } from '../../types';
import { RawRule } from '../../types';
// These definitions are dupes of the SO-types in stack_alerts/geo_containment
// There are not exported to avoid deep imports from stack_alerts plugins into here
@ -69,8 +69,8 @@ export function extractEntityAndBoundaryReferences(params: GeoContainmentParams)
}
export function extractRefsFromGeoContainmentAlert(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
if (doc.attributes.alertTypeId !== GEO_CONTAINMENT_ID) {
return doc;
}

View file

@ -6,7 +6,7 @@
*/
import { SavedObject } from 'kibana/server';
import { RawAlert } from '../types';
import { RawRule } from '../types';
import { getImportWarnings } from './get_import_warnings';
describe('getImportWarnings', () => {
@ -71,13 +71,13 @@ describe('getImportWarnings', () => {
references: [],
},
];
const warnings = getImportWarnings(savedObjectRules as unknown as Array<SavedObject<RawAlert>>);
const warnings = getImportWarnings(savedObjectRules as unknown as Array<SavedObject<RawRule>>);
expect(warnings[0].message).toBe('2 rules must be enabled after the import.');
});
it('return no warning messages if no rules were imported', () => {
const savedObjectRules = [] as Array<SavedObject<RawAlert>>;
const warnings = getImportWarnings(savedObjectRules as unknown as Array<SavedObject<RawAlert>>);
const savedObjectRules = [] as Array<SavedObject<RawRule>>;
const warnings = getImportWarnings(savedObjectRules as unknown as Array<SavedObject<RawRule>>);
expect(warnings.length).toBe(0);
});
});

View file

@ -16,7 +16,7 @@ import mappings from './mappings.json';
import { getMigrations } from './migrations';
import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server';
import { transformRulesForExport } from './transform_rule_for_export';
import { RawAlert } from '../types';
import { RawRule } from '../types';
import { getImportWarnings } from './get_import_warnings';
import { isRuleExportable } from './is_rule_exportable';
import { RuleTypeRegistry } from '../rule_type_registry';
@ -60,7 +60,7 @@ export function setupSavedObjects(
management: {
displayName: 'rule',
importableAndExportable: true,
getTitle(ruleSavedObject: SavedObject<RawAlert>) {
getTitle(ruleSavedObject: SavedObject<RawRule>) {
return `Rule: [${ruleSavedObject.attributes.name}]`;
},
onImport(ruleSavedObjects) {
@ -68,13 +68,13 @@ export function setupSavedObjects(
warnings: getImportWarnings(ruleSavedObjects),
};
},
onExport<RawAlert>(
onExport<RawRule>(
context: SavedObjectsExportTransformContext,
objects: Array<SavedObject<RawAlert>>
objects: Array<SavedObject<RawRule>>
) {
return transformRulesForExport(objects);
},
isExportable<RawAlert>(ruleSavedObject: SavedObject<RawAlert>) {
isExportable<RawRule>(ruleSavedObject: SavedObject<RawRule>) {
return isRuleExportable(ruleSavedObject, ruleTypeRegistry, logger);
},
},

View file

@ -6,7 +6,7 @@
*/
import { Logger, SavedObject } from 'kibana/server';
import { RawAlert } from '../types';
import { RawRule } from '../types';
import { RuleTypeRegistry } from '../rule_type_registry';
export function isRuleExportable(
@ -14,7 +14,7 @@ export function isRuleExportable(
ruleTypeRegistry: RuleTypeRegistry,
logger: Logger
): boolean {
const ruleSO = rule as SavedObject<RawAlert>;
const ruleSO = rule as SavedObject<RawRule>;
try {
const ruleType = ruleTypeRegistry.get(ruleSO.attributes.alertTypeId);
if (!ruleType.isExportable) {

View file

@ -7,7 +7,7 @@
import uuid from 'uuid';
import { getMigrations, isAnyActionSupportIncidents } from './migrations';
import { RawAlert } from '../types';
import { RawRule } from '../types';
import { SavedObjectUnsanitizedDoc } from 'kibana/server';
import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks';
import { migrationMocks } from 'src/core/server/mocks';
@ -512,7 +512,7 @@ describe('successful migrations', () => {
(actionTypeId) => {
const doc = {
attributes: { actions: [{ actionTypeId }, { actionTypeId: '.server-log' }] },
} as SavedObjectUnsanitizedDoc<RawAlert>;
} as SavedObjectUnsanitizedDoc<RawRule>;
expect(isAnyActionSupportIncidents(doc)).toBe(true);
}
);
@ -520,7 +520,7 @@ describe('successful migrations', () => {
test('isAnyActionSupportIncidents should return false when there is no connector that supports incidents', () => {
const doc = {
attributes: { actions: [{ actionTypeId: '.server-log' }] },
} as SavedObjectUnsanitizedDoc<RawAlert>;
} as SavedObjectUnsanitizedDoc<RawRule>;
expect(isAnyActionSupportIncidents(doc)).toBe(false);
});
@ -2254,7 +2254,7 @@ function getUpdatedAt(): string {
function getMockData(
overwrites: Record<string, unknown> = {},
withSavedObjectUpdatedAt: boolean = false
): SavedObjectUnsanitizedDoc<Partial<RawAlert>> {
): SavedObjectUnsanitizedDoc<Partial<RawRule>> {
return {
attributes: {
enabled: true,

View file

@ -17,7 +17,7 @@ import {
SavedObjectAttribute,
SavedObjectReference,
} from '../../../../../src/core/server';
import { RawAlert, RawAlertAction } from '../types';
import { RawRule, RawAlertAction } from '../types';
import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server';
import type { IsMigrationNeededPredicate } from '../../../encrypted_saved_objects/server';
import { extractRefsFromGeoContainmentAlert } from './geo_containment/migrations';
@ -28,19 +28,19 @@ export const LEGACY_LAST_MODIFIED_VERSION = 'pre-7.10.0';
export const FILEBEAT_7X_INDICATOR_PATH = 'threatintel.indicator';
interface AlertLogMeta extends LogMeta {
migrations: { alertDocument: SavedObjectUnsanitizedDoc<RawAlert> };
migrations: { alertDocument: SavedObjectUnsanitizedDoc<RawRule> };
}
type AlertMigration = (
doc: SavedObjectUnsanitizedDoc<RawAlert>
) => SavedObjectUnsanitizedDoc<RawAlert>;
doc: SavedObjectUnsanitizedDoc<RawRule>
) => SavedObjectUnsanitizedDoc<RawRule>;
function createEsoMigration(
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup,
isMigrationNeededPredicate: IsMigrationNeededPredicate<RawAlert, RawAlert>,
isMigrationNeededPredicate: IsMigrationNeededPredicate<RawRule, RawRule>,
migrationFunc: AlertMigration
) {
return encryptedSavedObjects.createMigration<RawAlert, RawAlert>({
return encryptedSavedObjects.createMigration<RawRule, RawRule>({
isMigrationNeededPredicate,
migration: migrationFunc,
shouldMigrateIfDecryptionFails: true, // shouldMigrateIfDecryptionFails flag that applies the migration to undecrypted document if decryption fails
@ -49,13 +49,13 @@ function createEsoMigration(
const SUPPORT_INCIDENTS_ACTION_TYPES = ['.servicenow', '.jira', '.resilient'];
export const isAnyActionSupportIncidents = (doc: SavedObjectUnsanitizedDoc<RawAlert>): boolean =>
export const isAnyActionSupportIncidents = (doc: SavedObjectUnsanitizedDoc<RawRule>): boolean =>
doc.attributes.actions.some((action) =>
SUPPORT_INCIDENTS_ACTION_TYPES.includes(action.actionTypeId)
);
// Deprecated in 8.0
export const isSiemSignalsRuleType = (doc: SavedObjectUnsanitizedDoc<RawAlert>): boolean =>
export const isSiemSignalsRuleType = (doc: SavedObjectUnsanitizedDoc<RawRule>): boolean =>
doc.attributes.alertTypeId === 'siem.signals';
/**
@ -66,7 +66,7 @@ export const isSiemSignalsRuleType = (doc: SavedObjectUnsanitizedDoc<RawAlert>):
* @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function
*/
export const isSecuritySolutionLegacyNotification = (
doc: SavedObjectUnsanitizedDoc<RawAlert>
doc: SavedObjectUnsanitizedDoc<RawRule>
): boolean => doc.attributes.alertTypeId === 'siem.notifications';
export function getMigrations(
@ -76,7 +76,7 @@ export function getMigrations(
const migrationWhenRBACWasIntroduced = createEsoMigration(
encryptedSavedObjects,
// migrate all documents in 7.10 in order to add the "meta" RBAC field
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => true,
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => true,
pipeMigrations(
markAsLegacyAndChangeConsumer,
setAlertIdAsDefaultDedupkeyOnPagerDutyActions,
@ -87,37 +87,37 @@ export function getMigrations(
const migrationAlertUpdatedAtAndNotifyWhen = createEsoMigration(
encryptedSavedObjects,
// migrate all documents in 7.11 in order to add the "updatedAt" and "notifyWhen" fields
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => true,
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => true,
pipeMigrations(setAlertUpdatedAtDate, setNotifyWhen)
);
const migrationActions7112 = createEsoMigration(
encryptedSavedObjects,
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => isAnyActionSupportIncidents(doc),
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => isAnyActionSupportIncidents(doc),
pipeMigrations(restructureConnectorsThatSupportIncident)
);
const migrationSecurityRules713 = createEsoMigration(
encryptedSavedObjects,
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => isSiemSignalsRuleType(doc),
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => isSiemSignalsRuleType(doc),
pipeMigrations(removeNullsFromSecurityRules)
);
const migrationSecurityRules714 = createEsoMigration(
encryptedSavedObjects,
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => isSiemSignalsRuleType(doc),
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => isSiemSignalsRuleType(doc),
pipeMigrations(removeNullAuthorFromSecurityRules)
);
const migrationSecurityRules715 = createEsoMigration(
encryptedSavedObjects,
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => isSiemSignalsRuleType(doc),
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => isSiemSignalsRuleType(doc),
pipeMigrations(addExceptionListsToReferences)
);
const migrateRules716 = createEsoMigration(
encryptedSavedObjects,
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => true,
(doc): doc is SavedObjectUnsanitizedDoc<RawRule> => true,
pipeMigrations(
setLegacyId,
getRemovePreconfiguredConnectorsFromReferencesFn(isPreconfigured),
@ -128,7 +128,7 @@ export function getMigrations(
const migrationRules800 = createEsoMigration(
encryptedSavedObjects,
(doc: SavedObjectUnsanitizedDoc<RawAlert>): doc is SavedObjectUnsanitizedDoc<RawAlert> => true,
(doc: SavedObjectUnsanitizedDoc<RawRule>): doc is SavedObjectUnsanitizedDoc<RawRule> => true,
pipeMigrations(
addThreatIndicatorPathToThreatMatchRules,
addRACRuleTypes,
@ -149,10 +149,10 @@ export function getMigrations(
}
function executeMigrationWithErrorHandling(
migrationFunc: SavedObjectMigrationFn<RawAlert, RawAlert>,
migrationFunc: SavedObjectMigrationFn<RawRule, RawRule>,
version: string
) {
return (doc: SavedObjectUnsanitizedDoc<RawAlert>, context: SavedObjectMigrationContext) => {
return (doc: SavedObjectUnsanitizedDoc<RawRule>, context: SavedObjectMigrationContext) => {
try {
return migrationFunc(doc, context);
} catch (ex) {
@ -170,8 +170,8 @@ function executeMigrationWithErrorHandling(
}
const setAlertUpdatedAtDate = (
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> => {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> => {
const updatedAt = doc.updated_at || doc.attributes.createdAt;
return {
...doc,
@ -183,8 +183,8 @@ const setAlertUpdatedAtDate = (
};
const setNotifyWhen = (
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> => {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> => {
const notifyWhen = doc.attributes.throttle ? 'onThrottleInterval' : 'onActiveAlert';
return {
...doc,
@ -204,8 +204,8 @@ const consumersToChange: Map<string, string> = new Map(
);
function markAsLegacyAndChangeConsumer(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const {
attributes: { consumer },
} = doc;
@ -223,8 +223,8 @@ function markAsLegacyAndChangeConsumer(
}
function setAlertIdAsDefaultDedupkeyOnPagerDutyActions(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const { attributes } = doc;
return {
...doc,
@ -251,8 +251,8 @@ function setAlertIdAsDefaultDedupkeyOnPagerDutyActions(
}
function initializeExecutionStatus(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const { attributes } = doc;
return {
...doc,
@ -277,8 +277,8 @@ function isEmptyObject(obj: {}) {
}
function restructureConnectorsThatSupportIncident(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const { actions } = doc.attributes;
const newActions = actions.reduce((acc, action) => {
if (
@ -416,8 +416,8 @@ function convertNullToUndefined(attribute: SavedObjectAttribute) {
}
function removeNullsFromSecurityRules(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const {
attributes: { params },
} = doc;
@ -490,8 +490,8 @@ function removeNullsFromSecurityRules(
* @returns The document with the author field fleshed in.
*/
function removeNullAuthorFromSecurityRules(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const {
attributes: { params },
} = doc;
@ -519,8 +519,8 @@ function removeNullAuthorFromSecurityRules(
* @returns The document migrated with saved object references
*/
function addExceptionListsToReferences(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const {
attributes: {
params: { exceptionsList },
@ -610,8 +610,8 @@ function removeMalformedExceptionsList(
* @returns The document migrated with saved object references
*/
function addRuleIdsToLegacyNotificationReferences(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const {
attributes: {
params: { ruleAlertId },
@ -641,9 +641,7 @@ function addRuleIdsToLegacyNotificationReferences(
}
}
function setLegacyId(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
function setLegacyId(doc: SavedObjectUnsanitizedDoc<RawRule>): SavedObjectUnsanitizedDoc<RawRule> {
const { id } = doc;
return {
...doc,
@ -655,8 +653,8 @@ function setLegacyId(
}
function addRACRuleTypes(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
const ruleType = doc.attributes.params.type;
return isSiemSignalsRuleType(doc) && isRuleType(ruleType)
? {
@ -674,8 +672,8 @@ function addRACRuleTypes(
}
function addThreatIndicatorPathToThreatMatchRules(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
return isSiemSignalsRuleType(doc) &&
doc.attributes.params?.type === 'threat_match' &&
!doc.attributes.params.threatIndicatorPath
@ -695,15 +693,15 @@ function addThreatIndicatorPathToThreatMatchRules(
function getRemovePreconfiguredConnectorsFromReferencesFn(
isPreconfigured: (connectorId: string) => boolean
) {
return (doc: SavedObjectUnsanitizedDoc<RawAlert>) => {
return (doc: SavedObjectUnsanitizedDoc<RawRule>) => {
return removePreconfiguredConnectorsFromReferences(doc, isPreconfigured);
};
}
function removePreconfiguredConnectorsFromReferences(
doc: SavedObjectUnsanitizedDoc<RawAlert>,
doc: SavedObjectUnsanitizedDoc<RawRule>,
isPreconfigured: (connectorId: string) => boolean
): SavedObjectUnsanitizedDoc<RawAlert> {
): SavedObjectUnsanitizedDoc<RawRule> {
const {
attributes: { actions },
references,
@ -719,7 +717,7 @@ function removePreconfiguredConnectorsFromReferences(
);
const updatedConnectorReferences: SavedObjectReference[] = [];
const updatedActions: RawAlert['actions'] = [];
const updatedActions: RawRule['actions'] = [];
// For each connector reference, check if connector is preconfigured
// If yes, we need to remove from the references array and update
@ -758,8 +756,8 @@ function removePreconfiguredConnectorsFromReferences(
// This fixes an issue whereby metrics.alert.inventory.threshold rules had the
// group for actions incorrectly spelt as metrics.invenotry_threshold.fired vs metrics.inventory_threshold.fired
function fixInventoryThresholdGroupId(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
doc: SavedObjectUnsanitizedDoc<RawRule>
): SavedObjectUnsanitizedDoc<RawRule> {
if (doc.attributes.alertTypeId === 'metrics.alert.inventory.threshold') {
const {
attributes: { actions },
@ -805,6 +803,6 @@ function getCorrespondingAction(
}
function pipeMigrations(...migrations: AlertMigration[]): AlertMigration {
return (doc: SavedObjectUnsanitizedDoc<RawAlert>) =>
return (doc: SavedObjectUnsanitizedDoc<RawRule>) =>
migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc);
}

View file

@ -6,7 +6,7 @@
*/
import { pick } from 'lodash';
import { RawAlert } from '../types';
import { RawRule } from '../types';
import {
SavedObjectsClient,
@ -17,7 +17,7 @@ import {
import { AlertAttributesExcludedFromAAD, AlertAttributesExcludedFromAADType } from './index';
export type PartiallyUpdateableAlertAttributes = Partial<
Pick<RawAlert, AlertAttributesExcludedFromAADType>
Pick<RawRule, AlertAttributesExcludedFromAADType>
>;
export interface PartiallyUpdateAlertSavedObjectOptions {
@ -40,7 +40,7 @@ export async function partiallyUpdateAlert(
): Promise<void> {
// ensure we only have the valid attributes excluded from AAD
const attributeUpdates = pick(attributes, AlertAttributesExcludedFromAAD);
const updateOptions: SavedObjectsUpdateOptions<RawAlert> = pick(
const updateOptions: SavedObjectsUpdateOptions<RawRule> = pick(
options,
'namespace',
'version',
@ -48,7 +48,7 @@ export async function partiallyUpdateAlert(
);
try {
await savedObjectsClient.update<RawAlert>('alert', id, attributeUpdates, updateOptions);
await savedObjectsClient.update<RawRule>('alert', id, attributeUpdates, updateOptions);
} catch (err) {
if (options?.ignore404 && SavedObjectsErrorHelpers.isNotFoundError(err)) {
return;

View file

@ -6,8 +6,8 @@
*/
import { transformRulesForExport } from './transform_rule_for_export';
jest.mock('../lib/alert_execution_status', () => ({
getAlertExecutionStatusPending: () => ({
jest.mock('../lib/rule_execution_status', () => ({
getRuleExecutionStatusPending: () => ({
status: 'pending',
lastExecutionDate: '2020-08-20T19:23:38Z',
error: null,

View file

@ -6,18 +6,18 @@
*/
import { SavedObject } from 'kibana/server';
import { getAlertExecutionStatusPending } from '../lib/alert_execution_status';
import { RawAlert } from '../types';
import { getRuleExecutionStatusPending } from '../lib/rule_execution_status';
import { RawRule } from '../types';
export function transformRulesForExport(rules: SavedObject[]): Array<SavedObject<RawAlert>> {
export function transformRulesForExport(rules: SavedObject[]): Array<SavedObject<RawRule>> {
const exportDate = new Date().toISOString();
return rules.map((rule) => transformRuleForExport(rule as SavedObject<RawAlert>, exportDate));
return rules.map((rule) => transformRuleForExport(rule as SavedObject<RawRule>, exportDate));
}
function transformRuleForExport(
rule: SavedObject<RawAlert>,
rule: SavedObject<RawRule>,
exportDate: string
): SavedObject<RawAlert> {
): SavedObject<RawRule> {
return {
...rule,
attributes: {
@ -27,7 +27,7 @@ function transformRuleForExport(
apiKey: null,
apiKeyOwner: null,
scheduledTaskId: null,
executionStatus: getAlertExecutionStatusPending(exportDate),
executionStatus: getRuleExecutionStatusPending(exportDate),
},
};
}

View file

@ -11,16 +11,16 @@ import { fold } from 'fp-ts/lib/Either';
import { ConcreteTaskInstance } from '../../../task_manager/server';
import {
SanitizedAlert,
AlertTaskState,
alertParamsSchema,
alertStateSchema,
AlertTaskParams,
RuleTaskState,
ruleParamsSchema,
ruleStateSchema,
RuleTaskParams,
AlertTypeParams,
} from '../../common';
export interface AlertTaskInstance extends ConcreteTaskInstance {
state: AlertTaskState;
params: AlertTaskParams;
state: RuleTaskState;
params: RuleTaskParams;
}
const enumerateErrorFields = (e: t.Errors) =>
@ -33,7 +33,7 @@ export function taskInstanceToAlertTaskInstance<Params extends AlertTypeParams>(
return {
...taskInstance,
params: pipe(
alertParamsSchema.decode(taskInstance.params),
ruleParamsSchema.decode(taskInstance.params),
fold((e: t.Errors) => {
throw new Error(
`Task "${taskInstance.id}" ${
@ -43,7 +43,7 @@ export function taskInstanceToAlertTaskInstance<Params extends AlertTypeParams>(
}, t.identity)
),
state: pipe(
alertStateSchema.decode(taskInstance.state),
ruleStateSchema.decode(taskInstance.state),
fold((e: t.Errors) => {
throw new Error(
`Task "${taskInstance.id}" ${

View file

@ -16,7 +16,7 @@ import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { KibanaRequest } from 'kibana/server';
import { asSavedObjectExecutionSource } from '../../../actions/server';
import { InjectActionParamsOpts } from './inject_action_params';
import { NormalizedAlertType } from '../rule_type_registry';
import { NormalizedRuleType } from '../rule_type_registry';
import {
AlertTypeParams,
AlertTypeState,
@ -28,7 +28,7 @@ jest.mock('./inject_action_params', () => ({
injectActionParams: jest.fn(),
}));
const alertType: NormalizedAlertType<
const ruleType: NormalizedRuleType<
AlertTypeParams,
AlertTypeParams,
AlertTypeState,
@ -71,12 +71,12 @@ const createExecutionHandlerParams: jest.Mocked<
> = {
actionsPlugin: mockActionsPlugin,
spaceId: 'test1',
alertId: '1',
alertName: 'name-of-alert',
ruleId: '1',
ruleName: 'name-of-alert',
tags: ['tag-A', 'tag-B'],
apiKey: 'MTIzOmFiYw==',
kibanaBaseUrl: 'http://localhost:5601',
alertType,
ruleType,
logger: loggingSystemMock.create().get(),
eventLogger: mockEventLogger,
actions: [
@ -93,13 +93,13 @@ const createExecutionHandlerParams: jest.Mocked<
},
],
request: {} as KibanaRequest,
alertParams: {
ruleParams: {
foo: true,
contextVal: 'My other {{context.value}} goes here',
stateVal: 'My other {{state.value}} goes here',
},
supportsEphemeralTasks: false,
maxEphemeralActionsPerAlert: 10,
maxEphemeralActionsPerRule: 10,
};
beforeEach(() => {
@ -123,7 +123,7 @@ test('enqueues execution per selected action', async () => {
actionGroup: 'default',
state: {},
context: {},
alertInstanceId: '2',
alertId: '2',
});
expect(mockActionsPlugin.getActionsClientWithRequest).toHaveBeenCalledWith(
createExecutionHandlerParams.request
@ -244,7 +244,7 @@ test(`doesn't call actionsPlugin.execute for disabled actionTypes`, async () =>
actionGroup: 'default',
state: {},
context: {},
alertInstanceId: '2',
alertId: '2',
});
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1);
expect(actionsClient.enqueueExecution).toHaveBeenCalledWith({
@ -296,7 +296,7 @@ test('trow error error message when action type is disabled', async () => {
actionGroup: 'default',
state: {},
context: {},
alertInstanceId: '2',
alertId: '2',
});
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(0);
@ -310,7 +310,7 @@ test('trow error error message when action type is disabled', async () => {
actionGroup: 'default',
state: {},
context: {},
alertInstanceId: '2',
alertId: '2',
});
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1);
});
@ -321,7 +321,7 @@ test('limits actionsPlugin.execute per action group', async () => {
actionGroup: 'other-group',
state: {},
context: {},
alertInstanceId: '2',
alertId: '2',
});
expect(actionsClient.enqueueExecution).not.toHaveBeenCalled();
});
@ -332,7 +332,7 @@ test('context attribute gets parameterized', async () => {
actionGroup: 'default',
context: { value: 'context-val' },
state: {},
alertInstanceId: '2',
alertId: '2',
});
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1);
expect(actionsClient.enqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
@ -373,7 +373,7 @@ test('state attribute gets parameterized', async () => {
actionGroup: 'default',
context: {},
state: { value: 'state-val' },
alertInstanceId: '2',
alertId: '2',
});
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(1);
expect(actionsClient.enqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
@ -408,7 +408,7 @@ test('state attribute gets parameterized', async () => {
`);
});
test(`logs an error when action group isn't part of actionGroups available for the alertType`, async () => {
test(`logs an error when action group isn't part of actionGroups available for the ruleType`, async () => {
const executionHandler = createExecutionHandler(createExecutionHandlerParams);
const result = await executionHandler({
// we have to trick the compiler as this is an invalid type and this test checks whether we
@ -416,10 +416,10 @@ test(`logs an error when action group isn't part of actionGroups available for t
actionGroup: 'invalid-group' as 'default' | 'other-group',
context: {},
state: {},
alertInstanceId: '2',
alertId: '2',
});
expect(result).toBeUndefined();
expect(createExecutionHandlerParams.logger.error).toHaveBeenCalledWith(
'Invalid action group "invalid-group" for alert "test".'
'Invalid action group "invalid-group" for rule "test".'
);
});

View file

@ -19,9 +19,9 @@ import {
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
RawAlert,
RawRule,
} from '../types';
import { NormalizedAlertType, UntypedNormalizedAlertType } from '../rule_type_registry';
import { NormalizedRuleType, UntypedNormalizedRuleType } from '../rule_type_registry';
import { isEphemeralTaskRejectedDueToCapacityError } from '../../../task_manager/server';
import { createAlertEventLogRecordObject } from '../lib/create_alert_event_log_record_object';
@ -34,15 +34,15 @@ export interface CreateExecutionHandlerOptions<
ActionGroupIds extends string,
RecoveryActionGroupId extends string
> {
alertId: string;
alertName: string;
ruleId: string;
ruleName: string;
tags?: string[];
actionsPlugin: ActionsPluginStartContract;
actions: AlertAction[];
spaceId: string;
apiKey: RawAlert['apiKey'];
apiKey: RawRule['apiKey'];
kibanaBaseUrl: string | undefined;
alertType: NormalizedAlertType<
ruleType: NormalizedRuleType<
Params,
ExtractedParams,
State,
@ -54,15 +54,15 @@ export interface CreateExecutionHandlerOptions<
logger: Logger;
eventLogger: IEventLogger;
request: KibanaRequest;
alertParams: AlertTypeParams;
ruleParams: AlertTypeParams;
supportsEphemeralTasks: boolean;
maxEphemeralActionsPerAlert: number;
maxEphemeralActionsPerRule: number;
}
interface ExecutionHandlerOptions<ActionGroupIds extends string> {
actionGroup: ActionGroupIds;
actionSubgroup?: string;
alertInstanceId: string;
alertId: string;
context: AlertInstanceContext;
state: AlertInstanceState;
}
@ -81,20 +81,20 @@ export function createExecutionHandler<
RecoveryActionGroupId extends string
>({
logger,
alertId,
alertName,
ruleId,
ruleName,
tags,
actionsPlugin,
actions: alertActions,
actions: ruleActions,
spaceId,
apiKey,
alertType,
ruleType,
kibanaBaseUrl,
eventLogger,
request,
alertParams,
ruleParams,
supportsEphemeralTasks,
maxEphemeralActionsPerAlert,
maxEphemeralActionsPerRule,
}: CreateExecutionHandlerOptions<
Params,
ExtractedParams,
@ -104,66 +104,66 @@ export function createExecutionHandler<
ActionGroupIds,
RecoveryActionGroupId
>): ExecutionHandler<ActionGroupIds | RecoveryActionGroupId> {
const alertTypeActionGroups = new Map(
alertType.actionGroups.map((actionGroup) => [actionGroup.id, actionGroup.name])
const ruleTypeActionGroups = new Map(
ruleType.actionGroups.map((actionGroup) => [actionGroup.id, actionGroup.name])
);
return async ({
actionGroup,
actionSubgroup,
context,
state,
alertInstanceId,
alertId,
}: ExecutionHandlerOptions<ActionGroupIds | RecoveryActionGroupId>) => {
if (!alertTypeActionGroups.has(actionGroup)) {
logger.error(`Invalid action group "${actionGroup}" for alert "${alertType.id}".`);
if (!ruleTypeActionGroups.has(actionGroup)) {
logger.error(`Invalid action group "${actionGroup}" for rule "${ruleType.id}".`);
return;
}
const actions = alertActions
const actions = ruleActions
.filter(({ group }) => group === actionGroup)
.map((action) => {
return {
...action,
params: transformActionParams({
actionsPlugin,
alertId,
alertType: alertType.id,
alertId: ruleId,
alertType: ruleType.id,
actionTypeId: action.actionTypeId,
alertName,
alertName: ruleName,
spaceId,
tags,
alertInstanceId,
alertInstanceId: alertId,
alertActionGroup: actionGroup,
alertActionGroupName: alertTypeActionGroups.get(actionGroup)!,
alertActionGroupName: ruleTypeActionGroups.get(actionGroup)!,
alertActionSubgroup: actionSubgroup,
context,
actionParams: action.params,
actionId: action.id,
state,
kibanaBaseUrl,
alertParams,
alertParams: ruleParams,
}),
};
})
.map((action) => ({
...action,
params: injectActionParams({
ruleId: alertId,
ruleId,
spaceId,
actionParams: action.params,
actionTypeId: action.actionTypeId,
}),
}));
const alertLabel = `${alertType.id}:${alertId}: '${alertName}'`;
const ruleLabel = `${ruleType.id}:${ruleId}: '${ruleName}'`;
const actionsClient = await actionsPlugin.getActionsClientWithRequest(request);
let ephemeralActionsToSchedule = maxEphemeralActionsPerAlert;
let ephemeralActionsToSchedule = maxEphemeralActionsPerRule;
for (const action of actions) {
if (
!actionsPlugin.isActionExecutable(action.id, action.actionTypeId, { notifyUsage: true })
) {
logger.warn(
`Alert "${alertId}" skipped scheduling action "${action.id}" because it is disabled`
`Rule "${ruleId}" skipped scheduling action "${action.id}" because it is disabled`
);
continue;
}
@ -176,15 +176,15 @@ export function createExecutionHandler<
spaceId,
apiKey: apiKey ?? null,
source: asSavedObjectExecutionSource({
id: alertId,
id: ruleId,
type: 'alert',
}),
relatedSavedObjects: [
{
id: alertId,
id: ruleId,
type: 'alert',
namespace: namespace.namespace,
typeId: alertType.id,
typeId: ruleType.id,
},
],
};
@ -203,18 +203,18 @@ export function createExecutionHandler<
}
const event = createAlertEventLogRecordObject({
ruleId: alertId,
ruleType: alertType as UntypedNormalizedAlertType,
ruleId,
ruleType: ruleType as UntypedNormalizedRuleType,
action: EVENT_LOG_ACTIONS.executeAction,
instanceId: alertInstanceId,
instanceId: alertId,
group: actionGroup,
subgroup: actionSubgroup,
ruleName: alertName,
ruleName,
savedObjects: [
{
type: 'alert',
id: alertId,
typeId: alertType.id,
id: ruleId,
typeId: ruleType.id,
relation: SAVED_OBJECT_REL_PRIMARY,
},
{
@ -224,7 +224,7 @@ export function createExecutionHandler<
},
],
...namespace,
message: `alert: ${alertLabel} instanceId: '${alertInstanceId}' scheduled ${
message: `alert: ${ruleLabel} instanceId: '${alertId}' scheduled ${
actionSubgroup
? `actionGroup(subgroup): '${actionGroup}(${actionSubgroup})'`
: `actionGroup: '${actionGroup}'`

File diff suppressed because it is too large Load diff

View file

@ -29,10 +29,10 @@ import { alertsMock, rulesClientMock } from '../mocks';
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { IEventLogger } from '../../../event_log/server';
import { Alert, RecoveredActionGroup } from '../../common';
import { UntypedNormalizedAlertType } from '../rule_type_registry';
import { UntypedNormalizedRuleType } from '../rule_type_registry';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
const ruleType: jest.Mocked<UntypedNormalizedAlertType> = {
const ruleType: jest.Mocked<UntypedNormalizedRuleType> = {
id: 'test',
name: 'My test rule',
actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup],
@ -100,7 +100,7 @@ describe('Task Runner Cancel', () => {
ruleTypeRegistry,
kibanaBaseUrl: 'https://localhost:5601',
supportsEphemeralTasks: false,
maxEphemeralActionsPerAlert: 10,
maxEphemeralActionsPerRule: 10,
cancelAlertsOnRuleTimeout: true,
};
@ -215,7 +215,7 @@ describe('Task Runner Cancel', () => {
scheduled: '1970-01-01T00:00:00.000Z',
},
},
message: 'alert execution start: "1"',
message: 'rule execution start: "1"',
rule: {
category: 'test',
id: '1',
@ -271,7 +271,7 @@ describe('Task Runner Cancel', () => {
scheduled: '1970-01-01T00:00:00.000Z',
},
},
message: `alert executed: test:1: 'rule-name'`,
message: `rule executed: test:1: 'rule-name'`,
rule: {
category: 'test',
id: '1',
@ -395,7 +395,7 @@ describe('Task Runner Cancel', () => {
const logger = taskRunnerFactoryInitializerParams.logger;
expect(logger.debug).toHaveBeenCalledTimes(6);
expect(logger.debug).nthCalledWith(1, 'executing alert test:1 at 1970-01-01T00:00:00.000Z');
expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z');
expect(logger.debug).nthCalledWith(
2,
`Cancelling rule type test with id 1 - execution exceeded rule type timeout of 5m`
@ -406,15 +406,15 @@ describe('Task Runner Cancel', () => {
);
expect(logger.debug).nthCalledWith(
4,
`alert test:1: 'rule-name' has 1 active alert instances: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`
`rule test:1: 'rule-name' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`
);
expect(logger.debug).nthCalledWith(
5,
`no scheduling of actions for alert test:1: 'rule-name': alert execution has been cancelled.`
`no scheduling of actions for rule test:1: 'rule-name': rule execution has been cancelled.`
);
expect(logger.debug).nthCalledWith(
6,
'alertExecutionStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}'
'ruleExecutionStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}'
);
const eventLogger = taskRunnerFactoryInitializerParams.eventLogger;
@ -440,7 +440,7 @@ describe('Task Runner Cancel', () => {
},
],
},
message: `alert execution start: \"1\"`,
message: `rule execution start: \"1\"`,
rule: {
category: 'test',
id: '1',
@ -498,7 +498,7 @@ describe('Task Runner Cancel', () => {
},
],
},
message: "alert executed: test:1: 'rule-name'",
message: "rule executed: test:1: 'rule-name'",
rule: {
category: 'test',
id: '1',
@ -512,7 +512,7 @@ describe('Task Runner Cancel', () => {
function testActionsExecute() {
const logger = taskRunnerFactoryInitializerParams.logger;
expect(logger.debug).toHaveBeenCalledTimes(5);
expect(logger.debug).nthCalledWith(1, 'executing alert test:1 at 1970-01-01T00:00:00.000Z');
expect(logger.debug).nthCalledWith(1, 'executing rule test:1 at 1970-01-01T00:00:00.000Z');
expect(logger.debug).nthCalledWith(
2,
`Cancelling rule type test with id 1 - execution exceeded rule type timeout of 5m`
@ -523,11 +523,11 @@ describe('Task Runner Cancel', () => {
);
expect(logger.debug).nthCalledWith(
4,
`alert test:1: 'rule-name' has 1 active alert instances: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`
`rule test:1: 'rule-name' has 1 active alerts: [{\"instanceId\":\"1\",\"actionGroup\":\"default\"}]`
);
expect(logger.debug).nthCalledWith(
5,
'alertExecutionStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}'
'ruleExecutionStatus for test:1: {"lastExecutionDate":"1970-01-01T00:00:00.000Z","status":"active"}'
);
const eventLogger = taskRunnerFactoryInitializerParams.eventLogger;
@ -553,7 +553,7 @@ describe('Task Runner Cancel', () => {
},
],
},
message: `alert execution start: "1"`,
message: `rule execution start: "1"`,
rule: {
category: 'test',
id: '1',
@ -609,7 +609,7 @@ describe('Task Runner Cancel', () => {
},
],
},
message: "test:1: 'rule-name' created new instance: '1'",
message: "test:1: 'rule-name' created new alert: '1'",
rule: {
category: 'test',
id: '1',
@ -636,7 +636,7 @@ describe('Task Runner Cancel', () => {
{ id: '1', namespace: undefined, rel: 'primary', type: 'alert', type_id: 'test' },
],
},
message: "test:1: 'rule-name' active instance: '1' in actionGroup: 'default'",
message: "test:1: 'rule-name' active alert: '1' in actionGroup: 'default'",
rule: {
category: 'test',
id: '1',
@ -700,7 +700,7 @@ describe('Task Runner Cancel', () => {
},
],
},
message: "alert executed: test:1: 'rule-name'",
message: "rule executed: test:1: 'rule-name'",
rule: {
category: 'test',
id: '1',

View file

@ -17,13 +17,13 @@ import {
import { actionsMock } from '../../../actions/server/mocks';
import { alertsMock, rulesClientMock } from '../mocks';
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { UntypedNormalizedAlertType } from '../rule_type_registry';
import { UntypedNormalizedRuleType } from '../rule_type_registry';
import { ruleTypeRegistryMock } from '../rule_type_registry.mock';
import { executionContextServiceMock } from '../../../../../src/core/server/mocks';
const executionContext = executionContextServiceMock.createSetupContract();
const alertType: UntypedNormalizedAlertType = {
const ruleType: UntypedNormalizedRuleType = {
id: 'test',
name: 'My test alert',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -83,7 +83,7 @@ describe('Task Runner Factory', () => {
ruleTypeRegistry: ruleTypeRegistryMock.create(),
kibanaBaseUrl: 'https://localhost:5601',
supportsEphemeralTasks: true,
maxEphemeralActionsPerAlert: 10,
maxEphemeralActionsPerRule: 10,
cancelAlertsOnRuleTimeout: true,
executionContext,
};
@ -96,7 +96,7 @@ describe('Task Runner Factory', () => {
test(`throws an error if factory isn't initialized`, () => {
const factory = new TaskRunnerFactory();
expect(() =>
factory.create(alertType, { taskInstance: mockedTaskInstance })
factory.create(ruleType, { taskInstance: mockedTaskInstance })
).toThrowErrorMatchingInlineSnapshot(`"TaskRunnerFactory not initialized"`);
});

View file

@ -28,7 +28,7 @@ import {
import { TaskRunner } from './task_runner';
import { IEventLogger } from '../../../event_log/server';
import { RulesClient } from '../rules_client';
import { NormalizedAlertType } from '../rule_type_registry';
import { NormalizedRuleType } from '../rule_type_registry';
export interface TaskRunnerContext {
logger: Logger;
@ -44,7 +44,7 @@ export interface TaskRunnerContext {
ruleTypeRegistry: RuleTypeRegistry;
kibanaBaseUrl: string | undefined;
supportsEphemeralTasks: boolean;
maxEphemeralActionsPerAlert: number;
maxEphemeralActionsPerRule: number;
cancelAlertsOnRuleTimeout: boolean;
}
@ -69,7 +69,7 @@ export class TaskRunnerFactory {
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
alertType: NormalizedAlertType<
ruleType: NormalizedRuleType<
Params,
ExtractedParams,
State,
@ -92,6 +92,6 @@ export class TaskRunnerFactory {
InstanceContext,
ActionGroupIds,
RecoveryActionGroupId
>(alertType, taskInstance, this.taskRunnerContext!);
>(ruleType, taskInstance, this.taskRunnerContext!);
}
}

View file

@ -118,7 +118,7 @@ export type ExecutorType<
export interface AlertTypeParamsValidator<Params extends AlertTypeParams> {
validate: (object: unknown) => Params;
}
export interface AlertType<
export interface RuleType<
Params extends AlertTypeParams = never,
ExtractedParams extends AlertTypeParams = never,
State extends AlertTypeState = never,
@ -163,7 +163,7 @@ export interface AlertType<
ruleTaskTimeout?: string;
cancelAlertsOnRuleTimeout?: boolean;
}
export type UntypedAlertType = AlertType<
export type UntypedRuleType = RuleType<
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
@ -184,7 +184,7 @@ export interface AlertMeta extends SavedObjectAttributes {
// note that the `error` property is "null-able", as we're doing a partial
// update on the alert when we update this data, but need to ensure we
// delete any previous error if the current status has no error
export interface RawAlertExecutionStatus extends SavedObjectAttributes {
export interface RawRuleExecutionStatus extends SavedObjectAttributes {
status: AlertExecutionStatuses;
lastExecutionDate: string;
lastDuration?: number;
@ -201,7 +201,7 @@ export interface AlertWithLegacyId<Params extends AlertTypeParams = never> exten
legacyId: string | null;
}
export type SanitizedAlertWithLegacyId<Params extends AlertTypeParams = never> = Omit<
export type SanitizedRuleWithLegacyId<Params extends AlertTypeParams = never> = Omit<
AlertWithLegacyId<Params>,
'apiKey'
>;
@ -212,11 +212,11 @@ export type PartialAlertWithLegacyId<Params extends AlertTypeParams = never> = P
> &
Partial<Omit<AlertWithLegacyId<Params>, 'id'>>;
export interface RawAlert extends SavedObjectAttributes {
export interface RawRule extends SavedObjectAttributes {
enabled: boolean;
name: string;
tags: string[];
alertTypeId: string;
alertTypeId: string; // this cannot be renamed since it is in the saved object
consumer: string;
legacyId: string | null;
schedule: SavedObjectAttributes;
@ -234,11 +234,11 @@ export interface RawAlert extends SavedObjectAttributes {
muteAll: boolean;
mutedInstanceIds: string[];
meta?: AlertMeta;
executionStatus: RawAlertExecutionStatus;
executionStatus: RawRuleExecutionStatus;
}
export type AlertInfoParams = Pick<
RawAlert,
RawRule,
| 'params'
| 'throttle'
| 'notifyWhen'

View file

@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import { MlPluginSetup } from '../../../../../ml/server';
import {
AlertType as RuleType,
RuleType,
AlertInstanceState as AlertState,
AlertInstanceContext as AlertContext,
} from '../../../../../alerting/server';

View file

@ -8,7 +8,7 @@
import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import { ActionGroupIdsOf } from '../../../../../alerting/common';
import { AlertType, PluginSetupContract } from '../../../../../alerting/server';
import { RuleType, PluginSetupContract } from '../../../../../alerting/server';
import { METRIC_EXPLORER_AGGREGATIONS } from '../../../../common/http_api';
import {
createMetricThresholdExecutor,
@ -31,7 +31,7 @@ import {
type MetricThresholdAllowedActionGroups = ActionGroupIdsOf<
typeof FIRED_ACTIONS | typeof WARNING_ACTIONS
>;
export type MetricThresholdAlertType = Omit<AlertType, 'ActionGroupIdsOf'> & {
export type MetricThresholdAlertType = Omit<RuleType, 'ActionGroupIdsOf'> & {
ActionGroupIdsOf: MetricThresholdAllowedActionGroups;
};

View file

@ -8,7 +8,7 @@
import { Logger, ElasticsearchClient } from 'kibana/server';
import { i18n } from '@kbn/i18n';
import {
AlertType,
RuleType,
AlertExecutorOptions,
AlertInstance,
RulesClient,
@ -80,7 +80,7 @@ export class BaseRule {
this.scopedLogger = Globals.app.getLogger(ruleOptions.id);
}
public getRuleType(): AlertType<never, never, never, never, never, 'default'> {
public getRuleType(): RuleType<never, never, never, never, never, 'default'> {
const { id, name, actionVariables } = this.ruleOptions;
return {
id,

View file

@ -12,14 +12,14 @@ import {
AlertTypeParams,
AlertTypeState,
} from '../../alerting/common';
import { AlertExecutorOptions, AlertServices, AlertType } from '../../alerting/server';
import { AlertExecutorOptions, AlertServices, RuleType } from '../../alerting/server';
import { AlertsClient } from './alert_data_client/alerts_client';
type SimpleAlertType<
TState extends AlertTypeState,
TParams extends AlertTypeParams = {},
TAlertInstanceContext extends AlertInstanceContext = {}
> = AlertType<TParams, TParams, TState, AlertInstanceState, TAlertInstanceContext, string, string>;
> = RuleType<TParams, TParams, TState, AlertInstanceState, TAlertInstanceContext, string, string>;
export type AlertTypeExecutor<
TState extends AlertTypeState,
@ -38,7 +38,7 @@ export type AlertTypeWithExecutor<
TAlertInstanceContext extends AlertInstanceContext = {},
TServices extends Record<string, any> = {}
> = Omit<
AlertType<TParams, TParams, TState, AlertInstanceState, TAlertInstanceContext, string, string>,
RuleType<TParams, TParams, TState, AlertInstanceState, TAlertInstanceContext, string, string>,
'executor'
> & {
executor: AlertTypeExecutor<TState, TParams, TAlertInstanceContext, TServices>;

View file

@ -10,7 +10,7 @@ import {
AlertExecutorOptions,
AlertInstanceContext,
AlertInstanceState,
AlertType,
RuleType,
AlertTypeParams,
AlertTypeState,
} from '../../../alerting/server';
@ -39,7 +39,7 @@ export type PersistenceAlertType<
TInstanceContext extends AlertInstanceContext = {},
TActionGroupIds extends string = never
> = Omit<
AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>,
RuleType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>,
'executor'
> & {
executor: (
@ -65,4 +65,4 @@ export type CreatePersistenceRuleTypeWrapper = (options: {
TActionGroupIds extends string = never
>(
type: PersistenceAlertType<TParams, TState, TInstanceContext, TActionGroupIds>
) => AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>;
) => RuleType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>;

View file

@ -10,7 +10,7 @@ import { schema, TypeOf } from '@kbn/config-schema';
import {
RulesClient,
PartialAlert,
AlertType,
RuleType,
AlertTypeParams,
AlertTypeState,
AlertInstanceState,
@ -103,7 +103,7 @@ export type LegacyNotificationExecutorOptions = AlertExecutorOptions<
*/
export const legacyIsNotificationAlertExecutor = (
obj: LegacyNotificationAlertTypeDefinition
): obj is AlertType<
): obj is RuleType<
LegacyRuleNotificationAlertTypeParams,
LegacyRuleNotificationAlertTypeParams,
AlertTypeState,
@ -117,7 +117,7 @@ export const legacyIsNotificationAlertExecutor = (
* @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function
*/
export type LegacyNotificationAlertTypeDefinition = Omit<
AlertType<
RuleType<
LegacyRuleNotificationAlertTypeParams,
LegacyRuleNotificationAlertTypeParams,
AlertTypeState,

View file

@ -11,7 +11,7 @@ import { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { Logger } from '@kbn/logging';
import { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types';
import { AlertExecutorOptions, AlertType } from '../../../../../alerting/server';
import { AlertExecutorOptions, RuleType } from '../../../../../alerting/server';
import {
AlertInstanceContext,
AlertInstanceState,
@ -73,7 +73,7 @@ export type SecurityAlertType<
TInstanceContext extends AlertInstanceContext = {},
TActionGroupIds extends string = never
> = Omit<
AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>,
RuleType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, TActionGroupIds>,
'executor'
> & {
executor: (
@ -107,7 +107,7 @@ export type CreateSecurityRuleTypeWrapper = (
TInstanceContext extends AlertInstanceContext = {}
>(
type: SecurityAlertType<TParams, TState, TInstanceContext, 'default'>
) => AlertType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, 'default'>;
) => RuleType<TParams, TParams, TState, AlertInstanceState, TInstanceContext, 'default'>;
export type RACAlertSignal = TypeOfFieldMap<AlertsFieldMap> & TypeOfFieldMap<RulesFieldMap>;
export type RACAlert = Exclude<

View file

@ -12,7 +12,7 @@ import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-t
import { Status } from '../../../../common/detection_engine/schemas/common/schemas';
import { RulesSchema } from '../../../../common/detection_engine/schemas/response/rules_schema';
import {
AlertType,
RuleType,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
@ -196,7 +196,7 @@ export type RuleExecutorOptions = AlertExecutorOptions<
// since we are only increasing the strictness of params.
export const isAlertExecutor = (
obj: SignalRuleAlertTypeDefinition
): obj is AlertType<
): obj is RuleType<
RuleParams,
RuleParams, // This type is used for useSavedObjectReferences, use an Omit here if you want to remove any values.
AlertTypeState,
@ -207,7 +207,7 @@ export const isAlertExecutor = (
return true;
};
export type SignalRuleAlertTypeDefinition = AlertType<
export type SignalRuleAlertTypeDefinition = RuleType<
RuleParams,
RuleParams, // This type is used for useSavedObjectReferences, use an Omit here if you want to remove any values.
AlertTypeState,

View file

@ -8,7 +8,7 @@
import { i18n } from '@kbn/i18n';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { Logger } from 'src/core/server';
import { AlertType, AlertExecutorOptions } from '../../types';
import { RuleType, AlertExecutorOptions } from '../../types';
import { ActionContext, EsQueryAlertActionContext, addMessages } from './action_context';
import {
EsQueryAlertParams,
@ -25,7 +25,7 @@ export const ES_QUERY_ID = '.es-query';
export const ActionGroupId = 'query matched';
export const ConditionMetAlertInstanceId = 'query matched';
export function getAlertType(logger: Logger): AlertType<
export function getAlertType(logger: Logger): RuleType<
EsQueryAlertParams,
never, // Only use if defining useSavedObjectReferences hook
EsQueryAlertState,

View file

@ -11,7 +11,7 @@ import { Logger, SavedObjectReference } from 'src/core/server';
import { STACK_ALERTS_FEATURE_ID } from '../../../common';
import { getGeoContainmentExecutor } from './geo_containment';
import {
AlertType,
RuleType,
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
@ -147,7 +147,7 @@ export interface GeoContainmentInstanceContext extends AlertInstanceContext {
containingBoundaryName: unknown;
}
export type GeoContainmentAlertType = AlertType<
export type GeoContainmentAlertType = RuleType<
GeoContainmentParams,
GeoContainmentExtractedParams,
GeoContainmentState,

View file

@ -7,7 +7,7 @@
import { i18n } from '@kbn/i18n';
import { Logger } from 'src/core/server';
import { AlertType, AlertExecutorOptions, StackAlertsStartDeps } from '../../types';
import { RuleType, AlertExecutorOptions, StackAlertsStartDeps } from '../../types';
import { Params, ParamsSchema } from './alert_type_params';
import { ActionContext, BaseActionContext, addMessages } from './action_context';
import { STACK_ALERTS_FEATURE_ID } from '../../../common';
@ -23,7 +23,7 @@ export const ActionGroupId = 'threshold met';
export function getAlertType(
logger: Logger,
data: Promise<StackAlertsStartDeps['triggersActionsUi']['data']>
): AlertType<Params, never, {}, {}, ActionContext, typeof ActionGroupId> {
): RuleType<Params, never, {}, {}, ActionContext, typeof ActionGroupId> {
const alertTypeName = i18n.translate('xpack.stackAlerts.indexThreshold.alertTypeTitle', {
defaultMessage: 'Index threshold',
});

View file

@ -10,7 +10,7 @@ import { PluginSetupContract as AlertingSetup } from '../../alerting/server';
export type {
PluginSetupContract as AlertingSetup,
AlertType,
RuleType,
RuleParamsAndRefs,
AlertExecutorOptions,
} from '../../alerting/server';

View file

@ -15,7 +15,7 @@ import type {
} from '../../../../../alerting/common';
import { PLUGIN, TRANSFORM_RULE_TYPE } from '../../../../common/constants';
import { transformHealthRuleParams, TransformHealthRuleParams } from './schema';
import { AlertType } from '../../../../../alerting/server';
import { RuleType } from '../../../../../alerting/server';
import { transformHealthServiceProvider } from './transform_health_service';
import type { PluginSetupContract as AlertingSetup } from '../../../../../alerting/server';
@ -57,7 +57,7 @@ export function registerTransformHealthRuleType(params: RegisterParams) {
alerting.registerType(getTransformHealthRuleType());
}
export function getTransformHealthRuleType(): AlertType<
export function getTransformHealthRuleType(): RuleType<
TransformHealthRuleParams,
never,
AlertTypeState,

View file

@ -5343,16 +5343,16 @@
"xpack.alerting.rulesClient.invalidDate": "パラメーター{field}の無効な日付:「{dateValue}」",
"xpack.alerting.rulesClient.validateActions.invalidGroups": "無効なアクショングループ:{groups}",
"xpack.alerting.rulesClient.validateActions.misconfiguredConnector": "無効なコネクター:{groups}",
"xpack.alerting.ruleTypeRegistry.get.missingAlertTypeError": "ルールタイプ「{id}」は登録されていません。",
"xpack.alerting.ruleTypeRegistry.get.missingRuleTypeError": "ルールタイプ「{id}」は登録されていません。",
"xpack.alerting.ruleTypeRegistry.register.customRecoveryActionGroupUsageError": "ルールタイプ[id=\"{id}\"]を登録できません。アクショングループ [{actionGroup}] は、復元とアクティブなアクショングループの両方として使用できません。",
"xpack.alerting.ruleTypeRegistry.register.duplicateAlertTypeError": "ルールタイプ\"{id}\"はすでに登録されています。",
"xpack.alerting.ruleTypeRegistry.register.invalidDefaultTimeoutAlertTypeError": "ルールタイプ\"{id}\"のデフォルト間隔が無効です:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidMinimumTimeoutAlertTypeError": "ルールタイプ\"{id}\"の最低間隔が無効です:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidTimeoutAlertTypeError": "ルールタイプ\"{id}\"のタイムアウトが無効です:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.duplicateRuleTypeError": "ルールタイプ\"{id}\"はすでに登録されています。",
"xpack.alerting.ruleTypeRegistry.register.invalidDefaultTimeoutRuleTypeError": "ルールタイプ\"{id}\"のデフォルト間隔が無効です:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidMinimumTimeoutRuleTypeError": "ルールタイプ\"{id}\"の最低間隔が無効です:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidTimeoutRuleTypeError": "ルールタイプ\"{id}\"のタイムアウトが無効です:{errorMessage}。",
"xpack.alerting.savedObjects.goToRulesButtonText": "ルールに移動",
"xpack.alerting.serverSideErrors.expirerdLicenseErrorMessage": "{licenseType} ライセンスの期限が切れたのでアラートタイプ {alertTypeId} は無効です。",
"xpack.alerting.serverSideErrors.invalidLicenseErrorMessage": "アラート{alertTypeId}は無効です。{licenseType}ライセンスが必要です。アップグレードオプションを表示するには、[ライセンス管理]に移動してください。",
"xpack.alerting.serverSideErrors.unavailableLicenseErrorMessage": "現時点でライセンス情報を入手できないため、アラートタイプ {alertTypeId} は無効です。",
"xpack.alerting.serverSideErrors.expirerdLicenseErrorMessage": "{licenseType} ライセンスの期限が切れたのでアラートタイプ {ruleTypeId} は無効です。",
"xpack.alerting.serverSideErrors.invalidLicenseErrorMessage": "アラート{ruleTypeId}は無効です。{licenseType}ライセンスが必要です。アップグレードオプションを表示するには、[ライセンス管理]に移動してください。",
"xpack.alerting.serverSideErrors.unavailableLicenseErrorMessage": "現時点でライセンス情報を入手できないため、アラートタイプ {ruleTypeId} は無効です。",
"xpack.alerting.serverSideErrors.unavailableLicenseInformationErrorMessage": "アラートを利用できません。現在ライセンス情報が利用できません。",
"xpack.apm.a.thresholdMet": "しきい値一致",
"xpack.apm.addDataButtonLabel": "データの追加",

View file

@ -5378,18 +5378,18 @@
"xpack.alerting.rulesClient.invalidDate": "参数 {field} 的日期无效:“{dateValue}”",
"xpack.alerting.rulesClient.validateActions.invalidGroups": "无效操作组:{groups}",
"xpack.alerting.rulesClient.validateActions.misconfiguredConnector": "无效的连接器:{groups}",
"xpack.alerting.ruleTypeRegistry.get.missingAlertTypeError": "未注册规则类型“{id}”。",
"xpack.alerting.ruleTypeRegistry.get.missingRuleTypeError": "未注册规则类型“{id}”。",
"xpack.alerting.ruleTypeRegistry.register.customRecoveryActionGroupUsageError": "无法注册规则类型 [id=\"{id}\"]。操作组 [{actionGroup}] 无法同时用作恢复和活动操作组。",
"xpack.alerting.ruleTypeRegistry.register.duplicateAlertTypeError": "已注册规则类型“{id}”。",
"xpack.alerting.ruleTypeRegistry.register.invalidDefaultTimeoutAlertTypeError": "规则类型“{id}”的默认时间间隔无效:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidMinimumTimeoutAlertTypeError": "规则类型“{id}”的最小时间间隔无效:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidTimeoutAlertTypeError": "规则类型“{id}”的超时无效:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.duplicateRuleTypeError": "已注册规则类型“{id}”。",
"xpack.alerting.ruleTypeRegistry.register.invalidDefaultTimeoutRuleTypeError": "规则类型“{id}”的默认时间间隔无效:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidMinimumTimeoutRuleTypeError": "规则类型“{id}”的最小时间间隔无效:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.invalidTimeoutRuleTypeError": "规则类型“{id}”的超时无效:{errorMessage}。",
"xpack.alerting.ruleTypeRegistry.register.reservedActionGroupUsageError": "无法注册规则类型 [id=\"{id}\"]。操作组 [{actionGroups}] 由框架保留。",
"xpack.alerting.savedObjects.goToRulesButtonText": "前往规则",
"xpack.alerting.savedObjects.onImportText": "导入后必须启用 {rulesSavedObjectsLength} 个{rulesSavedObjectsLength, plural,other {规则}}。",
"xpack.alerting.serverSideErrors.expirerdLicenseErrorMessage": "告警类型 {alertTypeId} 已禁用,因为您的{licenseType}许可证已过期。",
"xpack.alerting.serverSideErrors.invalidLicenseErrorMessage": "告警 {alertTypeId} 已禁用,因为它需要{licenseType}许可证。前往“许可证管理”以查看升级选项。",
"xpack.alerting.serverSideErrors.unavailableLicenseErrorMessage": "告警类型 {alertTypeId} 已禁用,因为许可证信息当前不可用。",
"xpack.alerting.serverSideErrors.expirerdLicenseErrorMessage": "告警类型 {ruleTypeId} 已禁用,因为您的{licenseType}许可证已过期。",
"xpack.alerting.serverSideErrors.invalidLicenseErrorMessage": "告警 {ruleTypeId} 已禁用,因为它需要{licenseType}许可证。前往“许可证管理”以查看升级选项。",
"xpack.alerting.serverSideErrors.unavailableLicenseErrorMessage": "告警类型 {ruleTypeId} 已禁用,因为许可证信息当前不可用。",
"xpack.alerting.serverSideErrors.unavailableLicenseInformationErrorMessage": "告警不可用 - 许可信息当前不可用。",
"xpack.apm.a.thresholdMet": "已达到阈值",
"xpack.apm.addDataButtonLabel": "添加数据",

View file

@ -8,12 +8,12 @@ import { HttpSetup } from 'kibana/public';
import { pipe } from 'fp-ts/lib/pipeable';
import { fold } from 'fp-ts/lib/Either';
import { Errors, identity } from 'io-ts';
import { AlertTaskState } from '../../../types';
import { RuleTaskState } from '../../../types';
import { INTERNAL_BASE_ALERTING_API_PATH } from '../../constants';
import { alertStateSchema } from '../../../../../alerting/common';
import { ruleStateSchema } from '../../../../../alerting/common';
import { AsApiContract, RewriteRequestCase } from '../../../../../actions/common';
const rewriteBodyRes: RewriteRequestCase<AlertTaskState> = ({
const rewriteBodyRes: RewriteRequestCase<RuleTaskState> = ({
rule_type_state: alertTypeState,
alerts: alertInstances,
previous_started_at: previousStartedAt,
@ -32,17 +32,17 @@ export async function loadAlertState({
}: {
http: HttpSetup;
alertId: string;
}): Promise<AlertTaskState> {
}): Promise<RuleTaskState> {
return await http
.get<AsApiContract<AlertTaskState> | EmptyHttpResponse>(
.get<AsApiContract<RuleTaskState> | EmptyHttpResponse>(
`${INTERNAL_BASE_ALERTING_API_PATH}/rule/${alertId}/state`
)
.then((state) => (state ? rewriteBodyRes(state) : {}))
.then((state: AlertTaskState) => {
.then((state: RuleTaskState) => {
return pipe(
alertStateSchema.decode(state),
ruleStateSchema.decode(state),
fold((e: Errors) => {
throw new Error(`Alert "${alertId}" has invalid state`);
throw new Error(`Rule "${alertId}" has invalid state`);
}, identity)
);
});

View file

@ -10,7 +10,7 @@ import React from 'react';
import {
Alert,
AlertType,
AlertTaskState,
RuleTaskState,
AlertSummary,
AlertingFrameworkHealth,
ResolvedRule,
@ -56,7 +56,7 @@ export interface ComponentOpts {
errors: string[];
}>;
loadAlert: (id: Alert['id']) => Promise<Alert>;
loadAlertState: (id: Alert['id']) => Promise<AlertTaskState>;
loadAlertState: (id: Alert['id']) => Promise<RuleTaskState>;
loadAlertSummary: (id: Alert['id']) => Promise<AlertSummary>;
loadAlertTypes: () => Promise<AlertType[]>;
getHealth: () => Promise<AlertingFrameworkHealth>;

View file

@ -27,7 +27,7 @@ import {
ResolvedSanitizedRule,
AlertAction,
AlertAggregations,
AlertTaskState,
RuleTaskState,
AlertSummary,
ExecutionDuration,
AlertStatus,
@ -36,7 +36,7 @@ import {
AlertNotifyWhenType,
AlertTypeParams,
ActionVariable,
AlertType as CommonAlertType,
RuleType as CommonRuleType,
} from '../../alerting/common';
// In Triggers and Actions we treat all `Alert`s as `SanitizedAlert<AlertTypeParams>`
@ -48,7 +48,7 @@ export type {
Alert,
AlertAction,
AlertAggregations,
AlertTaskState,
RuleTaskState,
AlertSummary,
ExecutionDuration,
AlertStatus,
@ -208,7 +208,7 @@ export interface AlertType<
ActionGroupIds extends string = string,
RecoveryActionGroupId extends string = string
> extends Pick<
CommonAlertType<ActionGroupIds, RecoveryActionGroupId>,
CommonRuleType<ActionGroupIds, RecoveryActionGroupId>,
| 'id'
| 'name'
| 'actionGroups'

View file

@ -22,7 +22,7 @@ export default function emailTest({ getService }: FtrProviderContext) {
statusCode: 403,
error: 'Forbidden',
message:
'Alert test.gold.noop is disabled because it requires a Gold license. Go to License Management to view upgrade options.',
'Rule test.gold.noop is disabled because it requires a Gold license. Go to License Management to view upgrade options.',
});
});
});

View file

@ -11,7 +11,7 @@ import { curry, times } from 'lodash';
import { ES_TEST_INDEX_NAME } from '../../../../lib';
import { FixtureStartDeps, FixtureSetupDeps } from './plugin';
import {
AlertType,
RuleType,
AlertInstanceState,
AlertInstanceContext,
AlertTypeState,
@ -62,7 +62,7 @@ function getAlwaysFiringAlertType() {
interface InstanceContext extends AlertInstanceContext {
instanceContextValue: boolean;
}
const result: AlertType<
const result: RuleType<
ParamsType & AlertTypeParams,
never, // Only use if defining useSavedObjectReferences hook
State,
@ -159,7 +159,7 @@ function getCumulativeFiringAlertType() {
interface InstanceState extends AlertInstanceState {
instanceStateValue: boolean;
}
const result: AlertType<{}, {}, State, InstanceState, {}, 'default' | 'other'> = {
const result: RuleType<{}, {}, State, InstanceState, {}, 'default' | 'other'> = {
id: 'test.cumulative-firing',
name: 'Test: Cumulative Firing',
actionGroups: [
@ -200,7 +200,7 @@ function getNeverFiringAlertType() {
interface State extends AlertTypeState {
globalStateValue: boolean;
}
const result: AlertType<ParamsType, never, State, {}, {}, 'default'> = {
const result: RuleType<ParamsType, never, State, {}, {}, 'default'> = {
id: 'test.never-firing',
name: 'Test: Never firing',
actionGroups: [
@ -241,7 +241,7 @@ function getFailingAlertType() {
reference: schema.string(),
});
type ParamsType = TypeOf<typeof paramsSchema>;
const result: AlertType<ParamsType, never, {}, {}, {}, 'default'> = {
const result: RuleType<ParamsType, never, {}, {}, {}, 'default'> = {
id: 'test.failing',
name: 'Test: Failing',
validate: {
@ -283,7 +283,7 @@ function getAuthorizationAlertType(core: CoreSetup<FixtureStartDeps>) {
reference: schema.string(),
});
type ParamsType = TypeOf<typeof paramsSchema>;
const result: AlertType<ParamsType, never, {}, {}, {}, 'default'> = {
const result: RuleType<ParamsType, never, {}, {}, {}, 'default'> = {
id: 'test.authorization',
name: 'Test: Authorization',
actionGroups: [
@ -371,7 +371,7 @@ function getValidationAlertType() {
param1: schema.string(),
});
type ParamsType = TypeOf<typeof paramsSchema>;
const result: AlertType<ParamsType, never, {}, {}, {}, 'default'> = {
const result: RuleType<ParamsType, never, {}, {}, {}, 'default'> = {
id: 'test.validation',
name: 'Test: Validation',
actionGroups: [
@ -404,7 +404,7 @@ function getPatternFiringAlertType() {
interface State extends AlertTypeState {
patternIndex?: number;
}
const result: AlertType<ParamsType, never, State, {}, {}, 'default'> = {
const result: RuleType<ParamsType, never, State, {}, {}, 'default'> = {
id: 'test.patternFiring',
name: 'Test: Firing on a Pattern',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -473,7 +473,7 @@ function getLongRunningPatternRuleType(cancelAlertsOnRuleTimeout: boolean = true
interface State extends AlertTypeState {
patternIndex?: number;
}
const result: AlertType<ParamsType, never, State, {}, {}, 'default'> = {
const result: RuleType<ParamsType, never, State, {}, {}, 'default'> = {
id: `test.patternLongRunning${
cancelAlertsOnRuleTimeout === true ? '.cancelAlertsOnRuleTimeout' : ''
}`,
@ -519,7 +519,7 @@ export function defineAlertTypes(
core: CoreSetup<FixtureStartDeps>,
{ alerting }: Pick<FixtureSetupDeps, 'alerting'>
) {
const noopAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const noopAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.noop',
name: 'Test: Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -529,7 +529,7 @@ export function defineAlertTypes(
isExportable: true,
async executor() {},
};
const goldNoopAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const goldNoopAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.gold.noop',
name: 'Test: Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -539,7 +539,7 @@ export function defineAlertTypes(
isExportable: true,
async executor() {},
};
const onlyContextVariablesAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const onlyContextVariablesAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.onlyContextVariables',
name: 'Test: Only Context Variables',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -552,7 +552,7 @@ export function defineAlertTypes(
},
async executor() {},
};
const onlyStateVariablesAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const onlyStateVariablesAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.onlyStateVariables',
name: 'Test: Only State Variables',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -565,7 +565,7 @@ export function defineAlertTypes(
isExportable: true,
async executor() {},
};
const throwAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const throwAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.throw',
name: 'Test: Throw',
actionGroups: [
@ -582,7 +582,7 @@ export function defineAlertTypes(
throw new Error('this alert is intended to fail');
},
};
const longRunningAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const longRunningAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.longRunning',
name: 'Test: Long Running',
actionGroups: [
@ -599,21 +599,20 @@ export function defineAlertTypes(
await new Promise((resolve) => setTimeout(resolve, 5000));
},
};
const exampleAlwaysFiringAlertType: AlertType<{}, {}, {}, {}, {}, 'small' | 'medium' | 'large'> =
{
id: 'example.always-firing',
name: 'Always firing',
actionGroups: [
{ id: 'small', name: 'Small t-shirt' },
{ id: 'medium', name: 'Medium t-shirt' },
{ id: 'large', name: 'Large t-shirt' },
],
defaultActionGroupId: 'small',
minimumLicenseRequired: 'basic',
isExportable: true,
async executor() {},
producer: 'alertsFixture',
};
const exampleAlwaysFiringAlertType: RuleType<{}, {}, {}, {}, {}, 'small' | 'medium' | 'large'> = {
id: 'example.always-firing',
name: 'Always firing',
actionGroups: [
{ id: 'small', name: 'Small t-shirt' },
{ id: 'medium', name: 'Medium t-shirt' },
{ id: 'large', name: 'Large t-shirt' },
],
defaultActionGroupId: 'small',
minimumLicenseRequired: 'basic',
isExportable: true,
async executor() {},
producer: 'alertsFixture',
};
alerting.registerType(getAlwaysFiringAlertType());
alerting.registerType(getCumulativeFiringAlertType());

View file

@ -16,7 +16,7 @@ import {
} from 'kibana/server';
import { schema } from '@kbn/config-schema';
import { InvalidatePendingApiKey } from '../../../../../../../plugins/alerting/server/types';
import { RawAlert } from '../../../../../../../plugins/alerting/server/types';
import { RawRule } from '../../../../../../../plugins/alerting/server/types';
import {
ConcreteTaskInstance,
TaskInstance,
@ -89,12 +89,12 @@ export function defineRoutes(core: CoreSetup<FixtureStartDeps>, { logger }: { lo
logger,
`/api/alerts_fixture/${id}/replace_api_key`,
async () => {
return await savedObjectsWithAlerts.update<RawAlert>(
return await savedObjectsWithAlerts.update<RawRule>(
'alert',
id,
{
...(
await encryptedSavedObjectsWithAlerts.getDecryptedAsInternalUser<RawAlert>(
await encryptedSavedObjectsWithAlerts.getDecryptedAsInternalUser<RawRule>(
'alert',
id,
{
@ -154,7 +154,7 @@ export function defineRoutes(core: CoreSetup<FixtureStartDeps>, { logger }: { lo
const savedObjectsWithAlerts = await savedObjects.getScopedClient(req, {
includedHiddenTypes: ['alert'],
});
const savedAlert = await savedObjectsWithAlerts.get<RawAlert>(type, id);
const savedAlert = await savedObjectsWithAlerts.get<RawRule>(type, id);
const result = await retryIfConflicts(
logger,
`/api/alerts_fixture/saved_object/${type}/${id}`,
@ -232,7 +232,7 @@ export function defineRoutes(core: CoreSetup<FixtureStartDeps>, { logger }: { lo
const savedObjectsWithTasksAndAlerts = await savedObjects.getScopedClient(req, {
includedHiddenTypes: ['task', 'alert'],
});
const alert = await savedObjectsWithTasksAndAlerts.get<RawAlert>('alert', id);
const alert = await savedObjectsWithTasksAndAlerts.get<RawRule>('alert', id);
const result = await retryIfConflicts(
logger,
`/api/alerts_fixture/{id}/reset_task_status`,

View file

@ -7,13 +7,13 @@
import { CoreSetup } from 'src/core/server';
import { FixtureStartDeps, FixtureSetupDeps } from './plugin';
import { AlertType } from '../../../../../../../plugins/alerting/server';
import { RuleType } from '../../../../../../../plugins/alerting/server';
export function defineAlertTypes(
core: CoreSetup<FixtureStartDeps>,
{ alerting }: Pick<FixtureSetupDeps, 'alerting'>
) {
const noopRestrictedAlertType: AlertType<{}, {}, {}, {}, {}, 'default', 'restrictedRecovered'> = {
const noopRestrictedAlertType: RuleType<{}, {}, {}, {}, {}, 'default', 'restrictedRecovered'> = {
id: 'test.restricted-noop',
name: 'Test: Restricted Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -24,7 +24,7 @@ export function defineAlertTypes(
recoveryActionGroup: { id: 'restrictedRecovered', name: 'Restricted Recovery' },
async executor() {},
};
const noopUnrestrictedAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
const noopUnrestrictedAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.unrestricted-noop',
name: 'Test: Unrestricted Noop',
actionGroups: [{ id: 'default', name: 'Default' }],

View file

@ -227,7 +227,7 @@ instanceStateValue: true
alertId,
ruleTypeId: 'test.always-firing',
outcome: 'success',
message: `alert executed: test.always-firing:${alertId}: 'abc'`,
message: `rule executed: test.always-firing:${alertId}: 'abc'`,
ruleObject: alertSearchResultWithoutDates,
});
break;

View file

@ -17,7 +17,7 @@ import {
TaskManagerDoc,
} from '../../../common/lib';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import { RawAlert } from '../../../../../plugins/alerting/server/types';
import { RawRule } from '../../../../../plugins/alerting/server/types';
// eslint-disable-next-line import/no-default-export
export default function createAlertTests({ getService }: FtrProviderContext) {
@ -190,7 +190,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) {
execution_status: response.body.execution_status,
});
const esResponse = await es.get<SavedObject<RawAlert>>(
const esResponse = await es.get<SavedObject<RawRule>>(
{
index: '.kibana',
id: `alert:${response.body.id}`,

View file

@ -133,7 +133,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
savedObjects: [
{ type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' },
],
message: `alert execution start: "${alertId}"`,
message: `rule execution start: "${alertId}"`,
shouldHaveTask: true,
rule: {
id: alertId,
@ -150,7 +150,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
{ type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' },
],
outcome: 'success',
message: `alert executed: test.patternFiring:${alertId}: 'abc'`,
message: `rule executed: test.patternFiring:${alertId}: 'abc'`,
status: executeStatuses[executeCount++],
shouldHaveTask: true,
rule: {
@ -182,15 +182,15 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
});
break;
case 'new-instance':
validateInstanceEvent(event, `created new instance: 'instance'`, false);
validateInstanceEvent(event, `created new alert: 'instance'`, false);
break;
case 'recovered-instance':
validateInstanceEvent(event, `instance 'instance' has recovered`, true);
validateInstanceEvent(event, `alert 'instance' has recovered`, true);
break;
case 'active-instance':
validateInstanceEvent(
event,
`active instance: 'instance' in actionGroup: 'default'`,
`active alert: 'instance' in actionGroup: 'default'`,
false
);
break;
@ -344,7 +344,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
savedObjects: [
{ type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' },
],
message: `alert execution start: "${alertId}"`,
message: `rule execution start: "${alertId}"`,
shouldHaveTask: true,
rule: {
id: alertId,
@ -361,7 +361,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
{ type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' },
],
outcome: 'success',
message: `alert executed: test.patternFiring:${alertId}: 'abc'`,
message: `rule executed: test.patternFiring:${alertId}: 'abc'`,
status: executeStatuses[executeCount++],
shouldHaveTask: true,
rule: {
@ -398,10 +398,10 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
});
break;
case 'new-instance':
validateInstanceEvent(event, `created new instance: 'instance'`, false);
validateInstanceEvent(event, `created new alert: 'instance'`, false);
break;
case 'recovered-instance':
validateInstanceEvent(event, `instance 'instance' has recovered`, true);
validateInstanceEvent(event, `alert 'instance' has recovered`, true);
break;
case 'active-instance':
expect(
@ -411,7 +411,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
).to.be(true);
validateInstanceEvent(
event,
`active instance: 'instance' in actionGroup(subgroup): 'default(${event?.kibana?.alerting?.action_subgroup})'`,
`active alert: 'instance' in actionGroup(subgroup): 'default(${event?.kibana?.alerting?.action_subgroup})'`,
false
);
break;
@ -490,7 +490,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
savedObjects: [
{ type: 'alert', id: alertId, rel: 'primary', type_id: 'test.patternFiring' },
],
message: `alert execution start: "${alertId}"`,
message: `rule execution start: "${alertId}"`,
shouldHaveTask: true,
rule: {
id: alertId,
@ -504,7 +504,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) {
spaceId: space.id,
savedObjects: [{ type: 'alert', id: alertId, rel: 'primary', type_id: 'test.throw' }],
outcome: 'failure',
message: `alert execution failure: test.throw:${alertId}: 'abc'`,
message: `rule execution failure: test.throw:${alertId}: 'abc'`,
errorMessage: 'this alert is intended to fail',
status: 'error',
reason: 'execute',

View file

@ -9,7 +9,7 @@ import expect from '@kbn/expect';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { getUrlPrefix } from '../../../common/lib';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import type { RawAlert, RawAlertAction } from '../../../../../plugins/alerting/server/types';
import type { RawRule, RawAlertAction } from '../../../../../plugins/alerting/server/types';
import { FILEBEAT_7X_INDICATOR_PATH } from '../../../../../plugins/alerting/server/saved_objects/migrations';
// eslint-disable-next-line import/no-default-export
@ -205,7 +205,7 @@ export default function createGetTests({ getService }: FtrProviderContext) {
});
it('7.16.0 migrates existing alerts to contain legacyId field', async () => {
const searchResult = await es.search<RawAlert>(
const searchResult = await es.search<RawRule>(
{
index: '.kibana',
body: {
@ -221,13 +221,13 @@ export default function createGetTests({ getService }: FtrProviderContext) {
expect(searchResult.statusCode).to.equal(200);
expect((searchResult.body.hits.total as estypes.SearchTotalHits).value).to.equal(1);
const hit = searchResult.body.hits.hits[0];
expect((hit!._source!.alert! as RawAlert).legacyId).to.equal(
expect((hit!._source!.alert! as RawRule).legacyId).to.equal(
'74f3e6d7-b7bb-477d-ac28-92ee22728e6e'
);
});
it('7.16.0 migrates existing rules so predefined connectors are not stored in references', async () => {
const searchResult = await es.search<RawAlert>(
const searchResult = await es.search<RawRule>(
{
index: '.kibana',
body: {
@ -243,7 +243,7 @@ export default function createGetTests({ getService }: FtrProviderContext) {
expect(searchResult.statusCode).to.equal(200);
expect((searchResult.body.hits.total as estypes.SearchTotalHits).value).to.equal(1);
const hit = searchResult.body.hits.hits[0];
expect((hit!._source!.alert! as RawAlert).actions! as RawAlertAction[]).to.eql([
expect((hit!._source!.alert! as RawRule).actions! as RawAlertAction[]).to.eql([
{
actionRef: 'action_0',
actionTypeId: 'test.noop',
@ -348,7 +348,7 @@ export default function createGetTests({ getService }: FtrProviderContext) {
});
it('8.0 migrates incorrect action group spellings on the Metrics Inventory Threshold rule type', async () => {
const response = await es.get<{ alert: RawAlert }>(
const response = await es.get<{ alert: RawRule }>(
{
index: '.kibana',
id: 'alert:92237b30-4e03-11ec-9ab9-d980518a2d28',

View file

@ -8,7 +8,7 @@
import { Plugin, CoreSetup } from 'kibana/server';
import {
PluginSetupContract as AlertingSetup,
AlertType,
RuleType,
} from '../../../../../../plugins/alerting/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../../../../../plugins/features/server';
@ -18,7 +18,7 @@ export interface AlertingExampleDeps {
features: FeaturesPluginSetup;
}
export const noopAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
export const noopAlertType: RuleType<{}, {}, {}, {}, {}, 'default'> = {
id: 'test.noop',
name: 'Test: Noop',
actionGroups: [{ id: 'default', name: 'Default' }],
@ -29,7 +29,7 @@ export const noopAlertType: AlertType<{}, {}, {}, {}, {}, 'default'> = {
producer: 'alerts',
};
export const alwaysFiringAlertType: AlertType<
export const alwaysFiringAlertType: RuleType<
{ instances: Array<{ id: string; state: any }> },
never, // Only use if defining useSavedObjectReferences hook
{
@ -67,7 +67,7 @@ export const alwaysFiringAlertType: AlertType<
},
};
export const failingAlertType: AlertType<never, never, never, never, never, 'default' | 'other'> = {
export const failingAlertType: RuleType<never, never, never, never, never, 'default' | 'other'> = {
id: 'test.failing',
name: 'Test: Failing',
actionGroups: [