[Alerting] Enable rule import/export and allow rule types to exclude themselves from export (#102999) (#103598)
* Removing feature flag changes * Adding isExportable flag to rule type definition * Adding isExportable flag to rule type definition * Adding isExportable flag to rule type definition * Filtering rule on export by rule type isExportable flag * Fixing types * Adding docs * Fix condition when exportCount is 0 * Unit test for fix condition when exportCount is 0 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: ymao1 <ying.mao@elastic.co>
This commit is contained in:
parent
40027878d5
commit
0fd977acc8
|
@ -80,6 +80,7 @@ The API returns the following:
|
|||
},
|
||||
"producer":"stackAlerts",
|
||||
"minimumLicenseRequired":"basic",
|
||||
"isExportable":true,
|
||||
"enabledInLicense":true,
|
||||
"authorizedConsumers":{
|
||||
"alerts":{
|
||||
|
@ -113,6 +114,9 @@ Each alert type contains the following properties:
|
|||
| `minimumLicenseRequired`
|
||||
| The license required to use the alert type.
|
||||
|
||||
| `isExportable`
|
||||
| Whether the rule type is exportable through the Saved Objects Management UI.
|
||||
|
||||
| `enabledInLicense`
|
||||
| Whether the alert type is enabled or disabled based on the license.
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ The API returns the following:
|
|||
},
|
||||
"producer":"stackAlerts",
|
||||
"minimum_license_required":"basic",
|
||||
"is_exportable":true,
|
||||
"enabled_in_license":true,
|
||||
"authorized_consumers":{
|
||||
"alerts":{
|
||||
|
@ -115,6 +116,9 @@ Each rule type contains the following properties:
|
|||
| `minimum_license_required`
|
||||
| The license required to use the rule type.
|
||||
|
||||
| `is_exportable`
|
||||
| Whether the rule type is exportable through the Saved Objects Management UI.
|
||||
|
||||
| `enabled_in_license`
|
||||
| Whether the rule type is enabled or disabled based on the license.
|
||||
|
||||
|
|
|
@ -152,6 +152,25 @@ You can perform these operations in bulk by multi-selecting rules, and then clic
|
|||
[role="screenshot"]
|
||||
image:images/bulk-mute-disable.png[The Manage rules button lets you mute/unmute, enable/disable, and delete in bulk,width=75%]
|
||||
|
||||
[float]
|
||||
[[importing-and-exporting-rules]]
|
||||
=== Import and export rules
|
||||
|
||||
To import and export rules, use the <<managing-saved-objects, Saved Objects Management UI>>.
|
||||
|
||||
[NOTE]
|
||||
==============================================
|
||||
Some rule types cannot be exported through this interface:
|
||||
|
||||
**Security rules** can be imported and exported using the {security-guide}/rules-ui-management.html#import-export-rules-ui[Security UI].
|
||||
|
||||
**Stack monitoring rules** are <<kibana-alerts, automatically created>> for you and therefore cannot be managed via the Saved Objects Management UI.
|
||||
==============================================
|
||||
|
||||
Rules are disabled on export. You are prompted to re-enable rule on successful import.
|
||||
[role="screenshot"]
|
||||
image::images/rules-imported-banner.png[Rules import banner, width=50%]
|
||||
|
||||
[float]
|
||||
[[rule-details]]
|
||||
=== Drilldown to rule details
|
||||
|
|
|
@ -101,6 +101,22 @@ describe('createSavedObjectsStreamFromNdJson', () => {
|
|||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('handles an ndjson stream that only contains excluded saved objects', async () => {
|
||||
const savedObjectsStream = await createSavedObjectsStreamFromNdJson(
|
||||
new Readable({
|
||||
read() {
|
||||
this.push(
|
||||
'{"excludedObjects":[{"id":"foo","reason":"excluded","type":"foo-type"}],"excludedObjectsCount":1,"exportedCount":0,"missingRefCount":0,"missingReferences":[]}\n'
|
||||
);
|
||||
this.push(null);
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const result = await readStreamToCompletion(savedObjectsStream);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateTypes', () => {
|
||||
|
|
|
@ -32,7 +32,7 @@ export async function createSavedObjectsStreamFromNdJson(ndJsonStream: Readable)
|
|||
}
|
||||
}),
|
||||
createFilterStream<SavedObject | SavedObjectsExportResultDetails>(
|
||||
(obj) => !!obj && !(obj as SavedObjectsExportResultDetails).exportedCount
|
||||
(obj) => !!obj && (obj as SavedObjectsExportResultDetails).exportedCount === undefined
|
||||
),
|
||||
createConcatStream([]),
|
||||
]);
|
||||
|
|
|
@ -53,6 +53,7 @@ export const alertType: AlertType<
|
|||
],
|
||||
defaultActionGroupId: DEFAULT_ACTION_GROUP,
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({
|
||||
services,
|
||||
params: { instances = DEFAULT_INSTANCES_TO_GENERATE, thresholds },
|
||||
|
|
|
@ -51,6 +51,7 @@ export const alertType: AlertType<
|
|||
name: 'People In Space Right Now',
|
||||
actionGroups: [{ id: 'default', name: 'default' }],
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
defaultActionGroupId: 'default',
|
||||
recoveryActionGroup: {
|
||||
id: 'hasLandedBackOnEarth',
|
||||
|
|
|
@ -118,6 +118,7 @@ The following table describes the properties of the `options` object.
|
|||
|executor|This is where the code for the rule type lives. This is a function to be called when executing a rule on an interval basis. For full details, see the executor section below.|Function|
|
||||
|producer|The id of the application producing this rule type.|string|
|
||||
|minimumLicenseRequired|The value of a minimum license. Most of the rules are licensed as "basic".|string|
|
||||
|isExportable|Whether the rule type is exportable from the Saved Objects Management UI.|boolean|
|
||||
|
||||
### Executor
|
||||
|
||||
|
@ -262,6 +263,7 @@ const myRuleType: AlertType<
|
|||
],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({
|
||||
alertId,
|
||||
startedAt,
|
||||
|
|
|
@ -20,6 +20,7 @@ export interface AlertType<
|
|||
defaultActionGroupId: ActionGroupIds;
|
||||
producer: string;
|
||||
minimumLicenseRequired: LicenseType;
|
||||
isExportable: boolean;
|
||||
}
|
||||
|
||||
export interface ActionGroup<ActionGroupIds extends string> {
|
||||
|
|
|
@ -24,6 +24,7 @@ describe('loadAlertTypes', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
producer: 'alerts',
|
||||
},
|
||||
|
@ -49,6 +50,7 @@ describe('loadAlertType', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -71,6 +73,7 @@ describe('loadAlertType', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ const mockAlertType = (id: string): AlertType => ({
|
|||
defaultActionGroupId: 'default',
|
||||
producer: 'alerts',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
});
|
||||
|
||||
describe('AlertNavigationRegistry', () => {
|
||||
|
|
|
@ -47,6 +47,7 @@ describe('has()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
});
|
||||
|
@ -67,6 +68,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -99,6 +101,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -129,6 +132,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -159,6 +163,7 @@ describe('register()', () => {
|
|||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
};
|
||||
const registry = new AlertTypeRegistry(alertTypeRegistryParams);
|
||||
registry.register(alertType);
|
||||
|
@ -203,6 +208,7 @@ describe('register()', () => {
|
|||
},
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -227,6 +233,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -257,6 +264,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -279,6 +287,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
});
|
||||
|
@ -294,6 +303,7 @@ describe('register()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
})
|
||||
|
@ -315,6 +325,7 @@ describe('get()', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
});
|
||||
|
@ -339,6 +350,7 @@ describe('get()', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"executor": [MockFunction],
|
||||
"id": "test",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "Test",
|
||||
"producer": "alerts",
|
||||
|
@ -377,6 +389,7 @@ describe('list()', () => {
|
|||
},
|
||||
],
|
||||
defaultActionGroupId: 'testActionGroup',
|
||||
isExportable: true,
|
||||
minimumLicenseRequired: 'basic',
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
|
@ -403,6 +416,7 @@ describe('list()', () => {
|
|||
"defaultActionGroupId": "testActionGroup",
|
||||
"enabledInLicense": false,
|
||||
"id": "test",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "Test",
|
||||
"producer": "alerts",
|
||||
|
@ -467,6 +481,7 @@ describe('ensureAlertTypeEnabled', () => {
|
|||
defaultActionGroupId: 'default',
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
isExportable: true,
|
||||
minimumLicenseRequired: 'basic',
|
||||
recoveryActionGroup: { id: 'recovered', name: 'Recovered' },
|
||||
});
|
||||
|
@ -497,6 +512,7 @@ function alertTypeWithVariables<ActionGroupIds extends string>(
|
|||
name: `${id}-name`,
|
||||
actionGroups: [],
|
||||
defaultActionGroupId: id,
|
||||
isExportable: true,
|
||||
minimumLicenseRequired: 'basic',
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
|
|
|
@ -46,6 +46,7 @@ export interface RegistryAlertType
|
|||
| 'actionVariables'
|
||||
| 'producer'
|
||||
| 'minimumLicenseRequired'
|
||||
| 'isExportable'
|
||||
> {
|
||||
id: string;
|
||||
enabledInLicense: boolean;
|
||||
|
@ -250,6 +251,7 @@ export class AlertTypeRegistry {
|
|||
actionVariables,
|
||||
producer,
|
||||
minimumLicenseRequired,
|
||||
isExportable,
|
||||
},
|
||||
]: [string, UntypedNormalizedAlertType]) => ({
|
||||
id,
|
||||
|
@ -260,6 +262,7 @@ export class AlertTypeRegistry {
|
|||
actionVariables,
|
||||
producer,
|
||||
minimumLicenseRequired,
|
||||
isExportable,
|
||||
enabledInLicense: !!this.licenseState.getLicenseCheckForAlertType(
|
||||
id,
|
||||
name,
|
||||
|
|
|
@ -58,6 +58,7 @@ describe('aggregate()', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myType',
|
||||
name: 'myType',
|
||||
|
@ -110,6 +111,7 @@ describe('aggregate()', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
producer: 'alerts',
|
||||
authorizedConsumers: {
|
||||
|
|
|
@ -1293,6 +1293,7 @@ describe('create()', () => {
|
|||
}),
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
});
|
||||
|
|
|
@ -67,6 +67,7 @@ describe('find()', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
id: 'myType',
|
||||
name: 'myType',
|
||||
producer: 'myApp',
|
||||
|
@ -126,6 +127,7 @@ describe('find()', () => {
|
|||
recoveryActionGroup: RecoveredActionGroup,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
producer: 'alerts',
|
||||
authorizedConsumers: {
|
||||
myApp: { read: true, all: true },
|
||||
|
|
|
@ -88,6 +88,7 @@ export function getBeforeSetup(
|
|||
recoveryActionGroup: RecoveredActionGroup,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
}));
|
||||
|
|
|
@ -58,6 +58,7 @@ describe('listAlertTypes', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'alertingAlertType',
|
||||
name: 'alertingAlertType',
|
||||
|
@ -69,6 +70,7 @@ describe('listAlertTypes', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -110,6 +112,7 @@ describe('listAlertTypes', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myType',
|
||||
name: 'myType',
|
||||
|
@ -122,6 +125,7 @@ describe('listAlertTypes', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
producer: 'alerts',
|
||||
enabledInLicense: true,
|
||||
|
@ -139,6 +143,7 @@ describe('listAlertTypes', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
producer: 'alerts',
|
||||
authorizedConsumers: {
|
||||
|
|
|
@ -127,6 +127,7 @@ describe('update()', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
|
@ -773,6 +774,7 @@ describe('update()', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
validate: {
|
||||
params: schema.object({
|
||||
|
@ -1096,6 +1098,7 @@ describe('update()', () => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
|
|
|
@ -335,6 +335,7 @@ beforeEach(() => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
|
@ -346,6 +347,7 @@ beforeEach(() => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
|
|
|
@ -203,6 +203,7 @@ beforeEach(() => {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
async executor() {},
|
||||
producer: 'myApp',
|
||||
|
@ -892,6 +893,7 @@ describe('AlertingAuthorization', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myOtherAppAlertType',
|
||||
name: 'myOtherAppAlertType',
|
||||
|
@ -903,6 +905,7 @@ describe('AlertingAuthorization', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -914,6 +917,7 @@ describe('AlertingAuthorization', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'mySecondAppAlertType',
|
||||
name: 'mySecondAppAlertType',
|
||||
|
@ -1242,6 +1246,7 @@ describe('AlertingAuthorization', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myOtherAppAlertType',
|
||||
name: 'myOtherAppAlertType',
|
||||
|
@ -1253,6 +1258,7 @@ describe('AlertingAuthorization', () => {
|
|||
actionVariables: undefined,
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -1300,6 +1306,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myAppAlertType",
|
||||
"producer": "myApp",
|
||||
|
@ -1328,6 +1335,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myOtherAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myOtherAppAlertType",
|
||||
"producer": "myOtherApp",
|
||||
|
@ -1387,6 +1395,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myAppAlertType",
|
||||
"producer": "myApp",
|
||||
|
@ -1423,6 +1432,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myOtherAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myOtherAppAlertType",
|
||||
"producer": "myOtherApp",
|
||||
|
@ -1502,6 +1512,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myOtherAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myOtherAppAlertType",
|
||||
"producer": "myOtherApp",
|
||||
|
@ -1526,6 +1537,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myAppAlertType",
|
||||
"producer": "myApp",
|
||||
|
@ -1605,6 +1617,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myOtherAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myOtherAppAlertType",
|
||||
"producer": "myOtherApp",
|
||||
|
@ -1633,6 +1646,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myAppAlertType",
|
||||
"producer": "myApp",
|
||||
|
@ -1703,6 +1717,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myAppAlertType",
|
||||
"producer": "myApp",
|
||||
|
@ -1807,6 +1822,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myOtherAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myOtherAppAlertType",
|
||||
"producer": "myOtherApp",
|
||||
|
@ -1831,6 +1847,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myAppAlertType",
|
||||
"producer": "myApp",
|
||||
|
@ -1914,6 +1931,7 @@ describe('AlertingAuthorization', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "myOtherAppAlertType",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "myOtherAppAlertType",
|
||||
"producer": "myOtherApp",
|
||||
|
|
|
@ -26,6 +26,7 @@ describe('asKqlFiltersByRuleTypeAndConsumer', () => {
|
|||
name: 'myAppAlertType',
|
||||
producer: 'myApp',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
authorizedConsumers: {
|
||||
myApp: { read: true, all: true },
|
||||
},
|
||||
|
@ -53,6 +54,7 @@ describe('asKqlFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -88,6 +90,7 @@ describe('asKqlFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -104,6 +107,7 @@ describe('asKqlFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myOtherAppAlertType',
|
||||
name: 'myOtherAppAlertType',
|
||||
|
@ -120,6 +124,7 @@ describe('asKqlFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'mySecondAppAlertType',
|
||||
name: 'mySecondAppAlertType',
|
||||
|
@ -162,6 +167,7 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => {
|
|||
name: 'myAppAlertType',
|
||||
producer: 'myApp',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
authorizedConsumers: {
|
||||
myApp: { read: true, all: true },
|
||||
},
|
||||
|
@ -216,6 +222,7 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -283,6 +290,7 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myAppAlertType',
|
||||
name: 'myAppAlertType',
|
||||
|
@ -299,6 +307,7 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'myOtherAppAlertType',
|
||||
name: 'myOtherAppAlertType',
|
||||
|
@ -315,6 +324,7 @@ describe('asEsDslFiltersByRuleTypeAndConsumer', () => {
|
|||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
id: 'mySecondAppAlertType',
|
||||
name: 'mySecondAppAlertType',
|
||||
|
|
|
@ -12,7 +12,6 @@ describe('config validation', () => {
|
|||
const config: Record<string, unknown> = {};
|
||||
expect(configSchema.validate(config)).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"enableImportExport": false,
|
||||
"healthCheck": Object {
|
||||
"interval": "60m",
|
||||
},
|
||||
|
|
|
@ -16,7 +16,6 @@ export const configSchema = schema.object({
|
|||
interval: schema.string({ validate: validateDurationSchema, defaultValue: '5m' }),
|
||||
removalDelay: schema.string({ validate: validateDurationSchema, defaultValue: '1h' }),
|
||||
}),
|
||||
enableImportExport: schema.boolean({ defaultValue: false }),
|
||||
});
|
||||
|
||||
export type AlertsConfig = TypeOf<typeof configSchema>;
|
||||
|
|
|
@ -71,7 +71,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
}),
|
||||
pollInterval
|
||||
).subscribe();
|
||||
|
@ -105,7 +104,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
}),
|
||||
pollInterval,
|
||||
retryDelay
|
||||
|
@ -150,7 +148,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
})
|
||||
).toPromise();
|
||||
|
||||
|
@ -181,7 +178,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
})
|
||||
).toPromise();
|
||||
|
||||
|
@ -212,7 +208,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
})
|
||||
).toPromise();
|
||||
|
||||
|
@ -240,7 +235,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
}),
|
||||
retryDelay
|
||||
).subscribe((status) => {
|
||||
|
@ -271,7 +265,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
}),
|
||||
retryDelay
|
||||
).subscribe((status) => {
|
||||
|
@ -308,7 +301,6 @@ describe('getHealthServiceStatusWithRetryAndErrorHandling', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
})
|
||||
).toPromise();
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ describe('getLicenseCheckForAlertType', () => {
|
|||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
minimumLicenseRequired: 'gold',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: { id: 'recovered', name: 'Recovered' },
|
||||
};
|
||||
|
||||
|
@ -204,6 +205,7 @@ describe('ensureLicenseForAlertType()', () => {
|
|||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
minimumLicenseRequired: 'gold',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: { id: 'recovered', name: 'Recovered' },
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import { AlertsConfig } from './config';
|
|||
import { AlertType } from './types';
|
||||
import { eventLogMock } from '../../event_log/server/mocks';
|
||||
import { actionsMock } from '../../actions/server/mocks';
|
||||
import mappings from './saved_objects/mappings.json';
|
||||
|
||||
describe('Alerting Plugin', () => {
|
||||
describe('setup()', () => {
|
||||
|
@ -37,7 +36,6 @@ describe('Alerting Plugin', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
});
|
||||
plugin = new AlertingPlugin(context);
|
||||
|
||||
|
@ -61,78 +59,13 @@ describe('Alerting Plugin', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should register saved object with no management capability if enableImportExport is false', async () => {
|
||||
const context = coreMock.createPluginInitializerContext<AlertsConfig>({
|
||||
healthCheck: {
|
||||
interval: '5m',
|
||||
},
|
||||
invalidateApiKeysTask: {
|
||||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
});
|
||||
plugin = new AlertingPlugin(context);
|
||||
|
||||
const setupMocks = coreMock.createSetup();
|
||||
await plugin.setup(setupMocks, {
|
||||
licensing: licensingMock.createSetup(),
|
||||
encryptedSavedObjects: encryptedSavedObjectsMock.createSetup(),
|
||||
taskManager: taskManagerMock.createSetup(),
|
||||
eventLog: eventLogServiceMock.create(),
|
||||
actions: actionsMock.createSetup(),
|
||||
statusService: statusServiceMock.createSetupContract(),
|
||||
});
|
||||
|
||||
expect(setupMocks.savedObjects.registerType).toHaveBeenCalledTimes(2);
|
||||
const registerAlertingSavedObject = setupMocks.savedObjects.registerType.mock.calls[0][0];
|
||||
expect(registerAlertingSavedObject.name).toEqual('alert');
|
||||
expect(registerAlertingSavedObject.hidden).toBe(true);
|
||||
expect(registerAlertingSavedObject.mappings).toEqual(mappings.alert);
|
||||
expect(registerAlertingSavedObject.management).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should register saved object with import/export capability if enableImportExport is true', async () => {
|
||||
const context = coreMock.createPluginInitializerContext<AlertsConfig>({
|
||||
healthCheck: {
|
||||
interval: '5m',
|
||||
},
|
||||
invalidateApiKeysTask: {
|
||||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: true,
|
||||
});
|
||||
plugin = new AlertingPlugin(context);
|
||||
|
||||
const setupMocks = coreMock.createSetup();
|
||||
await plugin.setup(setupMocks, {
|
||||
licensing: licensingMock.createSetup(),
|
||||
encryptedSavedObjects: encryptedSavedObjectsMock.createSetup(),
|
||||
taskManager: taskManagerMock.createSetup(),
|
||||
eventLog: eventLogServiceMock.create(),
|
||||
actions: actionsMock.createSetup(),
|
||||
statusService: statusServiceMock.createSetupContract(),
|
||||
});
|
||||
|
||||
expect(setupMocks.savedObjects.registerType).toHaveBeenCalledTimes(2);
|
||||
const registerAlertingSavedObject = setupMocks.savedObjects.registerType.mock.calls[0][0];
|
||||
expect(registerAlertingSavedObject.name).toEqual('alert');
|
||||
expect(registerAlertingSavedObject.hidden).toBe(true);
|
||||
expect(registerAlertingSavedObject.mappings).toEqual(mappings.alert);
|
||||
expect(registerAlertingSavedObject.management).not.toBeUndefined();
|
||||
expect(registerAlertingSavedObject.management?.importableAndExportable).toBe(true);
|
||||
expect(registerAlertingSavedObject.management?.getTitle).not.toBeUndefined();
|
||||
expect(registerAlertingSavedObject.management?.onImport).not.toBeUndefined();
|
||||
expect(registerAlertingSavedObject.management?.onExport).not.toBeUndefined();
|
||||
});
|
||||
|
||||
describe('registerType()', () => {
|
||||
let setup: PluginSetupContract;
|
||||
const sampleAlertType: AlertType<never, never, never, never, 'default'> = {
|
||||
id: 'test',
|
||||
name: 'test',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
actionGroups: [],
|
||||
defaultActionGroupId: 'default',
|
||||
producer: 'test',
|
||||
|
@ -189,7 +122,6 @@ describe('Alerting Plugin', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
});
|
||||
const plugin = new AlertingPlugin(context);
|
||||
|
||||
|
@ -229,7 +161,6 @@ describe('Alerting Plugin', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
});
|
||||
const plugin = new AlertingPlugin(context);
|
||||
|
||||
|
@ -283,7 +214,6 @@ describe('Alerting Plugin', () => {
|
|||
interval: '5m',
|
||||
removalDelay: '1h',
|
||||
},
|
||||
enableImportExport: false,
|
||||
});
|
||||
const plugin = new AlertingPlugin(context);
|
||||
|
||||
|
|
|
@ -192,8 +192,6 @@ export class AlertingPlugin {
|
|||
event: { provider: EVENT_LOG_PROVIDER },
|
||||
});
|
||||
|
||||
setupSavedObjects(core.savedObjects, plugins.encryptedSavedObjects, this.config);
|
||||
|
||||
this.eventLogService = plugins.eventLog;
|
||||
plugins.eventLog.registerProviderActions(EVENT_LOG_PROVIDER, Object.values(EVENT_LOG_ACTIONS));
|
||||
|
||||
|
@ -221,6 +219,13 @@ export class AlertingPlugin {
|
|||
});
|
||||
}
|
||||
|
||||
setupSavedObjects(
|
||||
core.savedObjects,
|
||||
plugins.encryptedSavedObjects,
|
||||
this.alertTypeRegistry,
|
||||
this.logger
|
||||
);
|
||||
|
||||
initializeApiKeyInvalidator(
|
||||
this.logger,
|
||||
core.getStartServices(),
|
||||
|
|
|
@ -47,6 +47,7 @@ describe('listAlertTypesRoute', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
authorizedConsumers: {},
|
||||
actionVariables: {
|
||||
|
@ -79,6 +80,7 @@ describe('listAlertTypesRoute', () => {
|
|||
"defaultActionGroupId": "default",
|
||||
"enabledInLicense": true,
|
||||
"id": "1",
|
||||
"isExportable": true,
|
||||
"minimumLicenseRequired": "basic",
|
||||
"name": "name",
|
||||
"producer": "test",
|
||||
|
@ -120,6 +122,7 @@ describe('listAlertTypesRoute', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
authorizedConsumers: {},
|
||||
actionVariables: {
|
||||
|
@ -172,6 +175,7 @@ describe('listAlertTypesRoute', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
authorizedConsumers: {},
|
||||
actionVariables: {
|
||||
|
|
|
@ -48,6 +48,7 @@ describe('ruleTypesRoute', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
authorizedConsumers: {},
|
||||
actionVariables: {
|
||||
|
@ -70,6 +71,7 @@ describe('ruleTypesRoute', () => {
|
|||
],
|
||||
default_action_group_id: 'default',
|
||||
minimum_license_required: 'basic',
|
||||
is_exportable: true,
|
||||
recovery_action_group: RecoveredActionGroup,
|
||||
authorized_consumers: {},
|
||||
action_variables: {
|
||||
|
@ -102,6 +104,7 @@ describe('ruleTypesRoute', () => {
|
|||
"default_action_group_id": "default",
|
||||
"enabled_in_license": true,
|
||||
"id": "1",
|
||||
"is_exportable": true,
|
||||
"minimum_license_required": "basic",
|
||||
"name": "name",
|
||||
"producer": "test",
|
||||
|
@ -143,6 +146,7 @@ describe('ruleTypesRoute', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
authorizedConsumers: {},
|
||||
actionVariables: {
|
||||
|
@ -195,6 +199,7 @@ describe('ruleTypesRoute', () => {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
authorizedConsumers: {},
|
||||
actionVariables: {
|
||||
|
|
|
@ -19,6 +19,7 @@ const rewriteBodyRes: RewriteResponseCase<RegistryAlertTypeWithAuth[]> = (result
|
|||
actionGroups,
|
||||
defaultActionGroupId,
|
||||
minimumLicenseRequired,
|
||||
isExportable,
|
||||
actionVariables,
|
||||
authorizedConsumers,
|
||||
...rest
|
||||
|
@ -29,6 +30,7 @@ const rewriteBodyRes: RewriteResponseCase<RegistryAlertTypeWithAuth[]> = (result
|
|||
action_groups: actionGroups,
|
||||
default_action_group_id: defaultActionGroupId,
|
||||
minimum_license_required: minimumLicenseRequired,
|
||||
is_exportable: isExportable,
|
||||
action_variables: actionVariables,
|
||||
authorized_consumers: authorizedConsumers,
|
||||
})
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import type {
|
||||
Logger,
|
||||
SavedObject,
|
||||
SavedObjectsExportTransformContext,
|
||||
SavedObjectsServiceSetup,
|
||||
|
@ -17,7 +18,9 @@ import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objec
|
|||
import { transformRulesForExport } from './transform_rule_for_export';
|
||||
import { RawAlert } from '../types';
|
||||
import { getImportWarnings } from './get_import_warnings';
|
||||
import { AlertsConfig } from '../config';
|
||||
import { isRuleExportable } from './is_rule_exportable';
|
||||
import { AlertTypeRegistry } from '../alert_type_registry';
|
||||
|
||||
export { partiallyUpdateAlert } from './partially_update_alert';
|
||||
|
||||
export const AlertAttributesExcludedFromAAD = [
|
||||
|
@ -44,65 +47,63 @@ export type AlertAttributesExcludedFromAADType =
|
|||
export function setupSavedObjects(
|
||||
savedObjects: SavedObjectsServiceSetup,
|
||||
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup,
|
||||
alertingConfig: Promise<AlertsConfig>
|
||||
ruleTypeRegistry: AlertTypeRegistry,
|
||||
logger: Logger
|
||||
) {
|
||||
alertingConfig.then((config: AlertsConfig) => {
|
||||
savedObjects.registerType({
|
||||
name: 'alert',
|
||||
hidden: true,
|
||||
namespaceType: 'single',
|
||||
migrations: getMigrations(encryptedSavedObjects),
|
||||
mappings: mappings.alert as SavedObjectsTypeMappingDefinition,
|
||||
...(config.enableImportExport
|
||||
? {
|
||||
management: {
|
||||
importableAndExportable: true,
|
||||
getTitle(ruleSavedObject: SavedObject<RawAlert>) {
|
||||
return `Rule: [${ruleSavedObject.attributes.name}]`;
|
||||
},
|
||||
onImport(ruleSavedObjects) {
|
||||
return {
|
||||
warnings: getImportWarnings(ruleSavedObjects),
|
||||
};
|
||||
},
|
||||
onExport<RawAlert>(
|
||||
context: SavedObjectsExportTransformContext,
|
||||
objects: Array<SavedObject<RawAlert>>
|
||||
) {
|
||||
return transformRulesForExport(objects);
|
||||
},
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
savedObjects.registerType({
|
||||
name: 'alert',
|
||||
hidden: true,
|
||||
namespaceType: 'single',
|
||||
migrations: getMigrations(encryptedSavedObjects),
|
||||
mappings: mappings.alert as SavedObjectsTypeMappingDefinition,
|
||||
management: {
|
||||
importableAndExportable: true,
|
||||
getTitle(ruleSavedObject: SavedObject<RawAlert>) {
|
||||
return `Rule: [${ruleSavedObject.attributes.name}]`;
|
||||
},
|
||||
onImport(ruleSavedObjects) {
|
||||
return {
|
||||
warnings: getImportWarnings(ruleSavedObjects),
|
||||
};
|
||||
},
|
||||
onExport<RawAlert>(
|
||||
context: SavedObjectsExportTransformContext,
|
||||
objects: Array<SavedObject<RawAlert>>
|
||||
) {
|
||||
return transformRulesForExport(objects);
|
||||
},
|
||||
isExportable<RawAlert>(ruleSavedObject: SavedObject<RawAlert>) {
|
||||
return isRuleExportable(ruleSavedObject, ruleTypeRegistry, logger);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
savedObjects.registerType({
|
||||
name: 'api_key_pending_invalidation',
|
||||
hidden: true,
|
||||
namespaceType: 'agnostic',
|
||||
mappings: {
|
||||
properties: {
|
||||
apiKeyId: {
|
||||
type: 'keyword',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'date',
|
||||
},
|
||||
savedObjects.registerType({
|
||||
name: 'api_key_pending_invalidation',
|
||||
hidden: true,
|
||||
namespaceType: 'agnostic',
|
||||
mappings: {
|
||||
properties: {
|
||||
apiKeyId: {
|
||||
type: 'keyword',
|
||||
},
|
||||
createdAt: {
|
||||
type: 'date',
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Encrypted attributes
|
||||
encryptedSavedObjects.registerType({
|
||||
type: 'alert',
|
||||
attributesToEncrypt: new Set(['apiKey']),
|
||||
attributesToExcludeFromAAD: new Set(AlertAttributesExcludedFromAAD),
|
||||
});
|
||||
// Encrypted attributes
|
||||
encryptedSavedObjects.registerType({
|
||||
type: 'alert',
|
||||
attributesToEncrypt: new Set(['apiKey']),
|
||||
attributesToExcludeFromAAD: new Set(AlertAttributesExcludedFromAAD),
|
||||
});
|
||||
|
||||
// Encrypted attributes
|
||||
encryptedSavedObjects.registerType({
|
||||
type: 'api_key_pending_invalidation',
|
||||
attributesToEncrypt: new Set(['apiKeyId']),
|
||||
});
|
||||
// Encrypted attributes
|
||||
encryptedSavedObjects.registerType({
|
||||
type: 'api_key_pending_invalidation',
|
||||
attributesToEncrypt: new Set(['apiKeyId']),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { MockedLogger, loggerMock } from '@kbn/logging/target/mocks';
|
||||
import { TaskRunnerFactory } from '../task_runner';
|
||||
import { AlertTypeRegistry, ConstructorOptions } from '../alert_type_registry';
|
||||
import { taskManagerMock } from '../../../task_manager/server/mocks';
|
||||
import { ILicenseState } from '../lib/license_state';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { licensingMock } from '../../../licensing/server/mocks';
|
||||
import { isRuleExportable } from './is_rule_exportable';
|
||||
|
||||
let ruleTypeRegistryParams: ConstructorOptions;
|
||||
let logger: MockedLogger;
|
||||
let mockedLicenseState: jest.Mocked<ILicenseState>;
|
||||
const taskManager = taskManagerMock.createSetup();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockedLicenseState = licenseStateMock.create();
|
||||
logger = loggerMock.create();
|
||||
ruleTypeRegistryParams = {
|
||||
taskManager,
|
||||
taskRunnerFactory: new TaskRunnerFactory(),
|
||||
licenseState: mockedLicenseState,
|
||||
licensing: licensingMock.createSetup(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('isRuleExportable', () => {
|
||||
it('should return true if rule type isExportable is true', () => {
|
||||
const registry = new AlertTypeRegistry(ruleTypeRegistryParams);
|
||||
registry.register({
|
||||
id: 'foo',
|
||||
name: 'Foo',
|
||||
actionGroups: [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
},
|
||||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
});
|
||||
expect(
|
||||
isRuleExportable(
|
||||
{
|
||||
id: '1',
|
||||
type: 'alert',
|
||||
attributes: {
|
||||
enabled: true,
|
||||
name: 'rule-name',
|
||||
tags: ['tag-1', 'tag-2'],
|
||||
alertTypeId: 'foo',
|
||||
consumer: 'alert-consumer',
|
||||
schedule: { interval: '1m' },
|
||||
actions: [],
|
||||
params: {},
|
||||
createdBy: 'me',
|
||||
updatedBy: 'me',
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
apiKey: '4tndskbuhewotw4klrhgjewrt9u',
|
||||
apiKeyOwner: 'me',
|
||||
throttle: null,
|
||||
notifyWhen: 'onActionGroupChange',
|
||||
muteAll: false,
|
||||
mutedInstanceIds: [],
|
||||
executionStatus: {
|
||||
status: 'active',
|
||||
lastExecutionDate: '2020-08-20T19:23:38Z',
|
||||
error: null,
|
||||
},
|
||||
scheduledTaskId: '2q5tjbf3q45twer',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
registry,
|
||||
logger
|
||||
)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return false and log warning if rule type isExportable is false', () => {
|
||||
const registry = new AlertTypeRegistry(ruleTypeRegistryParams);
|
||||
registry.register({
|
||||
id: 'foo',
|
||||
name: 'Foo',
|
||||
actionGroups: [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
},
|
||||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
});
|
||||
expect(
|
||||
isRuleExportable(
|
||||
{
|
||||
id: '1',
|
||||
type: 'alert',
|
||||
attributes: {
|
||||
enabled: true,
|
||||
name: 'rule-name',
|
||||
tags: ['tag-1', 'tag-2'],
|
||||
alertTypeId: 'foo',
|
||||
consumer: 'alert-consumer',
|
||||
schedule: { interval: '1m' },
|
||||
actions: [],
|
||||
params: {},
|
||||
createdBy: 'me',
|
||||
updatedBy: 'me',
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
apiKey: '4tndskbuhewotw4klrhgjewrt9u',
|
||||
apiKeyOwner: 'me',
|
||||
throttle: null,
|
||||
notifyWhen: 'onActionGroupChange',
|
||||
muteAll: false,
|
||||
mutedInstanceIds: [],
|
||||
executionStatus: {
|
||||
status: 'active',
|
||||
lastExecutionDate: '2020-08-20T19:23:38Z',
|
||||
error: null,
|
||||
},
|
||||
scheduledTaskId: '2q5tjbf3q45twer',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
registry,
|
||||
logger
|
||||
)
|
||||
).toEqual(false);
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
`Skipping export of rule \"1\" because rule type \"foo\" is not exportable through this interface.`
|
||||
);
|
||||
});
|
||||
|
||||
it('should return false and log warning if rule type is not registered', () => {
|
||||
const registry = new AlertTypeRegistry(ruleTypeRegistryParams);
|
||||
registry.register({
|
||||
id: 'foo',
|
||||
name: 'Foo',
|
||||
actionGroups: [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Default',
|
||||
},
|
||||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
});
|
||||
expect(
|
||||
isRuleExportable(
|
||||
{
|
||||
id: '1',
|
||||
type: 'alert',
|
||||
attributes: {
|
||||
enabled: true,
|
||||
name: 'rule-name',
|
||||
tags: ['tag-1', 'tag-2'],
|
||||
alertTypeId: 'bar',
|
||||
consumer: 'alert-consumer',
|
||||
schedule: { interval: '1m' },
|
||||
actions: [],
|
||||
params: {},
|
||||
createdBy: 'me',
|
||||
updatedBy: 'me',
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
apiKey: '4tndskbuhewotw4klrhgjewrt9u',
|
||||
apiKeyOwner: 'me',
|
||||
throttle: null,
|
||||
notifyWhen: 'onActionGroupChange',
|
||||
muteAll: false,
|
||||
mutedInstanceIds: [],
|
||||
executionStatus: {
|
||||
status: 'active',
|
||||
lastExecutionDate: '2020-08-20T19:23:38Z',
|
||||
error: null,
|
||||
},
|
||||
scheduledTaskId: '2q5tjbf3q45twer',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
registry,
|
||||
logger
|
||||
)
|
||||
).toEqual(false);
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
`Skipping export of rule \"1\" because rule type \"bar\" is not recognized.`
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Logger, SavedObject } from 'kibana/server';
|
||||
import { RawAlert } from '../types';
|
||||
import { AlertTypeRegistry } from '../alert_type_registry';
|
||||
|
||||
export function isRuleExportable(
|
||||
rule: SavedObject,
|
||||
ruleTypeRegistry: AlertTypeRegistry,
|
||||
logger: Logger
|
||||
): boolean {
|
||||
const ruleSO = rule as SavedObject<RawAlert>;
|
||||
try {
|
||||
const ruleType = ruleTypeRegistry.get(ruleSO.attributes.alertTypeId);
|
||||
if (!ruleType.isExportable) {
|
||||
logger.warn(
|
||||
`Skipping export of rule "${ruleSO.id}" because rule type "${ruleSO.attributes.alertTypeId}" is not exportable through this interface.`
|
||||
);
|
||||
}
|
||||
|
||||
return ruleType.isExportable;
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
`Skipping export of rule "${ruleSO.id}" because rule type "${ruleSO.attributes.alertTypeId}" is not recognized.`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@ const alertType: NormalizedAlertType<
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: {
|
||||
id: 'recovered',
|
||||
name: 'Recovered',
|
||||
|
|
|
@ -44,6 +44,7 @@ const alertType: jest.Mocked<UntypedNormalizedAlertType> = {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }, RecoveredActionGroup],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: RecoveredActionGroup,
|
||||
executor: jest.fn(),
|
||||
producer: 'alerts',
|
||||
|
|
|
@ -26,6 +26,7 @@ const alertType: UntypedNormalizedAlertType = {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: {
|
||||
id: 'recovered',
|
||||
name: 'Recovered',
|
||||
|
|
|
@ -146,6 +146,7 @@ export interface AlertType<
|
|||
params?: ActionVariable[];
|
||||
};
|
||||
minimumLicenseRequired: LicenseType;
|
||||
isExportable: boolean;
|
||||
}
|
||||
|
||||
export type UntypedAlertType = AlertType<
|
||||
|
|
|
@ -33,6 +33,7 @@ export const ALERT_TYPES_CONFIG: Record<
|
|||
actionGroups: Array<ActionGroup<ThresholdMetActionGroupId>>;
|
||||
defaultActionGroupId: ThresholdMetActionGroupId;
|
||||
minimumLicenseRequired: string;
|
||||
isExportable: boolean;
|
||||
producer: string;
|
||||
}
|
||||
> = {
|
||||
|
@ -44,6 +45,7 @@ export const ALERT_TYPES_CONFIG: Record<
|
|||
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
producer: 'apm',
|
||||
isExportable: true,
|
||||
},
|
||||
[AlertType.TransactionDuration]: {
|
||||
name: i18n.translate('xpack.apm.transactionDurationAlert.name', {
|
||||
|
@ -53,6 +55,7 @@ export const ALERT_TYPES_CONFIG: Record<
|
|||
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
producer: 'apm',
|
||||
isExportable: true,
|
||||
},
|
||||
[AlertType.TransactionDurationAnomaly]: {
|
||||
name: i18n.translate('xpack.apm.transactionDurationAnomalyAlert.name', {
|
||||
|
@ -62,6 +65,7 @@ export const ALERT_TYPES_CONFIG: Record<
|
|||
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
producer: 'apm',
|
||||
isExportable: true,
|
||||
},
|
||||
[AlertType.TransactionErrorRate]: {
|
||||
name: i18n.translate('xpack.apm.transactionErrorRateAlert.name', {
|
||||
|
@ -71,6 +75,7 @@ export const ALERT_TYPES_CONFIG: Record<
|
|||
defaultActionGroupId: THRESHOLD_MET_GROUP_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
producer: 'apm',
|
||||
isExportable: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ export function registerErrorCountAlertType({
|
|||
},
|
||||
producer: 'apm',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: async ({ services, params }) => {
|
||||
const config = await config$.pipe(take(1)).toPromise();
|
||||
const alertParams = params;
|
||||
|
|
|
@ -79,6 +79,7 @@ export function registerTransactionDurationAlertType({
|
|||
},
|
||||
producer: 'apm',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: async ({ services, params }) => {
|
||||
const config = await config$.pipe(take(1)).toPromise();
|
||||
const alertParams = params;
|
||||
|
|
|
@ -87,6 +87,7 @@ export function registerTransactionDurationAnomalyAlertType({
|
|||
},
|
||||
producer: 'apm',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: async ({ services, params }) => {
|
||||
if (!ml) {
|
||||
return {};
|
||||
|
|
|
@ -77,6 +77,7 @@ export function registerTransactionErrorRateAlertType({
|
|||
},
|
||||
producer: 'apm',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: async ({ services, params: alertParams }) => {
|
||||
const config = await config$.pipe(take(1)).toPromise();
|
||||
const indices = await getApmIndices({
|
||||
|
|
|
@ -89,6 +89,7 @@ export const registerMetricInventoryThresholdAlertType = (
|
|||
actionGroups: [FIRED_ACTIONS, WARNING_ACTIONS],
|
||||
producer: 'infrastructure',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: createInventoryMetricThresholdExecutor(libs),
|
||||
actionVariables: {
|
||||
context: [
|
||||
|
|
|
@ -107,6 +107,7 @@ export async function registerLogThresholdAlertType(
|
|||
defaultActionGroupId: FIRED_ACTIONS.id,
|
||||
actionGroups: [FIRED_ACTIONS],
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: createLogThresholdExecutor(libs),
|
||||
actionVariables: {
|
||||
context: [
|
||||
|
|
|
@ -64,6 +64,7 @@ export const registerMetricAnomalyAlertType = (
|
|||
actionGroups: [FIRED_ACTIONS],
|
||||
producer: 'infrastructure',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: createMetricAnomalyExecutor(libs, ml),
|
||||
actionVariables: {
|
||||
context: [
|
||||
|
|
|
@ -100,6 +100,7 @@ export function registerMetricThresholdAlertType(libs: InfraBackendLibs): Metric
|
|||
defaultActionGroupId: FIRED_ACTIONS.id,
|
||||
actionGroups: [FIRED_ACTIONS, WARNING_ACTIONS],
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor: createMetricThresholdExecutor(libs),
|
||||
actionVariables: {
|
||||
context: [
|
||||
|
|
|
@ -119,6 +119,7 @@ export function registerAnomalyDetectionAlertType({
|
|||
},
|
||||
producer: PLUGIN_ID,
|
||||
minimumLicenseRequired: MINIMUM_FULL_LICENSE,
|
||||
isExportable: true,
|
||||
async executor({ services, params, alertId, state, previousStartedAt, startedAt }) {
|
||||
const fakeRequest = {} as KibanaRequest;
|
||||
const { execute } = mlSharedServices.alertingServiceProvider(
|
||||
|
|
|
@ -96,6 +96,7 @@ export class BaseAlert {
|
|||
],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
executor: (
|
||||
options: AlertExecutorOptions<never, never, AlertInstanceState, never, 'default'> & {
|
||||
state: ExecutedState;
|
||||
|
|
|
@ -40,6 +40,7 @@ function createRule() {
|
|||
},
|
||||
id: 'test_type',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
name: 'Test type',
|
||||
producer: 'test',
|
||||
actionVariables: {
|
||||
|
|
|
@ -37,6 +37,7 @@ export const rulesNotificationAlertType = ({
|
|||
}),
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
async executor({ startedAt, previousStartedAt, alertId, services, params }) {
|
||||
const ruleAlertSavedObject = await services.savedObjectsClient.get<AlertAttributes>(
|
||||
'alert',
|
||||
|
|
|
@ -45,6 +45,7 @@ export const createEqlAlertType = (ruleDataClient: RuleDataClient, logger: Logge
|
|||
context: [{ name: 'server', description: 'the server' }],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
producer: 'security-solution',
|
||||
async executor({
|
||||
startedAt,
|
||||
|
|
|
@ -57,6 +57,7 @@ export const mlAlertType = createSecurityMlRuleType({
|
|||
context: [{ name: 'server', description: 'the server' }],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
producer: 'security-solution',
|
||||
async executor({
|
||||
services: { alertWithPersistence, findAlerts },
|
||||
|
|
|
@ -43,6 +43,7 @@ export const createQueryAlertType = (ruleDataClient: RuleDataClient, logger: Log
|
|||
context: [{ name: 'server', description: 'the server' }],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
producer: 'security-solution',
|
||||
async executor({
|
||||
services: { alertWithPersistence, findAlerts },
|
||||
|
|
|
@ -113,6 +113,7 @@ export const createThresholdAlertType = (ruleDataClient: RuleDataClient, logger:
|
|||
context: [{ name: 'server', description: 'the server' }],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
producer: 'security-solution',
|
||||
async executor({ startedAt, services, params, alertId }) {
|
||||
const fromDate = moment(startedAt).subtract(moment.duration(5, 'm')); // hardcoded 5-minute rule interval
|
||||
|
|
|
@ -103,6 +103,7 @@ export const signalRulesAlertType = ({
|
|||
},
|
||||
producer: SERVER_APP_ID,
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: false,
|
||||
async executor({
|
||||
previousStartedAt,
|
||||
startedAt,
|
||||
|
|
|
@ -140,6 +140,7 @@ export function getAlertType(
|
|||
],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor,
|
||||
producer: STACK_ALERTS_FEATURE_ID,
|
||||
};
|
||||
|
|
|
@ -177,5 +177,6 @@ export function getAlertType(logger: Logger): GeoContainmentAlertType {
|
|||
},
|
||||
actionVariables,
|
||||
minimumLicenseRequired: 'gold',
|
||||
isExportable: true,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ export function getAlertType(
|
|||
],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
executor,
|
||||
producer: STACK_ALERTS_FEATURE_ID,
|
||||
};
|
||||
|
|
|
@ -89,6 +89,7 @@ export const durationAnomalyAlertFactory: UptimeAlertTypeFactory<ActionGroupIds>
|
|||
state: [...durationAnomalyTranslations.actionVariables, ...commonStateTranslations],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({ options, uptimeEsClient, savedObjectsClient, dynamicSettings }) {
|
||||
const {
|
||||
services: { alertInstanceFactory },
|
||||
|
|
|
@ -258,6 +258,7 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory<ActionGroupIds> = (
|
|||
state: [...commonMonitorStateI18, ...commonStateTranslations],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({
|
||||
options: {
|
||||
params: rawParams,
|
||||
|
|
|
@ -112,6 +112,7 @@ export const tlsAlertFactory: UptimeAlertTypeFactory<ActionGroupIds> = (_server,
|
|||
state: [...tlsTranslations.actionVariables, ...commonStateTranslations],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({ options, dynamicSettings, uptimeEsClient }) {
|
||||
const {
|
||||
services: { alertInstanceFactory },
|
||||
|
|
|
@ -103,6 +103,7 @@ export const tlsLegacyAlertFactory: UptimeAlertTypeFactory<ActionGroupIds> = (_s
|
|||
state: [...tlsTranslations.actionVariables, ...commonStateTranslations],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({ options, dynamicSettings, uptimeEsClient }) {
|
||||
const {
|
||||
services: { alertInstanceFactory },
|
||||
|
|
|
@ -81,6 +81,7 @@ function getAlwaysFiringAlertType() {
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
actionVariables: {
|
||||
state: [{ name: 'instanceStateValue', description: 'the instance state value' }],
|
||||
params: [{ name: 'instanceParamsValue', description: 'the instance params value' }],
|
||||
|
@ -167,6 +168,7 @@ function getCumulativeFiringAlertType() {
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor(alertExecutorOptions) {
|
||||
const { services, state } = alertExecutorOptions;
|
||||
const group = 'default';
|
||||
|
@ -212,6 +214,7 @@ function getNeverFiringAlertType() {
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({ services, params, state }) {
|
||||
await services.scopedClusterClient.asCurrentUser.index({
|
||||
index: params.index,
|
||||
|
@ -252,6 +255,7 @@ function getFailingAlertType() {
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor({ services, params, state }) {
|
||||
await services.scopedClusterClient.asCurrentUser.index({
|
||||
index: params.index,
|
||||
|
@ -290,6 +294,7 @@ function getAuthorizationAlertType(core: CoreSetup<FixtureStartDeps>) {
|
|||
defaultActionGroupId: 'default',
|
||||
producer: 'alertsFixture',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
validate: {
|
||||
params: paramsSchema,
|
||||
},
|
||||
|
@ -376,6 +381,7 @@ function getValidationAlertType() {
|
|||
],
|
||||
producer: 'alertsFixture',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
defaultActionGroupId: 'default',
|
||||
validate: {
|
||||
params: paramsSchema,
|
||||
|
@ -404,6 +410,7 @@ function getPatternFiringAlertType() {
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor(alertExecutorOptions) {
|
||||
const { services, state, params } = alertExecutorOptions;
|
||||
const pattern = params.pattern;
|
||||
|
@ -468,6 +475,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
};
|
||||
const goldNoopAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
|
||||
|
@ -477,6 +485,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'gold',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
};
|
||||
const onlyContextVariablesAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
|
||||
|
@ -486,6 +495,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
actionVariables: {
|
||||
context: [{ name: 'aContextVariable', description: 'this is a context variable' }],
|
||||
},
|
||||
|
@ -501,6 +511,7 @@ export function defineAlertTypes(
|
|||
state: [{ name: 'aStateVariable', description: 'this is a state variable' }],
|
||||
},
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
};
|
||||
const throwAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
|
||||
|
@ -515,6 +526,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {
|
||||
throw new Error('this alert is intended to fail');
|
||||
},
|
||||
|
@ -531,6 +543,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {
|
||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||
},
|
||||
|
|
|
@ -20,6 +20,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsRestrictedFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
recoveryActionGroup: { id: 'restrictedRecovered', name: 'Restricted Recovery' },
|
||||
async executor() {},
|
||||
};
|
||||
|
@ -30,6 +31,7 @@ export function defineAlertTypes(
|
|||
producer: 'alertsRestrictedFixture',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
};
|
||||
alerting.registerType(noopRestrictedAlertType);
|
||||
|
|
|
@ -30,6 +30,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
|||
},
|
||||
producer: 'alertsFixture',
|
||||
minimum_license_required: 'basic',
|
||||
is_exportable: true,
|
||||
recovery_action_group: {
|
||||
id: 'recovered',
|
||||
name: 'Recovered',
|
||||
|
@ -56,6 +57,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
|||
},
|
||||
producer: 'alertsRestrictedFixture',
|
||||
minimum_license_required: 'basic',
|
||||
is_exportable: true,
|
||||
enabled_in_license: true,
|
||||
};
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
|||
},
|
||||
producer: 'alertsFixture',
|
||||
minimum_license_required: 'basic',
|
||||
is_exportable: true,
|
||||
enabled_in_license: true,
|
||||
});
|
||||
expect(Object.keys(authorizedConsumers)).to.contain('alertsFixture');
|
||||
|
@ -126,6 +127,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) {
|
|||
},
|
||||
producer: 'alertsFixture',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
enabledInLicense: true,
|
||||
});
|
||||
expect(Object.keys(authorizedConsumers)).to.contain('alertsFixture');
|
||||
|
|
|
@ -24,6 +24,7 @@ export const noopAlertType: AlertType<{}, {}, {}, {}, 'default'> = {
|
|||
actionGroups: [{ id: 'default', name: 'Default' }],
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {},
|
||||
producer: 'alerts',
|
||||
};
|
||||
|
@ -47,6 +48,7 @@ export const alwaysFiringAlertType: AlertType<
|
|||
defaultActionGroupId: 'default',
|
||||
producer: 'alerts',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor(alertExecutorOptions) {
|
||||
const { services, state, params } = alertExecutorOptions;
|
||||
|
||||
|
@ -76,6 +78,7 @@ export const failingAlertType: AlertType<never, never, never, never, 'default' |
|
|||
producer: 'alerts',
|
||||
defaultActionGroupId: 'default',
|
||||
minimumLicenseRequired: 'basic',
|
||||
isExportable: true,
|
||||
async executor() {
|
||||
throw new Error('Failed to execute alert type');
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue