diff --git a/x-pack/plugins/ingest_manager/common/constants/routes.ts b/x-pack/plugins/ingest_manager/common/constants/routes.ts index 08ba12a6e76a1d..a566db88fcb9dd 100644 --- a/x-pack/plugins/ingest_manager/common/constants/routes.ts +++ b/x-pack/plugins/ingest_manager/common/constants/routes.ts @@ -34,6 +34,7 @@ export const AGENT_CONFIG_API_ROUTES = { CREATE_PATTERN: `${AGENT_CONFIG_API_ROOT}`, UPDATE_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}`, DELETE_PATTERN: `${AGENT_CONFIG_API_ROOT}/delete`, + FULL_INFO_PATTERN: `${AGENT_CONFIG_API_ROOT}/{agentConfigId}/full`, }; // Agent API routes diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts b/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts index 9c43b0123409fd..29ccbf33f84ddf 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent_config.ts @@ -5,7 +5,13 @@ */ import { SavedObjectAttributes } from '../../../../../../src/core/public'; -import { Datasource } from './datasource'; +import { + Datasource, + DatasourcePackage, + DatasourceInput, + DatasourceInputStream, +} from './datasource'; +import { Output } from './output'; export enum AgentConfigStatus { Active = 'active', @@ -26,3 +32,27 @@ export interface AgentConfig extends NewAgentConfig, SavedObjectAttributes { updated_on: string; updated_by: string; } + +export type FullAgentConfigDatasource = Pick & { + package?: Pick; + use_output: string; + inputs: Array< + Omit & { + streams: Array< + Omit & { + [key: string]: any; + } + >; + } + >; +}; + +export interface FullAgentConfig { + id: string; + outputs: { + [key: string]: Pick & { + [key: string]: any; + }; + }; + datasources: FullAgentConfigDatasource[]; +} diff --git a/x-pack/plugins/ingest_manager/common/types/models/datasource.ts b/x-pack/plugins/ingest_manager/common/types/models/datasource.ts index 3336a712e20e0b..f0d4533a22c5ee 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/datasource.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/datasource.ts @@ -4,34 +4,40 @@ * you may not use this file except in compliance with the Elastic License. */ +export interface DatasourcePackage { + assets: Array<{ + id: string; + type: string; + }>; + description: string; + name: string; + title: string; + version: string; +} + +export interface DatasourceInputStream { + id: string; + enabled: boolean; + dataset: string; + processors?: string[]; + config?: Record; +} + +export interface DatasourceInput { + type: string; + enabled: boolean; + processors?: string[]; + streams: DatasourceInputStream[]; +} + export interface NewDatasource { name: string; namespace?: string; config_id: string; enabled: boolean; - package?: { - assets: Array<{ - id: string; - type: string; - }>; - description: string; - name: string; - title: string; - version: string; - }; + package?: DatasourcePackage; output_id: string; - inputs: Array<{ - type: string; - enabled: boolean; - processors?: string[]; - streams: Array<{ - id: string; - enabled: boolean; - dataset: string; - processors?: string[]; - config?: Record; - }>; - }>; + inputs: DatasourceInput[]; } export type Datasource = NewDatasource & { id: string }; diff --git a/x-pack/plugins/ingest_manager/common/types/rest_spec/agent_config.ts b/x-pack/plugins/ingest_manager/common/types/rest_spec/agent_config.ts index 476f74e781c3df..6a578ab18eef77 100644 --- a/x-pack/plugins/ingest_manager/common/types/rest_spec/agent_config.ts +++ b/x-pack/plugins/ingest_manager/common/types/rest_spec/agent_config.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { AgentConfig, NewAgentConfig } from '../models'; +import { AgentConfig, NewAgentConfig, FullAgentConfig } from '../models'; import { ListWithKuery } from './common'; export interface GetAgentConfigsRequest { @@ -57,3 +57,14 @@ export type DeleteAgentConfigsResponse = Array<{ id: string; success: boolean; }>; + +export interface GetFullAgentConfigRequest { + params: { + agentConfigId: string; + }; +} + +export interface GetFullAgentConfigResponse { + item: FullAgentConfig; + success: boolean; +} diff --git a/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts index 6f66d710d1f745..9e2fedccdc02c0 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent_config/handlers.ts @@ -12,6 +12,7 @@ import { CreateAgentConfigRequestSchema, UpdateAgentConfigRequestSchema, DeleteAgentConfigsRequestSchema, + GetFullAgentConfigRequestSchema, } from '../../types'; import { GetAgentConfigsResponse, @@ -19,6 +20,7 @@ import { CreateAgentConfigResponse, UpdateAgentConfigResponse, DeleteAgentConfigsResponse, + GetFullAgentConfigResponse, } from '../../../common'; export const getAgentConfigsHandler: RequestHandler< @@ -144,3 +146,35 @@ export const deleteAgentConfigsHandler: RequestHandler< }); } }; + +export const getFullAgentConfig: RequestHandler> = async (context, request, response) => { + const soClient = context.core.savedObjects.client; + + try { + const fullAgentConfig = await agentConfigService.getFullConfig( + soClient, + request.params.agentConfigId + ); + if (fullAgentConfig) { + const body: GetFullAgentConfigResponse = { + item: fullAgentConfig, + success: true, + }; + return response.ok({ + body, + }); + } else { + return response.customError({ + statusCode: 404, + body: { message: 'Agent config not found' }, + }); + } + } catch (e) { + return response.customError({ + statusCode: 500, + body: { message: e.message }, + }); + } +}; diff --git a/x-pack/plugins/ingest_manager/server/routes/agent_config/index.ts b/x-pack/plugins/ingest_manager/server/routes/agent_config/index.ts index 67ad915b71e45a..9481adbbac1953 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent_config/index.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent_config/index.ts @@ -11,6 +11,7 @@ import { CreateAgentConfigRequestSchema, UpdateAgentConfigRequestSchema, DeleteAgentConfigsRequestSchema, + GetFullAgentConfigRequestSchema, } from '../../types'; import { getAgentConfigsHandler, @@ -18,6 +19,7 @@ import { createAgentConfigHandler, updateAgentConfigHandler, deleteAgentConfigsHandler, + getFullAgentConfig, } from './handlers'; export const registerRoutes = (router: IRouter) => { @@ -70,4 +72,14 @@ export const registerRoutes = (router: IRouter) => { }, deleteAgentConfigsHandler ); + + // Get one full agent config + router.get( + { + path: AGENT_CONFIG_API_ROUTES.FULL_INFO_PATTERN, + validate: GetFullAgentConfigRequestSchema, + options: { tags: [`access:${PLUGIN_ID}`] }, + }, + getFullAgentConfig + ); }; diff --git a/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts index ce564372248a84..6c9dfdc9a3416c 100644 --- a/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/datasource/handlers.ts @@ -5,7 +5,7 @@ */ import { TypeOf } from '@kbn/config-schema'; import { RequestHandler } from 'kibana/server'; -import { datasourceService } from '../../services'; +import { appContextService, datasourceService, agentConfigService } from '../../services'; import { GetDatasourcesRequestSchema, GetOneDatasourceRequestSchema, @@ -70,8 +70,12 @@ export const createDatasourceHandler: RequestHandler< TypeOf > = async (context, request, response) => { const soClient = context.core.savedObjects.client; + const user = (await appContextService.getSecurity()?.authc.getCurrentUser(request)) || undefined; try { const datasource = await datasourceService.create(soClient, request.body); + await agentConfigService.assignDatasources(soClient, datasource.config_id, [datasource.id], { + user, + }); return response.ok({ body: { item: datasource, success: true }, }); diff --git a/x-pack/plugins/ingest_manager/server/services/agent_config.ts b/x-pack/plugins/ingest_manager/server/services/agent_config.ts index f178b07d08d994..3a10be82577cb0 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_config.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_config.ts @@ -4,10 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ import { SavedObjectsClientContract } from 'kibana/server'; -import { flatten } from 'lodash'; import { AuthenticatedUser } from '../../../security/server'; import { DEFAULT_AGENT_CONFIG, AGENT_CONFIG_SAVED_OBJECT_TYPE } from '../constants'; -import { NewAgentConfig, AgentConfig, AgentConfigStatus, ListWithKuery } from '../types'; +import { + Datasource, + NewAgentConfig, + AgentConfig, + FullAgentConfig, + FullAgentConfigDatasource, + AgentConfigStatus, + ListWithKuery, +} from '../types'; import { DeleteAgentConfigsResponse } from '../../common'; import { datasourceService } from './datasource'; import { outputService } from './output'; @@ -249,25 +256,38 @@ class AgentConfigService { return result; } - private storedDatasourceToAgentStreams(datasources: AgentConfig['datasources'] = []): any[] { - return flatten( - // @ts-ignore - datasources.map((ds: any) => { - return ds.streams.map((stream: any) => ({ - ...stream.input, - id: stream.id, - type: stream.input.type as any, - output: { use_output: stream.output_id }, - ...(stream.config || {}), - })); - }) - ); - } + private storedDatasourceToAgentDatasource = ( + datasource: Datasource + ): FullAgentConfigDatasource => { + const { name, namespace, enabled, package: pkg, output_id, inputs } = datasource; + return { + name, + namespace, + enabled, + package: pkg + ? { + name: pkg.name, + version: pkg.version, + } + : undefined, + use_output: output_id, + inputs: inputs + .filter(input => input.enabled) + .map(input => ({ + ...input, + streams: input.streams.map(stream => ({ + ...stream, + config: undefined, + ...(stream.config || {}), + })), + })), + }; + }; public async getFullConfig( soClient: SavedObjectsClientContract, id: string - ): Promise { + ): Promise { let config; try { @@ -282,25 +302,26 @@ class AgentConfigService { return null; } - const agentConfig = { + const agentConfig: FullAgentConfig = { id: config.id, outputs: { // TEMPORARY as we only support a default output ...[ await outputService.get(soClient, await outputService.getDefaultOutputId(soClient)), - ].reduce((outputs, { config: outputConfig, ...output }) => { - outputs[output.is_default ? 'default' : output.id] = { - ...output, - type: output.type as any, + ].reduce((outputs, { config: outputConfig, name, type, hosts, ca_sha256, api_key }) => { + outputs[name] = { + type, + hosts, + ca_sha256, + api_key, ...outputConfig, }; return outputs; - }, {} as any), + }, {} as FullAgentConfig['outputs']), }, - streams: - config.datasources && config.datasources.length - ? this.storedDatasourceToAgentStreams(config.datasources) - : [], + datasources: (config.datasources as Datasource[]).map(ds => + this.storedDatasourceToAgentDatasource(ds) + ), }; return agentConfig; diff --git a/x-pack/plugins/ingest_manager/server/types/index.tsx b/x-pack/plugins/ingest_manager/server/types/index.tsx index 1860d26a86b782..ab36176a2a8888 100644 --- a/x-pack/plugins/ingest_manager/server/types/index.tsx +++ b/x-pack/plugins/ingest_manager/server/types/index.tsx @@ -16,6 +16,8 @@ export { AgentAction, Datasource, NewDatasource, + FullAgentConfigDatasource, + FullAgentConfig, AgentConfig, NewAgentConfig, AgentConfigStatus, diff --git a/x-pack/plugins/ingest_manager/server/types/rest_spec/agent_config.ts b/x-pack/plugins/ingest_manager/server/types/rest_spec/agent_config.ts index 04e94f9f1f480e..7c40cc1b70009d 100644 --- a/x-pack/plugins/ingest_manager/server/types/rest_spec/agent_config.ts +++ b/x-pack/plugins/ingest_manager/server/types/rest_spec/agent_config.ts @@ -31,3 +31,9 @@ export const DeleteAgentConfigsRequestSchema = { agentConfigIds: schema.arrayOf(schema.string()), }), }; + +export const GetFullAgentConfigRequestSchema = { + params: schema.object({ + agentConfigId: schema.string(), + }), +};