[Observability AI Assistant] Feature controls (#163232)

This adds feature controls for the AI Assistant feature.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Dario Gieselaar 2023-08-07 19:53:18 +02:00 committed by GitHub
parent c6df737a7b
commit 0627686500
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 133 additions and 27 deletions

View file

@ -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: [],

View file

@ -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],

View file

@ -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';

View file

@ -13,7 +13,8 @@
"requiredPlugins": [
"triggersActionsUi",
"actions",
"security"
"security",
"features"
],
"requiredBundles": [
"kibanaReact"

View file

@ -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<ConfigSchema>) {
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,
});
}
}

View file

@ -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(() => {

View file

@ -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,

View file

@ -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 {}

View file

@ -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,

View file

@ -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;
}

View file

@ -24,7 +24,8 @@
"@kbn/spaces-plugin",
"@kbn/kibana-react-plugin",
"@kbn/shared-ux-utility",
"@kbn/alerting-plugin"
"@kbn/alerting-plugin",
"@kbn/features-plugin"
],
"exclude": [
"target/**/*",

View file

@ -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],
},
},
};

View file

@ -107,6 +107,7 @@ export default function ({ getService }: FtrProviderContext) {
'graph',
'guidedOnboardingFeature',
'monitoring',
'observabilityAIAssistant',
'observabilityCases',
'savedObjectsManagement',
'savedObjectsTagging',

View file

@ -24,6 +24,7 @@ export default function ({ getService }: FtrProviderContext) {
maps: ['all', 'read', 'minimal_all', 'minimal_read'],
generalCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'],
observabilityCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'],
observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'],
slo: ['all', 'read', 'minimal_all', 'minimal_read'],
fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'],
fleet: ['all', 'read', 'minimal_all', 'minimal_read'],

View file

@ -32,6 +32,7 @@ export default function ({ getService }: FtrProviderContext) {
maps: ['all', 'read', 'minimal_all', 'minimal_read'],
generalCases: ['all', 'read', 'minimal_all', 'minimal_read'],
observabilityCases: ['all', 'read', 'minimal_all', 'minimal_read'],
observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'],
slo: ['all', 'read', 'minimal_all', 'minimal_read'],
canvas: ['all', 'read', 'minimal_all', 'minimal_read'],
infrastructure: ['all', 'read', 'minimal_all', 'minimal_read'],
@ -97,6 +98,7 @@ export default function ({ getService }: FtrProviderContext) {
maps: ['all', 'read', 'minimal_all', 'minimal_read'],
generalCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'],
observabilityCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'],
observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'],
slo: ['all', 'read', 'minimal_all', 'minimal_read'],
fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'],
fleet: ['all', 'read', 'minimal_all', 'minimal_read'],