Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion x-pack/plugins/apm/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"security",
"ml",
"home",
"maps"
"maps",
"fleet"
],
"server": true,
"ui": true,
Expand Down
122 changes: 122 additions & 0 deletions x-pack/plugins/apm/server/lib/fleet/register_fleet_policy_callbacks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* 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 { APMPlugin, APMRouteHandlerResources } from '../..';
import { listConfigurations } from '../settings/agent_configuration/list_configurations';
import { setupRequest } from '../helpers/setup_request';
import { APMPluginStartDependencies } from '../../types';
import { ExternalCallback } from '../../../../fleet/server';
import { AGENT_NAME } from '../../../common/elasticsearch_fieldnames';
import { AgentConfiguration } from '../../../common/agent_configuration/configuration_types';

export async function registerFleetPolicyCallbacks({
plugins,
ruleDataClient,
config,
logger,
}: {
plugins: APMRouteHandlerResources['plugins'];
ruleDataClient: APMRouteHandlerResources['ruleDataClient'];
config: NonNullable<APMPlugin['currentConfig']>;
logger: NonNullable<APMPlugin['logger']>;
}) {
if (!plugins.fleet) {
return;
}
const fleetPluginStart = await plugins.fleet.start();

registerAgentConfigExternalCallback({
Comment thread
cauemarcondes marked this conversation as resolved.
fleetPluginStart,
callbackName: 'packagePolicyCreate',
Comment thread
cauemarcondes marked this conversation as resolved.
plugins,
ruleDataClient,
config,
logger,
});
registerAgentConfigExternalCallback({
fleetPluginStart,
callbackName: 'packagePolicyUpdate',
plugins,
ruleDataClient,
config,
logger,
});
}

type ExternalCallbackParams = Parameters<ExternalCallback[1]>;
type PackagePolicy = ExternalCallbackParams[0];
type Context = ExternalCallbackParams[1];
type Request = ExternalCallbackParams[2];

function registerAgentConfigExternalCallback({
fleetPluginStart,
callbackName,
plugins,
ruleDataClient,
config,
logger,
}: {
fleetPluginStart: NonNullable<APMPluginStartDependencies['fleet']>;
callbackName: ExternalCallback[0];
plugins: APMRouteHandlerResources['plugins'];
ruleDataClient: APMRouteHandlerResources['ruleDataClient'];
config: NonNullable<APMPlugin['currentConfig']>;
logger: NonNullable<APMPlugin['logger']>;
}) {
const callbackFn: ExternalCallback[1] = async (
packagePolicy: PackagePolicy,
context: Context,
request: Request
) => {
if (packagePolicy.package?.name !== 'apm') {
return packagePolicy;
}
const setup = await setupRequest({
context: context as any,
params: { query: { _inspect: false } },
core: null as any,
plugins,
request,
config,
logger,
ruleDataClient,
});
const agentConfigurations = await listConfigurations({ setup });
return getPackagePolicyWithAgentConfigurations(
packagePolicy,
agentConfigurations
);
};

fleetPluginStart.registerExternalCallback(callbackName, callbackFn);
}

export function getPackagePolicyWithAgentConfigurations(
packagePolicy: PackagePolicy,
agentConfigurations: AgentConfiguration[]
) {
const [firstInput, ...restInputs] = packagePolicy.inputs;
return {
...packagePolicy,
inputs: [
{
...firstInput,
config: {
agent_config: {
value: agentConfigurations.map((configuration) => ({
service: configuration.service,
config: configuration.settings,
etag: configuration.etag,
[AGENT_NAME]: configuration.agent_name,
})),
},
},
},
...restInputs,
],
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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 {
CoreSetup,
CoreStart,
SavedObjectsClientContract,
} from 'kibana/server';
import { APMPluginStartDependencies } from '../../types';
import { getInternalSavedObjectsClient } from '../helpers/get_internal_saved_objects_client';
import { Setup } from '../helpers/setup_request';
import { listConfigurations } from '../settings/agent_configuration/list_configurations';
import { getPackagePolicyWithAgentConfigurations } from './register_fleet_policy_callbacks';

export async function syncAgentConfigsToApmPackagePolicies({
core,
fleetPluginStart,
setup,
}: {
core: { setup: CoreSetup; start: () => Promise<CoreStart> };
fleetPluginStart: NonNullable<APMPluginStartDependencies['fleet']>;
setup: Setup;
}) {
const coreStart = await core.start();
const esClient = coreStart.elasticsearch.client.asInternalUser;
// @ts-ignore
const savedObjectsClient: SavedObjectsClientContract = await getInternalSavedObjectsClient(
core.setup
);
const agentConfigurations = await listConfigurations({ setup });
const packagePolicies = await fleetPluginStart.packagePolicyService.list(
savedObjectsClient,
{ kuery: 'ingest-package-policies.package.name:apm' }
);

return Promise.all(
packagePolicies.items.map(async (item) => {
const { id, revision, updated_at, updated_by, ...packagePolicy } = item; // eslint-disable-line @typescript-eslint/naming-convention
const updatedPackagePolicy = getPackagePolicyWithAgentConfigurations(
packagePolicy,
agentConfigurations
);
return fleetPluginStart.packagePolicyService.update(
savedObjectsClient,
esClient,
id,
updatedPackagePolicy
);
})
);
}
34 changes: 22 additions & 12 deletions x-pack/plugins/apm/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { mergeConfigs } from './index';
import { UI_SETTINGS } from '../../../../src/plugins/data/common';
import { APM_FEATURE, registerFeaturesUsage } from './feature';
import { registerApmAlerts } from './lib/alerts/register_apm_alerts';
import { registerFleetPolicyCallbacks } from './lib/fleet/register_fleet_policy_callbacks';
import { createApmTelemetry } from './lib/apm_telemetry';
import { createApmEventClient } from './lib/helpers/create_es_client/create_apm_event_client';
import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client';
Expand Down Expand Up @@ -196,6 +197,19 @@ export class APMPlugin
ready,
});

