diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index ea854c1b635f86..231a87099360ea 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -2254,6 +2254,9 @@ }, "observability-onboarding-state": { "properties": { + "type": { + "type": "keyword" + }, "state": { "type": "object", "dynamic": false diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts index 063ed46c443f6a..737522e973f98a 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts @@ -120,7 +120,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ml-module": "2225cbb4bd508ea5f69db4b848be9d8a74b60198", "ml-trained-model": "482195cefd6b04920e539d34d7356d22cb68e4f3", "monitoring-telemetry": "5d91bf75787d9d4dd2fae954d0b3f76d33d2e559", - "observability-onboarding-state": "55b112d6a33fedb7c1e4fec4da768d2bcc5fadc2", + "observability-onboarding-state": "c18631f47a0da568f12f859c9ab9d4ca73bdff7c", "osquery-manager-usage-metric": "983bcbc3b7dda0aad29b20907db233abba709bcc", "osquery-pack": "6ab4358ca4304a12dcfc1777c8135b75cffb4397", "osquery-pack-asset": "b14101d3172c4b60eb5404696881ce5275c84152", diff --git a/x-pack/plugins/observability_onboarding/public/assets/standalone_agent_setup.sh b/x-pack/plugins/observability_onboarding/public/assets/standalone_agent_setup.sh index 1153b933c7b1af..cf0ed05d844621 100755 --- a/x-pack/plugins/observability_onboarding/public/assets/standalone_agent_setup.sh +++ b/x-pack/plugins/observability_onboarding/public/assets/standalone_agent_setup.sh @@ -55,7 +55,7 @@ updateStepProgress() { local STATUS="$2" # "incomplete" | "complete" | "disabled" | "loading" | "warning" | "danger" | "current" local MESSAGE=${3:-} curl --request POST \ - --url "${API_ENDPOINT}/custom_logs/${ONBOARDING_ID}/step/${STEPNAME}" \ + --url "${API_ENDPOINT}/flow/${ONBOARDING_ID}/step/${STEPNAME}" \ --header "Authorization: ApiKey ${API_KEY_ENCODED}" \ --header "Content-Type: application/json" \ --header "kbn-xsrf: true" \ diff --git a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/api_key_banner.tsx b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/api_key_banner.tsx index 2254105f979ffa..57a7ba7b4cab10 100644 --- a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/api_key_banner.tsx +++ b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/api_key_banner.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { APIReturnType } from '../../../../services/rest/create_call_api'; type ApiKeyPayload = - APIReturnType<'POST /internal/observability_onboarding/custom_logs/save'>; + APIReturnType<'POST /internal/observability_onboarding/logs/flow'>; export type HasPrivileges = boolean; diff --git a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx index e29a2d84036e9a..7fc7c12fa47d43 100644 --- a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx +++ b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx @@ -60,7 +60,7 @@ export function InstallElasticAgent() { (callApi) => { if (!hasAlreadySavedFlow(getState())) { return callApi( - 'GET /internal/observability_onboarding/custom_logs/privileges' + 'GET /internal/observability_onboarding/logs/setup/privileges' ); } }, @@ -69,7 +69,7 @@ export function InstallElasticAgent() { const { data: setup } = useFetcher((callApi) => { return callApi( - 'GET /internal/observability_onboarding/custom_logs/install_shipper_setup' + 'GET /internal/observability_onboarding/logs/setup/environment' ); }, []); @@ -87,23 +87,20 @@ export function InstallElasticAgent() { logFilePaths, } = getState(); if (!hasAlreadySavedFlow(getState()) && monitoringRole?.hasPrivileges) { - return callApi( - 'POST /internal/observability_onboarding/custom_logs/save', - { - params: { - body: { - name: datasetName, - state: { - datasetName, - serviceName, - namespace, - customConfigurations, - logFilePaths, - }, + return callApi('POST /internal/observability_onboarding/logs/flow', { + params: { + body: { + name: datasetName, + state: { + datasetName, + serviceName, + namespace, + customConfigurations, + logFilePaths, }, }, - } - ); + }, + }); } }, [monitoringRole?.hasPrivileges] @@ -120,7 +117,7 @@ export function InstallElasticAgent() { } = getState(); if (onboardingId) { return callApi( - 'PUT /internal/observability_onboarding/custom_logs/{onboardingId}/save', + 'PUT /internal/observability_onboarding/flow/{onboardingId}', { params: { path: { onboardingId }, @@ -173,7 +170,7 @@ export function InstallElasticAgent() { (callApi) => { if (onboardingId) { return callApi( - 'GET /internal/observability_onboarding/custom_logs/{onboardingId}/progress', + 'GET /internal/observability_onboarding/flow/{onboardingId}/progress', { params: { path: { onboardingId } } } ); } diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_fallback_urls.ts b/x-pack/plugins/observability_onboarding/server/lib/get_fallback_urls.ts similarity index 90% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_fallback_urls.ts rename to x-pack/plugins/observability_onboarding/server/lib/get_fallback_urls.ts index 06e560315d5c34..3a8963f9d2bbce 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_fallback_urls.ts +++ b/x-pack/plugins/observability_onboarding/server/lib/get_fallback_urls.ts @@ -6,7 +6,7 @@ */ import { CoreStart } from '@kbn/core/server'; -import { EsLegacyConfigService } from '../../services/es_legacy_config_service'; +import { EsLegacyConfigService } from '../services/es_legacy_config_service'; export function getFallbackKibanaUrl({ http }: CoreStart) { const basePath = http.basePath; diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_observability_onboarding_state.ts b/x-pack/plugins/observability_onboarding/server/lib/state/get_observability_onboarding_flow.ts similarity index 82% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_observability_onboarding_state.ts rename to x-pack/plugins/observability_onboarding/server/lib/state/get_observability_onboarding_flow.ts index fd0c3edfb611b4..70232fffe77942 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_observability_onboarding_state.ts +++ b/x-pack/plugins/observability_onboarding/server/lib/state/get_observability_onboarding_flow.ts @@ -7,20 +7,20 @@ import { SavedObjectsClientContract } from '@kbn/core/server'; import { + ObservabilityOnboardingFlow, OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, - ObservabilityOnboardingState, - SavedObservabilityOnboardingState, + SavedObservabilityOnboardingFlow, } from '../../saved_objects/observability_onboarding_status'; -export async function getObservabilityOnboardingState({ +export async function getObservabilityOnboardingFlow({ savedObjectsClient, savedObjectId, }: { savedObjectsClient: SavedObjectsClientContract; savedObjectId: string; -}): Promise { +}): Promise { try { - const result = await savedObjectsClient.get( + const result = await savedObjectsClient.get( OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, savedObjectId ); diff --git a/x-pack/plugins/observability_onboarding/server/lib/state/index.ts b/x-pack/plugins/observability_onboarding/server/lib/state/index.ts new file mode 100644 index 00000000000000..4308f5f9b1239a --- /dev/null +++ b/x-pack/plugins/observability_onboarding/server/lib/state/index.ts @@ -0,0 +1,9 @@ +/* + * 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 * from './get_observability_onboarding_flow'; +export * from './save_observability_onboarding_flow'; diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/save_observability_onboarding_state.ts b/x-pack/plugins/observability_onboarding/server/lib/state/save_observability_onboarding_flow.ts similarity index 78% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/save_observability_onboarding_state.ts rename to x-pack/plugins/observability_onboarding/server/lib/state/save_observability_onboarding_flow.ts index ca18c18e18f610..13eb2e871d2a78 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/save_observability_onboarding_state.ts +++ b/x-pack/plugins/observability_onboarding/server/lib/state/save_observability_onboarding_flow.ts @@ -8,35 +8,36 @@ import { SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; import { OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, - ObservabilityOnboardingState, - SavedObservabilityOnboardingState, + ObservabilityOnboardingFlow, + SavedObservabilityOnboardingFlow, } from '../../saved_objects/observability_onboarding_status'; interface Options { savedObjectsClient: SavedObjectsClientContract; - observabilityOnboardingState: ObservabilityOnboardingState; + observabilityOnboardingState: ObservabilityOnboardingFlow; savedObjectId?: string; } -export async function saveObservabilityOnboardingState({ +export async function saveObservabilityOnboardingFlow({ savedObjectsClient, observabilityOnboardingState, savedObjectId, -}: Options): Promise { +}: Options): Promise { let savedObject: Omit< - SavedObject, + SavedObject, 'attributes' | 'references' >; if (savedObjectId) { - savedObject = await savedObjectsClient.update( + savedObject = await savedObjectsClient.update( OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, savedObjectId, { + type: observabilityOnboardingState.type, state: observabilityOnboardingState.state, progress: { ...observabilityOnboardingState.progress }, } ); } else { - savedObject = await savedObjectsClient.create( + savedObject = await savedObjectsClient.create( OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, observabilityOnboardingState ); diff --git a/x-pack/plugins/observability_onboarding/server/plugin.ts b/x-pack/plugins/observability_onboarding/server/plugin.ts index 9dc78fea2c6d50..6ed20935398ab3 100644 --- a/x-pack/plugins/observability_onboarding/server/plugin.ts +++ b/x-pack/plugins/observability_onboarding/server/plugin.ts @@ -23,7 +23,7 @@ import { ObservabilityOnboardingPluginStartDependencies, } from './types'; import { ObservabilityOnboardingConfig } from '.'; -import { observabilityOnboardingState } from './saved_objects/observability_onboarding_status'; +import { observabilityOnboardingFlow } from './saved_objects/observability_onboarding_status'; import { EsLegacyConfigService } from './services/es_legacy_config_service'; export class ObservabilityOnboardingPlugin @@ -52,7 +52,7 @@ export class ObservabilityOnboardingPlugin this.logger.debug('observability_onboarding: Setup'); this.esLegacyConfigService.setup(core.elasticsearch.legacy.config$); - core.savedObjects.registerType(observabilityOnboardingState); + core.savedObjects.registerType(observabilityOnboardingFlow); const resourcePlugins = mapValues(plugins, (value, key) => { return { diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/find_latest_observability_onboarding_state.ts b/x-pack/plugins/observability_onboarding/server/routes/custom_logs/find_latest_observability_onboarding_state.ts deleted file mode 100644 index fa379fc089c651..00000000000000 --- a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/find_latest_observability_onboarding_state.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -import { SavedObjectsClientContract } from '@kbn/core/server'; -import { - OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, - ObservabilityOnboardingState, - SavedObservabilityOnboardingState, -} from '../../saved_objects/observability_onboarding_status'; - -export async function findLatestObservabilityOnboardingState({ - savedObjectsClient, -}: { - savedObjectsClient: SavedObjectsClientContract; -}): Promise { - const result = await savedObjectsClient.find({ - type: OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, - page: 1, - perPage: 1, - sortField: `updated_at`, - sortOrder: 'desc', - }); - if (result.total === 0) { - return undefined; - } - const { id, updated_at: updatedAt, attributes } = result.saved_objects[0]; - return { - id, - updatedAt: updatedAt ? Date.parse(updatedAt) : 0, - ...attributes, - }; -} diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts b/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts index 1d243845d580f0..fe5549b7b8f163 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts +++ b/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts @@ -8,9 +8,9 @@ import * as t from 'io-ts'; import { getAuthenticationAPIKey } from '../../lib/get_authentication_api_key'; import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route'; -import { getObservabilityOnboardingState } from '../custom_logs/get_observability_onboarding_state'; import { generateYml } from './generate_yml'; -import { getFallbackESUrl } from '../custom_logs/get_fallback_urls'; +import { getFallbackESUrl } from '../../lib/get_fallback_urls'; +import { getObservabilityOnboardingFlow } from '../../lib/state'; const generateConfig = createObservabilityOnboardingServerRoute({ endpoint: 'GET /internal/observability_onboarding/elastic_agent/config', @@ -38,22 +38,22 @@ const generateConfig = createObservabilityOnboardingServerRoute({ ? [plugins.cloud?.setup?.elasticsearchUrl] : await getFallbackESUrl(esLegacyConfigService); - const savedState = await getObservabilityOnboardingState({ + const savedState = await getObservabilityOnboardingFlow({ savedObjectsClient, savedObjectId: onboardingId, }); const yaml = generateYml({ - datasetName: savedState?.state.datasetName, - customConfigurations: savedState?.state.customConfigurations, - logFilePaths: savedState?.state.logFilePaths, - namespace: savedState?.state.namespace, + datasetName: savedState?.state?.datasetName, + customConfigurations: savedState?.state?.customConfigurations, + logFilePaths: savedState?.state?.logFilePaths, + namespace: savedState?.state?.namespace, apiKey: authApiKey ? `${authApiKey?.apiKeyId}:${authApiKey?.apiKey}` : '$API_KEY', esHost: elasticsearchUrl, logfileId: `custom-logs-${Date.now()}`, - serviceName: savedState?.state.serviceName, + serviceName: savedState?.state?.serviceName, }); return yaml; diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_has_logs.ts b/x-pack/plugins/observability_onboarding/server/routes/flow/get_has_logs.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/get_has_logs.ts rename to x-pack/plugins/observability_onboarding/server/routes/flow/get_has_logs.ts diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/route.ts b/x-pack/plugins/observability_onboarding/server/routes/flow/route.ts similarity index 51% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/route.ts rename to x-pack/plugins/observability_onboarding/server/routes/flow/route.ts index b71292b94aa93f..2776af522388fb 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/route.ts +++ b/x-pack/plugins/observability_onboarding/server/routes/flow/route.ts @@ -7,113 +7,22 @@ import Boom from '@hapi/boom'; import * as t from 'io-ts'; -import { ObservabilityOnboardingState } from '../../saved_objects/observability_onboarding_status'; +import { + getObservabilityOnboardingFlow, + saveObservabilityOnboardingFlow, +} from '../../lib/state'; +import { ObservabilityOnboardingFlow } from '../../saved_objects/observability_onboarding_status'; import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route'; -import { createShipperApiKey } from './api_key/create_shipper_api_key'; -import { hasLogMonitoringPrivileges } from './api_key/has_log_monitoring_privileges'; -import { getFallbackKibanaUrl } from './get_fallback_urls'; import { getHasLogs } from './get_has_logs'; -import { getObservabilityOnboardingState } from './get_observability_onboarding_state'; -import { saveObservabilityOnboardingState } from './save_observability_onboarding_state'; -const logMonitoringPrivilegesRoute = createObservabilityOnboardingServerRoute({ - endpoint: 'GET /internal/observability_onboarding/custom_logs/privileges', - options: { tags: [] }, - - handler: async (resources): Promise<{ hasPrivileges: boolean }> => { - const { context } = resources; - - const { - elasticsearch: { client }, - } = await context.core; - - const hasPrivileges = await hasLogMonitoringPrivileges( - client.asCurrentUser - ); - - return { hasPrivileges }; - }, -}); - -const installShipperSetupRoute = createObservabilityOnboardingServerRoute({ - endpoint: - 'GET /internal/observability_onboarding/custom_logs/install_shipper_setup', - options: { tags: [] }, - async handler(resources): Promise<{ - apiEndpoint: string; - scriptDownloadUrl: string; - elasticAgentVersion: string; - }> { - const { core, plugins, kibanaVersion } = resources; - const coreStart = await core.start(); - - const kibanaUrl = - core.setup.http.basePath.publicBaseUrl ?? // priority given to server.publicBaseUrl - plugins.cloud?.setup?.kibanaUrl ?? // then cloud id - getFallbackKibanaUrl(coreStart); // falls back to local network binding - const scriptDownloadUrl = `${kibanaUrl}/plugins/observabilityOnboarding/assets/standalone_agent_setup.sh`; - const apiEndpoint = `${kibanaUrl}/internal/observability_onboarding`; - - return { - apiEndpoint, - scriptDownloadUrl, - elasticAgentVersion: kibanaVersion, - }; - }, -}); - -const createApiKeyRoute = createObservabilityOnboardingServerRoute({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/save', - options: { tags: [] }, - params: t.type({ - body: t.type({ - name: t.string, - state: t.record(t.string, t.unknown), - }), - }), - async handler( - resources - ): Promise<{ apiKeyEncoded: string; onboardingId: string }> { - const { - context, - params: { - body: { name, state }, - }, - core, - request, - } = resources; - const coreStart = await core.start(); - const { - elasticsearch: { client }, - } = await context.core; - const { encoded: apiKeyEncoded } = await createShipperApiKey( - client.asCurrentUser, - name - ); - - const savedObjectsClient = coreStart.savedObjects.getScopedClient(request); - - const { id } = await saveObservabilityOnboardingState({ - savedObjectsClient, - observabilityOnboardingState: { - state: state as ObservabilityOnboardingState['state'], - progress: {}, - }, - }); - - return { apiKeyEncoded, onboardingId: id }; - }, -}); - -const updateOnboardingStateRoute = createObservabilityOnboardingServerRoute({ - endpoint: - 'PUT /internal/observability_onboarding/custom_logs/{onboardingId}/save', +const updateOnboardingFlowRoute = createObservabilityOnboardingServerRoute({ + endpoint: 'PUT /internal/observability_onboarding/flow/{onboardingId}', options: { tags: [] }, params: t.type({ path: t.type({ onboardingId: t.string, }), - body: t.type({ + body: t.partial({ state: t.record(t.string, t.unknown), }), }), @@ -128,18 +37,21 @@ const updateOnboardingStateRoute = createObservabilityOnboardingServerRoute({ } = resources; const coreStart = await core.start(); const savedObjectsClient = coreStart.savedObjects.getScopedClient(request); - const { id } = await saveObservabilityOnboardingState({ + const { id } = await saveObservabilityOnboardingFlow({ savedObjectsClient, savedObjectId: onboardingId, - observabilityOnboardingState: { state } as ObservabilityOnboardingState, + observabilityOnboardingState: { + type: 'logFiles', + state, + progress: {}, + } as ObservabilityOnboardingFlow, }); return { onboardingId: id }; }, }); const stepProgressUpdateRoute = createObservabilityOnboardingServerRoute({ - endpoint: - 'POST /internal/observability_onboarding/custom_logs/{id}/step/{name}', + endpoint: 'POST /internal/observability_onboarding/flow/{id}/step/{name}', options: { tags: [] }, params: t.type({ path: t.type({ @@ -166,7 +78,7 @@ const stepProgressUpdateRoute = createObservabilityOnboardingServerRoute({ coreStart.savedObjects.createInternalRepository(); const savedObservabilityOnboardingState = - await getObservabilityOnboardingState({ + await getObservabilityOnboardingFlow({ savedObjectsClient, savedObjectId: id, }); @@ -183,7 +95,7 @@ const stepProgressUpdateRoute = createObservabilityOnboardingServerRoute({ ...observabilityOnboardingState } = savedObservabilityOnboardingState; - await saveObservabilityOnboardingState({ + await saveObservabilityOnboardingFlow({ savedObjectsClient, savedObjectId, observabilityOnboardingState: { @@ -200,7 +112,7 @@ const stepProgressUpdateRoute = createObservabilityOnboardingServerRoute({ const getProgressRoute = createObservabilityOnboardingServerRoute({ endpoint: - 'GET /internal/observability_onboarding/custom_logs/{onboardingId}/progress', + 'GET /internal/observability_onboarding/flow/{onboardingId}/progress', options: { tags: [] }, params: t.type({ path: t.type({ @@ -220,7 +132,7 @@ const getProgressRoute = createObservabilityOnboardingServerRoute({ const coreStart = await core.start(); const savedObjectsClient = coreStart.savedObjects.getScopedClient(request); const savedObservabilityOnboardingState = - await getObservabilityOnboardingState({ + await getObservabilityOnboardingFlow({ savedObjectsClient, savedObjectId: onboardingId, }); @@ -236,9 +148,11 @@ const getProgressRoute = createObservabilityOnboardingServerRoute({ const esClient = coreStart.elasticsearch.client.asScoped(request).asCurrentUser; - const { - state: { datasetName: dataset, namespace }, - } = savedObservabilityOnboardingState; + const dataset = savedObservabilityOnboardingState.state + ?.datasetName as string; + const namespace = savedObservabilityOnboardingState.state + ?.namespace as string; + if (progress['ea-status']?.status === 'complete') { try { const hasLogs = await getHasLogs({ @@ -262,11 +176,8 @@ const getProgressRoute = createObservabilityOnboardingServerRoute({ }, }); -export const customLogsRouteRepository = { - ...logMonitoringPrivilegesRoute, - ...installShipperSetupRoute, - ...createApiKeyRoute, - ...updateOnboardingStateRoute, +export const flowRouteRepository = { + ...updateOnboardingFlowRoute, ...stepProgressUpdateRoute, ...getProgressRoute, }; diff --git a/x-pack/plugins/observability_onboarding/server/routes/index.ts b/x-pack/plugins/observability_onboarding/server/routes/index.ts index 4833f44a2936ca..133ba446d34425 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/index.ts +++ b/x-pack/plugins/observability_onboarding/server/routes/index.ts @@ -8,14 +8,14 @@ import type { EndpointOf, ServerRouteRepository, } from '@kbn/server-route-repository'; -import { statusRouteRepository } from './status/route'; -import { customLogsRouteRepository } from './custom_logs/route'; import { elasticAgentRouteRepository } from './elastic_agent/route'; +import { flowRouteRepository } from './flow/route'; +import { logsOnboardingRouteRepository } from './logs/route'; function getTypedObservabilityOnboardingServerRouteRepository() { const repository = { - ...statusRouteRepository, - ...customLogsRouteRepository, + ...flowRouteRepository, + ...logsOnboardingRouteRepository, ...elasticAgentRouteRepository, }; diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/api_key/create_shipper_api_key.ts b/x-pack/plugins/observability_onboarding/server/routes/logs/api_key/create_shipper_api_key.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/api_key/create_shipper_api_key.ts rename to x-pack/plugins/observability_onboarding/server/routes/logs/api_key/create_shipper_api_key.ts diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/api_key/has_log_monitoring_privileges.ts b/x-pack/plugins/observability_onboarding/server/routes/logs/api_key/has_log_monitoring_privileges.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/api_key/has_log_monitoring_privileges.ts rename to x-pack/plugins/observability_onboarding/server/routes/logs/api_key/has_log_monitoring_privileges.ts diff --git a/x-pack/plugins/observability_onboarding/server/routes/custom_logs/api_key/monitoring_config.ts b/x-pack/plugins/observability_onboarding/server/routes/logs/api_key/monitoring_config.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/custom_logs/api_key/monitoring_config.ts rename to x-pack/plugins/observability_onboarding/server/routes/logs/api_key/monitoring_config.ts diff --git a/x-pack/plugins/observability_onboarding/server/routes/logs/route.ts b/x-pack/plugins/observability_onboarding/server/routes/logs/route.ts new file mode 100644 index 00000000000000..4afe189ed7279c --- /dev/null +++ b/x-pack/plugins/observability_onboarding/server/routes/logs/route.ts @@ -0,0 +1,113 @@ +/* + * 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. + */ + +import * as t from 'io-ts'; +import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route'; +import { getFallbackKibanaUrl } from '../../lib/get_fallback_urls'; +import { hasLogMonitoringPrivileges } from './api_key/has_log_monitoring_privileges'; +import { saveObservabilityOnboardingFlow } from '../../lib/state'; +import { createShipperApiKey } from './api_key/create_shipper_api_key'; +import { ObservabilityOnboardingFlow } from '../../saved_objects/observability_onboarding_status'; + +const logMonitoringPrivilegesRoute = createObservabilityOnboardingServerRoute({ + endpoint: 'GET /internal/observability_onboarding/logs/setup/privileges', + options: { tags: [] }, + + handler: async (resources): Promise<{ hasPrivileges: boolean }> => { + const { context } = resources; + + const { + elasticsearch: { client }, + } = await context.core; + + const hasPrivileges = await hasLogMonitoringPrivileges( + client.asCurrentUser + ); + + return { hasPrivileges }; + }, +}); + +const installShipperSetupRoute = createObservabilityOnboardingServerRoute({ + endpoint: 'GET /internal/observability_onboarding/logs/setup/environment', + options: { tags: [] }, + async handler(resources): Promise<{ + apiEndpoint: string; + scriptDownloadUrl: string; + elasticAgentVersion: string; + }> { + const { core, plugins, kibanaVersion } = resources; + const coreStart = await core.start(); + + const kibanaUrl = + core.setup.http.basePath.publicBaseUrl ?? // priority given to server.publicBaseUrl + plugins.cloud?.setup?.kibanaUrl ?? // then cloud id + getFallbackKibanaUrl(coreStart); // falls back to local network binding + const scriptDownloadUrl = `${kibanaUrl}/plugins/observabilityOnboarding/assets/standalone_agent_setup.sh`; + const apiEndpoint = `${kibanaUrl}/internal/observability_onboarding`; + + return { + apiEndpoint, + scriptDownloadUrl, + elasticAgentVersion: kibanaVersion, + }; + }, +}); + +const createFlowRoute = createObservabilityOnboardingServerRoute({ + endpoint: 'POST /internal/observability_onboarding/logs/flow', + options: { tags: [] }, + params: t.type({ + body: t.intersection([ + t.type({ + name: t.string, + }), + t.partial({ + state: t.record(t.string, t.unknown), + }), + ]), + }), + async handler( + resources + ): Promise<{ apiKeyEncoded: string; onboardingId: string }> { + const { + context, + params: { + body: { name, state }, + }, + core, + request, + } = resources; + const coreStart = await core.start(); + const { + elasticsearch: { client }, + } = await context.core; + const { encoded: apiKeyEncoded } = await createShipperApiKey( + client.asCurrentUser, + name + ); + + const savedObjectsClient = coreStart.savedObjects.getScopedClient(request); + + const { id } = await saveObservabilityOnboardingFlow({ + savedObjectsClient, + observabilityOnboardingState: { + type: 'logFiles', + state: state as ObservabilityOnboardingFlow['state'], + progress: {}, + }, + }); + + return { apiKeyEncoded, onboardingId: id }; + }, +}); + +export const logsOnboardingRouteRepository = { + ...logMonitoringPrivilegesRoute, + ...installShipperSetupRoute, + ...createFlowRoute, +}; diff --git a/x-pack/plugins/observability_onboarding/server/routes/status/route.ts b/x-pack/plugins/observability_onboarding/server/routes/status/route.ts deleted file mode 100644 index 438bbe7e8b6a55..00000000000000 --- a/x-pack/plugins/observability_onboarding/server/routes/status/route.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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. - */ - -import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route'; - -const statusRoute = createObservabilityOnboardingServerRoute({ - endpoint: 'GET /internal/observability_onboarding/get_status', - options: { - tags: [], - }, - async handler(resources): Promise<{ status: 'incomplete' | 'complete' }> { - return { status: 'complete' }; - }, -}); - -export const statusRouteRepository = { - ...statusRoute, -}; diff --git a/x-pack/plugins/observability_onboarding/server/saved_objects/observability_onboarding_status.ts b/x-pack/plugins/observability_onboarding/server/saved_objects/observability_onboarding_status.ts index adc5291f73f728..4c151e29a1b2a1 100644 --- a/x-pack/plugins/observability_onboarding/server/saved_objects/observability_onboarding_status.ts +++ b/x-pack/plugins/observability_onboarding/server/saved_objects/observability_onboarding_status.ts @@ -9,15 +9,19 @@ import { SavedObjectsType } from '@kbn/core/server'; export const OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE = 'observability-onboarding-state'; +export interface LogFilesState { + datasetName: string; + serviceName?: string; + customConfigurations?: string; + logFilePaths: string[]; + namespace: string; +} + +type ObservabilityOnboardingFlowState = LogFilesState | undefined; -export interface ObservabilityOnboardingState { - state: { - datasetName: string; - serviceName?: string; - customConfigurations?: string; - logFilePaths: string[]; - namespace: string; - }; +export interface ObservabilityOnboardingFlow { + type: 'logFiles'; + state: ObservabilityOnboardingFlowState; progress: Record< string, { @@ -27,18 +31,19 @@ export interface ObservabilityOnboardingState { >; } -export interface SavedObservabilityOnboardingState - extends ObservabilityOnboardingState { +export interface SavedObservabilityOnboardingFlow + extends ObservabilityOnboardingFlow { id: string; updatedAt: number; } -export const observabilityOnboardingState: SavedObjectsType = { +export const observabilityOnboardingFlow: SavedObjectsType = { name: OBSERVABILITY_ONBOARDING_STATE_SAVED_OBJECT_TYPE, hidden: false, namespaceType: 'agnostic', mappings: { properties: { + type: { type: 'keyword' }, state: { type: 'object', dynamic: false }, progress: { type: 'object', dynamic: false }, }, diff --git a/x-pack/plugins/observability_onboarding/server/test_helpers/create_observability_onboarding_users/authentication.ts b/x-pack/plugins/observability_onboarding/server/test_helpers/create_observability_onboarding_users/authentication.ts index 300cc029d92ce7..95da640fa40ae1 100644 --- a/x-pack/plugins/observability_onboarding/server/test_helpers/create_observability_onboarding_users/authentication.ts +++ b/x-pack/plugins/observability_onboarding/server/test_helpers/create_observability_onboarding_users/authentication.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { - cluster, - indices, -} from '../../routes/custom_logs/api_key/monitoring_config'; +import { cluster, indices } from '../../routes/logs/api_key/monitoring_config'; export enum ObservabilityOnboardingUsername { noAccessUser = 'no_access_user', diff --git a/x-pack/test/observability_onboarding_api_integration/tests/elastic_agent/config.spec.ts b/x-pack/test/observability_onboarding_api_integration/tests/elastic_agent/config.spec.ts index 0deffa986676af..5b4f5041d1d11e 100644 --- a/x-pack/test/observability_onboarding_api_integration/tests/elastic_agent/config.spec.ts +++ b/x-pack/test/observability_onboarding_api_integration/tests/elastic_agent/config.spec.ts @@ -33,7 +33,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { before(async () => { const req = await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/save', + endpoint: 'POST /internal/observability_onboarding/logs/flow', params: { body: { name: 'name', diff --git a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/progress/es_utils.ts b/x-pack/test/observability_onboarding_api_integration/tests/flow/progress/es_utils.ts similarity index 100% rename from x-pack/test/observability_onboarding_api_integration/tests/custom_logs/progress/es_utils.ts rename to x-pack/test/observability_onboarding_api_integration/tests/flow/progress/es_utils.ts diff --git a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/progress/progress.spec.ts b/x-pack/test/observability_onboarding_api_integration/tests/flow/progress/progress.spec.ts similarity index 96% rename from x-pack/test/observability_onboarding_api_integration/tests/custom_logs/progress/progress.spec.ts rename to x-pack/test/observability_onboarding_api_integration/tests/flow/progress/progress.spec.ts index c22b555b398d7f..a6076261d81c4b 100644 --- a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/progress/progress.spec.ts +++ b/x-pack/test/observability_onboarding_api_integration/tests/flow/progress/progress.spec.ts @@ -25,7 +25,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { user?: ObservabilityOnboardingApiClientKey; }) { return await observabilityOnboardingApiClient[user]({ - endpoint: 'GET /internal/observability_onboarding/custom_logs/{onboardingId}/progress', + endpoint: 'GET /internal/observability_onboarding/flow/{onboardingId}/progress', params: { path: { onboardingId, @@ -41,7 +41,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { before(async () => { const req = await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/save', + endpoint: 'POST /internal/observability_onboarding/logs/flow', params: { body: { name: 'name', @@ -104,7 +104,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { describe('should not skip logs verification', () => { before(async () => { await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/{id}/step/{name}', + endpoint: 'POST /internal/observability_onboarding/flow/{id}/step/{name}', params: { path: { id: onboardingId, diff --git a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/save.spec.ts b/x-pack/test/observability_onboarding_api_integration/tests/logs/create.spec.ts similarity index 92% rename from x-pack/test/observability_onboarding_api_integration/tests/custom_logs/save.spec.ts rename to x-pack/test/observability_onboarding_api_integration/tests/logs/create.spec.ts index ad00d135d423e0..1de222e2d2368d 100644 --- a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/save.spec.ts +++ b/x-pack/test/observability_onboarding_api_integration/tests/logs/create.spec.ts @@ -18,7 +18,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApiWithoutPrivileges(state = {}) { return await observabilityOnboardingApiClient.readUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/save', + endpoint: 'POST /internal/observability_onboarding/logs/flow', params: { body: { name: 'name', @@ -30,7 +30,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApiWithPrivileges(state = {}) { return await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/save', + endpoint: 'POST /internal/observability_onboarding/logs/flow', params: { body: { name: 'name', @@ -76,7 +76,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { id: request.body.onboardingId, }); - expect(savedState.attributes).to.be.eql({ state, progress: {} }); + expect(savedState.attributes).to.be.eql({ type: 'logFiles', state, progress: {} }); }); }); }); diff --git a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/install_shipper_setup.spec.ts b/x-pack/test/observability_onboarding_api_integration/tests/logs/environment.spec.ts similarity index 95% rename from x-pack/test/observability_onboarding_api_integration/tests/custom_logs/install_shipper_setup.spec.ts rename to x-pack/test/observability_onboarding_api_integration/tests/logs/environment.spec.ts index b2a1c601f39051..95626901d452a0 100644 --- a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/install_shipper_setup.spec.ts +++ b/x-pack/test/observability_onboarding_api_integration/tests/logs/environment.spec.ts @@ -15,7 +15,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApiWithPrivileges() { return await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'GET /internal/observability_onboarding/custom_logs/install_shipper_setup', + endpoint: 'GET /internal/observability_onboarding/logs/setup/environment', }); } diff --git a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/privileges.spec.ts b/x-pack/test/observability_onboarding_api_integration/tests/logs/privileges.spec.ts similarity index 95% rename from x-pack/test/observability_onboarding_api_integration/tests/custom_logs/privileges.spec.ts rename to x-pack/test/observability_onboarding_api_integration/tests/logs/privileges.spec.ts index eefce48cde878e..02de274373b208 100644 --- a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/privileges.spec.ts +++ b/x-pack/test/observability_onboarding_api_integration/tests/logs/privileges.spec.ts @@ -15,7 +15,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApiAs(user: ObservabilityOnboardingApiClientKey) { return await observabilityOnboardingApiClient[user]({ - endpoint: 'GET /internal/observability_onboarding/custom_logs/privileges', + endpoint: 'GET /internal/observability_onboarding/logs/setup/privileges', }); } diff --git a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/update_step_progress.spec.ts b/x-pack/test/observability_onboarding_api_integration/tests/logs/update_step_progress.spec.ts similarity index 96% rename from x-pack/test/observability_onboarding_api_integration/tests/custom_logs/update_step_progress.spec.ts rename to x-pack/test/observability_onboarding_api_integration/tests/logs/update_step_progress.spec.ts index 1fd7c77abb7f25..0826b3719837b0 100644 --- a/x-pack/test/observability_onboarding_api_integration/tests/custom_logs/update_step_progress.spec.ts +++ b/x-pack/test/observability_onboarding_api_integration/tests/logs/update_step_progress.spec.ts @@ -28,7 +28,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { message?: string; }) { return await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/{id}/step/{name}', + endpoint: 'POST /internal/observability_onboarding/flow/{id}/step/{name}', params: { path: { id, @@ -64,7 +64,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { beforeEach(async () => { const req = await observabilityOnboardingApiClient.logMonitoringUser({ - endpoint: 'POST /internal/observability_onboarding/custom_logs/save', + endpoint: 'POST /internal/observability_onboarding/logs/flow', params: { body: { name: 'name',