mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Actionable Observability] - Add alert details page feature flag by App (#142839)
* Update the feature flags * Fix tests and AlertFlyout footer * Add unit test for the helper * Update the order of the checks to fix tests * Add test for edge cases * Fix test direct access to the page * Fix test
This commit is contained in:
parent
5b269e3a47
commit
608ac5adff
18 changed files with 444 additions and 34 deletions
|
@ -298,7 +298,10 @@ kibana_vars=(
|
|||
xpack.ingestManager.registryUrl
|
||||
xpack.observability.annotations.index
|
||||
xpack.observability.unsafe.slo.enabled
|
||||
xpack.observability.unsafe.alertDetails.enabled
|
||||
xpack.observability.unsafe.alertDetails.apm.enabled
|
||||
xpack.observability.unsafe.alertDetails.metrics.enabled
|
||||
xpack.observability.unsafe.alertDetails.logs.enabled
|
||||
xpack.observability.unsafe.alertDetails.uptime.enabled
|
||||
xpack.reporting.capture.browser.autoDownload
|
||||
xpack.reporting.capture.browser.chromium.disableSandbox
|
||||
xpack.reporting.capture.browser.chromium.inspect
|
||||
|
|
|
@ -219,7 +219,10 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.trigger_actions_ui.enableGeoTrackingThresholdAlert (boolean)',
|
||||
'xpack.upgrade_assistant.readonly (boolean)',
|
||||
'xpack.upgrade_assistant.ui.enabled (boolean)',
|
||||
'xpack.observability.unsafe.alertDetails.enabled (boolean)',
|
||||
'xpack.observability.unsafe.alertDetails.apm.enabled (boolean)',
|
||||
'xpack.observability.unsafe.alertDetails.metrics.enabled (boolean)',
|
||||
'xpack.observability.unsafe.alertDetails.logs.enabled (boolean)',
|
||||
'xpack.observability.unsafe.alertDetails.uptime.enabled (boolean)',
|
||||
'xpack.observability.unsafe.slo.enabled (boolean)',
|
||||
];
|
||||
// We don't assert that actualExposedConfigKeys and expectedExposedConfigKeys are equal, because test failure messages with large
|
||||
|
|
|
@ -4,16 +4,33 @@ This directory tree contains files subject to the Elastic License 2.0. The files
|
|||
to the Elastic License 2.0 are grouped in this directory to clearly separate them
|
||||
from files dual-licensed under the Server Side Public License and the Elastic License 2.0.
|
||||
|
||||
## Alert Details page (feature flag)
|
||||
## Alert Details page feature flags (feature-flag-per-App)
|
||||
|
||||
If you have:
|
||||
|
||||
```yaml
|
||||
xpack.observability.unsafe.alertDetails.enabled: true
|
||||
xpack.observability.unsafe.alertDetails.apm.enabled: true
|
||||
```
|
||||
In Kibana configuration, will allow the user to navigate to the new Alert Details page, instead of the Alert Flyout when clicking on `View alert details` in the Alert table
|
||||
|
||||
**[For APM rule types]** In Kibana configuration, will allow the user to navigate to the new Alert Details page, instead of the Alert Flyout when clicking on `View alert details` in the Alert table
|
||||
|
||||
```yaml
|
||||
xpack.observability.unsafe.alertDetails.metrics.enabled: true
|
||||
```
|
||||
|
||||
**[For Infrastructure rule types]** In Kibana configuration, will allow the user to navigate to the new Alert Details page, instead of the Alert Flyout when clicking on `View alert details` in the Alert table
|
||||
|
||||
```yaml
|
||||
xpack.observability.unsafe.alertDetails.logs.enabled: true
|
||||
```
|
||||
|
||||
**[For Logs threshold rule type]** In Kibana configuration, will allow the user to navigate to the new Alert Details page, instead of the Alert Flyout when clicking on `View alert details` in the Alert table
|
||||
|
||||
```yaml
|
||||
xpack.observability.unsafe.alertDetails.uptime.enabled: true
|
||||
```
|
||||
|
||||
**[For Uptime rule type]** In Kibana configuration, will allow the user to navigate to the new Alert Details page, instead of the Alert Flyout when clicking on `View alert details` in the Alert table
|
||||
|
||||
# Development
|
||||
|
||||
|
@ -31,15 +48,16 @@ For information on testing, see [the Elastic functional test development guide](
|
|||
|
||||
#### Running functional tests
|
||||
|
||||
The functional UI tests, the API integration tests, and the SAML API integration tests are all run against a live browser, Kibana, and Elasticsearch install. Each set of tests is specified with a unique config that describes how to start the Elasticsearch server, the Kibana server, and what tests to run against them. The sets of tests that exist today are *functional UI tests* ([specified by this config](test/functional/config.base.js)), *API integration tests* ([specified by this config](test/api_integration/config.ts)), and *SAML API integration tests* ([specified by this config](test/security_api_integration/saml.config.ts)).
|
||||
The functional UI tests, the API integration tests, and the SAML API integration tests are all run against a live browser, Kibana, and Elasticsearch install. Each set of tests is specified with a unique config that describes how to start the Elasticsearch server, the Kibana server, and what tests to run against them. The sets of tests that exist today are _functional UI tests_ ([specified by this config](test/functional/config.base.js)), _API integration tests_ ([specified by this config](test/api_integration/config.ts)), and _SAML API integration tests_ ([specified by this config](test/security_api_integration/saml.config.ts)).
|
||||
|
||||
The script runs all sets of tests sequentially like so:
|
||||
* builds Elasticsearch and X-Pack
|
||||
* runs Elasticsearch with X-Pack
|
||||
* starts up the Kibana server with X-Pack
|
||||
* runs the functional UI tests against those servers
|
||||
* tears down the servers
|
||||
* repeats the same process for the API and SAML API integration test configs.
|
||||
|
||||
- builds Elasticsearch and X-Pack
|
||||
- runs Elasticsearch with X-Pack
|
||||
- starts up the Kibana server with X-Pack
|
||||
- runs the functional UI tests against those servers
|
||||
- tears down the servers
|
||||
- repeats the same process for the API and SAML API integration test configs.
|
||||
|
||||
To do all of this in a single command run:
|
||||
|
||||
|
@ -100,4 +118,5 @@ yarn test:jest_integration
|
|||
See [here](./test/functional/apps/dashboard/reporting/README.md) for more information on running reporting tests.
|
||||
|
||||
#### Running Security Solution Cypress E2E/integration tests
|
||||
|
||||
See [here](./plugins/security_solution/cypress/README.md) for information on running this test suite.
|
||||
|
|
|
@ -68,7 +68,12 @@ describe('renderApp', () => {
|
|||
|
||||
const config = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -45,7 +45,12 @@ describe('APMSection', () => {
|
|||
});
|
||||
const config = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -71,7 +71,12 @@ const params = {
|
|||
|
||||
const config = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: true },
|
||||
alertDetails: {
|
||||
apm: { enabled: true },
|
||||
logs: { enabled: true },
|
||||
metrics: { enabled: true },
|
||||
uptime: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { useParams } from 'react-router-dom';
|
||||
import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui';
|
||||
|
||||
import { isAlertDetailsEnabledPerApp } from '../../../utils/is_alert_details_enabled';
|
||||
import { useKibana } from '../../../utils/kibana_react';
|
||||
import { usePluginContext } from '../../../hooks/use_plugin_context';
|
||||
import { useBreadcrumbs } from '../../../hooks/use_breadcrumbs';
|
||||
|
@ -48,15 +49,15 @@ export function AlertDetails() {
|
|||
},
|
||||
]);
|
||||
|
||||
// Redirect to the the 404 page when the user hit the page url directly in the browser while the feature flag is off.
|
||||
if (!config.unsafe.alertDetails.enabled) {
|
||||
return <PageNotFound />;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return <CenterJustifiedSpinner />;
|
||||
}
|
||||
|
||||
// Redirect to the the 404 page when the user hit the page url directly in the browser while the feature flag is off.
|
||||
if (alert && !isAlertDetailsEnabledPerApp(alert, config)) {
|
||||
return <PageNotFound />;
|
||||
}
|
||||
|
||||
if (!isLoading && !alert)
|
||||
return (
|
||||
<EuiPanel data-test-subj="alertDetailsError">
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import React from 'react';
|
||||
import { EuiFlyoutFooter, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { isAlertDetailsEnabledPerApp } from '../../../../utils/is_alert_details_enabled';
|
||||
import { usePluginContext } from '../../../../hooks/use_plugin_context';
|
||||
import { FlyoutProps } from './types';
|
||||
import { translations, paths } from '../../../../config';
|
||||
|
@ -18,7 +19,7 @@ export default function AlertsFlyoutFooter({ alert, isInApp }: FlyoutProps & { i
|
|||
const { http } = services;
|
||||
const prepend = http?.basePath.prepend;
|
||||
const getAlertDetailsButton = () => {
|
||||
if (!config?.unsafe?.alertDetails.enabled || !alert) return <></>;
|
||||
if (!isAlertDetailsEnabledPerApp(alert, config)) return <></>;
|
||||
return (
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
|
|
|
@ -31,7 +31,12 @@ jest.mock('../../../hooks/use_get_user_cases_permissions', () => ({
|
|||
|
||||
const config = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import React, { useMemo, useState, useCallback } from 'react';
|
|||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { CommentType } from '@kbn/cases-plugin/common';
|
||||
import type { ActionProps } from '@kbn/timelines-plugin/common';
|
||||
import { isAlertDetailsEnabledPerApp } from '../../../utils/is_alert_details_enabled';
|
||||
import { useKibana } from '../../../utils/kibana_react';
|
||||
import { useGetUserCasesPermissions } from '../../../hooks/use_get_user_cases_permissions';
|
||||
import { parseAlert } from './parse_alert';
|
||||
|
@ -143,7 +144,7 @@ export function ObservabilityActions({
|
|||
: []),
|
||||
|
||||
...[
|
||||
config?.unsafe?.alertDetails.enabled && linkToAlert ? (
|
||||
isAlertDetailsEnabledPerApp(alert, config) && linkToAlert ? (
|
||||
<EuiContextMenuItem
|
||||
key="viewAlertDetailsPage"
|
||||
data-test-subj="viewAlertDetailsPage"
|
||||
|
@ -171,11 +172,11 @@ export function ObservabilityActions({
|
|||
handleAddToExistingCaseClick,
|
||||
handleAddToNewCaseClick,
|
||||
linkToRule,
|
||||
config.unsafe.alertDetails.enabled,
|
||||
alert,
|
||||
config,
|
||||
linkToAlert,
|
||||
closeActionsPopover,
|
||||
setFlyoutAlert,
|
||||
alert,
|
||||
]);
|
||||
|
||||
const actionsToolTip =
|
||||
|
|
|
@ -77,7 +77,12 @@ const withCore = makeDecorator({
|
|||
|
||||
const config = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -36,7 +36,12 @@ jest.mock('@kbn/triggers-actions-ui-plugin/public', () => ({
|
|||
|
||||
const config = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -54,7 +54,20 @@ import getAppDataView from './utils/observability_data_views/get_app_data_view';
|
|||
|
||||
export interface ConfigSchema {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: boolean };
|
||||
alertDetails: {
|
||||
apm: {
|
||||
enabled: boolean;
|
||||
};
|
||||
metrics: {
|
||||
enabled: boolean;
|
||||
};
|
||||
logs: {
|
||||
enabled: boolean;
|
||||
};
|
||||
uptime: {
|
||||
enabled: boolean;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
export type ObservabilityPublicSetup = ReturnType<Plugin['setup']>;
|
||||
|
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* 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 {
|
||||
ALERT_DURATION,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_INSTANCE_ID,
|
||||
ALERT_RULE_NAME,
|
||||
ALERT_RULE_TAGS,
|
||||
ALERT_RULE_TYPE_ID,
|
||||
ALERT_RULE_UUID,
|
||||
ALERT_START,
|
||||
ALERT_STATUS,
|
||||
ALERT_UUID,
|
||||
ALERT_WORKFLOW_STATUS,
|
||||
EVENT_ACTION,
|
||||
EVENT_KIND,
|
||||
SPACE_IDS,
|
||||
TIMESTAMP,
|
||||
VERSION,
|
||||
} from '@kbn/rule-data-utils';
|
||||
import { TopAlert } from '../pages/alerts';
|
||||
import { ConfigSchema } from '../plugin';
|
||||
import { isAlertDetailsEnabledPerApp } from './is_alert_details_enabled';
|
||||
const defaultConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
describe('isAlertDetailsEnabled', () => {
|
||||
describe('Logs alert', () => {
|
||||
const logsAlert = {
|
||||
reason: 'reason message',
|
||||
fields: {
|
||||
[ALERT_STATUS]: 'active',
|
||||
[TIMESTAMP]: '2022-09-02T13:08:51.750Z',
|
||||
[ALERT_DURATION]: 882076000,
|
||||
[ALERT_WORKFLOW_STATUS]: 'open',
|
||||
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
|
||||
[ALERT_START]: '2021-09-02T12:54:09.674Z',
|
||||
[ALERT_RULE_TYPE_ID]: 'logs.alert.document.count',
|
||||
[EVENT_ACTION]: 'active',
|
||||
[ALERT_EVALUATION_VALUE]: 1957,
|
||||
[ALERT_INSTANCE_ID]: '*',
|
||||
[ALERT_RULE_NAME]: 'mockedRule',
|
||||
[ALERT_UUID]: '432ab7c0-0bec-11ec-9ae2-4b10ca857438',
|
||||
[SPACE_IDS]: ['default'],
|
||||
[VERSION]: '8.0.0',
|
||||
[EVENT_KIND]: 'signal',
|
||||
[ALERT_RULE_TAGS]: [],
|
||||
},
|
||||
active: true,
|
||||
start: 1630587249674,
|
||||
lastUpdated: 1630588131750,
|
||||
} as unknown as TopAlert;
|
||||
it('returns FALSE when logs: { enabled: false }', () => {
|
||||
expect(isAlertDetailsEnabledPerApp(logsAlert, defaultConfig)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns TRUE when logs: { enabled: true }', () => {
|
||||
const updatedConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: true },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
expect(isAlertDetailsEnabledPerApp(logsAlert, updatedConfig)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
describe('APM alert', () => {
|
||||
const APMAlert = {
|
||||
reason: 'reason message',
|
||||
fields: {
|
||||
[ALERT_STATUS]: 'active',
|
||||
[TIMESTAMP]: '2022-09-02T13:08:51.750Z',
|
||||
[ALERT_DURATION]: 882076000,
|
||||
[ALERT_WORKFLOW_STATUS]: 'open',
|
||||
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
|
||||
[ALERT_START]: '2021-09-02T12:54:09.674Z',
|
||||
[ALERT_RULE_TYPE_ID]: 'apm.transaction_error_rate',
|
||||
[EVENT_ACTION]: 'active',
|
||||
[ALERT_EVALUATION_VALUE]: 1957,
|
||||
[ALERT_INSTANCE_ID]: '*',
|
||||
[ALERT_RULE_NAME]: 'mockedRule',
|
||||
[ALERT_UUID]: '432ab7c0-0bec-11ec-9ae2-4b10ca857438',
|
||||
[SPACE_IDS]: ['default'],
|
||||
[VERSION]: '8.0.0',
|
||||
[EVENT_KIND]: 'signal',
|
||||
[ALERT_RULE_TAGS]: [],
|
||||
},
|
||||
active: true,
|
||||
start: 1630587249674,
|
||||
lastUpdated: 1630588131750,
|
||||
} as unknown as TopAlert;
|
||||
it('returns FALSE when apm: { enabled: false }', () => {
|
||||
expect(isAlertDetailsEnabledPerApp(APMAlert, defaultConfig)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns TRUE when apm: { enabled: true }', () => {
|
||||
const updatedConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: true },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
expect(isAlertDetailsEnabledPerApp(APMAlert, updatedConfig)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
describe('Metrics alert', () => {
|
||||
const metricsAlert = {
|
||||
reason: 'reason message',
|
||||
fields: {
|
||||
[ALERT_STATUS]: 'active',
|
||||
[TIMESTAMP]: '2022-09-02T13:08:51.750Z',
|
||||
[ALERT_DURATION]: 882076000,
|
||||
[ALERT_WORKFLOW_STATUS]: 'open',
|
||||
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
|
||||
[ALERT_START]: '2021-09-02T12:54:09.674Z',
|
||||
[ALERT_RULE_TYPE_ID]: 'metrics.alert.inventory.threshold',
|
||||
[EVENT_ACTION]: 'active',
|
||||
[ALERT_EVALUATION_VALUE]: 1957,
|
||||
[ALERT_INSTANCE_ID]: '*',
|
||||
[ALERT_RULE_NAME]: 'mockedRule',
|
||||
[ALERT_UUID]: '432ab7c0-0bec-11ec-9ae2-4b10ca857438',
|
||||
[SPACE_IDS]: ['default'],
|
||||
[VERSION]: '8.0.0',
|
||||
[EVENT_KIND]: 'signal',
|
||||
[ALERT_RULE_TAGS]: [],
|
||||
},
|
||||
active: true,
|
||||
start: 1630587249674,
|
||||
lastUpdated: 1630588131750,
|
||||
} as unknown as TopAlert;
|
||||
it('returns FALSE when metrics: { enabled: false }', () => {
|
||||
expect(isAlertDetailsEnabledPerApp(metricsAlert, defaultConfig)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns TRUE when metrics: { enabled: true }', () => {
|
||||
const updatedConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: true },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
expect(isAlertDetailsEnabledPerApp(metricsAlert, updatedConfig)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
describe('Uptime alert', () => {
|
||||
const uptimeAlert = {
|
||||
reason: 'reason message',
|
||||
fields: {
|
||||
[ALERT_STATUS]: 'active',
|
||||
[TIMESTAMP]: '2022-09-02T13:08:51.750Z',
|
||||
[ALERT_DURATION]: 882076000,
|
||||
[ALERT_WORKFLOW_STATUS]: 'open',
|
||||
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
|
||||
[ALERT_START]: '2021-09-02T12:54:09.674Z',
|
||||
[ALERT_RULE_TYPE_ID]: 'xpack.uptime.alerts.monitorStatus',
|
||||
[EVENT_ACTION]: 'active',
|
||||
[ALERT_EVALUATION_VALUE]: 1957,
|
||||
[ALERT_INSTANCE_ID]: '*',
|
||||
[ALERT_RULE_NAME]: 'mockedRule',
|
||||
[ALERT_UUID]: '432ab7c0-0bec-11ec-9ae2-4b10ca857438',
|
||||
[SPACE_IDS]: ['default'],
|
||||
[VERSION]: '8.0.0',
|
||||
[EVENT_KIND]: 'signal',
|
||||
[ALERT_RULE_TAGS]: [],
|
||||
},
|
||||
active: true,
|
||||
start: 1630587249674,
|
||||
lastUpdated: 1630588131750,
|
||||
} as unknown as TopAlert;
|
||||
it('returns FALSE when uptime: { enabled: false }', () => {
|
||||
expect(isAlertDetailsEnabledPerApp(uptimeAlert, defaultConfig)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns TRUE when uptime: { enabled: true }', () => {
|
||||
const updatedConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
expect(isAlertDetailsEnabledPerApp(uptimeAlert, updatedConfig)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
describe('Edge cases', () => {
|
||||
it('returns FALSE when no config provided', () => {
|
||||
const uptimeAlert = {
|
||||
reason: 'reason message',
|
||||
fields: {
|
||||
[ALERT_STATUS]: 'active',
|
||||
[TIMESTAMP]: '2022-09-02T13:08:51.750Z',
|
||||
[ALERT_DURATION]: 882076000,
|
||||
[ALERT_WORKFLOW_STATUS]: 'open',
|
||||
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
|
||||
[ALERT_START]: '2021-09-02T12:54:09.674Z',
|
||||
[ALERT_RULE_TYPE_ID]: 'xpack.uptime.alerts.monitorStatus',
|
||||
[EVENT_ACTION]: 'active',
|
||||
[ALERT_EVALUATION_VALUE]: 1957,
|
||||
[ALERT_INSTANCE_ID]: '*',
|
||||
[ALERT_RULE_NAME]: 'mockedRule',
|
||||
[ALERT_UUID]: '432ab7c0-0bec-11ec-9ae2-4b10ca857438',
|
||||
[SPACE_IDS]: ['default'],
|
||||
[VERSION]: '8.0.0',
|
||||
[EVENT_KIND]: 'signal',
|
||||
[ALERT_RULE_TAGS]: [],
|
||||
},
|
||||
active: true,
|
||||
start: 1630587249674,
|
||||
lastUpdated: 1630588131750,
|
||||
} as unknown as TopAlert;
|
||||
expect(isAlertDetailsEnabledPerApp(uptimeAlert, null)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('returns FALSE when no alert provided', () => {
|
||||
const updatedConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: true },
|
||||
logs: { enabled: true },
|
||||
metrics: { enabled: true },
|
||||
uptime: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
expect(isAlertDetailsEnabledPerApp(undefined, updatedConfig)).toBeFalsy();
|
||||
});
|
||||
it('returns FALSE when a none-listed rule type is checked', () => {
|
||||
const updatedConfig = {
|
||||
unsafe: {
|
||||
alertDetails: {
|
||||
apm: { enabled: true },
|
||||
logs: { enabled: true },
|
||||
metrics: { enabled: true },
|
||||
uptime: { enabled: true },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
const noneListedRuleType = {
|
||||
reason: 'reason message',
|
||||
fields: {
|
||||
[ALERT_STATUS]: 'active',
|
||||
[TIMESTAMP]: '2022-09-02T13:08:51.750Z',
|
||||
[ALERT_DURATION]: 882076000,
|
||||
[ALERT_WORKFLOW_STATUS]: 'open',
|
||||
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
|
||||
[ALERT_START]: '2021-09-02T12:54:09.674Z',
|
||||
[ALERT_RULE_TYPE_ID]: 'new.rule.type.not.listed',
|
||||
[EVENT_ACTION]: 'active',
|
||||
[ALERT_EVALUATION_VALUE]: 1957,
|
||||
[ALERT_INSTANCE_ID]: '*',
|
||||
[ALERT_RULE_NAME]: 'mockedRule',
|
||||
[ALERT_UUID]: '432ab7c0-0bec-11ec-9ae2-4b10ca857438',
|
||||
[SPACE_IDS]: ['default'],
|
||||
[VERSION]: '8.0.0',
|
||||
[EVENT_KIND]: 'signal',
|
||||
[ALERT_RULE_TAGS]: [],
|
||||
},
|
||||
active: true,
|
||||
start: 1630587249674,
|
||||
lastUpdated: 1630588131750,
|
||||
} as unknown as TopAlert;
|
||||
expect(isAlertDetailsEnabledPerApp(noneListedRuleType, updatedConfig)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 { ALERT_RULE_TYPE_ID } from '@kbn/rule-data-utils';
|
||||
import { TopAlert } from '../pages/alerts';
|
||||
import { ConfigSchema } from '../plugin';
|
||||
|
||||
// We are mapping the ruleTypeId from the feature flag with the ruleTypeId form the alert
|
||||
// to know whether the feature flag is enabled or not.
|
||||
export const isAlertDetailsEnabledPerApp = (
|
||||
alert?: TopAlert | null,
|
||||
config?: ConfigSchema | null
|
||||
): boolean => {
|
||||
if (!alert || !config) return false;
|
||||
const ruleTypeIdFromFeatureFlag = Object.keys(config.unsafe.alertDetails);
|
||||
let ruleTypeId = alert.fields[ALERT_RULE_TYPE_ID].split('.')[0] as string;
|
||||
|
||||
// Uptime rule type id is not following the same name convention as all the other rules, so dedicated treatment needed.
|
||||
if (alert.fields[ALERT_RULE_TYPE_ID] === 'xpack.uptime.alerts.monitorStatus')
|
||||
ruleTypeId = 'uptime';
|
||||
|
||||
const appName = ruleTypeId as unknown as keyof ConfigSchema['unsafe']['alertDetails'];
|
||||
return (
|
||||
ruleTypeIdFromFeatureFlag.includes(ruleTypeId) && config?.unsafe?.alertDetails[appName].enabled
|
||||
);
|
||||
};
|
|
@ -29,7 +29,12 @@ const observabilityRuleTypeRegistry = createObservabilityRuleTypeRegistryMock();
|
|||
|
||||
const defaultConfig = {
|
||||
unsafe: {
|
||||
alertDetails: { enabled: false },
|
||||
alertDetails: {
|
||||
apm: { enabled: false },
|
||||
logs: { enabled: false },
|
||||
metrics: { enabled: false },
|
||||
uptime: { enabled: false },
|
||||
},
|
||||
},
|
||||
} as ConfigSchema;
|
||||
|
||||
|
|
|
@ -32,7 +32,18 @@ const configSchema = schema.object({
|
|||
enabled: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
alertDetails: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: false }),
|
||||
apm: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
metrics: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
logs: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
uptime: schema.object({
|
||||
enabled: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import uuid from 'uuid';
|
||||
import { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
|
@ -28,10 +27,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs');
|
||||
});
|
||||
|
||||
it('should show 404 page when the feature flag is disabled', async () => {
|
||||
await observability.alerts.common.navigateToAlertDetails(uuid.v4());
|
||||
it('should show 404 page when the feature flag is disabled but the alert exists', async () => {
|
||||
await observability.alerts.common.navigateToAlertDetails(
|
||||
'4c87bd11-ff31-4a05-8a04-833e2da94858'
|
||||
);
|
||||
await retry.waitFor(
|
||||
'Alerts page to be visible',
|
||||
'The 404 - Not found page to be visible',
|
||||
async () => await testSubjects.exists('pageNotFound')
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue