mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution] Support experimental features in timelines (#189028)
## Summary Adding generic support for experimental features in timelines --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
7e5907e816
commit
7db28682dd
9 changed files with 97 additions and 5 deletions
|
@ -336,6 +336,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
|
|||
'xpack.stack_connectors.enableExperimental (array)',
|
||||
'xpack.trigger_actions_ui.enableExperimental (array)',
|
||||
'xpack.trigger_actions_ui.enableGeoTrackingThresholdAlert (boolean)',
|
||||
'xpack.timelines.enableExperimental (array)',
|
||||
'xpack.alerting.rules.run.alerts.max (number)',
|
||||
'xpack.upgrade_assistant.featureSet.migrateSystemIndices (boolean)',
|
||||
'xpack.upgrade_assistant.featureSet.mlSnapshots (boolean)',
|
||||
|
|
|
@ -935,4 +935,3 @@ components:
|
|||
type: http
|
||||
security:
|
||||
- BasicAuth: []
|
||||
tags: !<tag:yaml.org,2002:js/undefined> ''
|
||||
|
|
|
@ -863,4 +863,3 @@ components:
|
|||
type: http
|
||||
security:
|
||||
- BasicAuth: []
|
||||
tags: !<tag:yaml.org,2002:js/undefined> ''
|
||||
|
|
47
x-pack/plugins/timelines/common/experimental_features.ts
Normal file
47
x-pack/plugins/timelines/common/experimental_features.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export const allowedExperimentalValues = Object.freeze({
|
||||
// NOTE: remove this after some actual flags are added, without it line 36 fails ts validation
|
||||
sample: false,
|
||||
});
|
||||
|
||||
export type ExperimentalFeatures = { [K in keyof typeof allowedExperimentalValues]: boolean };
|
||||
|
||||
const allowedKeys = Object.keys(allowedExperimentalValues);
|
||||
|
||||
type Mutable<T> = { -readonly [P in keyof T]: T[P] };
|
||||
|
||||
/**
|
||||
* Parses the string value used in `xpack.timelines.enableExperimental` kibana configuration,
|
||||
* which should be a string of values delimited by a comma (`,`)
|
||||
*
|
||||
* @param configValue
|
||||
* @throws SecuritySolutionInvalidExperimentalValue
|
||||
*/
|
||||
export const parseExperimentalConfigValue = (
|
||||
configValue: string[]
|
||||
): { features: ExperimentalFeatures; invalid: string[] } => {
|
||||
const enabledFeatures: Mutable<Partial<ExperimentalFeatures>> = {};
|
||||
const invalidKeys: string[] = [];
|
||||
|
||||
for (const value of configValue) {
|
||||
if (!allowedKeys.includes(value as keyof ExperimentalFeatures)) {
|
||||
invalidKeys.push(value);
|
||||
} else {
|
||||
enabledFeatures[value as keyof ExperimentalFeatures] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
features: {
|
||||
...allowedExperimentalValues,
|
||||
...enabledFeatures,
|
||||
},
|
||||
invalid: invalidKeys,
|
||||
};
|
||||
};
|
10
x-pack/plugins/timelines/server/config.ts
Normal file
10
x-pack/plugins/timelines/server/config.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export interface ConfigSchema {
|
||||
enableExperimental: string[];
|
||||
}
|
|
@ -5,7 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { PluginInitializerContext } from '@kbn/core/server';
|
||||
import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { ConfigSchema } from './config';
|
||||
|
||||
export async function plugin(initializerContext: PluginInitializerContext) {
|
||||
const { TimelinesPlugin } = await import('./plugin');
|
||||
|
@ -13,3 +15,28 @@ export async function plugin(initializerContext: PluginInitializerContext) {
|
|||
}
|
||||
|
||||
export type { TimelinesPluginUI, TimelinesPluginStart } from './types';
|
||||
|
||||
const configSchema = schema.object({
|
||||
/**
|
||||
* For internal use. A list of string values (comma delimited) that will enable experimental
|
||||
* type of functionality that is not yet released. Valid values for this settings need to
|
||||
* be defined in:
|
||||
* `x-pack/plugins/timelines/common/experimental_features.ts`
|
||||
* under the `allowedExperimentalValues` object
|
||||
*
|
||||
* @example
|
||||
* xpack.timelines.enableExperimental:
|
||||
* - someCrazyFeature
|
||||
* - someEvenCrazierFeature
|
||||
*/
|
||||
enableExperimental: schema.arrayOf(schema.string(), {
|
||||
defaultValue: () => [],
|
||||
}),
|
||||
});
|
||||
|
||||
export const config: PluginConfigDescriptor<ConfigSchema> = {
|
||||
exposeToBrowser: {
|
||||
enableExperimental: true,
|
||||
},
|
||||
schema: configSchema,
|
||||
};
|
||||
|
|
|
@ -12,6 +12,8 @@ import { SetupPlugins, StartPlugins, TimelinesPluginUI, TimelinesPluginStart } f
|
|||
import { timelineSearchStrategyProvider } from './search_strategy/timeline';
|
||||
import { timelineEqlSearchStrategyProvider } from './search_strategy/timeline/eql';
|
||||
import { indexFieldsProvider } from './search_strategy/index_fields';
|
||||
import { parseExperimentalConfigValue } from '../common/experimental_features';
|
||||
import { ConfigSchema } from './config';
|
||||
|
||||
export class TimelinesPlugin
|
||||
implements Plugin<TimelinesPluginUI, TimelinesPluginStart, SetupPlugins, StartPlugins>
|
||||
|
@ -21,6 +23,11 @@ export class TimelinesPlugin
|
|||
|
||||
constructor(initializerContext: PluginInitializerContext) {
|
||||
this.logger = initializerContext.logger.get();
|
||||
|
||||
// NOTE: underscored to skip lint warning, but it can be used to implement experimental features behind a flag
|
||||
const { features: _experimentalFeatures } = parseExperimentalConfigValue(
|
||||
initializerContext.config.get<ConfigSchema>().enableExperimental
|
||||
);
|
||||
}
|
||||
|
||||
public setup(core: CoreSetup<StartPlugins, TimelinesPluginStart>, plugins: SetupPlugins) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import { ENHANCED_ES_SEARCH_STRATEGY } from '@kbn/data-plugin/common';
|
|||
import { SecurityPluginSetup } from '@kbn/security-plugin/server';
|
||||
import { Logger } from '@kbn/logging';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { searchStrategyRequestSchema } from '../../../common/api/search_strategy';
|
||||
import {
|
||||
TimelineFactoryQueryTypes,
|
||||
|
@ -30,7 +31,7 @@ import { isAggCardinalityAggregate } from './factory/helpers/is_agg_cardinality_
|
|||
export const timelineSearchStrategyProvider = (
|
||||
data: PluginStart,
|
||||
logger: Logger,
|
||||
security?: SecurityPluginSetup
|
||||
_security?: SecurityPluginSetup
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
): ISearchStrategy<z.input<typeof searchStrategyRequestSchema>, any> => {
|
||||
const es = data.search.getSearchStrategy(ENHANCED_ES_SEARCH_STRATEGY);
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
"@kbn/search-errors",
|
||||
"@kbn/search-types",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/field-formats-plugin"
|
||||
"@kbn/field-formats-plugin",
|
||||
"@kbn/config-schema"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue