[Fleet] Improve error status code for package (#93696)
This commit is contained in:
parent
14069d5c2c
commit
02be8c16c9
|
@ -21,8 +21,13 @@ export class IngestManagerError extends Error {
|
|||
}
|
||||
export class RegistryError extends IngestManagerError {}
|
||||
export class RegistryConnectionError extends RegistryError {}
|
||||
export class RegistryResponseError extends RegistryError {}
|
||||
export class RegistryResponseError extends RegistryError {
|
||||
constructor(message?: string, public readonly status?: number) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
export class PackageNotFoundError extends IngestManagerError {}
|
||||
export class PackageKeyInvalidError extends IngestManagerError {}
|
||||
export class PackageOutdatedError extends IngestManagerError {}
|
||||
export class AgentPolicyError extends IngestManagerError {}
|
||||
export class AgentPolicyNameExistsError extends AgentPolicyError {}
|
||||
|
|
|
@ -30,7 +30,12 @@ import {
|
|||
} from '../archive';
|
||||
import { streamToBuffer } from '../streams';
|
||||
import { appContextService } from '../..';
|
||||
import { PackageNotFoundError, PackageCacheError } from '../../../errors';
|
||||
import {
|
||||
PackageKeyInvalidError,
|
||||
PackageNotFoundError,
|
||||
PackageCacheError,
|
||||
RegistryResponseError,
|
||||
} from '../../../errors';
|
||||
|
||||
import { fetchUrl, getResponse, getResponseStream } from './requests';
|
||||
import { getRegistryUrl } from './registry_url';
|
||||
|
@ -53,13 +58,15 @@ export function splitPkgKey(pkgkey: string): { pkgName: string; pkgVersion: stri
|
|||
// this will return an empty string if `indexOf` returns -1
|
||||
const pkgName = pkgkey.substr(0, pkgkey.indexOf('-'));
|
||||
if (pkgName === '') {
|
||||
throw new Error('Package key parsing failed: package name was empty');
|
||||
throw new PackageKeyInvalidError('Package key parsing failed: package name was empty');
|
||||
}
|
||||
|
||||
// this will return the entire string if `indexOf` return -1
|
||||
const pkgVersion = pkgkey.substr(pkgkey.indexOf('-') + 1);
|
||||
if (!semverValid(pkgVersion)) {
|
||||
throw new Error('Package key parsing failed: package version was not a valid semver');
|
||||
throw new PackageKeyInvalidError(
|
||||
'Package key parsing failed: package version was not a valid semver'
|
||||
);
|
||||
}
|
||||
return { pkgName, pkgVersion };
|
||||
}
|
||||
|
@ -112,7 +119,16 @@ export async function fetchFindLatestPackage(packageName: string): Promise<Regis
|
|||
|
||||
export async function fetchInfo(pkgName: string, pkgVersion: string): Promise<RegistryPackage> {
|
||||
const registryUrl = getRegistryUrl();
|
||||
return fetchUrl(`${registryUrl}/package/${pkgName}/${pkgVersion}`).then(JSON.parse);
|
||||
try {
|
||||
const res = await fetchUrl(`${registryUrl}/package/${pkgName}/${pkgVersion}`).then(JSON.parse);
|
||||
|
||||
return res;
|
||||
} catch (err) {
|
||||
if (err instanceof RegistryResponseError && err.status === 404) {
|
||||
throw new PackageNotFoundError(`${pkgName}@${pkgVersion} not found`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getFile(
|
||||
|
|
|
@ -109,6 +109,7 @@ describe('setupIngestManager', () => {
|
|||
await expect(promise).rejects.toThrow(
|
||||
`'404 Not Found' error response from package registry at https://example.com`
|
||||
);
|
||||
await expect(promise).rejects.toMatchObject({ status: 404 });
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
@ -124,6 +125,7 @@ describe('setupIngestManager', () => {
|
|||
await expect(promise).rejects.toThrow(
|
||||
`'429 Too Many Requests' error response from package registry at https://example.com`
|
||||
);
|
||||
await expect(promise).rejects.toMatchObject({ status: 429 });
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
@ -139,6 +141,7 @@ describe('setupIngestManager', () => {
|
|||
await expect(promise).rejects.toThrow(
|
||||
`'500 Internal Server Error' error response from package registry at https://example.com`
|
||||
);
|
||||
await expect(promise).rejects.toMatchObject({ status: 500 });
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ async function registryFetch(url: string) {
|
|||
const message = `'${status} ${statusText}' error response from package registry at ${
|
||||
resUrl || url
|
||||
}`;
|
||||
const responseError = new RegistryResponseError(message);
|
||||
const responseError = new RegistryResponseError(message, status);
|
||||
|
||||
throw new pRetry.AbortError(responseError);
|
||||
}
|
||||
|
|
|
@ -9,14 +9,12 @@ import expect from '@kbn/expect';
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { FtrProviderContext } from '../../../api_integration/ftr_provider_context';
|
||||
import { warnAndSkipTest } from '../../helpers';
|
||||
import { skipIfNoDockerRegistry } from '../../helpers';
|
||||
|
||||
export default function (providerContext: FtrProviderContext) {
|
||||
const { getService } = providerContext;
|
||||
const log = getService('log');
|
||||
|
||||
const supertest = getService('supertest');
|
||||
const dockerServers = getService('dockerServers');
|
||||
const server = dockerServers.get('registry');
|
||||
|
||||
const testPkgKey = 'apache-0.1.4';
|
||||
|
||||
|
@ -36,75 +34,60 @@ export default function (providerContext: FtrProviderContext) {
|
|||
);
|
||||
|
||||
describe('EPM - get', () => {
|
||||
skipIfNoDockerRegistry(providerContext);
|
||||
it('returns package info from the registry if it was installed from the registry', async function () {
|
||||
if (server.enabled) {
|
||||
// this will install through the registry by default
|
||||
await installPackage(testPkgKey);
|
||||
const res = await supertest.get(`/api/fleet/epm/packages/${testPkgKey}`).expect(200);
|
||||
const packageInfo = res.body.response;
|
||||
// the uploaded version will have this description
|
||||
expect(packageInfo.description).to.not.equal('Apache Uploaded Test Integration');
|
||||
// download property should exist
|
||||
expect(packageInfo.download).to.not.equal(undefined);
|
||||
await uninstallPackage(testPkgKey);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
// this will install through the registry by default
|
||||
await installPackage(testPkgKey);
|
||||
const res = await supertest.get(`/api/fleet/epm/packages/${testPkgKey}`).expect(200);
|
||||
const packageInfo = res.body.response;
|
||||
// the uploaded version will have this description
|
||||
expect(packageInfo.description).to.not.equal('Apache Uploaded Test Integration');
|
||||
// download property should exist
|
||||
expect(packageInfo.download).to.not.equal(undefined);
|
||||
await uninstallPackage(testPkgKey);
|
||||
});
|
||||
it('returns correct package info if it was installed by upload', async function () {
|
||||
if (server.enabled) {
|
||||
const buf = fs.readFileSync(testPkgArchiveZip);
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.type('application/zip')
|
||||
.send(buf)
|
||||
.expect(200);
|
||||
const buf = fs.readFileSync(testPkgArchiveZip);
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.type('application/zip')
|
||||
.send(buf)
|
||||
.expect(200);
|
||||
|
||||
const res = await supertest.get(`/api/fleet/epm/packages/${testPkgKey}`).expect(200);
|
||||
const packageInfo = res.body.response;
|
||||
// the uploaded version will have this description
|
||||
expect(packageInfo.description).to.equal('Apache Uploaded Test Integration');
|
||||
// download property should not exist on uploaded packages
|
||||
expect(packageInfo.download).to.equal(undefined);
|
||||
await uninstallPackage(testPkgKey);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
const res = await supertest.get(`/api/fleet/epm/packages/${testPkgKey}`).expect(200);
|
||||
const packageInfo = res.body.response;
|
||||
// the uploaded version will have this description
|
||||
expect(packageInfo.description).to.equal('Apache Uploaded Test Integration');
|
||||
// download property should not exist on uploaded packages
|
||||
expect(packageInfo.download).to.equal(undefined);
|
||||
await uninstallPackage(testPkgKey);
|
||||
});
|
||||
it('returns correct package info from registry if a different version is installed by upload', async function () {
|
||||
if (server.enabled) {
|
||||
const buf = fs.readFileSync(testPkgArchiveZip);
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.type('application/zip')
|
||||
.send(buf)
|
||||
.expect(200);
|
||||
const buf = fs.readFileSync(testPkgArchiveZip);
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.type('application/zip')
|
||||
.send(buf)
|
||||
.expect(200);
|
||||
|
||||
const res = await supertest.get(`/api/fleet/epm/packages/apache-0.1.3`).expect(200);
|
||||
const packageInfo = res.body.response;
|
||||
expect(packageInfo.description).to.equal('Apache Integration');
|
||||
expect(packageInfo.download).to.not.equal(undefined);
|
||||
await uninstallPackage(testPkgKey);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
const res = await supertest.get(`/api/fleet/epm/packages/apache-0.1.3`).expect(200);
|
||||
const packageInfo = res.body.response;
|
||||
expect(packageInfo.description).to.equal('Apache Integration');
|
||||
expect(packageInfo.download).to.not.equal(undefined);
|
||||
await uninstallPackage(testPkgKey);
|
||||
});
|
||||
it('returns a 500 for a package key without a proper name', async function () {
|
||||
if (server.enabled) {
|
||||
await supertest.get('/api/fleet/epm/packages/-0.1.0').expect(500);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
it('returns a 400 for a package key without a proper name', async function () {
|
||||
await supertest.get('/api/fleet/epm/packages/-0.1.0').expect(400);
|
||||
});
|
||||
|
||||
it('returns a 500 for a package key without a proper semver version', async function () {
|
||||
if (server.enabled) {
|
||||
await supertest.get('/api/fleet/epm/packages/endpoint-0.1.0.1.2.3').expect(500);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
it('returns a 404 for a package that do not exists', async function () {
|
||||
await supertest.get('/api/fleet/epm/packages/notexists-99.99.99').expect(404);
|
||||
});
|
||||
|
||||
it('returns a 400 for a package key without a proper semver version', async function () {
|
||||
await supertest.get('/api/fleet/epm/packages/endpoint-0.1.0.1.2.3').expect(400);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue