From fbacdc6315ccc599fe82795a42b0c77559494aa6 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Thu, 13 Oct 2022 11:26:23 +0100 Subject: [PATCH] [Fleet] Simplify `skipArchive` behaviour for input packages (#141671) * add test for missing pkg policy field * test create package policy API * always try and get info from registry * remove skipArchive * fix mock * remove comment * change log message * add download key to archive packages * add clarifying comment --- .../server/services/epm/packages/get.test.ts | 4 ++ .../fleet/server/services/epm/packages/get.ts | 11 ++-- .../server/services/epm/registry/index.ts | 4 +- .../fleet_api_integration/apis/epm/get.ts | 12 ++++ .../apis/package_policy/create.ts | 66 +++++++++++++++++++ 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts index 1dacf4ed7df8a..20ed655d97176 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.test.ts @@ -188,6 +188,10 @@ describe('When using EPM `get` services', () => { name: 'my-package', version: '1.0.0', } as RegistryPackage); + MockRegistry.fetchInfo.mockResolvedValue({ + name: 'my-package', + version: '1.0.0', + } as RegistryPackage); MockRegistry.getPackage.mockResolvedValue({ paths: [], packageInfo: { diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get.ts b/x-pack/plugins/fleet/server/services/epm/packages/get.ts index 0ce4e3c1cbea3..b8b447a8de526 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get.ts @@ -152,13 +152,12 @@ export async function getPackageInfo({ // If same version is available in registry and skipArchive is true, use the info from the registry (faster), // otherwise build it from the archive let paths: string[]; - let packageInfo: RegistryPackage | ArchivePackage | undefined = skipArchive - ? await Registry.fetchInfo(pkgName, resolvedPkgVersion).catch(() => undefined) - : undefined; - + const registryInfo = await Registry.fetchInfo(pkgName, resolvedPkgVersion).catch(() => undefined); + let packageInfo; // We need to get input only packages from source to get all fields // see https://github.com/elastic/package-registry/issues/864 - if (packageInfo && packageInfo.type !== 'input') { + if (registryInfo && skipArchive && registryInfo.type !== 'input') { + packageInfo = registryInfo; // Fix the paths paths = packageInfo.assets?.map((path) => @@ -293,7 +292,7 @@ export async function getPackageFromSource(options: { } } else { res = await Registry.getPackage(pkgName, pkgVersion, { ignoreUnverified }); - logger.debug(`retrieved uninstalled package ${pkgName}-${pkgVersion}`); + logger.debug(`retrieved package ${pkgName}-${pkgVersion} from registry`); } if (!res) { throw new FleetError(`package info for ${pkgName}-${pkgVersion} does not exist`); diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index 3f648a7fd73dc..e4ebf9013f55e 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -265,7 +265,9 @@ async function getPackageInfoFromArchiveOrCache( archiveBuffer, ensureContentType(archivePath) ); - setPackageInfo({ packageInfo, name, version }); + // set the download URL as it isn't contained in the manifest + // this allows us to re-download the archive during package install + setPackageInfo({ packageInfo: { ...packageInfo, download: archivePath }, name, version }); return packageInfo; } else { return cachedInfo; diff --git a/x-pack/test/fleet_api_integration/apis/epm/get.ts b/x-pack/test/fleet_api_integration/apis/epm/get.ts index 2a63e1c8b3905..280922b2e4a33 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/get.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/get.ts @@ -144,6 +144,18 @@ export default function (providerContext: FtrProviderContext) { expect(packageInfo.name).to.equal('apache'); await uninstallPackage(testPkgName, testPkgVersion); }); + it('should return all fields for input only packages', async function () { + // input packages have to get their package info from the manifest directly + // not from the package registry. This is because they contain a field the registry + // does not support + const res = await supertest + .get(`/api/fleet/epm/packages/integration_to_input/0.9.1`) + .expect(200); + + const packageInfo = res.body.item; + expect(packageInfo.policy_templates.length).to.equal(1); + expect(packageInfo.policy_templates[0].vars).not.to.be(undefined); + }); describe('Pkg verification', () => { it('should return validation error for unverified input only pkg', async function () { const res = await supertest.get(`/api/fleet/epm/packages/input_only/0.1.0`).expect(400); diff --git a/x-pack/test/fleet_api_integration/apis/package_policy/create.ts b/x-pack/test/fleet_api_integration/apis/package_policy/create.ts index 10b1b709d188f..21a5fa0f6dc2a 100644 --- a/x-pack/test/fleet_api_integration/apis/package_policy/create.ts +++ b/x-pack/test/fleet_api_integration/apis/package_policy/create.ts @@ -446,6 +446,72 @@ export default function (providerContext: FtrProviderContext) { expect(policy.name).to.equal(nameWithWhitespace.trim()); }); + describe('input only packages', () => { + it('should return 400 if dataset not provided for input only pkg', async function () { + await supertest + .post(`/api/fleet/package_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + policy_id: agentPolicyId, + package: { + name: 'integration_to_input', + version: '0.9.1', + }, + name: 'integration_to_input-1', + description: '', + namespace: 'default', + inputs: { + 'logs-logfile': { + enabled: true, + streams: { + 'integration_to_input.logs': { + enabled: true, + vars: { + paths: ['/tmp/test.log'], + tags: ['tag1'], + ignore_older: '72h', + }, + }, + }, + }, + }, + }) + .expect(400); + }); + it('should successfully create an input only package policy with all required vars', async function () { + await supertest + .post(`/api/fleet/package_policies`) + .set('kbn-xsrf', 'xxxx') + .send({ + policy_id: agentPolicyId, + package: { + name: 'integration_to_input', + version: '0.9.1', + }, + name: 'integration_to_input-2', + description: '', + namespace: 'default', + inputs: { + 'logs-logfile': { + enabled: true, + streams: { + 'integration_to_input.logs': { + enabled: true, + vars: { + paths: ['/tmp/test.log'], + tags: ['tag1'], + ignore_older: '72h', + 'data_stream.dataset': 'generic', + }, + }, + }, + }, + }, + }) + .expect(200); + }); + }); + describe('Simplified package policy', () => { it('should work with valid values', async () => { await supertest