const resourcePlugins = mapValues(plugins, (value, key) => {
return {
setup: value,
start: () =>
core.getStartServices().then((services) => {
const [, pluginsStartContracts] = services;
return pluginsStartContracts[
key as keyof APMPluginStartDependencies
];
}),
};
}) as APMRouteHandlerResources['plugins'];

registerRoutes({
core: {
setup: core,
Expand All @@ -205,18 +219,7 @@ export class APMPlugin
config: currentConfig,
repository: getGlobalApmServerRouteRepository(),
ruleDataClient,
plugins: mapValues(plugins, (value, key) => {
return {
setup: value,
start: () =>
core.getStartServices().then((services) => {
const [, pluginsStartContracts] = services;
return pluginsStartContracts[
key as keyof APMPluginStartDependencies
];
}),
};
}) as APMRouteHandlerResources['plugins'],
plugins: resourcePlugins,
});

const boundGetApmIndices = async () =>
Expand All @@ -235,6 +238,13 @@ export class APMPlugin
});
}

registerFleetPolicyCallbacks({
plugins: resourcePlugins,
ruleDataClient,
config: this.currentConfig,
logger: this.logger,
});

return {
config$: mergedConfig$,
getApmIndices: boundGetApmIndices,
Expand Down
14 changes: 13 additions & 1 deletion x-pack/plugins/apm/server/routes/settings/agent_configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from '../../../common/agent_configuration/runtime_types/agent_configuration_intake_rt';
import { getSearchAggregatedTransactions } from '../../lib/helpers/aggregated_transactions';
import { createApmServerRouteRepository } from '../create_apm_server_route_repository';
import { syncAgentConfigsToApmPackagePolicies } from '../../lib/fleet/sync_agent_configs_to_apm_package_policies';

// get list of configurations
const agentConfigurationRoute = createApmServerRoute({
Expand Down Expand Up @@ -114,7 +115,7 @@ const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
]),
handler: async (resources) => {
const setup = await setupRequest(resources);
const { params, logger } = resources;
const { params, logger, core } = resources;
const { body, query } = params;

// if the config already exists, it is fetched and updated
Expand Down Expand Up @@ -142,6 +143,17 @@ const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
configurationIntake: body,
setup,
});

if (resources.plugins.fleet) {
await syncAgentConfigsToApmPackagePolicies({
core,
fleetPluginStart: await resources.plugins.fleet.start(),
setup,
});
logger.info(
`Saved latest agent settings to Fleet integration policy for APM.`
);
}
},
});

Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/apm/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ import {
TaskManagerSetupContract,
TaskManagerStartContract,
} from '../../task_manager/server';
import {
FleetSetupContract as FleetPluginSetup,
FleetStartContract as FleetPluginStart,
} from '../../fleet/server';
import { APMConfig } from '.';
import { getApmIndices } from './lib/settings/apm_indices/get_apm_indices';
import { createApmEventClient } from './lib/helpers/create_es_client/create_apm_event_client';
Expand Down Expand Up @@ -123,6 +127,10 @@ interface DependencyMap {
setup: RuleRegistryPluginSetupContract;
start: RuleRegistryPluginStartContract;
};
fleet: {
setup: FleetPluginSetup;
start: FleetPluginStart;
};
}

const requiredDependencies = [
Expand All @@ -148,6 +156,7 @@ const optionalDependencies = [
'ml',
'home',
'maps',
'fleet',
] as const;

type RequiredDependencies = Pick<
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/apm/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
{ "path": "../rule_registry/tsconfig.json" },
{ "path": "../security/tsconfig.json" },
{ "path": "../task_manager/tsconfig.json" },
{ "path": "../triggers_actions_ui/tsconfig.json" }
{ "path": "../triggers_actions_ui/tsconfig.json" },
{ "path": "../fleet/tsconfig.json" }
]
}