diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/settings/agent_configurations/list/confirm_delete_modal.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/settings/agent_configurations/list/confirm_delete_modal.tsx index 914c664946fc2..0fe71a9f0ca0d 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/settings/agent_configurations/list/confirm_delete_modal.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/settings/agent_configurations/list/confirm_delete_modal.tsx @@ -66,11 +66,9 @@ async function deleteConfig(config: Config, toasts: NotificationsStart['toasts'] await callApmApi('DELETE /api/apm/settings/agent-configuration 2023-10-31', { signal: null, params: { - body: { - service: { - name: config.service.name, - environment: config.service.environment, - }, + query: { + serviceName: config.service.name, + serviceEnvironment: config.service.environment, }, }, }); diff --git a/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts index bc8109dfa2808..7358773a4dc6d 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/settings/agent_configuration/route.ts @@ -96,7 +96,7 @@ const getSingleAgentConfigurationRoute = createApmServerRoute({ }); // delete configuration -const deleteAgentConfigurationRoute = createApmServerRoute({ +const deleteAgentConfigurationBodyRoute = createApmServerRoute({ endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31', options: { tags: ['access:apm', 'access:apm_settings_write'], @@ -110,8 +110,73 @@ const deleteAgentConfigurationRoute = createApmServerRoute({ handler: async (resources): Promise<{ result: string }> => { throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags); - const { params, logger, core, telemetryUsageCounter } = resources; const { service } = params.body; + + const apmIndices = await resources.getApmIndices(); + const [internalESClient, apmEventClient] = await Promise.all([ + createInternalESClientWithResources(resources), + getApmEventClient(resources), + ]); + const exactConfig = await findExactConfiguration({ + service, + internalESClient, + apmEventClient, + }); + if (!exactConfig) { + logger.info(`Config was not found for ${service.name}/${service.environment}`); + + throw Boom.notFound(); + } + + logger.info(`Deleting config ${service.name}/${service.environment} (${exactConfig.id})`); + + const deleteConfigurationResult = await deleteConfiguration({ + configurationId: exactConfig.id!, + internalESClient, + }); + + if (resources.plugins.fleet) { + await syncAgentConfigsToApmPackagePolicies({ + coreStartPromise: core.start(), + fleetPluginStart: await resources.plugins.fleet.start(), + internalESClient, + apmIndices, + telemetryUsageCounter, + }); + logger.info( + `Updated Fleet integration policy for APM to remove the deleted agent configuration.` + ); + } + + return deleteConfigurationResult; + }, +}); + +// delete configuration +const deleteAgentConfigurationQueryRoute = createApmServerRoute({ + endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31', + options: { + tags: ['access:apm', 'access:apm_settings_write'], + access: 'public', + }, + params: t.partial({ + query: t.intersection([ + t.partial({ serviceName: t.string }), + t.partial({ serviceEnvironment: t.string }), + ]), + }), + handler: async (resources): Promise<{ result: string }> => { + throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags); + + const { params, logger, core, telemetryUsageCounter } = resources; + const { serviceName, serviceEnvironment } = params.query; + const name = serviceName ? decodeURIComponent(serviceName) : undefined; + const environment = serviceEnvironment ? decodeURIComponent(serviceEnvironment) : undefined; + const service = { + name, + environment, + }; + const apmIndices = await resources.getApmIndices(); const [internalESClient, apmEventClient] = await Promise.all([ createInternalESClientWithResources(resources), @@ -347,7 +412,8 @@ const agentConfigurationAgentNameRoute = createApmServerRoute({ export const agentConfigurationRouteRepository = { ...agentConfigurationRoute, ...getSingleAgentConfigurationRoute, - ...deleteAgentConfigurationRoute, + ...deleteAgentConfigurationBodyRoute, + ...deleteAgentConfigurationQueryRoute, ...createOrUpdateAgentConfigurationRoute, ...agentConfigurationSearchRoute, ...listAgentConfigurationEnvironmentsRoute, diff --git a/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts b/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts index 5ffc8c29c3495..eb47c774aab9b 100644 --- a/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts +++ b/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts @@ -55,7 +55,7 @@ export default function featureControlsTests({ getService }: FtrProviderContext) } function deleteAgent( - body: APIClientRequestParamsOf<'DELETE /api/apm/settings/agent-configuration 2023-10-31'>['params']['body'] + query: APIClientRequestParamsOf<'DELETE /api/apm/settings/agent-configuration 2023-10-31'>['params']['body'] ) { return apmApiClient.writeUser({ endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31', diff --git a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts index 9ef09aaf58cb0..d67a58cbac95d 100644 --- a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts +++ b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts @@ -53,10 +53,24 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { }); } + async function deleteConfigurationQuery(configuration: any) { + return apmApiClient.writeUser({ + endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31', + params: { + query: { + name: configuration.service.name, + environment: configuration.service.environment, + }, + }, + }); + } + async function deleteConfiguration(configuration: any) { return apmApiClient.writeUser({ endpoint: 'DELETE /api/apm/settings/agent-configuration 2023-10-31', - params: { body: { service: configuration.service } }, + params: { + body: { service: configuration.service }, + }, }); } @@ -196,6 +210,29 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { }); }); + describe('Agent config with query DELETE', () => { + let packagePolicyWithAgentConfig: PackagePolicy; + const testConfiguration = { + service: {}, + settings: { transaction_sample_rate: '0.55' }, + }; + before(async () => { + await createConfiguration(testConfiguration); + packagePolicyWithAgentConfig = await getPackagePolicy(bettertest, packagePolicyId); + }); + + after(async () => { + await deleteConfigurationQuery(testConfiguration); + }); + + it('sets the expected agent configs on the new package policy object', async () => { + const agentConfigs = get(packagePolicyWithAgentConfig, AGENT_CONFIG_PATH)!; + const { service, config } = agentConfigs[0]; + expect(service).to.eql({}); + expect(config).to.eql({ transaction_sample_rate: '0.55' }); + }); + }); + describe('Source maps', () => { let resp: APIReturnType<'POST /api/apm/sourcemaps 2023-10-31'>; diff --git a/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts b/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts index a490c89a32778..cfd0bc73c96ff 100644 --- a/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts +++ b/x-pack/test/apm_api_integration/tests/settings/agent_configuration/agent_configuration.spec.ts @@ -95,7 +95,7 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte return apmApiClient.readUser({ endpoint: 'GET /api/apm/settings/agent-configuration/view 2023-10-31', params: { - query: { + body: { name, environment, },