mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[8.x] [Attack Discovery][Scheduling] Use core.services.featureFlags
to control access to assistantAttackDiscoverySchedulingEnabled
feature flag (#12005) (#217306) (#217480)
# Backport This will backport the following commits from `main` to `8.x`: - [[Attack Discovery][Scheduling] Use `core.services.featureFlags` to control access to `assistantAttackDiscoverySchedulingEnabled` feature flag (#12005) (#217306)](https://github.com/elastic/kibana/pull/217306) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Ievgen Sorokopud","email":"ievgen.sorokopud@elastic.co"},"sourceCommit":{"committedDate":"2025-04-08T08:24:35Z","message":"[Attack Discovery][Scheduling] Use `core.services.featureFlags` to control access to `assistantAttackDiscoverySchedulingEnabled` feature flag (#12005) (#217306)\n\n## Summary\n\nFeature description: [internal\nlink](https://github.com/elastic/security-team/issues/10142)\nPart of: [internal\nlink](https://github.com/elastic/security-team/issues/12005)\n\nThese changes we switched to `core.services.featureFlags` to manage the\n`assistantAttackDiscoverySchedulingEnabled` feature flag to control\nvisibility of the Attack Discovery Scheduling feature.\n\nTo enable the flag locally, add this in the `kibana.dev.yml`:\n\n```\nfeature_flags.overrides:\n securitySolution.assistantAttackDiscoverySchedulingEnabled: true\n```","sha":"6ab8808d72e2482646ad832a1cad2a59e94cb32d","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team: SecuritySolution","Team:Security Generative AI","backport:version","v9.1.0","v8.19.0"],"title":"[Attack Discovery][Scheduling] Use `core.services.featureFlags` to control access to `assistantAttackDiscoverySchedulingEnabled` feature flag (#12005)","number":217306,"url":"https://github.com/elastic/kibana/pull/217306","mergeCommit":{"message":"[Attack Discovery][Scheduling] Use `core.services.featureFlags` to control access to `assistantAttackDiscoverySchedulingEnabled` feature flag (#12005) (#217306)\n\n## Summary\n\nFeature description: [internal\nlink](https://github.com/elastic/security-team/issues/10142)\nPart of: [internal\nlink](https://github.com/elastic/security-team/issues/12005)\n\nThese changes we switched to `core.services.featureFlags` to manage the\n`assistantAttackDiscoverySchedulingEnabled` feature flag to control\nvisibility of the Attack Discovery Scheduling feature.\n\nTo enable the flag locally, add this in the `kibana.dev.yml`:\n\n```\nfeature_flags.overrides:\n securitySolution.assistantAttackDiscoverySchedulingEnabled: true\n```","sha":"6ab8808d72e2482646ad832a1cad2a59e94cb32d"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/217306","number":217306,"mergeCommit":{"message":"[Attack Discovery][Scheduling] Use `core.services.featureFlags` to control access to `assistantAttackDiscoverySchedulingEnabled` feature flag (#12005) (#217306)\n\n## Summary\n\nFeature description: [internal\nlink](https://github.com/elastic/security-team/issues/10142)\nPart of: [internal\nlink](https://github.com/elastic/security-team/issues/12005)\n\nThese changes we switched to `core.services.featureFlags` to manage the\n`assistantAttackDiscoverySchedulingEnabled` feature flag to control\nvisibility of the Attack Discovery Scheduling feature.\n\nTo enable the flag locally, add this in the `kibana.dev.yml`:\n\n```\nfeature_flags.overrides:\n securitySolution.assistantAttackDiscoverySchedulingEnabled: true\n```","sha":"6ab8808d72e2482646ad832a1cad2a59e94cb32d"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
815dfb01a9
commit
a6915c1a32
10 changed files with 45 additions and 28 deletions
|
@ -62,4 +62,6 @@ export const DEFEND_INSIGHTS = `${ELASTIC_AI_ASSISTANT_INTERNAL_URL}/defend_insi
|
|||
export const DEFEND_INSIGHTS_BY_ID = `${DEFEND_INSIGHTS}/{id}`;
|
||||
|
||||
// Attack Discovery
|
||||
export const ATTACK_DISCOVERY_SCHEDULES_ENABLED_FEATURE_FLAG =
|
||||
'securitySolution.assistantAttackDiscoverySchedulingEnabled' as const;
|
||||
export const ATTACK_DISCOVERY_SCHEDULES_ALERT_TYPE_ID = 'attack-discovery' as const;
|
||||
|
|
|
@ -21,5 +21,4 @@ export type AssistantFeatureKey = keyof AssistantFeatures;
|
|||
export const defaultAssistantFeatures = Object.freeze({
|
||||
assistantModelEvaluation: false,
|
||||
defendInsights: false,
|
||||
assistantAttackDiscoverySchedulingEnabled: false,
|
||||
});
|
||||
|
|
|
@ -20,5 +20,4 @@ export type GetCapabilitiesResponse = z.infer<typeof GetCapabilitiesResponse>;
|
|||
export const GetCapabilitiesResponse = z.object({
|
||||
assistantModelEvaluation: z.boolean(),
|
||||
defendInsights: z.boolean(),
|
||||
assistantAttackDiscoverySchedulingEnabled: z.boolean(),
|
||||
});
|
||||
|
|
|
@ -24,12 +24,9 @@ paths:
|
|||
type: boolean
|
||||
defendInsights:
|
||||
type: boolean
|
||||
assistantAttackDiscoverySchedulingEnabled:
|
||||
type: boolean
|
||||
required:
|
||||
- assistantModelEvaluation
|
||||
- defendInsights
|
||||
- assistantAttackDiscoverySchedulingEnabled
|
||||
'400':
|
||||
description: Generic Error
|
||||
content:
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
|
||||
import { PluginInitializerContext, CoreStart, Plugin, Logger } from '@kbn/core/server';
|
||||
|
||||
import { AssistantFeatures } from '@kbn/elastic-assistant-common';
|
||||
import {
|
||||
ATTACK_DISCOVERY_SCHEDULES_ENABLED_FEATURE_FLAG,
|
||||
AssistantFeatures,
|
||||
} from '@kbn/elastic-assistant-common';
|
||||
import { ReplaySubject, type Subject } from 'rxjs';
|
||||
import { MlPluginSetup } from '@kbn/ml-plugin/server';
|
||||
import { events } from './lib/telemetry/event_based_telemetry';
|
||||
|
@ -89,6 +92,25 @@ export class ElasticAssistantPlugin
|
|||
|
||||
registerRoutes(router, this.logger, this.getElserId);
|
||||
|
||||
// The featureFlags service is not available in the core setup, so we need
|
||||
// to wait for the start services to be available to read the feature flags.
|
||||
// This can take a while, but the plugin setup phase cannot run for a long time.
|
||||
// As a workaround, this promise does not block the setup phase.
|
||||
core
|
||||
.getStartServices()
|
||||
.then(([{ featureFlags }]) => {
|
||||
// read all feature flags:
|
||||
void Promise.all([
|
||||
featureFlags.getBooleanValue(ATTACK_DISCOVERY_SCHEDULES_ENABLED_FEATURE_FLAG, false),
|
||||
// add more feature flags here
|
||||
]).then(([assistantAttackDiscoverySchedulingEnabled]) => {
|
||||
// TODO: use `assistantAttackDiscoverySchedulingEnabled` to conditionally create alerts index
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.logger.error(`error in security assistant plugin setup: ${error}`);
|
||||
});
|
||||
|
||||
return {
|
||||
actions: plugins.actions,
|
||||
getRegisteredFeatures: (pluginName: string) => {
|
||||
|
|
|
@ -55,7 +55,6 @@ describe('AppContextService', () => {
|
|||
appContextService.registerFeatures('super', {
|
||||
assistantModelEvaluation: true,
|
||||
defendInsights: true,
|
||||
assistantAttackDiscoverySchedulingEnabled: true,
|
||||
});
|
||||
appContextService.stop();
|
||||
|
||||
|
@ -107,7 +106,6 @@ describe('AppContextService', () => {
|
|||
...defaultAssistantFeatures,
|
||||
assistantModelEvaluation: true,
|
||||
defendInsights: true,
|
||||
assistantAttackDiscoverySchedulingEnabled: true,
|
||||
};
|
||||
|
||||
appContextService.start(mockAppContext);
|
||||
|
@ -124,14 +122,12 @@ describe('AppContextService', () => {
|
|||
...defaultAssistantFeatures,
|
||||
assistantModelEvaluation: true,
|
||||
defendInsights: true,
|
||||
assistantAttackDiscoverySchedulingEnabled: true,
|
||||
};
|
||||
const pluginTwo = 'plugin2';
|
||||
const featuresTwo: AssistantFeatures = {
|
||||
...defaultAssistantFeatures,
|
||||
assistantModelEvaluation: false,
|
||||
defendInsights: false,
|
||||
assistantAttackDiscoverySchedulingEnabled: false,
|
||||
};
|
||||
|
||||
appContextService.start(mockAppContext);
|
||||
|
@ -148,13 +144,11 @@ describe('AppContextService', () => {
|
|||
...defaultAssistantFeatures,
|
||||
assistantModelEvaluation: true,
|
||||
defendInsights: true,
|
||||
assistantAttackDiscoverySchedulingEnabled: true,
|
||||
};
|
||||
const featuresTwo: AssistantFeatures = {
|
||||
...defaultAssistantFeatures,
|
||||
assistantModelEvaluation: false,
|
||||
defendInsights: false,
|
||||
assistantAttackDiscoverySchedulingEnabled: false,
|
||||
};
|
||||
|
||||
appContextService.start(mockAppContext);
|
||||
|
@ -177,7 +171,6 @@ describe('AppContextService', () => {
|
|||
const featuresSubset: Partial<AssistantFeatures> = {
|
||||
assistantModelEvaluation: true,
|
||||
defendInsights: true,
|
||||
assistantAttackDiscoverySchedulingEnabled: true,
|
||||
};
|
||||
|
||||
appContextService.start(mockAppContext);
|
||||
|
|
|
@ -114,11 +114,6 @@ export const allowedExperimentalValues = Object.freeze({
|
|||
*/
|
||||
assistantModelEvaluation: false,
|
||||
|
||||
/**
|
||||
* Enables the Attack Discovery Scheduling functionality and API endpoint`.
|
||||
*/
|
||||
assistantAttackDiscoverySchedulingEnabled: false,
|
||||
|
||||
/**
|
||||
* Enables the Managed User section inside the new user details flyout.
|
||||
*/
|
||||
|
|
|
@ -13,7 +13,6 @@ import { DEFAULT_END, DEFAULT_START } from '@kbn/elastic-assistant-common';
|
|||
import { SettingsFlyout } from '.';
|
||||
import { ATTACK_DISCOVERY_SETTINGS } from './translations';
|
||||
import { getDefaultQuery } from '../helpers';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { TestProviders } from '../../../common/mock';
|
||||
import { useSourcererDataView } from '../../../sourcerer/containers';
|
||||
|
@ -81,15 +80,19 @@ const mockUseKibana = useKibana as jest.MockedFunction<typeof useKibana>;
|
|||
const mockUseSourcererDataView = useSourcererDataView as jest.MockedFunction<
|
||||
typeof useSourcererDataView
|
||||
>;
|
||||
const getBooleanValueMock = jest.fn();
|
||||
|
||||
describe('SettingsFlyout', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(false);
|
||||
getBooleanValueMock.mockReturnValue(false);
|
||||
|
||||
mockUseKibana.mockReturnValue({
|
||||
services: {
|
||||
featureFlags: {
|
||||
getBooleanValue: getBooleanValueMock,
|
||||
},
|
||||
lens: {
|
||||
EmbeddableComponent: () => <div data-test-subj="mockEmbeddableComponent" />,
|
||||
},
|
||||
|
@ -216,9 +219,9 @@ describe('SettingsFlyout', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when `assistantAttackDiscoverySchedulingEnabled` feature flag is enabled', () => {
|
||||
describe('when `securitySolution.assistantAttackDiscoverySchedulingEnabled` feature flag is enabled', () => {
|
||||
beforeEach(() => {
|
||||
(useIsExperimentalFeatureEnabled as jest.Mock).mockReturnValue(true);
|
||||
getBooleanValueMock.mockReturnValue(true);
|
||||
render(
|
||||
<TestProviders>
|
||||
<SettingsFlyout {...defaultProps} />
|
||||
|
|
|
@ -17,9 +17,14 @@ import {
|
|||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { DEFAULT_ATTACK_DISCOVERY_MAX_ALERTS } from '@kbn/elastic-assistant';
|
||||
import { DEFAULT_END, DEFAULT_START } from '@kbn/elastic-assistant-common';
|
||||
import {
|
||||
ATTACK_DISCOVERY_SCHEDULES_ENABLED_FEATURE_FLAG,
|
||||
DEFAULT_END,
|
||||
DEFAULT_START,
|
||||
} from '@kbn/elastic-assistant-common';
|
||||
import type { Filter, Query } from '@kbn/es-query';
|
||||
|
||||
import { useKibana } from '../../../common/lib/kibana';
|
||||
import { Footer } from './footer';
|
||||
import * as i18n from './translations';
|
||||
import { useSettingsView } from './hooks/use_settings_view';
|
||||
|
@ -28,7 +33,6 @@ import type { AlertsSelectionSettings } from './types';
|
|||
import { MIN_FLYOUT_WIDTH } from './constants';
|
||||
import { getMaxAlerts } from './alert_selection/helpers/get_max_alerts';
|
||||
import { getDefaultQuery } from '../helpers';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features';
|
||||
|
||||
export const DEFAULT_STACK_BY_FIELD = 'kibana.alert.rule.name';
|
||||
|
||||
|
@ -59,12 +63,17 @@ const SettingsFlyoutComponent: React.FC<Props> = ({
|
|||
setStart,
|
||||
start,
|
||||
}) => {
|
||||
const {
|
||||
services: { featureFlags },
|
||||
} = useKibana();
|
||||
|
||||
const flyoutTitleId = useGeneratedHtmlId({
|
||||
prefix: 'attackDiscoverySettingsFlyoutTitle',
|
||||
});
|
||||
|
||||
const isAttackDiscoverySchedulingEnabled = useIsExperimentalFeatureEnabled(
|
||||
'assistantAttackDiscoverySchedulingEnabled'
|
||||
const isAttackDiscoverySchedulingEnabled = featureFlags.getBooleanValue(
|
||||
ATTACK_DISCOVERY_SCHEDULES_ENABLED_FEATURE_FLAG,
|
||||
false
|
||||
);
|
||||
|
||||
const [settings, setSettings] = useState<AlertsSelectionSettings>({
|
||||
|
|
|
@ -591,8 +591,6 @@ export class Plugin implements ISecuritySolutionPlugin {
|
|||
plugins.elasticAssistant.registerTools(APP_UI_ID, assistantTools);
|
||||
const features = {
|
||||
assistantModelEvaluation: config.experimentalFeatures.assistantModelEvaluation,
|
||||
assistantAttackDiscoverySchedulingEnabled:
|
||||
config.experimentalFeatures.assistantAttackDiscoverySchedulingEnabled,
|
||||
};
|
||||
plugins.elasticAssistant.registerFeatures(APP_UI_ID, features);
|
||||
plugins.elasticAssistant.registerFeatures('management', features);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue