From 0ec0a5a40da3d8b67493e57d62da316f1265bc15 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Mon, 24 Jul 2023 15:41:04 +0200 Subject: [PATCH] [Observability AI Assistant] Feature controls --- x-pack/plugins/apm/server/feature.ts | 4 +- x-pack/plugins/infra/server/features.ts | 8 +-- .../common/feature.ts | 8 +++ .../observability_ai_assistant/kibana.jsonc | 3 +- .../public/plugin.ts | 17 +++-- .../public/service/create_service.test.ts | 11 ++-- .../public/service/create_service.ts | 10 ++- .../public/types.ts | 10 ++- .../server/plugin.ts | 62 ++++++++++++++++++- .../server/types.ts | 16 +++-- x-pack/plugins/profiling/server/feature.ts | 4 +- 11 files changed, 127 insertions(+), 26 deletions(-) create mode 100644 x-pack/plugins/observability_ai_assistant/common/feature.ts diff --git a/x-pack/plugins/apm/server/feature.ts b/x-pack/plugins/apm/server/feature.ts index 292f48bf18156..09681f01da2d6 100644 --- a/x-pack/plugins/apm/server/feature.ts +++ b/x-pack/plugins/apm/server/feature.ts @@ -35,7 +35,7 @@ export const APM_FEATURE = { privileges: { all: { app: [APM_SERVER_FEATURE_ID, 'ux', 'kibana'], - api: [APM_SERVER_FEATURE_ID, 'apm_write', 'rac', 'ai_assistant'], + api: [APM_SERVER_FEATURE_ID, 'apm_write', 'rac'], catalogue: [APM_SERVER_FEATURE_ID], savedObject: { all: [], @@ -56,7 +56,7 @@ export const APM_FEATURE = { }, read: { app: [APM_SERVER_FEATURE_ID, 'ux', 'kibana'], - api: [APM_SERVER_FEATURE_ID, 'rac', 'ai_assistant'], + api: [APM_SERVER_FEATURE_ID, 'rac'], catalogue: [APM_SERVER_FEATURE_ID], savedObject: { all: [], diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index 41f60ab5eac9b..e9fec4a5b4f5d 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -33,7 +33,7 @@ export const METRICS_FEATURE = { all: { app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops', 'metrics'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], savedObject: { all: ['infrastructure-ui-source'], read: ['index-pattern'], @@ -54,7 +54,7 @@ export const METRICS_FEATURE = { read: { app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops', 'metrics'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], savedObject: { all: [], read: ['infrastructure-ui-source', 'index-pattern'], @@ -92,7 +92,7 @@ export const LOGS_FEATURE = { all: { app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], savedObject: { all: [infraSourceConfigurationSavedObjectName, logViewSavedObjectName], read: [], @@ -113,7 +113,7 @@ export const LOGS_FEATURE = { read: { app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], alerting: { rule: { read: [LOG_DOCUMENT_COUNT_RULE_TYPE_ID], diff --git a/x-pack/plugins/observability_ai_assistant/common/feature.ts b/x-pack/plugins/observability_ai_assistant/common/feature.ts new file mode 100644 index 0000000000000..db06ec43086f2 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/common/feature.ts @@ -0,0 +1,8 @@ +/* + * 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 OBSERVABILITY_AI_ASSISTANT_FEATURE_ID = 'observabilityAIAssistant'; diff --git a/x-pack/plugins/observability_ai_assistant/kibana.jsonc b/x-pack/plugins/observability_ai_assistant/kibana.jsonc index 05e0e2e450553..2faf2c7de57e9 100644 --- a/x-pack/plugins/observability_ai_assistant/kibana.jsonc +++ b/x-pack/plugins/observability_ai_assistant/kibana.jsonc @@ -13,7 +13,8 @@ "requiredPlugins": [ "triggersActionsUi", "actions", - "security" + "security", + "features" ], "requiredBundles": [ "kibanaReact" diff --git a/x-pack/plugins/observability_ai_assistant/public/plugin.ts b/x-pack/plugins/observability_ai_assistant/public/plugin.ts index 607f54a3c6da7..187275b127dd3 100644 --- a/x-pack/plugins/observability_ai_assistant/public/plugin.ts +++ b/x-pack/plugins/observability_ai_assistant/public/plugin.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; +import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; import type { Logger } from '@kbn/logging'; import { createService } from './service/create_service'; import type { @@ -29,11 +29,20 @@ export class ObservabilityAIAssistantPlugin constructor(context: PluginInitializerContext) { this.logger = context.logger.get(); } - setup(): ObservabilityAIAssistantPluginSetup { + setup( + core: CoreSetup, + pluginsSetup: ObservabilityAIAssistantPluginSetupDependencies + ): ObservabilityAIAssistantPluginSetup { return {}; } - start(coreStart: CoreStart): ObservabilityAIAssistantPluginStart { - return createService(coreStart); + start( + coreStart: CoreStart, + pluginsStart: ObservabilityAIAssistantPluginStartDependencies + ): ObservabilityAIAssistantPluginStart { + return createService({ + coreStart, + enabled: coreStart.application.capabilities.observabilityAIAssistant.show === true, + }); } } diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts index 010503e7abf4f..8a7ec44bfd9bc 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts @@ -41,10 +41,13 @@ describe('createService', () => { beforeEach(() => { service = createService({ - http: { - post: httpPostSpy, - }, - } as unknown as CoreStart); + coreStart: { + http: { + post: httpPostSpy, + }, + } as unknown as CoreStart, + enabled: true, + }); }); afterEach(() => { diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts index 4c54bef460eb7..da29de585c9d1 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts @@ -12,12 +12,18 @@ import { createCallObservabilityAIAssistantAPI } from '../api'; import { CreateChatCompletionResponseChunk, ObservabilityAIAssistantService } from '../types'; import { readableStreamReaderIntoObservable } from '../utils/readable_stream_reader_into_observable'; -export function createService(coreStart: CoreStart): ObservabilityAIAssistantService { +export function createService({ + coreStart, + enabled, +}: { + coreStart: CoreStart; + enabled: boolean; +}): ObservabilityAIAssistantService { const client = createCallObservabilityAIAssistantAPI(coreStart); return { isEnabled: () => { - return true; + return enabled; }, async chat({ connectorId, diff --git a/x-pack/plugins/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_ai_assistant/public/types.ts index fc553cb201010..69d826c7ebf17 100644 --- a/x-pack/plugins/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_ai_assistant/public/types.ts @@ -8,11 +8,13 @@ import type { TriggersAndActionsUIPublicPluginSetup, TriggersAndActionsUIPublicPluginStart, } from '@kbn/triggers-actions-ui-plugin/public'; +import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public'; import type { CreateChatCompletionResponse, CreateChatCompletionResponseChoicesInner, } from 'openai'; import type { Observable } from 'rxjs'; +import type { FeaturesPluginSetup, FeaturesPluginStart } from '@kbn/features-plugin/public'; import type { Message } from '../common/types'; import type { ObservabilityAIAssistantAPIClient } from './api'; @@ -40,10 +42,14 @@ export interface ObservabilityAIAssistantPluginStart extends ObservabilityAIAssi export interface ObservabilityAIAssistantPluginSetup {} export interface ObservabilityAIAssistantPluginSetupDependencies { - triggersActions: TriggersAndActionsUIPublicPluginSetup; + triggersActionsUi: TriggersAndActionsUIPublicPluginSetup; + security: SecurityPluginSetup; + features: FeaturesPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { - triggersActions: TriggersAndActionsUIPublicPluginStart; + triggersActionsUi: TriggersAndActionsUIPublicPluginStart; + security: SecurityPluginStart; + features: FeaturesPluginStart; } export interface ConfigSchema {} diff --git a/x-pack/plugins/observability_ai_assistant/server/plugin.ts b/x-pack/plugins/observability_ai_assistant/server/plugin.ts index 23efe49ab24a7..a81b9e18a0a80 100644 --- a/x-pack/plugins/observability_ai_assistant/server/plugin.ts +++ b/x-pack/plugins/observability_ai_assistant/server/plugin.ts @@ -5,14 +5,22 @@ * 2.0. */ -import type { +import { CoreSetup, CoreStart, + DEFAULT_APP_CATEGORIES, Logger, Plugin, PluginInitializerContext, } from '@kbn/core/server'; import { mapValues } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + ACTION_SAVED_OBJECT_TYPE, + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, +} from '@kbn/actions-plugin/server/constants/saved_objects'; +import { OBSERVABILITY_AI_ASSISTANT_FEATURE_ID } from '../common/feature'; import type { ObservabilityAIAssistantConfig } from './config'; import { registerServerRoutes } from './routes/register_routes'; import { ObservabilityAIAssistantRouteHandlerResources } from './routes/types'; @@ -50,6 +58,58 @@ export class ObservabilityAIAssistantPlugin >, plugins: ObservabilityAIAssistantPluginSetupDependencies ): ObservabilityAIAssistantPluginSetup { + plugins.features.registerKibanaFeature({ + id: OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, + name: i18n.translate('xpack.observabilityAiAssistant.featureRegistry.featureName', { + defaultMessage: 'Observability AI Assistant', + }), + order: 8600, + category: DEFAULT_APP_CATEGORIES.observability, + app: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'kibana'], + catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID], + management: { + insightsAndAlerting: ['triggersActionsConnectors'], + }, + minimumLicense: 'enterprise', + // see x-pack/plugins/features/common/feature_kibana_privileges.ts + privileges: { + all: { + app: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'kibana'], + api: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'ai_assistant'], + catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID], + savedObject: { + all: [ + ACTION_SAVED_OBJECT_TYPE, + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + ], + read: [], + }, + management: { + insightsAndAlerting: ['triggersActionsConnectors'], + }, + ui: ['show'], + }, + read: { + app: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'kibana'], + api: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'ai_assistant'], + catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID], + savedObject: { + all: [], + read: [ + ACTION_SAVED_OBJECT_TYPE, + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + ], + }, + management: { + insightsAndAlerting: ['triggersActionsConnectors'], + }, + ui: ['show'], + }, + }, + }); + const routeHandlerPlugins = mapValues(plugins, (value, key) => { return { setup: value, diff --git a/x-pack/plugins/observability_ai_assistant/server/types.ts b/x-pack/plugins/observability_ai_assistant/server/types.ts index faa5c346541c0..58f890c80000f 100644 --- a/x-pack/plugins/observability_ai_assistant/server/types.ts +++ b/x-pack/plugins/observability_ai_assistant/server/types.ts @@ -4,18 +4,26 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import type { PluginSetupContract, PluginStartContract } from '@kbn/actions-plugin/server'; +import type { + PluginStartContract as FeaturesPluginStart, + PluginSetupContract as FeaturesPluginSetup, +} from '@kbn/features-plugin/server'; +import type { + PluginSetupContract as ActionsPluginSetup, + PluginStartContract as ActionsPluginStart, +} from '@kbn/actions-plugin/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; /* eslint-disable @typescript-eslint/no-empty-interface*/ export interface ObservabilityAIAssistantPluginStart {} export interface ObservabilityAIAssistantPluginSetup {} export interface ObservabilityAIAssistantPluginSetupDependencies { - actions: PluginSetupContract; + actions: ActionsPluginSetup; security: SecurityPluginSetup; + features: FeaturesPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { - actions: PluginStartContract; + actions: ActionsPluginStart; security: SecurityPluginStart; + features: FeaturesPluginStart; } diff --git a/x-pack/plugins/profiling/server/feature.ts b/x-pack/plugins/profiling/server/feature.ts index 446a436145c77..13e064364b7b8 100644 --- a/x-pack/plugins/profiling/server/feature.ts +++ b/x-pack/plugins/profiling/server/feature.ts @@ -27,7 +27,7 @@ export const PROFILING_FEATURE = { read: [], }, ui: ['show'], - api: [PROFILING_SERVER_FEATURE_ID, 'ai_assistant'], + api: [PROFILING_SERVER_FEATURE_ID], }, read: { app: [PROFILING_SERVER_FEATURE_ID, 'ux', 'kibana'], @@ -36,7 +36,7 @@ export const PROFILING_FEATURE = { read: [], }, ui: ['show'], - api: [PROFILING_SERVER_FEATURE_ID, 'ai_assistant'], + api: [PROFILING_SERVER_FEATURE_ID], }, }, };