From 87ac3e98510d892a34485f7da96d88ff59f60902 Mon Sep 17 00:00:00 2001 From: "Devin W. Hurley" Date: Wed, 5 May 2021 22:25:41 -0400 Subject: [PATCH] adds consumer / owner field to alerts created by rule registry (#11) --- x-pack/plugins/apm/common/alert_types.ts | 10 ++++++---- .../alerting/alerting_flyout/index.tsx | 7 +++++-- x-pack/plugins/apm/server/feature.ts | 4 ++-- x-pack/plugins/apm/server/index.ts | 1 + .../alerts/register_error_count_alert_type.ts | 3 ++- ...register_transaction_duration_alert_type.ts | 8 ++++++-- ..._transaction_duration_anomaly_alert_type.ts | 3 ++- ...gister_transaction_error_rate_alert_type.ts | 8 ++++++-- .../common/field_map/base_rule_field_map.ts | 1 + .../index.ts | 2 ++ .../create_lifecycle_rule_type_factory.ts | 11 +++++++++-- x-pack/plugins/rule_registry/server/types.ts | 18 ++++++++++++++++++ .../signals/build_bulk_body.ts | 5 ++--- .../detection_engine/signals/build_signal.ts | 2 +- .../signals/single_bulk_create.ts | 4 ++-- .../lib/detection_engine/signals/types.ts | 1 + 16 files changed, 66 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/apm/common/alert_types.ts b/x-pack/plugins/apm/common/alert_types.ts index 12df93d54b296..19a429a0c1a7a 100644 --- a/x-pack/plugins/apm/common/alert_types.ts +++ b/x-pack/plugins/apm/common/alert_types.ts @@ -10,6 +10,8 @@ import type { ValuesType } from 'utility-types'; import type { ActionGroup } from '../../alerting/common'; import { ANOMALY_SEVERITY, ANOMALY_THRESHOLD } from './ml_constants'; +export const APM_SERVER_FEATURE_ID = 'apm'; + export enum AlertType { ErrorCount = 'apm.error_rate', // ErrorRate was renamed to ErrorCount but the key is kept as `error_rate` for backwards-compat. TransactionErrorRate = 'apm.transaction_error_rate', @@ -43,7 +45,7 @@ export const ALERT_TYPES_CONFIG: Record< actionGroups: [THRESHOLD_MET_GROUP], defaultActionGroupId: THRESHOLD_MET_GROUP_ID, minimumLicenseRequired: 'basic', - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, }, [AlertType.TransactionDuration]: { name: i18n.translate('xpack.apm.transactionDurationAlert.name', { @@ -52,7 +54,7 @@ export const ALERT_TYPES_CONFIG: Record< actionGroups: [THRESHOLD_MET_GROUP], defaultActionGroupId: THRESHOLD_MET_GROUP_ID, minimumLicenseRequired: 'basic', - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, }, [AlertType.TransactionDurationAnomaly]: { name: i18n.translate('xpack.apm.transactionDurationAnomalyAlert.name', { @@ -61,7 +63,7 @@ export const ALERT_TYPES_CONFIG: Record< actionGroups: [THRESHOLD_MET_GROUP], defaultActionGroupId: THRESHOLD_MET_GROUP_ID, minimumLicenseRequired: 'basic', - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, }, [AlertType.TransactionErrorRate]: { name: i18n.translate('xpack.apm.transactionErrorRateAlert.name', { @@ -70,7 +72,7 @@ export const ALERT_TYPES_CONFIG: Record< actionGroups: [THRESHOLD_MET_GROUP], defaultActionGroupId: THRESHOLD_MET_GROUP_ID, minimumLicenseRequired: 'basic', - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, }, }; diff --git a/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx b/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx index 50788c28999b5..e227dc863f9e1 100644 --- a/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/alerting_flyout/index.tsx @@ -8,7 +8,10 @@ import React, { useCallback, useMemo } from 'react'; import { useParams } from 'react-router-dom'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; -import { AlertType } from '../../../../common/alert_types'; +import { + AlertType, + APM_SERVER_FEATURE_ID, +} from '../../../../common/alert_types'; import { getInitialAlertValues } from '../get_initial_alert_values'; import { TriggersAndActionsUIPublicPluginStart } from '../../../../../triggers_actions_ui/public'; interface Props { @@ -38,7 +41,7 @@ export function AlertingFlyout(props: Props) { () => alertType && triggersActionsUi.getAddAlertFlyout({ - consumer: 'apm', + consumer: APM_SERVER_FEATURE_ID, onClose: onCloseAddFlyout, alertTypeId: alertType, canChangeTrigger: false, diff --git a/x-pack/plugins/apm/server/feature.ts b/x-pack/plugins/apm/server/feature.ts index a340a940f4a3b..ae5d3db70f7c1 100644 --- a/x-pack/plugins/apm/server/feature.ts +++ b/x-pack/plugins/apm/server/feature.ts @@ -7,7 +7,7 @@ import { i18n } from '@kbn/i18n'; import { LicenseType } from '../../licensing/common/types'; -import { AlertType } from '../common/alert_types'; +import { AlertType, APM_SERVER_FEATURE_ID } from '../common/alert_types'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; import { LicensingPluginSetup, @@ -15,7 +15,7 @@ import { } from '../../licensing/server'; export const APM_FEATURE = { - id: 'apm', + id: APM_SERVER_FEATURE_ID, name: i18n.translate('xpack.apm.featureRegistry.apmFeatureName', { defaultMessage: 'APM and User Experience', }), diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index 9ab56c1a303ea..f603249b8d1e2 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -120,6 +120,7 @@ export function mergeConfigs( export const plugin = (initContext: PluginInitializerContext) => new APMPlugin(initContext); +export { APM_SERVER_FEATURE_ID } from '../common/alert_types'; export { APMPlugin } from './plugin'; export { APMPluginSetup } from './types'; export { APMServerRouteRepository } from './routes/get_global_apm_server_route_repository'; diff --git a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts index 15ec5d0ef0bd0..b4624009c5f6a 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts @@ -22,6 +22,7 @@ import { apmActionVariables } from './action_variables'; import { alertingEsClient } from './alerting_es_client'; import { RegisterRuleDependencies } from './register_apm_alerts'; import { createAPMLifecycleRuleType } from './create_apm_lifecycle_rule_type'; +import { APM_SERVER_FEATURE_ID } from '../../../common/alert_types'; const paramsSchema = schema.object({ windowSize: schema.number(), @@ -55,7 +56,7 @@ export function registerErrorCountAlertType({ apmActionVariables.interval, ], }, - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, minimumLicenseRequired: 'basic', executor: async ({ services, params }) => { const config = await config$.pipe(take(1)).toPromise(); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts index 4918a6cc892b7..9ac310d1fa557 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts @@ -9,7 +9,11 @@ import { schema } from '@kbn/config-schema'; import { take } from 'rxjs/operators'; import { QueryContainer } from '@elastic/elasticsearch/api/types'; import { parseEnvironmentUrlParam } from '../../../common/environment_filter_values'; -import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types'; +import { + AlertType, + ALERT_TYPES_CONFIG, + APM_SERVER_FEATURE_ID, +} from '../../../common/alert_types'; import { PROCESSOR_EVENT, SERVICE_ENVIRONMENT, @@ -65,7 +69,7 @@ export function registerTransactionDurationAlertType({ apmActionVariables.interval, ], }, - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, minimumLicenseRequired: 'basic', executor: async ({ services, params }) => { const config = await config$.pipe(take(1)).toPromise(); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts index 67ff7cdb8e4e0..fe7758cce5479 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts @@ -24,6 +24,7 @@ import { AlertType, ALERT_TYPES_CONFIG, ANOMALY_ALERT_SEVERITY_TYPES, + APM_SERVER_FEATURE_ID, } from '../../../common/alert_types'; import { getMLJobs } from '../service_map/get_service_anomalies'; import { apmActionVariables } from './action_variables'; @@ -70,7 +71,7 @@ export function registerTransactionDurationAnomalyAlertType({ apmActionVariables.triggerValue, ], }, - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, minimumLicenseRequired: 'basic', executor: async ({ services, params }) => { if (!ml) { diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts index bead17e308f06..8fdd043072552 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts @@ -7,7 +7,11 @@ import { schema } from '@kbn/config-schema'; import { take } from 'rxjs/operators'; -import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types'; +import { + AlertType, + ALERT_TYPES_CONFIG, + APM_SERVER_FEATURE_ID, +} from '../../../common/alert_types'; import { EVENT_OUTCOME, PROCESSOR_EVENT, @@ -59,7 +63,7 @@ export function registerTransactionErrorRateAlertType({ apmActionVariables.interval, ], }, - producer: 'apm', + producer: APM_SERVER_FEATURE_ID, minimumLicenseRequired: 'basic', executor: async ({ services, params: alertParams }) => { const config = await config$.pipe(take(1)).toPromise(); diff --git a/x-pack/plugins/rule_registry/common/field_map/base_rule_field_map.ts b/x-pack/plugins/rule_registry/common/field_map/base_rule_field_map.ts index 22a74212d2ce0..d9e52a5801f0c 100644 --- a/x-pack/plugins/rule_registry/common/field_map/base_rule_field_map.ts +++ b/x-pack/plugins/rule_registry/common/field_map/base_rule_field_map.ts @@ -28,6 +28,7 @@ export const baseRuleFieldMap = { 'kibana.rac.alert.severity.level': { type: 'keyword' }, 'kibana.rac.alert.severity.value': { type: 'long' }, 'kibana.rac.alert.status': { type: 'keyword' }, + 'kibana.rac.alert.owner': { type: 'keyword' }, } as const; export type BaseRuleFieldMap = typeof baseRuleFieldMap; diff --git a/x-pack/plugins/rule_registry/server/rule_registry/create_scoped_rule_registry_client/index.ts b/x-pack/plugins/rule_registry/server/rule_registry/create_scoped_rule_registry_client/index.ts index 0d7735380b640..15df4b0d1ee98 100644 --- a/x-pack/plugins/rule_registry/server/rule_registry/create_scoped_rule_registry_client/index.ts +++ b/x-pack/plugins/rule_registry/server/rule_registry/create_scoped_rule_registry_client/index.ts @@ -17,6 +17,8 @@ import { TypeOfFieldMap } from '../../../common'; import { ScopedRuleRegistryClient, EventsOf } from './types'; import { BaseRuleFieldMap } from '../../../common'; import { RuleRegistry } from '..'; +import { SERVER_APP_ID } from '../../../../security_solution/server'; +import { APM_SERVER_FEATURE_ID } from '../../../../apm/server'; const createPathReporterError = (either: Either) => { const error = new Error(`Failed to validate alert event`); diff --git a/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts b/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts index 6dcf47489631f..4320259e0222d 100644 --- a/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts +++ b/x-pack/plugins/rule_registry/server/rule_registry/rule_type_helpers/create_lifecycle_rule_type_factory.ts @@ -10,7 +10,7 @@ import v4 from 'uuid/v4'; import { Mutable } from 'utility-types'; import { AlertInstance } from '../../../../alerting/server'; import { ActionVariable, AlertInstanceState } from '../../../../alerting/common'; -import { RuleParams, RuleType } from '../../types'; +import { AlertAttributes, RuleParams, RuleType } from '../../types'; import { BaseRuleFieldMap, OutputOfFieldMap } from '../../../common'; import { PrepopulatedRuleEventFields } from '../create_scoped_rule_registry_client/types'; import { RuleRegistry } from '..'; @@ -68,6 +68,13 @@ export function createLifecycleRuleTypeFactory(): CreateLifecycleRuleType( + 'alert', + rule.uuid + ); + + console.error('RULE REGISTRY CONSUMER', so.attributes.consumer); + const decodedState = wrappedStateRt.decode(previousState); const state = isLeft(decodedState) @@ -169,7 +176,7 @@ export function createLifecycleRuleTypeFactory(): CreateLifecycleRuleType; +export interface AlertAttributes { + // actions: RuleAlertAction[]; + consumer: string; + enabled: boolean; + name: string; + tags: string[]; + createdBy: string; + createdAt: string; + updatedBy: string; + schedule: { + interval: string; + }; + throttle: string; + params: T; +} + type TypeOfRuleParams = TypeOf; type RuleExecutorServices< diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts index d20514661b323..a82f0e05604a7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_bulk_body.ts @@ -25,12 +25,11 @@ import { generateSignalId, wrapBuildingBlocks, wrapSignal } from './utils'; // format search_after result for signals index. export const buildBulkBody = ( ruleSO: SavedObject, - doc: SignalSourceHit, - owner: typeof SERVER_APP_ID + doc: SignalSourceHit ): SignalHit => { const rule = buildRuleWithOverrides(ruleSO, doc._source!); const signal: Signal = { - ...buildSignal([doc], rule, owner), + ...buildSignal([doc], rule, ruleSO.attributes.consumer), ...additionalSignalFields(doc), }; const event = buildEventTypeSignal(doc); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts index 06f2d09cd6d74..57bd58ced1494 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_signal.ts @@ -80,7 +80,7 @@ export const removeClashes = (doc: BaseSignalHit): BaseSignalHit => { export const buildSignal = ( docs: BaseSignalHit[], rule: RulesSchema, - owner: typeof SERVER_APP_ID + owner: string // typeof SERVER_APP_ID ): Signal => { const _meta = { version: SIGNALS_TEMPLATE_VERSION, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts index 91985a2e3f9fa..efaa242f9cf9a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_bulk_create.ts @@ -123,7 +123,7 @@ export const singleBulkCreate = async ({ ), }, }, - buildBulkBody(ruleSO, doc, SERVER_APP_ID), + buildBulkBody(ruleSO, doc), ]); const start = performance.now(); const { body: response } = await services.scopedClusterClient.asInternalUser.bulk({ @@ -142,7 +142,7 @@ export const singleBulkCreate = async ({ .map((doc, index) => ({ _id: response.items[index].create?._id ?? '', _index: response.items[index].create?._index ?? '', - ...buildBulkBody(ruleSO, doc, SERVER_APP_ID), + ...buildBulkBody(ruleSO, doc), })) .filter((_, index) => get(response.items[index], 'create.status') === 201); const createdItemsCount = createdItems.length; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index f77189ea393ea..3fe3311c565bf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -227,6 +227,7 @@ export interface SignalHit { export interface AlertAttributes { actions: RuleAlertAction[]; + consumer: string; enabled: boolean; name: string; tags: string[];