mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Fleet] Fix preconfiguration variable values (#119749)
This commit is contained in:
parent
a0ca3d90bc
commit
9f47e386c9
3 changed files with 909 additions and 38 deletions
|
@ -39,7 +39,8 @@ import type {
|
|||
import { IngestManagerError } from '../errors';
|
||||
|
||||
import {
|
||||
overridePackageInputs,
|
||||
preconfigurePackageInputs,
|
||||
updatePackageInputs,
|
||||
packagePolicyService,
|
||||
_applyIndexPrivileges,
|
||||
} from './package_policy';
|
||||
|
@ -1170,7 +1171,776 @@ describe('Package policy service', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('overridePackageInputs', () => {
|
||||
describe('preconfigurePackageInputs', () => {
|
||||
describe('when variable is already defined', () => {
|
||||
it('override original variable value', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
name: 'base-package-policy',
|
||||
description: 'Base Package Policy',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'xxxx',
|
||||
output_id: 'xxxx',
|
||||
package: {
|
||||
name: 'test-package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_1',
|
||||
enabled: true,
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: ['/var/log/logfile.log'],
|
||||
},
|
||||
},
|
||||
streams: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const packageInfo: PackageInfo = {
|
||||
name: 'test-package',
|
||||
description: 'Test Package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
latestVersion: '0.0.1',
|
||||
release: 'experimental',
|
||||
format_version: '1.0.0',
|
||||
owner: { github: 'elastic/fleet' },
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'template_1',
|
||||
title: 'Template 1',
|
||||
description: 'Template 1',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [
|
||||
{
|
||||
name: 'path',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// @ts-ignore
|
||||
assets: {},
|
||||
};
|
||||
|
||||
const inputsOverride: NewPackagePolicyInput[] = [
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: '/var/log/new-logfile.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const result = preconfigurePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
// that it no longer causes unresolvable type errors when used directly
|
||||
inputsOverride as InputsOverride[]
|
||||
);
|
||||
expect(result.inputs[0]?.vars?.path.value).toEqual('/var/log/new-logfile.log');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when variable is undefined in original object', () => {
|
||||
it('adds the variable definition to the resulting object', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
name: 'base-package-policy',
|
||||
description: 'Base Package Policy',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'xxxx',
|
||||
output_id: 'xxxx',
|
||||
package: {
|
||||
name: 'test-package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_1',
|
||||
enabled: true,
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: ['/var/log/logfile.log'],
|
||||
},
|
||||
},
|
||||
streams: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const packageInfo: PackageInfo = {
|
||||
name: 'test-package',
|
||||
description: 'Test Package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
latestVersion: '0.0.1',
|
||||
release: 'experimental',
|
||||
format_version: '1.0.0',
|
||||
owner: { github: 'elastic/fleet' },
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'template_1',
|
||||
title: 'Template 1',
|
||||
description: 'Template 1',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [
|
||||
{
|
||||
name: 'path',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'path_2',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// @ts-ignore
|
||||
assets: {},
|
||||
};
|
||||
|
||||
const inputsOverride: NewPackagePolicyInput[] = [
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
policy_template: 'template_1',
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: '/var/log/new-logfile.log',
|
||||
},
|
||||
path_2: {
|
||||
type: 'text',
|
||||
value: '/var/log/custom.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const result = preconfigurePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
// that it no longer causes unresolvable type errors when used directly
|
||||
inputsOverride as InputsOverride[]
|
||||
);
|
||||
|
||||
expect(result.inputs[0]?.vars?.path_2.value).toEqual('/var/log/custom.log');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when variable is undefined in original object and policy_template is undefined', () => {
|
||||
it('adds the variable definition to the resulting object', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
name: 'base-package-policy',
|
||||
description: 'Base Package Policy',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'xxxx',
|
||||
output_id: 'xxxx',
|
||||
package: {
|
||||
name: 'test-package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_1',
|
||||
enabled: true,
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: ['/var/log/logfile.log'],
|
||||
},
|
||||
},
|
||||
streams: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const packageInfo: PackageInfo = {
|
||||
name: 'test-package',
|
||||
description: 'Test Package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
latestVersion: '0.0.1',
|
||||
release: 'experimental',
|
||||
format_version: '1.0.0',
|
||||
owner: { github: 'elastic/fleet' },
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'template_1',
|
||||
title: 'Template 1',
|
||||
description: 'Template 1',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [
|
||||
{
|
||||
name: 'path',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'path_2',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// @ts-ignore
|
||||
assets: {},
|
||||
};
|
||||
|
||||
const inputsOverride: NewPackagePolicyInput[] = [
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
policy_template: undefined, // preconfigured input overrides don't have a policy_template
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: '/var/log/new-logfile.log',
|
||||
},
|
||||
path_2: {
|
||||
type: 'text',
|
||||
value: '/var/log/custom.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const result = preconfigurePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
// that it no longer causes unresolvable type errors when used directly
|
||||
inputsOverride as InputsOverride[]
|
||||
);
|
||||
|
||||
expect(result.inputs[0]?.vars?.path_2.value).toEqual('/var/log/custom.log');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an input of the same type exists under multiple policy templates', () => {
|
||||
it('adds variable definitions to the proper streams', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
name: 'base-package-policy',
|
||||
description: 'Base Package Policy',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'xxxx',
|
||||
output_id: 'xxxx',
|
||||
package: {
|
||||
name: 'test-package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_1',
|
||||
enabled: true,
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_2',
|
||||
enabled: true,
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const packageInfo: PackageInfo = {
|
||||
name: 'test-package',
|
||||
description: 'Test Package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
latestVersion: '0.0.1',
|
||||
release: 'experimental',
|
||||
format_version: '1.0.0',
|
||||
owner: { github: 'elastic/fleet' },
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'template_1',
|
||||
title: 'Template 1',
|
||||
description: 'Template 1',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'template_2',
|
||||
title: 'Template 2',
|
||||
description: 'Template 2',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// @ts-ignore
|
||||
assets: {},
|
||||
};
|
||||
|
||||
const inputsOverride: NewPackagePolicyInput[] = [
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
policy_template: 'template_1',
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
value: '/var/log/template1-logfile.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
policy_template: 'template_2',
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
value: '/var/log/template2-logfile.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const result = preconfigurePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
// that it no longer causes unresolvable type errors when used directly
|
||||
inputsOverride as InputsOverride[]
|
||||
);
|
||||
|
||||
expect(result.inputs).toHaveLength(2);
|
||||
|
||||
const template1Input = result.inputs.find(
|
||||
(input) => input.policy_template === 'template_1'
|
||||
);
|
||||
const template2Input = result.inputs.find(
|
||||
(input) => input.policy_template === 'template_2'
|
||||
);
|
||||
|
||||
expect(template1Input).toBeDefined();
|
||||
expect(template2Input).toBeDefined();
|
||||
|
||||
expect(template1Input?.streams[0].vars?.log_file_path.value).toBe(
|
||||
'/var/log/template1-logfile.log'
|
||||
);
|
||||
|
||||
expect(template2Input?.streams[0].vars?.log_file_path.value).toBe(
|
||||
'/var/log/template2-logfile.log'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when an input or stream is disabled on the original policy object', () => {
|
||||
it('remains disabled on the resulting policy object', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
name: 'base-package-policy',
|
||||
description: 'Base Package Policy',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'xxxx',
|
||||
output_id: 'xxxx',
|
||||
package: {
|
||||
name: 'test-package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_1',
|
||||
enabled: false,
|
||||
streams: [
|
||||
{
|
||||
enabled: false,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile2',
|
||||
},
|
||||
vars: {
|
||||
log_file_path_2: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'logs_2',
|
||||
policy_template: 'template_1',
|
||||
enabled: true,
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_2',
|
||||
enabled: true,
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const packageInfo: PackageInfo = {
|
||||
name: 'test-package',
|
||||
description: 'Test Package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
latestVersion: '0.0.1',
|
||||
release: 'experimental',
|
||||
format_version: '1.0.0',
|
||||
owner: { github: 'elastic/fleet' },
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'template_1',
|
||||
title: 'Template 1',
|
||||
description: 'Template 1',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [],
|
||||
},
|
||||
{
|
||||
type: 'logs_2',
|
||||
title: 'Log 2',
|
||||
description: 'Log Input 2',
|
||||
vars: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'template_2',
|
||||
title: 'Template 2',
|
||||
description: 'Template 2',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// @ts-ignore
|
||||
assets: {},
|
||||
};
|
||||
|
||||
const inputsOverride: NewPackagePolicyInput[] = [
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
policy_template: 'template_1',
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
value: '/var/log/template1-logfile.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile2',
|
||||
},
|
||||
vars: {
|
||||
log_file_path_2: {
|
||||
type: 'text',
|
||||
value: '/var/log/template1-logfile2.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
policy_template: 'template_2',
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: {
|
||||
dataset: 'test.logs',
|
||||
type: 'logfile',
|
||||
},
|
||||
vars: {
|
||||
log_file_path: {
|
||||
type: 'text',
|
||||
value: '/var/log/template2-logfile.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const result = preconfigurePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
// that it no longer causes unresolvable type errors when used directly
|
||||
inputsOverride as InputsOverride[]
|
||||
);
|
||||
|
||||
const template1Inputs = result.inputs.filter(
|
||||
(input) => input.policy_template === 'template_1'
|
||||
);
|
||||
|
||||
const template2Inputs = result.inputs.filter(
|
||||
(input) => input.policy_template === 'template_2'
|
||||
);
|
||||
|
||||
expect(template1Inputs).toHaveLength(2);
|
||||
expect(template2Inputs).toHaveLength(1);
|
||||
|
||||
const logsInput = template1Inputs?.find((input) => input.type === 'logs');
|
||||
expect(logsInput?.enabled).toBe(false);
|
||||
|
||||
const logfileStream = logsInput?.streams.find(
|
||||
(stream) => stream.data_stream.type === 'logfile'
|
||||
);
|
||||
|
||||
expect(logfileStream?.enabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a datastream is deleted from an input', () => {
|
||||
it('it remove the non existing datastream', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
name: 'base-package-policy',
|
||||
description: 'Base Package Policy',
|
||||
namespace: 'default',
|
||||
enabled: true,
|
||||
policy_id: 'xxxx',
|
||||
output_id: 'xxxx',
|
||||
package: {
|
||||
name: 'test-package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
},
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
policy_template: 'template_1',
|
||||
enabled: true,
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: ['/var/log/logfile.log'],
|
||||
},
|
||||
},
|
||||
streams: [
|
||||
{
|
||||
enabled: true,
|
||||
data_stream: { dataset: 'dataset.test123', type: 'log' },
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const packageInfo: PackageInfo = {
|
||||
name: 'test-package',
|
||||
description: 'Test Package',
|
||||
title: 'Test Package',
|
||||
version: '0.0.1',
|
||||
latestVersion: '0.0.1',
|
||||
release: 'experimental',
|
||||
format_version: '1.0.0',
|
||||
owner: { github: 'elastic/fleet' },
|
||||
policy_templates: [
|
||||
{
|
||||
name: 'template_1',
|
||||
title: 'Template 1',
|
||||
description: 'Template 1',
|
||||
inputs: [
|
||||
{
|
||||
type: 'logs',
|
||||
title: 'Log',
|
||||
description: 'Log Input',
|
||||
vars: [
|
||||
{
|
||||
name: 'path',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
// @ts-ignore
|
||||
assets: {},
|
||||
};
|
||||
|
||||
const inputsOverride: NewPackagePolicyInput[] = [
|
||||
{
|
||||
type: 'logs',
|
||||
enabled: true,
|
||||
streams: [],
|
||||
vars: {
|
||||
path: {
|
||||
type: 'text',
|
||||
value: '/var/log/new-logfile.log',
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const result = preconfigurePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
// that it no longer causes unresolvable type errors when used directly
|
||||
inputsOverride as InputsOverride[]
|
||||
);
|
||||
expect(result.inputs[0]?.vars?.path.value).toEqual('/var/log/new-logfile.log');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('updatePackageInputs', () => {
|
||||
describe('when variable is already defined', () => {
|
||||
it('preserves original variable value without overwriting', () => {
|
||||
const basePackagePolicy: NewPackagePolicy = {
|
||||
|
@ -1248,7 +2018,7 @@ describe('Package policy service', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const result = overridePackageInputs(
|
||||
const result = updatePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
|
@ -1346,7 +2116,7 @@ describe('Package policy service', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const result = overridePackageInputs(
|
||||
const result = updatePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
|
@ -1445,7 +2215,7 @@ describe('Package policy service', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const result = overridePackageInputs(
|
||||
const result = updatePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
|
@ -1598,7 +2368,7 @@ describe('Package policy service', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const result = overridePackageInputs(
|
||||
const result = updatePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
|
@ -1819,7 +2589,7 @@ describe('Package policy service', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const result = overridePackageInputs(
|
||||
const result = updatePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
|
@ -1932,7 +2702,7 @@ describe('Package policy service', () => {
|
|||
},
|
||||
];
|
||||
|
||||
const result = overridePackageInputs(
|
||||
const result = updatePackageInputs(
|
||||
basePackagePolicy,
|
||||
packageInfo,
|
||||
// TODO: Update this type assertion when the `InputsOverride` type is updated such
|
||||
|
|
|
@ -590,7 +590,7 @@ class PackagePolicyService {
|
|||
try {
|
||||
const { packagePolicy, packageInfo } = await this.getUpgradePackagePolicyInfo(soClient, id);
|
||||
|
||||
const updatePackagePolicy = overridePackageInputs(
|
||||
const updatePackagePolicy = updatePackageInputs(
|
||||
{
|
||||
...omit(packagePolicy, 'id'),
|
||||
inputs: packagePolicy.inputs,
|
||||
|
@ -648,7 +648,7 @@ class PackagePolicyService {
|
|||
packageVersion
|
||||
);
|
||||
|
||||
const updatedPackagePolicy = overridePackageInputs(
|
||||
const updatedPackagePolicy = updatePackageInputs(
|
||||
{
|
||||
...omit(packagePolicy, 'id'),
|
||||
inputs: packagePolicy.inputs,
|
||||
|
@ -1030,13 +1030,13 @@ export const packagePolicyService = new PackagePolicyService();
|
|||
|
||||
export type { PackagePolicyService };
|
||||
|
||||
export function overridePackageInputs(
|
||||
export function updatePackageInputs(
|
||||
basePackagePolicy: NewPackagePolicy,
|
||||
packageInfo: PackageInfo,
|
||||
inputsOverride?: InputsOverride[],
|
||||
inputsUpdated?: InputsOverride[],
|
||||
dryRun?: boolean
|
||||
): DryRunPackagePolicy {
|
||||
if (!inputsOverride) return basePackagePolicy;
|
||||
if (!inputsUpdated) return basePackagePolicy;
|
||||
|
||||
const availablePolicyTemplates = packageInfo.policy_templates ?? [];
|
||||
|
||||
|
@ -1065,42 +1065,40 @@ export function overridePackageInputs(
|
|||
}),
|
||||
];
|
||||
|
||||
for (const override of inputsOverride) {
|
||||
// Preconfiguration does not currently support multiple policy templates, so overrides will have an undefined
|
||||
// policy template, so we only match on `type` in that case.
|
||||
let originalInput = override.policy_template
|
||||
? inputs.find(
|
||||
(i) => i.type === override.type && i.policy_template === override.policy_template
|
||||
)
|
||||
: inputs.find((i) => i.type === override.type);
|
||||
for (const update of inputsUpdated) {
|
||||
// If update have an undefined policy template
|
||||
// we only match on `type` .
|
||||
let originalInput = update.policy_template
|
||||
? inputs.find((i) => i.type === update.type && i.policy_template === update.policy_template)
|
||||
: inputs.find((i) => i.type === update.type);
|
||||
|
||||
// If there's no corresponding input on the original package policy, just
|
||||
// take the override value from the new package as-is. This case typically
|
||||
// occurs when inputs or package policy templates are added/removed between versions.
|
||||
if (originalInput === undefined) {
|
||||
inputs.push(override as NewPackagePolicyInput);
|
||||
inputs.push(update as NewPackagePolicyInput);
|
||||
continue;
|
||||
}
|
||||
|
||||
// For flags like this, we only want to override the original value if it was set
|
||||
// as `undefined` in the original object. An explicit true/false value should be
|
||||
// persisted from the original object to the result after the override process is complete.
|
||||
if (originalInput.enabled === undefined && override.enabled !== undefined) {
|
||||
originalInput.enabled = override.enabled;
|
||||
if (originalInput.enabled === undefined && update.enabled !== undefined) {
|
||||
originalInput.enabled = update.enabled;
|
||||
}
|
||||
|
||||
if (originalInput.keep_enabled === undefined && override.keep_enabled !== undefined) {
|
||||
originalInput.keep_enabled = override.keep_enabled;
|
||||
if (originalInput.keep_enabled === undefined && update.keep_enabled !== undefined) {
|
||||
originalInput.keep_enabled = update.keep_enabled;
|
||||
}
|
||||
|
||||
if (override.vars) {
|
||||
if (update.vars) {
|
||||
const indexOfInput = inputs.indexOf(originalInput);
|
||||
inputs[indexOfInput] = deepMergeVars(originalInput, override) as NewPackagePolicyInput;
|
||||
inputs[indexOfInput] = deepMergeVars(originalInput, update, true) as NewPackagePolicyInput;
|
||||
originalInput = inputs[indexOfInput];
|
||||
}
|
||||
|
||||
if (override.streams) {
|
||||
for (const stream of override.streams) {
|
||||
if (update.streams) {
|
||||
for (const stream of update.streams) {
|
||||
let originalStream = originalInput?.streams.find(
|
||||
(s) => s.data_stream.dataset === stream.data_stream.dataset
|
||||
);
|
||||
|
@ -1118,7 +1116,8 @@ export function overridePackageInputs(
|
|||
const indexOfStream = originalInput.streams.indexOf(originalStream);
|
||||
originalInput.streams[indexOfStream] = deepMergeVars(
|
||||
originalStream,
|
||||
stream as InputsOverride
|
||||
stream as InputsOverride,
|
||||
true
|
||||
);
|
||||
originalStream = originalInput.streams[indexOfStream];
|
||||
}
|
||||
|
@ -1128,9 +1127,8 @@ export function overridePackageInputs(
|
|||
// Filter all stream that have been removed from the input
|
||||
originalInput.streams = originalInput.streams.filter((originalStream) => {
|
||||
return (
|
||||
override.streams?.some(
|
||||
(s) => s.data_stream.dataset === originalStream.data_stream.dataset
|
||||
) ?? false
|
||||
update.streams?.some((s) => s.data_stream.dataset === originalStream.data_stream.dataset) ??
|
||||
false
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -1171,7 +1169,110 @@ export function overridePackageInputs(
|
|||
return resultingPackagePolicy;
|
||||
}
|
||||
|
||||
function deepMergeVars(original: any, override: any): any {
|
||||
export function preconfigurePackageInputs(
|
||||
basePackagePolicy: NewPackagePolicy,
|
||||
packageInfo: PackageInfo,
|
||||
preconfiguredInputs?: InputsOverride[]
|
||||
): NewPackagePolicy {
|
||||
if (!preconfiguredInputs) return basePackagePolicy;
|
||||
|
||||
const inputs = [...basePackagePolicy.inputs];
|
||||
|
||||
for (const preconfiguredInput of preconfiguredInputs) {
|
||||
// Preconfiguration does not currently support multiple policy templates, so overrides will have an undefined
|
||||
// policy template, so we only match on `type` in that case.
|
||||
let originalInput = preconfiguredInput.policy_template
|
||||
? inputs.find(
|
||||
(i) =>
|
||||
i.type === preconfiguredInput.type &&
|
||||
i.policy_template === preconfiguredInput.policy_template
|
||||
)
|
||||
: inputs.find((i) => i.type === preconfiguredInput.type);
|
||||
|
||||
// If the input do not exist skip
|
||||
if (originalInput === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For flags like this, we only want to override the original value if it was set
|
||||
// as `undefined` in the original object. An explicit true/false value should be
|
||||
// persisted from the original object to the result after the override process is complete.
|
||||
if (originalInput.enabled === undefined && preconfiguredInput.enabled !== undefined) {
|
||||
originalInput.enabled = preconfiguredInput.enabled;
|
||||
}
|
||||
|
||||
if (originalInput.keep_enabled === undefined && preconfiguredInput.keep_enabled !== undefined) {
|
||||
originalInput.keep_enabled = preconfiguredInput.keep_enabled;
|
||||
}
|
||||
|
||||
if (preconfiguredInput.vars) {
|
||||
const indexOfInput = inputs.indexOf(originalInput);
|
||||
inputs[indexOfInput] = deepMergeVars(
|
||||
originalInput,
|
||||
preconfiguredInput
|
||||
) as NewPackagePolicyInput;
|
||||
originalInput = inputs[indexOfInput];
|
||||
}
|
||||
|
||||
if (preconfiguredInput.streams) {
|
||||
for (const stream of preconfiguredInput.streams) {
|
||||
let originalStream = originalInput?.streams.find(
|
||||
(s) => s.data_stream.dataset === stream.data_stream.dataset
|
||||
);
|
||||
|
||||
if (originalStream === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (originalStream?.enabled === undefined) {
|
||||
originalStream.enabled = stream.enabled;
|
||||
}
|
||||
|
||||
if (stream.vars) {
|
||||
const indexOfStream = originalInput.streams.indexOf(originalStream);
|
||||
originalInput.streams[indexOfStream] = deepMergeVars(
|
||||
originalStream,
|
||||
stream as InputsOverride
|
||||
);
|
||||
originalStream = originalInput.streams[indexOfStream];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const resultingPackagePolicy: NewPackagePolicy = {
|
||||
...basePackagePolicy,
|
||||
inputs,
|
||||
};
|
||||
|
||||
const validationResults = validatePackagePolicy(resultingPackagePolicy, packageInfo, safeLoad);
|
||||
|
||||
if (validationHasErrors(validationResults)) {
|
||||
const responseFormattedValidationErrors = Object.entries(getFlattenedObject(validationResults))
|
||||
.map(([key, value]) => ({
|
||||
key,
|
||||
message: value,
|
||||
}))
|
||||
.filter(({ message }) => !!message);
|
||||
|
||||
if (responseFormattedValidationErrors.length) {
|
||||
throw new PackagePolicyValidationError(
|
||||
i18n.translate('xpack.fleet.packagePolicyInvalidError', {
|
||||
defaultMessage: 'Package policy is invalid: {errors}',
|
||||
values: {
|
||||
errors: responseFormattedValidationErrors
|
||||
.map(({ key, message }) => `${key}: ${message}`)
|
||||
.join('\n'),
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return resultingPackagePolicy;
|
||||
}
|
||||
|
||||
function deepMergeVars(original: any, override: any, keepOriginalValue = false): any {
|
||||
if (!original.vars) {
|
||||
original.vars = { ...override.vars };
|
||||
}
|
||||
|
@ -1192,7 +1293,7 @@ function deepMergeVars(original: any, override: any): any {
|
|||
|
||||
// Ensure that any value from the original object is persisted on the newly merged resulting object,
|
||||
// even if we merge other data about the given variable
|
||||
if (originalVar?.value) {
|
||||
if (keepOriginalValue && originalVar?.value) {
|
||||
result.vars[name].value = originalVar.value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ import { ensurePackagesCompletedInstall } from './epm/packages/install';
|
|||
import { bulkInstallPackages } from './epm/packages/bulk_install_packages';
|
||||
import { agentPolicyService, addPackageToAgentPolicy } from './agent_policy';
|
||||
import type { InputsOverride } from './package_policy';
|
||||
import { overridePackageInputs, packagePolicyService } from './package_policy';
|
||||
import { preconfigurePackageInputs, packagePolicyService } from './package_policy';
|
||||
import { appContextService } from './app_context';
|
||||
import type { UpgradeManagedPackagePoliciesResult } from './managed_package_policies';
|
||||
import { upgradeManagedPackagePolicies } from './managed_package_policies';
|
||||
|
@ -428,7 +428,7 @@ async function addPreconfiguredPolicyPackages(
|
|||
defaultOutput,
|
||||
name,
|
||||
description,
|
||||
(policy) => overridePackageInputs(policy, packageInfo, inputs),
|
||||
(policy) => preconfigurePackageInputs(policy, packageInfo, inputs),
|
||||
bumpAgentPolicyRevison
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue