Skip to content

Commit

Permalink
[Fleet] Fix bug with duplicate Fleet Server inputs in Cloud deploymen…
Browse files Browse the repository at this point in the history
…ts (elastic#119925)

* Fix bug with duplicate Fleet Server inputs

Rework logic around looking up `originalInput` value to handle cases in
which `policy_template` is `undefined` on the policy's input object.

* Set policy_template when possible

* Add tests for duplicate input case
  • Loading branch information
kpollich authored and kibanamachine committed Nov 30, 2021
1 parent 3e497d0 commit bf77f4f
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 5 deletions.
101 changes: 101 additions & 0 deletions x-pack/plugins/fleet/server/services/package_policy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2707,6 +2707,107 @@ describe('Package policy service', () => {
expect(result.inputs[0]?.vars?.path.value).toEqual(['/var/log/logfile.log']);
});
});

describe('when policy_template is defined on update, but undefined on existing input with matching type', () => {
it('generates the proper inputs, and adds a policy_template field', () => {
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',
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 = updatePackageInputs(
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[],
false
);

expect(result.inputs.length).toBe(1);
expect(result.inputs[0]?.vars?.path.value).toEqual(['/var/log/logfile.log']);
expect(result.inputs[0]?.vars?.path_2.value).toBe('/var/log/custom.log');
expect(result.inputs[0]?.policy_template).toBe('template_1');
});
});
});
});

Expand Down
31 changes: 26 additions & 5 deletions x-pack/plugins/fleet/server/services/package_policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1058,11 +1058,26 @@ export function updatePackageInputs(
];

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);
let originalInput: NewPackagePolicyInput | undefined;

if (update.policy_template) {
// If the updated value defines a policy template, try to find an original input
// with the same policy template value
const matchingInput = inputs.find(
(i) => i.type === update.type && i.policy_template === update.policy_template
);

// If we didn't find an input with the same policy template, try to look for one
// with the same type, but with an undefined policy template. This ensures we catch
// cases where we're upgrading an older policy from before policy template was
// reliably define on package policy inputs.
originalInput =
matchingInput || inputs.find((i) => i.type === update.type && !i.policy_template);
} else {
// For inputs that don't specify a policy template, just grab the first input
// that matches its `type`
originalInput = 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
Expand All @@ -1083,6 +1098,12 @@ export function updatePackageInputs(
originalInput.keep_enabled = update.keep_enabled;
}

// `policy_template` should always be defined, so if we have an older policy here we need
// to ensure we set it
if (originalInput.policy_template === undefined && update.policy_template !== undefined) {
originalInput.policy_template = update.policy_template;
}

if (update.vars) {
const indexOfInput = inputs.indexOf(originalInput);
inputs[indexOfInput] = deepMergeVars(originalInput, update, true) as NewPackagePolicyInput;
Expand Down

0 comments on commit bf77f4f

Please sign in to comment.