Skip to content

Commit

Permalink
Merge branch 'master' into fix-search-examples-kibana-version
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Nov 15, 2020
2 parents 4bd60ba + bd08439 commit b20952d
Show file tree
Hide file tree
Showing 47 changed files with 3,277 additions and 1,161 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
"rison-node": "1.0.2",
"rxjs": "^6.5.5",
"seedrandom": "^3.0.5",
"semver": "^5.7.0",
"semver": "^7.3.2",
"set-value": "^3.0.2",
"source-map-support": "^0.5.19",
"squel": "^5.13.0",
Expand Down Expand Up @@ -536,7 +536,7 @@
"@types/request": "^2.48.2",
"@types/seedrandom": ">=2.0.0 <4.0.0",
"@types/selenium-webdriver": "^4.0.9",
"@types/semver": "^5.5.0",
"@types/semver": "^7",
"@types/set-value": "^2.0.0",
"@types/sinon": "^7.0.13",
"@types/source-map-support": "^0.5.3",
Expand Down
3,507 changes: 2,498 additions & 1,009 deletions packages/kbn-pm/dist/index.js

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/plugins/dashboard/common/migrate_to_730_panels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import { i18n } from '@kbn/i18n';
import semver from 'semver';
import semverSatisfies from 'semver/functions/satisfies';
import uuid from 'uuid';
import {
GridData,
Expand Down Expand Up @@ -60,23 +60,23 @@ function isPre61Panel(
}

function is61Panel(panel: unknown | RawSavedDashboardPanel610): panel is RawSavedDashboardPanel610 {
return semver.satisfies((panel as RawSavedDashboardPanel610).version, '6.1.x');
return semverSatisfies((panel as RawSavedDashboardPanel610).version, '6.1.x');
}

function is62Panel(panel: unknown | RawSavedDashboardPanel620): panel is RawSavedDashboardPanel620 {
return semver.satisfies((panel as RawSavedDashboardPanel620).version, '6.2.x');
return semverSatisfies((panel as RawSavedDashboardPanel620).version, '6.2.x');
}

function is63Panel(panel: unknown | RawSavedDashboardPanel630): panel is RawSavedDashboardPanel630 {
return semver.satisfies((panel as RawSavedDashboardPanel630).version, '6.3.x');
return semverSatisfies((panel as RawSavedDashboardPanel630).version, '6.3.x');
}

function is640To720Panel(
panel: unknown | RawSavedDashboardPanel640To720
): panel is RawSavedDashboardPanel640To720 {
return (
semver.satisfies((panel as RawSavedDashboardPanel630).version, '>6.3') &&
semver.satisfies((panel as RawSavedDashboardPanel630).version, '<7.3')
semverSatisfies((panel as RawSavedDashboardPanel630).version, '>6.3') &&
semverSatisfies((panel as RawSavedDashboardPanel630).version, '<7.3')
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import semver from 'semver';
import semverSatisfies from 'semver/functions/satisfies';
import { i18n } from '@kbn/i18n';
import { METRIC_TYPE } from '@kbn/analytics';

Expand Down Expand Up @@ -68,7 +68,7 @@ export function migrateAppState(
usageCollection.reportUiStats('DashboardPanelVersionInUrl', METRIC_TYPE.LOADED, `${version}`);
}

return semver.satisfies(version, '<7.3');
return semverSatisfies(version, '<7.3');
});

if (panelNeedsMigration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
* under the License.
*/

import semver from 'semver';
import SemVer from 'semver/classes/semver';
import semverParse from 'semver/functions/parse';
import { TelemetrySavedObject } from './types';

interface GetTelemetryOptInConfig {
Expand Down Expand Up @@ -80,10 +81,10 @@ export const getTelemetryOptIn: GetTelemetryOptIn = ({
return savedOptIn;
};

function parseSemver(version: string): semver.SemVer | null {
function parseSemver(version: string): SemVer | null {
// semver functions both return nulls AND throw exceptions: "it depends!"
try {
return semver.parse(version);
return semverParse(version);
} catch (err) {
return null;
}
Expand Down
6 changes: 4 additions & 2 deletions src/plugins/vis_type_vega/public/vega_visualization.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ describe('VegaVisualizations', () => {
mockHeight.mockRestore();
});

test('should show vegalite graph and update on resize (may fail in dev env)', async () => {
// SKIP: https://github.com/elastic/kibana/issues/83385
test.skip('should show vegalite graph and update on resize (may fail in dev env)', async () => {
let vegaVis;
try {
vegaVis = new VegaVisualization(domNode, jest.fn());
Expand Down Expand Up @@ -131,7 +132,8 @@ describe('VegaVisualizations', () => {
}
});

test('should show vega graph (may fail in dev env)', async () => {
// SKIP: https://github.com/elastic/kibana/issues/83385
test.skip('should show vega graph (may fail in dev env)', async () => {
let vegaVis;
try {
vegaVis = new VegaVisualization(domNode, jest.fn());
Expand Down
18 changes: 18 additions & 0 deletions x-pack/plugins/alerts/common/builtin_action_groups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { ActionGroup } from './alert_type';

export const ResolvedActionGroup: ActionGroup = {
id: 'resolved',
name: i18n.translate('xpack.alerts.builtinActionGroups.resolved', {
defaultMessage: 'Resolved',
}),
};

export function getBuiltinActionGroups(): ActionGroup[] {
return [ResolvedActionGroup];
}
6 changes: 1 addition & 5 deletions x-pack/plugins/alerts/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ export * from './alert_instance';
export * from './alert_task_instance';
export * from './alert_navigation';
export * from './alert_instance_summary';

export interface ActionGroup {
id: string;
name: string;
}
export * from './builtin_action_groups';

export interface AlertingFrameworkHealth {
isSufficientlySecure: boolean;
Expand Down
35 changes: 35 additions & 0 deletions x-pack/plugins/alerts/server/alert_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,33 @@ describe('register()', () => {
);
});

test('throws if AlertType action groups contains reserved group id', () => {
const alertType = {
id: 'test',
name: 'Test',
actionGroups: [
{
id: 'default',
name: 'Default',
},
{
id: 'resolved',
name: 'Resolved',
},
],
defaultActionGroupId: 'default',
executor: jest.fn(),
producer: 'alerts',
};
const registry = new AlertTypeRegistry(alertTypeRegistryParams);

expect(() => registry.register(alertType)).toThrowError(
new Error(
`Alert type [id="${alertType.id}"] cannot be registered. Action groups [resolved] are reserved by the framework.`
)
);
});

test('registers the executor with the task manager', () => {
const alertType = {
id: 'test',
Expand Down Expand Up @@ -201,6 +228,10 @@ describe('get()', () => {
"id": "default",
"name": "Default",
},
Object {
"id": "resolved",
"name": "Resolved",
},
],
"actionVariables": Object {
"context": Array [],
Expand Down Expand Up @@ -255,6 +286,10 @@ describe('list()', () => {
"id": "testActionGroup",
"name": "Test Action Group",
},
Object {
"id": "resolved",
"name": "Resolved",
},
],
"actionVariables": Object {
"context": Array [],
Expand Down
25 changes: 25 additions & 0 deletions x-pack/plugins/alerts/server/alert_type_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import Boom from '@hapi/boom';
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import typeDetect from 'type-detect';
import { intersection } from 'lodash';
import _ from 'lodash';
import { RunContext, TaskManagerSetupContract } from '../../task_manager/server';
import { TaskRunnerFactory } from './task_runner';
import {
Expand All @@ -16,7 +18,9 @@ import {
AlertTypeState,
AlertInstanceState,
AlertInstanceContext,
ActionGroup,
} from './types';
import { getBuiltinActionGroups } from '../common';

interface ConstructorOptions {
taskManager: TaskManagerSetupContract;
Expand Down Expand Up @@ -82,6 +86,8 @@ export class AlertTypeRegistry {
);
}
alertType.actionVariables = normalizedActionVariables(alertType.actionVariables);
validateActionGroups(alertType.id, alertType.actionGroups);
alertType.actionGroups = [...alertType.actionGroups, ..._.cloneDeep(getBuiltinActionGroups())];
this.alertTypes.set(alertIdSchema.validate(alertType.id), { ...alertType } as AlertType);
this.taskManager.registerTaskDefinitions({
[`alerting:${alertType.id}`]: {
Expand Down Expand Up @@ -137,3 +143,22 @@ function normalizedActionVariables(actionVariables: AlertType['actionVariables']
params: actionVariables?.params ?? [],
};
}

function validateActionGroups(alertTypeId: string, actionGroups: ActionGroup[]) {
const reservedActionGroups = intersection(
actionGroups.map((item) => item.id),
getBuiltinActionGroups().map((item) => item.id)
);
if (reservedActionGroups.length > 0) {
throw new Error(
i18n.translate('xpack.alerts.alertTypeRegistry.register.reservedActionGroupUsageError', {
defaultMessage:
'Alert type [id="{alertTypeId}"] cannot be registered. Action groups [{actionGroups}] are reserved by the framework.',
values: {
actionGroups: reservedActionGroups.join(', '),
alertTypeId,
},
})
);
}
}
87 changes: 84 additions & 3 deletions x-pack/plugins/alerts/server/task_runner/task_runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ import { alertsMock, alertsClientMock } from '../mocks';
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { IEventLogger } from '../../../event_log/server';
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
import { Alert } from '../../common';
import { Alert, ResolvedActionGroup } from '../../common';
import { omit } from 'lodash';
const alertType = {
id: 'test',
name: 'My test alert',
actionGroups: [{ id: 'default', name: 'Default' }],
actionGroups: [{ id: 'default', name: 'Default' }, ResolvedActionGroup],
defaultActionGroupId: 'default',
executor: jest.fn(),
producer: 'alerts',
Expand Down Expand Up @@ -91,7 +91,7 @@ describe('Task Runner', () => {
throttle: null,
muteAll: false,
enabled: true,
alertTypeId: '123',
alertTypeId: alertType.id,
apiKey: '',
apiKeyOwner: 'elastic',
schedule: { interval: '10s' },
Expand All @@ -112,6 +112,14 @@ describe('Task Runner', () => {
foo: true,
},
},
{
group: ResolvedActionGroup.id,
id: '2',
actionTypeId: 'action',
params: {
isResolved: true,
},
},
],
executionStatus: {
status: 'unknown',
Expand Down Expand Up @@ -507,6 +515,79 @@ describe('Task Runner', () => {
`);
});

test('fire resolved actions for execution for the alertInstances which is in the resolved state', async () => {
taskRunnerFactoryInitializerParams.actionsPlugin.isActionTypeEnabled.mockReturnValue(true);
taskRunnerFactoryInitializerParams.actionsPlugin.isActionExecutable.mockReturnValue(true);

alertType.executor.mockImplementation(
({ services: executorServices }: AlertExecutorOptions) => {
executorServices.alertInstanceFactory('1').scheduleActions('default');
}
);
const taskRunner = new TaskRunner(
alertType,
{
...mockedTaskInstance,
state: {
...mockedTaskInstance.state,
alertInstances: {
'1': { meta: {}, state: { bar: false } },
'2': { meta: {}, state: { bar: false } },
},
},
},
taskRunnerFactoryInitializerParams
);
alertsClient.get.mockResolvedValue(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValue({
id: '1',
type: 'alert',
attributes: {
apiKey: Buffer.from('123:abc').toString('base64'),
},
references: [],
});
const runnerResult = await taskRunner.run();
expect(runnerResult.state.alertInstances).toMatchInlineSnapshot(`
Object {
"1": Object {
"meta": Object {
"lastScheduledActions": Object {
"date": 1970-01-01T00:00:00.000Z,
"group": "default",
},
},
"state": Object {
"bar": false,
},
},
}
`);

const eventLogger = taskRunnerFactoryInitializerParams.eventLogger;
expect(eventLogger.logEvent).toHaveBeenCalledTimes(5);
expect(actionsClient.enqueueExecution).toHaveBeenCalledTimes(2);
expect(actionsClient.enqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
Array [
Object {
"apiKey": "MTIzOmFiYw==",
"id": "2",
"params": Object {
"isResolved": true,
},
"source": Object {
"source": Object {
"id": "1",
"type": "alert",
},
"type": "SAVED_OBJECT",
},
"spaceId": undefined,
},
]
`);
});

test('persists alertInstances passed in from state, only if they are scheduled for execution', async () => {
alertType.executor.mockImplementation(
({ services: executorServices }: AlertExecutorOptions) => {
Expand Down
Loading

0 comments on commit b20952d

Please sign in to comment.