Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP][Fleet] Granular integrations, phase 1 #96360

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
00f06ba
Adjust registry typings for new fields added to support integrations …
jen-huang Mar 31, 2021
72b563c
Initial pass at showing integration tiles (search doesn't quite work …
jen-huang Apr 1, 2021
21d5c09
Second pass at integration tiles, search now works too
jen-huang Apr 1, 2021
88c27ae
Pass integration name from tiles through package details page and pol…
jen-huang Apr 1, 2021
a528915
Fix missing dep
jen-huang Apr 1, 2021
53aea47
Create common service `doesPackageHaveIntegrations()`
jen-huang Apr 1, 2021
067d95f
Initial pass at supporting package-level vars
jen-huang Apr 2, 2021
de1e2c4
Merge remote-tracking branch 'upstream/master' into integration-search
jen-huang Apr 2, 2021
aab68b6
First pass at building package policy from package with integrations …
jen-huang Apr 5, 2021
61968e5
Add new field to keep track of integrations instead
jen-huang Apr 6, 2021
4260a01
Merge remote-tracking branch 'upstream/master' into integration-search
jen-huang Apr 6, 2021
4c5eca8
Merge remote-tracking branch 'upstream/master' into integration-search
jen-huang Apr 6, 2021
a40800e
Revert storing `integration` key on inputs, group by input groups ins…
jen-huang Apr 6, 2021
06d4749
Adjust package policy validation service to match, move it to /common
jen-huang Apr 6, 2021
7e60f3c
Adjust UI to show package input groups
jen-huang Apr 6, 2021
5dad3d7
Allow package-level vars in API schema
jen-huang Apr 6, 2021
5fc6aa8
Make `packageToPackagePolicy` params an object, fix types
jen-huang Apr 6, 2021
09ea207
Pass `integrations` param to policy editor to allow only certain poli…
jen-huang Apr 7, 2021
a51a571
Fix imports
jen-huang Apr 7, 2021
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
1,077 changes: 1,077 additions & 0 deletions x-pack/plugins/fleet/common/services/__snapshots__/group_inputs.test.ts.snap

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2,111 changes: 2,111 additions & 0 deletions x-pack/plugins/fleet/common/services/fixtures/packages.ts

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions x-pack/plugins/fleet/common/services/group_inputs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 { groupInputs } from './group_inputs';
import { packageWithPolicyTemplates } from './fixtures/packages';

describe('groupInputs()', () => {
it('should group inputs for a package with multiple policy templates and input groups correctly', () => {
expect(groupInputs(packageWithPolicyTemplates)).toMatchSnapshot();
});
});
108 changes: 108 additions & 0 deletions x-pack/plugins/fleet/common/services/group_inputs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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 type {
PackageInfo,
RegistryInputGroup,
RegistryVarsEntry,
RegistryStream,
NewPackagePolicyInputStream,
} from '../types';

type InputGroupWithStreams = RegistryInputGroup & {
vars?: RegistryVarsEntry[];
streams: Array<StreamWithDataStreamMeta & { policyTemplate?: string }>;
};

type StreamWithDataStreamMeta = RegistryStream & Pick<NewPackagePolicyInputStream, 'data_stream'>;

import { doesPackageHaveIntegrations } from './';

const findDataStreamsByNames = (
names: string[] = [],
dataStreams: PackageInfo['data_streams'] = []
): PackageInfo['data_streams'] => {
return names.length
? dataStreams.filter((dataStream) => names.includes(dataStream.path))
: dataStreams;
};

const getStreamsForInputType = (
inputType: string,
dataStreams: PackageInfo['data_streams'] = []
): StreamWithDataStreamMeta[] => {
const streams: StreamWithDataStreamMeta[] = [];

dataStreams.forEach((dataStream) => {
(dataStream.streams || []).forEach((stream) => {
if (stream.input === inputType) {
streams.push({
...stream,
data_stream: {
type: dataStream.type,
dataset: dataStream.dataset,
},
});
}
});
});

return streams;
};

export const groupInputs = (packageInfo: PackageInfo): InputGroupWithStreams[] => {
const inputGroups: InputGroupWithStreams[] = [
...(packageInfo.input_groups?.map((inputGroup) => ({ ...inputGroup, streams: [] })) || []),
];
const hasIntegrations = doesPackageHaveIntegrations(packageInfo);
const { policy_templates: policyTemplates = [] } = packageInfo;

// If no policy templates, return no groups
if (policyTemplates.length === 0) {
return inputGroups;
}

// If no integrations, return first policy template's inputs as groups
if (!hasIntegrations) {
(policyTemplates[0].inputs || []).forEach(({ type, ...input }) => {
inputGroups.push({
...input,
name: type,
streams: getStreamsForInputType(type, packageInfo.data_streams),
});
});
return inputGroups;
}

// Otherwise look in each policy template
policyTemplates.forEach((policyTemplate) => {
const policyTemplateDataStreams = findDataStreamsByNames(
policyTemplate.data_streams,
packageInfo.data_streams
);

(policyTemplate.inputs || []).forEach(({ type, input_group: inputGroupName }) => {
// Package should already have `input_groups` defined and each input should have an `input_group`
// If either one of these conditions aren't met, skip adding this input
const inputGroup = inputGroupName
? inputGroups.find((group) => group.name === inputGroupName)
: undefined;

if (!inputGroup) {
return;
}

inputGroup.streams.push(
...getStreamsForInputType(type, policyTemplateDataStreams).map((stream) => ({
...stream,
policyTemplate: policyTemplate.name,
}))
);
});
});

return inputGroups;
};
12 changes: 12 additions & 0 deletions x-pack/plugins/fleet/common/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,15 @@ export { isValidNamespace } from './is_valid_namespace';
export { isDiffPathProtocol } from './is_diff_path_protocol';
export { LicenseService } from './license';
export { isAgentUpgradeable } from './is_agent_upgradeable';
export { doesPackageHaveIntegrations } from './packages_with_integrations';
export { groupInputs } from './group_inputs';

export {
PackagePolicyValidationResults,
PackagePolicyConfigValidationResults,
PackagePolicyInputValidationResults,
validatePackagePolicy,
validatePackagePolicyConfig,
validationHasErrors,
countValidationErrors,
} from './validate_package_policy';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import type { PackageInfo } from '../types';

import { packageWithPolicyTemplates } from './fixtures/packages';
import { packageToPackagePolicy, packageToPackagePolicyInputs } from './package_to_package_policy';

describe('Fleet - packageToPackagePolicy', () => {
Expand Down Expand Up @@ -324,9 +325,11 @@ describe('Fleet - packageToPackagePolicy', () => {

describe('packageToPackagePolicy', () => {
it('returns package policy with default name', () => {
expect(packageToPackagePolicy(mockPackage, '1', '2')).toEqual({
expect(
packageToPackagePolicy({ packageInfo: mockPackage, agentPolicyId: '1', outputId: '2' })
).toEqual({
policy_id: '1',
namespace: '',
namespace: 'default',
enabled: true,
inputs: [],
name: 'mock-package-1',
Expand All @@ -338,8 +341,16 @@ describe('Fleet - packageToPackagePolicy', () => {
},
});
});

it('returns package policy with custom name', () => {
expect(packageToPackagePolicy(mockPackage, '1', '2', 'default', 'pkgPolicy-1')).toEqual({
expect(
packageToPackagePolicy({
name: 'pkgPolicy-1',
packageInfo: mockPackage,
agentPolicyId: '1',
outputId: '2',
})
).toEqual({
policy_id: '1',
namespace: 'default',
enabled: true,
Expand All @@ -353,16 +364,17 @@ describe('Fleet - packageToPackagePolicy', () => {
},
});
});

it('returns package policy with namespace and description', () => {
expect(
packageToPackagePolicy(
mockPackage,
'1',
'2',
'mock-namespace',
'pkgPolicy-1',
'Test description'
)
packageToPackagePolicy({
name: 'pkgPolicy-1',
namespace: 'mock-namespace',
description: 'Test description',
packageInfo: mockPackage,
agentPolicyId: '1',
outputId: '2',
})
).toEqual({
policy_id: '1',
enabled: true,
Expand All @@ -378,27 +390,58 @@ describe('Fleet - packageToPackagePolicy', () => {
},
});
});
it('returns package policy with inputs', () => {
const mockPackageWithPolicyTemplates = ({

it('returns package policy with inputs and package-level vars', () => {
const mockPackageWithPackageVars = ({
...mockPackage,
policy_templates: [{ inputs: [{ type: 'foo' }] }],
vars: [{ default: 'foo-var-value', name: 'var-name', type: 'text' }],
} as unknown) as PackageInfo;

expect(
packageToPackagePolicy(mockPackageWithPolicyTemplates, '1', '2', 'default', 'pkgPolicy-1')
packageToPackagePolicy({
name: 'pkgPolicy-1',
packageInfo: mockPackageWithPackageVars,
agentPolicyId: '1',
outputId: '2',
})
).toEqual({
policy_id: '1',
namespace: 'default',
enabled: true,
inputs: [{ type: 'foo', enabled: true, streams: [] }],
name: 'pkgPolicy-1',
output_id: '2',
package: {
name: 'mock-package',
title: 'Mock package',
version: '0.0.0',
},
inputs: [{ type: 'foo', enabled: true, streams: [] }],
vars: { 'var-name': { value: 'foo-var-value', type: 'text' } },
});
});

it('returns package policy with multiple policy templates correctly', () => {
expect(
packageToPackagePolicy({
name: 'aws-1',
packageInfo: packageWithPolicyTemplates,
agentPolicyId: 'some-policy-id',
outputId: 'some-output-id',
})
).toMatchSnapshot();
});

it('only enables streams matching a particular policy template if given', () => {
expect(
packageToPackagePolicy({
name: 'aws-1',
packageInfo: packageWithPolicyTemplates,
agentPolicyId: 'some-policy-id',
outputId: 'some-output-id',
enablePolicyTemplate: 'dynamodb',
})
).toMatchSnapshot();
});
});
});
Loading