Skip to content

Commit

Permalink
[Fleet] Fixes to preconfigure API (elastic#96094)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zacqary committed Apr 7, 2021
1 parent 3726c7b commit c5117ad
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 23 deletions.
4 changes: 4 additions & 0 deletions x-pack/plugins/fleet/common/types/models/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ export interface PreconfiguredAgentPolicy extends Omit<NewAgentPolicy, 'namespac
}
>;
}

export interface PreconfiguredPackage extends Omit<PackagePolicyPackage, 'title'> {
force?: boolean;
}
5 changes: 3 additions & 2 deletions x-pack/plugins/fleet/server/services/epm/packages/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ export async function ensureInstalledPackage(options: {
pkgName: string;
esClient: ElasticsearchClient;
pkgVersion?: string;
force?: boolean;
}): Promise<Installation> {
const { savedObjectsClient, pkgName, esClient, pkgVersion } = options;
const { savedObjectsClient, pkgName, esClient, pkgVersion, force } = options;
const installedPackage = await isPackageVersionInstalled({
savedObjectsClient,
pkgName,
Expand All @@ -136,7 +137,7 @@ export async function ensureInstalledPackage(options: {
savedObjectsClient,
pkgkey,
esClient,
force: true,
force,
});
} else {
await installLatestPackage({
Expand Down
30 changes: 20 additions & 10 deletions x-pack/plugins/fleet/server/services/preconfiguration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,19 @@ function getPutPreconfiguredPackagesMock() {
}

jest.mock('./epm/packages/install', () => ({
ensureInstalledPackage({ pkgName, pkgVersion }: { pkgName: string; pkgVersion: string }) {
ensureInstalledPackage({
pkgName,
pkgVersion,
force,
}: {
pkgName: string;
pkgVersion: string;
force?: boolean;
}) {
const installedPackage = mockInstalledPackages.get(pkgName);
if (installedPackage) return installedPackage;
if (installedPackage) {
if (installedPackage.version === pkgVersion) return installedPackage;
}

const packageInstallation = { name: pkgName, version: pkgVersion, title: pkgName };
mockInstalledPackages.set(pkgName, packageInstallation);
Expand Down Expand Up @@ -138,12 +148,12 @@ describe('policy preconfiguration', () => {
soClient,
esClient,
[],
[{ name: 'test-package', version: '3.0.0' }],
[{ name: 'test_package', version: '3.0.0' }],
mockDefaultOutput
);

expect(policies.length).toBe(0);
expect(packages).toEqual(expect.arrayContaining(['test-package:3.0.0']));
expect(packages).toEqual(expect.arrayContaining(['test_package-3.0.0']));
});

it('should install packages and configure agent policies successfully', async () => {
Expand All @@ -160,19 +170,19 @@ describe('policy preconfiguration', () => {
id: 'test-id',
package_policies: [
{
package: { name: 'test-package' },
package: { name: 'test_package' },
name: 'Test package',
},
],
},
] as PreconfiguredAgentPolicy[],
[{ name: 'test-package', version: '3.0.0' }],
[{ name: 'test_package', version: '3.0.0' }],
mockDefaultOutput
);

expect(policies.length).toEqual(1);
expect(policies[0].id).toBe('mocked-test-id');
expect(packages).toEqual(expect.arrayContaining(['test-package:3.0.0']));
expect(packages).toEqual(expect.arrayContaining(['test_package-3.0.0']));
});

it('should throw an error when trying to install duplicate packages', async () => {
Expand All @@ -185,13 +195,13 @@ describe('policy preconfiguration', () => {
esClient,
[],
[
{ name: 'test-package', version: '3.0.0' },
{ name: 'test-package', version: '2.0.0' },
{ name: 'test_package', version: '3.0.0' },
{ name: 'test_package', version: '2.0.0' },
],
mockDefaultOutput
)
).rejects.toThrow(
'Duplicate packages specified in configuration: test-package:3.0.0, test-package:2.0.0'
'Duplicate packages specified in configuration: test_package-3.0.0, test_package-2.0.0'
);
});

Expand Down
39 changes: 28 additions & 11 deletions x-pack/plugins/fleet/server/services/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@

import type { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server';
import { i18n } from '@kbn/i18n';
import { groupBy } from 'lodash';
import { groupBy, omit } from 'lodash';

import type {
PackagePolicyPackage,
NewPackagePolicy,
AgentPolicy,
Installation,
Output,
NewPackagePolicyInput,
NewPackagePolicyInputStream,
PreconfiguredAgentPolicy,
PreconfiguredPackage,
} from '../../common';

import { pkgToPkgKey } from './epm/registry';
import { getInstallation } from './epm/packages';
import { ensureInstalledPackage } from './epm/packages/install';
import { agentPolicyService, addPackageToAgentPolicy } from './agent_policy';
Expand All @@ -32,7 +33,7 @@ export async function ensurePreconfiguredPackagesAndPolicies(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
policies: PreconfiguredAgentPolicy[] = [],
packages: Array<Omit<PackagePolicyPackage, 'title'>> = [],
packages: PreconfiguredPackage[] = [],
defaultOutput: Output
) {
// Validate configured packages to ensure there are no version conflicts
Expand All @@ -45,7 +46,7 @@ export async function ensurePreconfiguredPackagesAndPolicies(
// If there are multiple packages with duplicate versions, separate them with semicolons, e.g
// package-a:1.0.0, package-a:2.0.0; package-b:1.0.0, package-b:2.0.0
const duplicateList = duplicatePackages
.map(([, versions]) => versions.map((v) => `${v.name}:${v.version}`).join(', '))
.map(([, versions]) => versions.map((v) => pkgToPkgKey(v)).join(', '))
.join('; ');

throw new Error(
Expand All @@ -60,8 +61,8 @@ export async function ensurePreconfiguredPackagesAndPolicies(

// Preinstall packages specified in Kibana config
const preconfiguredPackages = await Promise.all(
packages.map(({ name, version }) =>
ensureInstalledPreconfiguredPackage(soClient, esClient, name, version)
packages.map(({ name, version, force }) =>
ensureInstalledPreconfiguredPackage(soClient, esClient, name, version, force)
)
);

Expand All @@ -71,7 +72,7 @@ export async function ensurePreconfiguredPackagesAndPolicies(
const { created, policy } = await agentPolicyService.ensurePreconfiguredAgentPolicy(
soClient,
esClient,
preconfiguredAgentPolicy
omit(preconfiguredAgentPolicy, 'is_managed') // Don't add `is_managed` until the policy has been fully configured
);

if (!created) return { created, policy };
Expand Down Expand Up @@ -101,12 +102,22 @@ export async function ensurePreconfiguredPackagesAndPolicies(
})
);

return { created, policy, installedPackagePolicies };
return {
created,
policy,
installedPackagePolicies,
shouldAddIsManagedFlag: preconfiguredAgentPolicy.is_managed,
};
})
);

for (const preconfiguredPolicy of preconfiguredPolicies) {
const { created, policy, installedPackagePolicies } = preconfiguredPolicy;
const {
created,
policy,
installedPackagePolicies,
shouldAddIsManagedFlag,
} = preconfiguredPolicy;
if (created) {
await addPreconfiguredPolicyPackages(
soClient,
Expand All @@ -115,6 +126,10 @@ export async function ensurePreconfiguredPackagesAndPolicies(
installedPackagePolicies!,
defaultOutput
);
// Add the is_managed flag after configuring package policies to avoid errors
if (shouldAddIsManagedFlag) {
agentPolicyService.update(soClient, esClient, policy.id, { is_managed: true });
}
}
}

Expand All @@ -123,7 +138,7 @@ export async function ensurePreconfiguredPackagesAndPolicies(
id: p.policy.id,
updated_at: p.policy.updated_at,
})),
packages: preconfiguredPackages.map((pkg) => `${pkg.name}:${pkg.version}`),
packages: preconfiguredPackages.map((pkg) => pkgToPkgKey(pkg)),
};
}

Expand Down Expand Up @@ -160,13 +175,15 @@ async function ensureInstalledPreconfiguredPackage(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
pkgName: string,
pkgVersion: string
pkgVersion: string,
force?: boolean
) {
return ensureInstalledPackage({
savedObjectsClient: soClient,
pkgName,
esClient,
pkgVersion,
force,
});
}

Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/fleet/server/types/models/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const PreconfiguredPackagesSchema = schema.arrayOf(
}
},
}),
force: schema.maybe(schema.boolean()),
})
);

Expand All @@ -41,6 +42,8 @@ export const PreconfiguredAgentPoliciesSchema = schema.arrayOf(
...AgentPolicyBaseSchema,
namespace: schema.maybe(NamespaceSchema),
id: schema.oneOf([schema.string(), schema.number()]),
is_default: schema.maybe(schema.boolean()),
is_default_fleet_server: schema.maybe(schema.boolean()),
package_policies: schema.arrayOf(
schema.object({
name: schema.string(),
Expand Down

0 comments on commit c5117ad

Please sign in to comment.