mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Fleet] Handle invalid old package in getPackages (#162832)
## Summary Resolve https://github.com/elastic/kibana/issues/161768 Handle invalid old packages in the `getPackages` method, by ignoring and logging a warning instead of crashing. ## Test Tested by a unit test How to manually reproduce? this can be reproduced by installing in 7.17 zscaler in version 0.1.2 then upgrade to 8.8. --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
6751324a80
commit
8683621a65
2 changed files with 114 additions and 23 deletions
|
@ -325,6 +325,83 @@ owner: elastic`,
|
|||
]);
|
||||
});
|
||||
|
||||
it('should filter installed package that are not in registry and not valid packages', async () => {
|
||||
const mockContract = createAppContextStartContractMock();
|
||||
appContextService.start(mockContract);
|
||||
|
||||
const soClient = savedObjectsClientMock.create();
|
||||
soClient.find.mockResolvedValue({
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'invalidpackage',
|
||||
attributes: {
|
||||
name: 'invalidpackage',
|
||||
version: '0.0.1',
|
||||
install_source: 'upload',
|
||||
install_version: '0.0.1',
|
||||
},
|
||||
},
|
||||
],
|
||||
} as any);
|
||||
soClient.get.mockImplementation((type) => {
|
||||
if (type === 'epm-packages-assets') {
|
||||
return Promise.resolve({
|
||||
attributes: {
|
||||
data_utf8: `
|
||||
name: invalidpackage
|
||||
version: 0.0.1
|
||||
test: invalid manifest`,
|
||||
},
|
||||
} as any);
|
||||
} else {
|
||||
return Promise.resolve({
|
||||
id: 'invalidpackage',
|
||||
attributes: {
|
||||
name: 'invalidpackage',
|
||||
version: '0.0.1',
|
||||
install_source: 'upload',
|
||||
package_assets: [],
|
||||
data_utf8: `
|
||||
name: invalidpackage
|
||||
version: 0.0.1
|
||||
title: Elastic
|
||||
test: invalid manifest`,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
soClient.bulkGet.mockResolvedValue({
|
||||
saved_objects: [
|
||||
{
|
||||
id: 'test',
|
||||
references: [],
|
||||
type: 'epm-package-assets',
|
||||
attributes: {
|
||||
asset_path: 'invalidpackage-0.0.1/manifest.yml',
|
||||
data_utf8: `
|
||||
name: invalidpackage
|
||||
version: 0.0.1
|
||||
title: Elastic
|
||||
test: invalid manifest
|
||||
`,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
const packages = await getPackages({
|
||||
savedObjectsClient: soClient,
|
||||
});
|
||||
expect(packages).toMatchObject([
|
||||
{ id: 'fleet_server', name: 'fleet_server', title: 'Fleet Server', version: '1.0.0' },
|
||||
{ id: 'nginx', name: 'nginx', title: 'Nginx', version: '1.0.0' },
|
||||
]);
|
||||
|
||||
expect(jest.mocked(appContextService.getLogger().warn)).toBeCalledTimes(1);
|
||||
expect(jest.mocked(appContextService.getLogger().warn)).toBeCalledWith(
|
||||
'Installed package invalidpackage 0.0.1 is not a valid package anymore'
|
||||
);
|
||||
});
|
||||
|
||||
it('should call audit logger', async () => {
|
||||
const soClient = savedObjectsClientMock.create();
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ import {
|
|||
PackageFailedVerificationError,
|
||||
PackageNotFoundError,
|
||||
RegistryResponseError,
|
||||
PackageInvalidArchiveError,
|
||||
} from '../../../errors';
|
||||
import { appContextService } from '../..';
|
||||
import * as Registry from '../registry';
|
||||
|
@ -78,6 +79,7 @@ export async function getPackages(
|
|||
excludeInstallStatus?: boolean;
|
||||
} & GetPackagesRequest['query']
|
||||
) {
|
||||
const logger = appContextService.getLogger();
|
||||
const {
|
||||
savedObjectsClient,
|
||||
category,
|
||||
|
@ -98,29 +100,41 @@ export async function getPackages(
|
|||
(pkg) => !registryItems.some((item) => item.name === pkg.id)
|
||||
);
|
||||
|
||||
const uploadedPackagesNotInRegistry = await pMap(
|
||||
packagesNotInRegistry.entries(),
|
||||
async ([i, pkg]) => {
|
||||
// fetching info of uploaded packages to populate title, description
|
||||
// limit to 10 for performance
|
||||
if (i < MAX_PKGS_TO_LOAD_TITLE) {
|
||||
const packageInfo = await withSpan({ name: 'get-package-info', type: 'package' }, () =>
|
||||
getPackageInfo({
|
||||
savedObjectsClient,
|
||||
pkgName: pkg.id,
|
||||
pkgVersion: pkg.attributes.version,
|
||||
})
|
||||
);
|
||||
return createInstallableFrom({ ...packageInfo, id: pkg.id }, pkg);
|
||||
} else {
|
||||
return createInstallableFrom(
|
||||
{ ...pkg.attributes, title: nameAsTitle(pkg.id), id: pkg.id },
|
||||
pkg
|
||||
);
|
||||
}
|
||||
},
|
||||
{ concurrency: 10 }
|
||||
);
|
||||
const uploadedPackagesNotInRegistry = (
|
||||
await pMap(
|
||||
packagesNotInRegistry.entries(),
|
||||
async ([i, pkg]) => {
|
||||
// fetching info of uploaded packages to populate title, description
|
||||
// limit to 10 for performance
|
||||
if (i < MAX_PKGS_TO_LOAD_TITLE) {
|
||||
try {
|
||||
const packageInfo = await withSpan({ name: 'get-package-info', type: 'package' }, () =>
|
||||
getPackageInfo({
|
||||
savedObjectsClient,
|
||||
pkgName: pkg.id,
|
||||
pkgVersion: pkg.attributes.version,
|
||||
})
|
||||
);
|
||||
return createInstallableFrom({ ...packageInfo, id: pkg.id }, pkg);
|
||||
} catch (err) {
|
||||
if (err instanceof PackageInvalidArchiveError) {
|
||||
logger.warn(
|
||||
`Installed package ${pkg.id} ${pkg.attributes.version} is not a valid package anymore`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
} else {
|
||||
return createInstallableFrom(
|
||||
{ ...pkg.attributes, title: nameAsTitle(pkg.id), id: pkg.id },
|
||||
pkg
|
||||
);
|
||||
}
|
||||
},
|
||||
{ concurrency: 10 }
|
||||
)
|
||||
).filter((p): p is Installable<any> => p !== null);
|
||||
|
||||
const filteredPackages = getFilteredSearchPackages();
|
||||
const packageList = registryItems
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue