Skip to content

Commit

Permalink
[Fleet] Add functional tests for bundled packages (#126595)
Browse files Browse the repository at this point in the history
* Add first pass functional tests for bundled packages

* Address PR feedback + fix TS errors

* Move docker wait hook

* Move setupFleetAndAgents call in test

* Try disabling bundled tests to debug CI

* Fix failing jest tests

* Fix type errors

* Fix type errors

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
kpollich and kibanamachine authored Mar 2, 2022
1 parent 08b8bb8 commit 31261df
Show file tree
Hide file tree
Showing 18 changed files with 190 additions and 19 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,3 @@ fleet-server-*
elastic-agent.yml
fleet-server.yml

/x-pack/plugins/fleet/server/bundled_packages
2 changes: 1 addition & 1 deletion src/dev/build/tasks/bundle_fleet_packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import JSON5 from 'json5';
import { readCliArgs } from '../args';
import { Task, read, downloadToDisk } from '../lib';

const BUNDLED_PACKAGES_DIR = 'x-pack/plugins/fleet/server/bundled_packages';
const BUNDLED_PACKAGES_DIR = 'x-pack/plugins/fleet/target/bundled_packages';

interface FleetPackage {
name: string;
Expand Down
3 changes: 0 additions & 3 deletions src/dev/precommit_hook/casing_check_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,6 @@ export const IGNORE_FILE_GLOBS = [

'x-pack/plugins/maps/server/fonts/**/*',

// Bundled package names typically use a format like ${pkgName}-${pkgVersion}, so don't lint them
'x-pack/plugins/fleet/server/bundled_packages/**/*',

// Bazel default files
'**/WORKSPACE.bazel',
'**/BUILD.bazel',
Expand Down
13 changes: 13 additions & 0 deletions x-pack/plugins/fleet/common/openapi/bundled.json
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,19 @@
"type"
]
}
},
"_meta": {
"type": "object",
"properties": {
"install_source": {
"type": "string",
"enum": [
"registry",
"upload",
"bundled"
]
}
}
}
},
"required": [
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/fleet/common/openapi/bundled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,15 @@ paths:
required:
- id
- type
_meta:
type: object
properties:
install_source:
type: string
enum:
- registry
- upload
- bundled
required:
- items
operationId: install-package
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ post:
required:
- id
- type
_meta:
type: object
properties:
install_source:
type: string
enum:
- registry
- upload
- bundled
required:
- items
operationId: install-package
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/fleet/common/types/models/epm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface DefaultPackagesInstallationError {
}

export type InstallType = 'reinstall' | 'reupdate' | 'rollback' | 'update' | 'install' | 'unknown';
export type InstallSource = 'registry' | 'upload';
export type InstallSource = 'registry' | 'upload' | 'bundled';

export type EpmPackageInstallStatus =
| 'installed'
Expand Down
5 changes: 5 additions & 0 deletions x-pack/plugins/fleet/common/types/rest_spec/epm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
PackageInfo,
PackageUsageStats,
InstallType,
InstallSource,
} from '../models/epm';

export interface GetCategoriesRequest {
Expand Down Expand Up @@ -108,6 +109,9 @@ export interface InstallPackageRequest {

export interface InstallPackageResponse {
items: AssetReference[];
_meta: {
install_source: InstallSource;
};
// deprecated in 8.0
response?: AssetReference[];
}
Expand All @@ -123,6 +127,7 @@ export interface InstallResult {
status?: 'installed' | 'already_installed';
error?: Error;
installType: InstallType;
installSource: InstallSource;
}

export interface BulkInstallPackageInfo {
Expand Down
7 changes: 7 additions & 0 deletions x-pack/plugins/fleet/server/routes/epm/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,13 @@ export const installPackageFromRegistryHandler: FleetRequestHandler<
force: request.body?.force,
ignoreConstraints: request.body?.ignore_constraints,
});

if (!res.error) {
const body: InstallPackageResponse = {
items: res.assets || [],
_meta: {
install_source: res.installSource,
},
};
return response.ok({ body });
} else {
Expand Down Expand Up @@ -342,6 +346,9 @@ export const installPackageByUploadHandler: FleetRequestHandler<
const body: InstallPackageResponse = {
items: res.assets || [],
response: res.assets || [],
_meta: {
install_source: res.installSource,
},
};
return response.ok({ body });
} else {
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/fleet/server/routes/epm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export const registerRoutes = (router: FleetAuthzRouter) => {
response
);
if (resp.payload?.items) {
return response.ok({ body: { response: resp.payload.items } });
return response.ok({ body: { ...resp.payload, response: resp.payload.items } });
}
return resp;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { BundledPackage } from '../../../types';
import { appContextService } from '../../app_context';
import { splitPkgKey } from '../registry';

const BUNDLED_PACKAGE_DIRECTORY = path.join(__dirname, '../../../bundled_packages');
const BUNDLED_PACKAGE_DIRECTORY = path.join(__dirname, '../../../../target/bundled_packages');

export async function getBundledPackages(): Promise<BundledPackage[]> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ describe('install', () => {
.mockImplementation(() => Promise.resolve({ packageInfo: { license: 'basic' } } as any));

mockGetBundledPackages.mockReset();
(install._installPackage as jest.Mock).mockClear();
});

describe('registry', () => {
Expand Down
22 changes: 12 additions & 10 deletions x-pack/plugins/fleet/server/services/epm/packages/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ async function installPackageFromRegistry({
],
status: 'already_installed',
installType,
installSource: 'registry',
};
}
}
Expand Down Expand Up @@ -307,7 +308,7 @@ async function installPackageFromRegistry({
...telemetryEvent,
errorMessage: err.message,
});
return { error: err, installType };
return { error: err, installType, installSource: 'registry' };
}

const savedObjectsImporter = appContextService
Expand Down Expand Up @@ -338,7 +339,7 @@ async function installPackageFromRegistry({
...telemetryEvent,
status: 'success',
});
return { assets, status: 'installed', installType };
return { assets, status: 'installed', installType, installSource: 'registry' };
})
.catch(async (err: Error) => {
logger.warn(`Failure to install package [${pkgName}]: [${err.toString()}]`);
Expand All @@ -355,7 +356,7 @@ async function installPackageFromRegistry({
...telemetryEvent,
errorMessage: err.message,
});
return { error: err, installType };
return { error: err, installType, installSource: 'registry' };
});
} catch (e) {
sendEvent({
Expand All @@ -365,6 +366,7 @@ async function installPackageFromRegistry({
return {
error: e,
installType,
installSource: 'registry',
};
}
}
Expand Down Expand Up @@ -454,7 +456,7 @@ async function installPackageByUpload({
...telemetryEvent,
errorMessage: e.message,
});
return { error: e, installType };
return { error: e, installType, installSource: 'upload' };
}
}

Expand All @@ -463,9 +465,10 @@ export type InstallPackageParams = {
} & (
| ({ installSource: Extract<InstallSource, 'registry'> } & InstallRegistryPackageParams)
| ({ installSource: Extract<InstallSource, 'upload'> } & InstallUploadedArchiveParams)
| ({ installSource: Extract<InstallSource, 'bundled'> } & InstallUploadedArchiveParams)
);

export async function installPackage(args: InstallPackageParams) {
export async function installPackage(args: InstallPackageParams): Promise<InstallResult> {
if (!('installSource' in args)) {
throw new Error('installSource is required');
}
Expand All @@ -487,19 +490,19 @@ export async function installPackage(args: InstallPackageParams) {
`found bundled package for requested install of ${pkgkey} - installing from bundled package archive`
);

const response = installPackageByUpload({
const response = await installPackageByUpload({
savedObjectsClient,
esClient,
archiveBuffer: matchingBundledPackage.buffer,
contentType: 'application/zip',
spaceId,
});

return response;
return { ...response, installSource: 'bundled' };
}

logger.debug(`kicking off install of ${pkgkey} from registry`);
const response = installPackageFromRegistry({
const response = await installPackageFromRegistry({
savedObjectsClient,
pkgkey,
esClient,
Expand All @@ -510,7 +513,7 @@ export async function installPackage(args: InstallPackageParams) {
return response;
} else if (args.installSource === 'upload') {
const { archiveBuffer, contentType, spaceId } = args;
const response = installPackageByUpload({
const response = await installPackageByUpload({
savedObjectsClient,
esClient,
archiveBuffer,
Expand All @@ -519,7 +522,6 @@ export async function installPackage(args: InstallPackageParams) {
});
return response;
}
// @ts-expect-error s/b impossibe b/c `never` by this point, but just in case
throw new Error(`Unknown installSource: ${args.installSource}`);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ jest.mock('./epm/packages/install', () => ({
return {
error: new Error(installError),
installType: 'install',
installSource: 'registry',
};
}

Expand All @@ -157,6 +158,7 @@ jest.mock('./epm/packages/install', () => ({
return {
status: 'installed',
installType: 'install',
installSource: 'registry',
};
} else if (args.installSource === 'upload') {
const { archiveBuffer } = args;
Expand All @@ -168,7 +170,7 @@ jest.mock('./epm/packages/install', () => ({
const packageInstallation = { name: pkgName, version: '1.0.0', title: pkgName };
mockInstalledPackages.set(pkgName, packageInstallation);

return { status: 'installed', installType: 'install' };
return { status: 'installed', installType: 'install', installSource: 'upload' };
}
},
ensurePackagesCompletedInstall() {
Expand Down
1 change: 1 addition & 0 deletions x-pack/test/fleet_api_integration/apis/epm/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default function loadTests({ loadTestFile }) {
loadTestFile(require.resolve('./file'));
loadTestFile(require.resolve('./template'));
loadTestFile(require.resolve('./ilm'));
// loadTestFile(require.resolve('./install_bundled'));
loadTestFile(require.resolve('./install_by_upload'));
loadTestFile(require.resolve('./install_endpoint'));
loadTestFile(require.resolve('./install_overrides'));
Expand Down
Loading

0 comments on commit 31261df

Please sign in to comment.