Skip to content

Commit

Permalink
Merge branch 'master' of github.com:elastic/kibana into dev/dashboard…
Browse files Browse the repository at this point in the history
…-drilldown-so2
  • Loading branch information
Dosant committed Nov 7, 2020
2 parents 4441cc1 + fb8cd5b commit e1aef10
Show file tree
Hide file tree
Showing 179 changed files with 4,116 additions and 1,343 deletions.
3 changes: 3 additions & 0 deletions docs/settings/apm-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ Changing these settings may disable features of the APM App.
| `xpack.apm.enabled`
| Set to `false` to disable the APM app. Defaults to `true`.

| `xpack.apm.maxServiceEnvironments`
| Maximum number of unique service environments recognized by the UI. Defaults to `100`.

| `xpack.apm.serviceMapFingerprintBucketSize`
| Maximum number of unique transaction combinations sampled for generating service map focused on a specific service. Defaults to `100`.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -844,8 +844,8 @@
"vinyl-fs": "^3.0.3",
"wait-on": "^5.0.1",
"watchpack": "^1.6.0",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.8.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2",
"write-pkg": "^4.0.0",
"xml-crypto": "^2.0.0",
Expand Down
34 changes: 27 additions & 7 deletions x-pack/plugins/alerts/common/alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ export interface IntervalSchedule extends SavedObjectAttributes {
export const AlertExecutionStatusValues = ['ok', 'active', 'error', 'pending', 'unknown'] as const;
export type AlertExecutionStatuses = typeof AlertExecutionStatusValues[number];

export const AlertExecutionStatusErrorReasonValues = [
'read',
'decrypt',
'execute',
'unknown',
] as const;
export type AlertExecutionStatusErrorReasons = typeof AlertExecutionStatusErrorReasonValues[number];
export enum AlertExecutionStatusErrorReasons {
Read = 'read',
Decrypt = 'decrypt',
Execute = 'execute',
Unknown = 'unknown',
}

export interface AlertExecutionStatus {
status: AlertExecutionStatuses;
Expand Down Expand Up @@ -74,3 +73,24 @@ export interface Alert {
}

export type SanitizedAlert = Omit<Alert, 'apiKey'>;

export enum HealthStatus {
OK = 'ok',
Warning = 'warn',
Error = 'error',
}

export interface AlertsHealth {
decryptionHealth: {
status: HealthStatus;
timestamp: string;
};
executionHealth: {
status: HealthStatus;
timestamp: string;
};
readHealth: {
status: HealthStatus;
timestamp: string;
};
}
3 changes: 3 additions & 0 deletions x-pack/plugins/alerts/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { AlertsHealth } from './alert';

export * from './alert';
export * from './alert_type';
export * from './alert_instance';
Expand All @@ -19,6 +21,7 @@ export interface ActionGroup {
export interface AlertingFrameworkHealth {
isSufficientlySecure: boolean;
hasPermanentEncryptionKey: boolean;
alertingFrameworkHeath: AlertsHealth;
}

export const BASE_ALERT_API_PATH = '/api/alerts';
Expand Down
19 changes: 19 additions & 0 deletions x-pack/plugins/alerts/server/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { configSchema } from './config';

describe('config validation', () => {
test('alerts defaults', () => {
const config: Record<string, unknown> = {};
expect(configSchema.validate(config)).toMatchInlineSnapshot(`
Object {
"healthCheck": Object {
"interval": "60m",
},
}
`);
});
});
16 changes: 16 additions & 0 deletions x-pack/plugins/alerts/server/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { schema, TypeOf } from '@kbn/config-schema';
import { validateDurationSchema } from './lib';

export const configSchema = schema.object({
healthCheck: schema.object({
interval: schema.string({ validate: validateDurationSchema, defaultValue: '60m' }),
}),
});

export type AlertsConfig = TypeOf<typeof configSchema>;
221 changes: 221 additions & 0 deletions x-pack/plugins/alerts/server/health/get_health.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { savedObjectsRepositoryMock } from '../../../../../src/core/server/mocks';
import { AlertExecutionStatusErrorReasons, HealthStatus } from '../types';
import { getHealth } from './get_health';

const savedObjectsRepository = savedObjectsRepositoryMock.create();

describe('getHealth()', () => {
test('return true if some of alerts has a decryption error', async () => {
const lastExecutionDateError = new Date().toISOString();
const lastExecutionDate = new Date().toISOString();
savedObjectsRepository.find.mockResolvedValueOnce({
total: 1,
per_page: 1,
page: 1,
saved_objects: [
{
id: '1',
type: 'alert',
attributes: {
alertTypeId: 'myType',
schedule: { interval: '10s' },
params: {
bar: true,
},
createdAt: new Date().toISOString(),
actions: [
{
group: 'default',
actionRef: 'action_0',
params: {
foo: true,
},
},
],
executionStatus: {
status: 'error',
lastExecutionDate: lastExecutionDateError,
error: {
reason: AlertExecutionStatusErrorReasons.Decrypt,
message: 'Failed decrypt',
},
},
},
score: 1,
references: [
{
name: 'action_0',
type: 'action',
id: '1',
},
],
},
],
});
savedObjectsRepository.find.mockResolvedValueOnce({
total: 0,
per_page: 10,
page: 1,
saved_objects: [],
});

savedObjectsRepository.find.mockResolvedValueOnce({
total: 0,
per_page: 10,
page: 1,
saved_objects: [],
});

savedObjectsRepository.find.mockResolvedValueOnce({
total: 1,
per_page: 1,
page: 1,
saved_objects: [
{
id: '2',
type: 'alert',
attributes: {
alertTypeId: 'myType',
schedule: { interval: '1s' },
params: {
bar: true,
},
createdAt: new Date().toISOString(),
actions: [],
executionStatus: {
status: 'ok',
lastExecutionDate,
},
},
score: 1,
references: [],
},
],
});
const result = await getHealth(savedObjectsRepository);
expect(result).toStrictEqual({
executionHealth: {
status: HealthStatus.OK,
timestamp: lastExecutionDate,
},
readHealth: {
status: HealthStatus.OK,
timestamp: lastExecutionDate,
},
decryptionHealth: {
status: HealthStatus.Warning,
timestamp: lastExecutionDateError,
},
});
expect(savedObjectsRepository.find).toHaveBeenCalledTimes(4);
});

test('return false if no alerts with a decryption error', async () => {
const lastExecutionDateError = new Date().toISOString();
const lastExecutionDate = new Date().toISOString();
savedObjectsRepository.find.mockResolvedValueOnce({
total: 0,
per_page: 10,
page: 1,
saved_objects: [],
});

savedObjectsRepository.find.mockResolvedValueOnce({
total: 1,
per_page: 1,
page: 1,
saved_objects: [
{
id: '1',
type: 'alert',
attributes: {
alertTypeId: 'myType',
schedule: { interval: '10s' },
params: {
bar: true,
},
createdAt: new Date().toISOString(),
actions: [
{
group: 'default',
actionRef: 'action_0',
params: {
foo: true,
},
},
],
executionStatus: {
status: 'error',
lastExecutionDate: lastExecutionDateError,
error: {
reason: AlertExecutionStatusErrorReasons.Execute,
message: 'Failed',
},
},
},
score: 1,
references: [
{
name: 'action_0',
type: 'action',
id: '1',
},
],
},
],
});
savedObjectsRepository.find.mockResolvedValueOnce({
total: 0,
per_page: 10,
page: 1,
saved_objects: [],
});

savedObjectsRepository.find.mockResolvedValueOnce({
total: 1,
per_page: 1,
page: 1,
saved_objects: [
{
id: '2',
type: 'alert',
attributes: {
alertTypeId: 'myType',
schedule: { interval: '1s' },
params: {
bar: true,
},
createdAt: new Date().toISOString(),
actions: [],
executionStatus: {
status: 'ok',
lastExecutionDate,
},
},
score: 1,
references: [],
},
],
});
const result = await getHealth(savedObjectsRepository);
expect(result).toStrictEqual({
executionHealth: {
status: HealthStatus.Warning,
timestamp: lastExecutionDateError,
},
readHealth: {
status: HealthStatus.OK,
timestamp: lastExecutionDate,
},
decryptionHealth: {
status: HealthStatus.OK,
timestamp: lastExecutionDate,
},
});
});
});
Loading

0 comments on commit e1aef10

Please sign in to comment.