[Fleet] Handle ID's for preconfigured package policies (#120664) (#120761)

* Handle ID's for preconfigured package policies

- For Fleet's default policies, add a hard-coded ID to the generated
  package policies
- Require an ID value for all preconfigured package policies

Resolves #120612

* Add required package_policies.id field to docs

* Specify that id is unique in docs

* Tweak docs

* Fall back to UUID value if no preconfigured ID

* Fix default fleet server policy id
# Conflicts:
#	x-pack/plugins/fleet/server/services/agent_policy.ts
#	x-pack/plugins/fleet/server/types/models/preconfiguration.ts
This commit is contained in:
Kyle Pollich 2021-12-08 10:17:34 -05:00 committed by GitHub
parent 2c4032df0f
commit c50e53100e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 28 additions and 1 deletions

View file

@ -90,6 +90,7 @@ Optional properties are:
`data_output_id`:: ID of the output to send data (Need to be identical to `monitoring_output_id`)
`monitoring_output_id`:: ID of the output to send monitoring data. (Need to be identical to `data_output_id`)
`package_policies`:: List of integration policies to add to this policy.
`id`::: Unique ID of the integration policy. The ID may be a number or string.
`name`::: (required) Name of the integration policy.
`package`::: (required) Integration that this policy configures
`name`:::: Name of the integration associated with this policy.
@ -131,6 +132,7 @@ xpack.fleet.agentPolicies:
- package:
name: system
name: System Integration
id: preconfigured-system
inputs:
- type: system/metrics
enabled: true

View file

@ -27,12 +27,15 @@ type PreconfiguredAgentPolicyWithDefaultInputs = Omit<
package_policies: Array<Omit<PreconfiguredAgentPolicy['package_policies'][0], 'inputs'>>;
};
export const DEFAULT_SYSTEM_PACKAGE_POLICY_ID = 'default-system-policy';
export const DEFAULT_AGENT_POLICY: PreconfiguredAgentPolicyWithDefaultInputs = {
name: 'Default policy',
namespace: 'default',
description: 'Default agent policy created by Kibana',
package_policies: [
{
id: DEFAULT_SYSTEM_PACKAGE_POLICY_ID,
name: `${FLEET_SYSTEM_PACKAGE}-1`,
package: {
name: FLEET_SYSTEM_PACKAGE,
@ -44,12 +47,15 @@ export const DEFAULT_AGENT_POLICY: PreconfiguredAgentPolicyWithDefaultInputs = {
monitoring_enabled: monitoringTypes,
};
export const DEFAULT_FLEET_SERVER_POLICY_ID = 'default-fleet-server-policy';
export const DEFAULT_FLEET_SERVER_AGENT_POLICY: PreconfiguredAgentPolicyWithDefaultInputs = {
name: 'Default Fleet Server policy',
namespace: 'default',
description: 'Default Fleet Server agent policy created by Kibana',
package_policies: [
{
id: DEFAULT_FLEET_SERVER_POLICY_ID,
name: `${FLEET_SERVER_PACKAGE}-1`,
package: {
name: FLEET_SERVER_PACKAGE,

View file

@ -56,6 +56,7 @@ export interface PackagePolicyInput extends Omit<NewPackagePolicyInput, 'streams
}
export interface NewPackagePolicy {
id?: string | number;
name: string;
description?: string;
namespace: string;

View file

@ -25,6 +25,7 @@ export interface PreconfiguredAgentPolicy extends Omit<NewAgentPolicy, 'namespac
namespace?: string;
package_policies: Array<
Partial<Omit<NewPackagePolicy, 'inputs' | 'package'>> & {
id?: string | number;
name: string;
package: Partial<PackagePolicyPackage> & { name: string };
inputs?: InputsOverride[];

View file

@ -7,6 +7,7 @@
import { uniq, omit } from 'lodash';
import uuid from 'uuid/v4';
import uuidv5 from 'uuid/v5';
import type {
ElasticsearchClient,
SavedObjectsClientContract,
@ -57,8 +58,12 @@ import { agentPolicyUpdateEventHandler } from './agent_policy_update';
import { normalizeKuery, escapeSearchQueryPhrase } from './saved_object';
import { appContextService } from './app_context';
import { getFullAgentPolicy } from './agent_policies';
const SAVED_OBJECT_TYPE = AGENT_POLICY_SAVED_OBJECT_TYPE;
// UUID v5 values require a namespace
const UUID_V5_NAMESPACE = 'dde7c2de-1370-4c19-9975-b473d0e03508';
class AgentPolicyService {
private triggerAgentPolicyUpdatedEvent = async (
soClient: SavedObjectsClientContract,
@ -780,6 +785,7 @@ export async function addPackageToAgentPolicy(
agentPolicy: AgentPolicy,
defaultOutput: Output,
packagePolicyName?: string,
packagePolicyId?: string | number,
packagePolicyDescription?: string,
transformPackagePolicy?: (p: NewPackagePolicy) => NewPackagePolicy
) {
@ -802,7 +808,14 @@ export async function addPackageToAgentPolicy(
? transformPackagePolicy(basePackagePolicy)
: basePackagePolicy;
// If an ID is provided via preconfiguration, use that value. Otherwise fall back to
// a UUID v5 value seeded from the agent policy's ID and the provided package policy name.
const id = packagePolicyId
? String(packagePolicyId)
: uuidv5(`${agentPolicy.id}-${packagePolicyName}`, UUID_V5_NAMESPACE);
await packagePolicyService.create(soClient, esClient, newPackagePolicy, {
id,
bumpRevision: false,
skipEnsureInstalled: true,
});

View file

@ -332,6 +332,7 @@ describe('policy preconfiguration', () => {
id: 'test-id',
package_policies: [
{
id: 'test-package',
package: { name: 'test_package' },
name: 'Test package',
},

View file

@ -406,6 +406,7 @@ async function addPreconfiguredPolicyPackages(
agentPolicy: AgentPolicy,
installedPackagePolicies: Array<
Partial<Omit<NewPackagePolicy, 'inputs'>> & {
id?: string | number;
name: string;
installedPackage: Installation;
inputs?: InputsOverride[];
@ -414,7 +415,7 @@ async function addPreconfiguredPolicyPackages(
defaultOutput: Output
) {
// Add packages synchronously to avoid overwriting
for (const { installedPackage, name, description, inputs } of installedPackagePolicies) {
for (const { installedPackage, id, name, description, inputs } of installedPackagePolicies) {
const packageInfo = await getPackageInfo({
savedObjectsClient: soClient,
pkgName: installedPackage.name,
@ -428,6 +429,7 @@ async function addPreconfiguredPolicyPackages(
agentPolicy,
defaultOutput,
name,
id,
description,
(policy) => preconfigurePackageInputs(policy, packageInfo, inputs)
);

View file

@ -97,6 +97,7 @@ export const PreconfiguredAgentPoliciesSchema = schema.arrayOf(
monitoring_output_id: schema.maybe(schema.string()),
package_policies: schema.arrayOf(
schema.object({
id: schema.maybe(schema.oneOf([schema.string(), schema.number()])),
name: schema.string(),
package: schema.object({
name: schema.string(),