[8.0] [Fleet] Avoid breaking setup when compatible package is not available in registry (#125525) (#125672)

* [Fleet] Avoid breaking setup when compatible package is not available in registry (#125525)

(cherry picked from commit 928638e395)

* [Fleet] Use registry version check on main (#125495)

* [Fleet] Get package info should not store the whole package (#123509)

Co-authored-by: Josh Dover <1813008+joshdover@users.noreply.github.com>
Co-authored-by: Nicolas Chaulet <nicolas.chaulet@elastic.co>
This commit is contained in:
Kibana Machine 2022-02-16 07:41:23 -05:00 committed by GitHub
parent 38c6c85855
commit 226be06574
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 206 additions and 747 deletions

View file

@ -646,6 +646,9 @@
"properties": {
"force": {
"type": "boolean"
},
"ignore_constraints": {
"type": "boolean"
}
}
}

View file

@ -396,6 +396,8 @@ paths:
properties:
force:
type: boolean
ignore_constraints:
type: boolean
put:
summary: Packages - Update
tags: []

View file

@ -78,6 +78,8 @@ post:
properties:
force:
type: boolean
ignore_constraints:
type: boolean
put:
summary: Packages - Update
tags: []

View file

@ -43,7 +43,7 @@ import {
getCategories,
getPackages,
getFile,
getPackageInfo,
getPackageInfoFromRegistry,
isBulkInstallError,
installPackage,
removeInstallation,
@ -198,7 +198,7 @@ export const getInfoHandler: FleetRequestHandler<TypeOf<typeof GetInfoRequestSch
if (pkgVersion && !semverValid(pkgVersion)) {
throw new IngestManagerError('Package version is not a valid semver');
}
const res = await getPackageInfo({
const res = await getPackageInfoFromRegistry({
savedObjectsClient,
pkgName,
pkgVersion: pkgVersion || '',
@ -263,6 +263,7 @@ export const installPackageFromRegistryHandler: FleetRequestHandler<
esClient,
spaceId,
force: request.body?.force,
ignoreConstraints: request.body?.ignore_constraints,
});
if (!res.error) {
const body: InstallPackageResponse = {

View file

@ -88,7 +88,7 @@ jest.mock(
jest.mock('../../services/epm/packages', () => {
return {
ensureInstalledPackage: jest.fn(() => Promise.resolve()),
getPackageInfo: jest.fn(() => Promise.resolve()),
getPackageInfoFromRegistry: jest.fn(() => Promise.resolve()),
};
});

View file

@ -19,6 +19,8 @@ import * as Registry from '../registry';
import { createAppContextStartContractMock } from '../../../mocks';
import { appContextService } from '../../app_context';
import { PackageNotFoundError } from '../../../errors';
import { getPackageInfo, getPackageUsageStats } from './get';
const MockRegistry = Registry as jest.Mocked<typeof Registry>;
@ -279,5 +281,45 @@ describe('When using EPM `get` services', () => {
});
});
});
describe('registry fetch errors', () => {
it('throws when a package that is not installed is not available in the registry', async () => {
MockRegistry.fetchFindLatestPackage.mockResolvedValue(undefined);
const soClient = savedObjectsClientMock.create();
soClient.get.mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError());
await expect(
getPackageInfo({
savedObjectsClient: soClient,
pkgName: 'my-package',
pkgVersion: '1.0.0',
})
).rejects.toThrowError(PackageNotFoundError);
});
it('sets the latestVersion to installed version when an installed package is not available in the registry', async () => {
MockRegistry.fetchFindLatestPackage.mockResolvedValue(undefined);
const soClient = savedObjectsClientMock.create();
soClient.get.mockResolvedValue({
id: 'my-package',
type: PACKAGES_SAVED_OBJECT_TYPE,
references: [],
attributes: {
install_status: 'installed',
},
});
await expect(
getPackageInfo({
savedObjectsClient: soClient,
pkgName: 'my-package',
pkgVersion: '1.0.0',
})
).resolves.toMatchObject({
latestVersion: '1.0.0',
status: 'installed',
});
});
});
});
});

View file

@ -21,7 +21,7 @@ import type {
GetCategoriesRequest,
} from '../../../../common/types';
import type { Installation, PackageInfo } from '../../../types';
import { IngestManagerError } from '../../../errors';
import { IngestManagerError, PackageNotFoundError } from '../../../errors';
import { appContextService } from '../../';
import * as Registry from '../registry';
import { getEsPackage } from '../archive/storage';
@ -98,7 +98,7 @@ export async function getPackageSavedObjects(
export const getInstallations = getPackageSavedObjects;
export async function getPackageInfo(options: {
export async function getPackageInfoFromRegistry(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
pkgVersion: string;
@ -111,11 +111,50 @@ export async function getPackageInfo(options: {
// If no package version is provided, use the installed version in the response
let responsePkgVersion = pkgVersion || savedObject?.attributes.install_version;
// If no installed version of the given package exists, default to the latest version of the package
if (!responsePkgVersion) {
responsePkgVersion = latestPackage.version;
}
const packageInfo = await Registry.fetchInfo(pkgName, responsePkgVersion);
// Fix the paths
const paths =
packageInfo?.assets?.map((path) =>
path.replace(`/package/${pkgName}/${pkgVersion}`, `${pkgName}-${pkgVersion}`)
) ?? [];
// add properties that aren't (or aren't yet) on the package
const additions: EpmPackageAdditions = {
latestVersion: latestPackage.version,
title: packageInfo.title || nameAsTitle(packageInfo.name),
assets: Registry.groupPathsByService(paths || []),
removable: true,
notice: Registry.getNoticePath(paths || []),
keepPoliciesUpToDate: savedObject?.attributes.keep_policies_up_to_date ?? false,
};
const updated = { ...packageInfo, ...additions };
return createInstallableFrom(updated, savedObject);
}
export async function getPackageInfo(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
pkgVersion: string;
}): Promise<PackageInfo> {
const { savedObjectsClient, pkgName, pkgVersion } = options;
const [savedObject, latestPackage] = await Promise.all([
getInstallationObject({ savedObjectsClient, pkgName }),
Registry.fetchFindLatestPackage(pkgName, { throwIfNotFound: false }),
]);
if (!savedObject && !latestPackage) {
throw new PackageNotFoundError(`[${pkgName}] package not installed or found in registry`);
}
// If no package version is provided, use the installed version in the response, fallback to package from registry
const responsePkgVersion =
pkgVersion ?? savedObject?.attributes.install_version ?? latestPackage!.version;
const getPackageRes = await getPackageFromSource({
pkgName,
@ -127,7 +166,7 @@ export async function getPackageInfo(options: {
// add properties that aren't (or aren't yet) on the package
const additions: EpmPackageAdditions = {
latestVersion: latestPackage.version,
latestVersion: latestPackage?.version ?? responsePkgVersion,
title: packageInfo.title || nameAsTitle(packageInfo.name),
assets: Registry.groupPathsByService(paths || []),
removable: !isUnremovablePackage(pkgName),

View file

@ -24,6 +24,7 @@ export {
getInstallation,
getInstallations,
getPackageInfo,
getPackageInfoFromRegistry,
getPackages,
getLimitedPackages,
} from './get';

View file

@ -209,6 +209,7 @@ interface InstallRegistryPackageParams {
esClient: ElasticsearchClient;
spaceId: string;
force?: boolean;
ignoreConstraints?: boolean;
}
function getTelemetryEvent(pkgName: string, pkgVersion: string): PackageUpdateEvent {
@ -237,6 +238,7 @@ async function installPackageFromRegistry({
esClient,
spaceId,
force = false,
ignoreConstraints = false,
}: InstallRegistryPackageParams): Promise<InstallResult> {
const logger = appContextService.getLogger();
// TODO: change epm API to /packageName/version so we don't need to do this
@ -253,7 +255,7 @@ async function installPackageFromRegistry({
installType = getInstallType({ pkgVersion, installedPkg });
// get latest package version
const latestPackage = await Registry.fetchFindLatestPackage(pkgName);
const latestPackage = await Registry.fetchFindLatestPackage(pkgName, { ignoreConstraints });
// let the user install if using the force flag or needing to reinstall or install a previous version due to failed update
const installOutOfDateVersionOk =
@ -476,7 +478,7 @@ export async function installPackage(args: InstallPackageParams) {
const { savedObjectsClient, esClient } = args;
if (args.installSource === 'registry') {
const { pkgkey, force, spaceId } = args;
const { pkgkey, force, ignoreConstraints, spaceId } = args;
logger.debug(`kicking off install of ${pkgkey} from registry`);
const response = installPackageFromRegistry({
savedObjectsClient,
@ -484,6 +486,7 @@ export async function installPackage(args: InstallPackageParams) {
esClient,
spaceId,
force,
ignoreConstraints,
});
return response;
} else if (args.installSource === 'upload') {

View file

@ -65,18 +65,33 @@ export async function fetchList(params?: SearchParams): Promise<RegistrySearchRe
return fetchUrl(url.toString()).then(JSON.parse);
}
export async function fetchFindLatestPackage(packageName: string): Promise<RegistrySearchResult> {
// When `throwIfNotFound` is true or undefined, return type will never be undefined.
export async function fetchFindLatestPackage(
packageName: string,
options?: { ignoreConstraints?: boolean; throwIfNotFound?: true }
): Promise<RegistrySearchResult>;
export async function fetchFindLatestPackage(
packageName: string,
options: { ignoreConstraints?: boolean; throwIfNotFound: false }
): Promise<RegistrySearchResult | undefined>;
export async function fetchFindLatestPackage(
packageName: string,
options?: { ignoreConstraints?: boolean; throwIfNotFound?: boolean }
): Promise<RegistrySearchResult | undefined> {
const { ignoreConstraints = false, throwIfNotFound = true } = options ?? {};
const registryUrl = getRegistryUrl();
const url = new URL(`${registryUrl}/search?package=${packageName}&experimental=true`);
setKibanaVersion(url);
if (!ignoreConstraints) {
setKibanaVersion(url);
}
const res = await fetchUrl(url.toString());
const searchResults = JSON.parse(res);
if (searchResults.length) {
return searchResults[0];
} else {
throw new PackageNotFoundError(`${packageName} not found`);
} else if (throwIfNotFound) {
throw new PackageNotFoundError(`[${packageName}] package not found in registry`);
}
}
@ -116,10 +131,8 @@ function setKibanaVersion(url: URL) {
}
const kibanaVersion = appContextService.getKibanaVersion().split('-')[0]; // may be x.y.z-SNAPSHOT
const kibanaBranch = appContextService.getKibanaBranch();
// on master, request all packages regardless of version
if (kibanaVersion && kibanaBranch !== 'master') {
if (kibanaVersion) {
url.searchParams.set('kibana.version', kibanaVersion);
}
}

View file

@ -74,7 +74,8 @@ export const InstallPackageFromRegistryRequestSchema = {
}),
body: schema.nullable(
schema.object({
force: schema.boolean(),
force: schema.boolean({ defaultValue: false }),
ignore_constraints: schema.boolean({ defaultValue: false }),
})
),
};

View file

@ -1,712 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Fleet Endpoints EPM Endpoints installs packages from direct upload should install a zip archive correctly and package info should return correctly after validation 1`] = `
Object {
"assets": Object {
"elasticsearch": Object {
"ingest_pipeline": Array [
Object {
"dataset": "access",
"file": "default.yml",
"path": "apache-0.1.4/data_stream/access/elasticsearch/ingest_pipeline/default.yml",
"pkgkey": "apache-0.1.4",
"service": "elasticsearch",
"type": "ingest_pipeline",
},
Object {
"dataset": "error",
"file": "default.yml",
"path": "apache-0.1.4/data_stream/error/elasticsearch/ingest_pipeline/default.yml",
"pkgkey": "apache-0.1.4",
"service": "elasticsearch",
"type": "ingest_pipeline",
},
],
},
"kibana": Object {
"dashboard": Array [
Object {
"file": "apache-Logs-Apache-Dashboard-ecs-new.json",
"path": "apache-0.1.4/kibana/dashboard/apache-Logs-Apache-Dashboard-ecs-new.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "dashboard",
},
Object {
"file": "apache-Metrics-Apache-HTTPD-server-status-ecs.json",
"path": "apache-0.1.4/kibana/dashboard/apache-Metrics-Apache-HTTPD-server-status-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "dashboard",
},
],
"search": Array [
Object {
"file": "Apache-access-logs-ecs.json",
"path": "apache-0.1.4/kibana/search/Apache-access-logs-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "search",
},
Object {
"file": "Apache-errors-log-ecs.json",
"path": "apache-0.1.4/kibana/search/Apache-errors-log-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "search",
},
Object {
"file": "Apache-HTTPD-ecs.json",
"path": "apache-0.1.4/kibana/search/Apache-HTTPD-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "search",
},
],
"visualization": Array [
Object {
"file": "Apache-access-unique-IPs-map-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-access-unique-IPs-map-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-CPU-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-CPU-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-Load1-slash-5-slash-15-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-Load1-slash-5-slash-15-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-response-codes-over-time-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-response-codes-over-time-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-Workers-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-Workers-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-Hostname-list-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-Hostname-list-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-error-logs-over-time-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-error-logs-over-time-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-Scoreboard-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-Scoreboard-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-Uptime-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-Uptime-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-operating-systems-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-operating-systems-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-HTTPD-Total-accesses-and-kbytes-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-HTTPD-Total-accesses-and-kbytes-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-browsers-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-browsers-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
Object {
"file": "Apache-response-codes-of-top-URLs-ecs.json",
"path": "apache-0.1.4/kibana/visualization/Apache-response-codes-of-top-URLs-ecs.json",
"pkgkey": "apache-0.1.4",
"service": "kibana",
"type": "visualization",
},
],
},
},
"categories": Array [
"web",
],
"conditions": Object {
"kibana.version": "^7.9.0",
},
"data_streams": Array [
Object {
"dataset": "apache.access",
"package": "apache",
"path": "access",
"release": "experimental",
"streams": Array [
Object {
"description": "Collect Apache access logs",
"input": "logfile",
"template_path": "log.yml.hbs",
"title": "Apache access logs",
"vars": Array [
Object {
"default": Array [
"/var/log/apache2/access.log*",
"/var/log/apache2/other_vhosts_access.log*",
"/var/log/httpd/access_log*",
],
"multi": true,
"name": "paths",
"required": true,
"show_user": true,
"title": "Paths",
"type": "text",
},
],
},
],
"title": "Apache access logs",
"type": "logs",
},
Object {
"dataset": "apache.status",
"package": "apache",
"path": "status",
"release": "experimental",
"streams": Array [
Object {
"description": "Collect Apache status metrics",
"input": "apache/metrics",
"template_path": "stream.yml.hbs",
"title": "Apache status metrics",
"vars": Array [
Object {
"default": "10s",
"multi": false,
"name": "period",
"required": true,
"show_user": true,
"title": "Period",
"type": "text",
},
Object {
"default": "/server-status",
"multi": false,
"name": "server_status_path",
"required": true,
"show_user": false,
"title": "Server Status Path",
"type": "text",
},
],
},
],
"title": "Apache status metrics",
"type": "metrics",
},
Object {
"dataset": "apache.error",
"package": "apache",
"path": "error",
"release": "experimental",
"streams": Array [
Object {
"description": "Collect Apache error logs",
"input": "logfile",
"template_path": "log.yml.hbs",
"title": "Apache error logs",
"vars": Array [
Object {
"default": Array [
"/var/log/apache2/error.log*",
"/var/log/httpd/error_log*",
],
"multi": true,
"name": "paths",
"required": true,
"show_user": true,
"title": "Paths",
"type": "text",
},
],
},
],
"title": "Apache error logs",
"type": "logs",
},
],
"description": "Apache Uploaded Test Integration",
"format_version": "1.0.0",
"icons": Array [
Object {
"size": "32x32",
"src": "/img/logo_apache_test.svg",
"title": "Apache Logo",
"type": "image/svg+xml",
},
],
"keepPoliciesUpToDate": false,
"license": "basic",
"name": "apache",
"owner": Object {
"github": "elastic/integrations-services",
},
"policy_templates": Array [
Object {
"description": "Collect logs and metrics from Apache instances",
"inputs": Array [
Object {
"description": "Collecting Apache access and error logs",
"title": "Collect logs from Apache instances",
"type": "logfile",
"vars": Array [],
},
Object {
"description": "Collecting Apache status metrics",
"title": "Collect metrics from Apache instances",
"type": "apache/metrics",
"vars": Array [
Object {
"default": Array [
"http://127.0.0.1",
],
"multi": true,
"name": "hosts",
"required": true,
"show_user": true,
"title": "Hosts",
"type": "text",
},
],
},
],
"multiple": true,
"name": "apache",
"title": "Apache logs and metrics",
},
],
"readme": "/package/apache/0.1.4/docs/README.md",
"release": "experimental",
"removable": true,
"savedObject": Object {
"attributes": Object {
"es_index_patterns": Object {
"access": "logs-apache.access-*",
"error": "logs-apache.error-*",
"status": "metrics-apache.status-*",
},
"install_source": "upload",
"install_status": "installed",
"install_version": "0.1.4",
"installed_es": Array [
Object {
"id": "logs-apache.access-0.1.4-default",
"type": "ingest_pipeline",
},
Object {
"id": "logs-apache.error-0.1.4-default",
"type": "ingest_pipeline",
},
Object {
"id": "logs-apache.access",
"type": "index_template",
},
Object {
"id": "logs-apache.access@settings",
"type": "component_template",
},
Object {
"id": "logs-apache.access@custom",
"type": "component_template",
},
Object {
"id": "metrics-apache.status",
"type": "index_template",
},
Object {
"id": "metrics-apache.status@settings",
"type": "component_template",
},
Object {
"id": "metrics-apache.status@custom",
"type": "component_template",
},
Object {
"id": "logs-apache.error",
"type": "index_template",
},
Object {
"id": "logs-apache.error@settings",
"type": "component_template",
},
Object {
"id": "logs-apache.error@custom",
"type": "component_template",
},
],
"installed_kibana": Array [
Object {
"id": "apache-Logs-Apache-Dashboard-ecs",
"type": "dashboard",
},
Object {
"id": "apache-Metrics-Apache-HTTPD-server-status-ecs",
"type": "dashboard",
},
Object {
"id": "Apache-access-unique-IPs-map-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-CPU-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-Load1-slash-5-slash-15-ecs",
"type": "visualization",
},
Object {
"id": "Apache-response-codes-over-time-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-Workers-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-Hostname-list-ecs",
"type": "visualization",
},
Object {
"id": "Apache-error-logs-over-time-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-Scoreboard-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-Uptime-ecs",
"type": "visualization",
},
Object {
"id": "Apache-operating-systems-ecs",
"type": "visualization",
},
Object {
"id": "Apache-HTTPD-Total-accesses-and-kbytes-ecs",
"type": "visualization",
},
Object {
"id": "Apache-browsers-ecs",
"type": "visualization",
},
Object {
"id": "Apache-response-codes-of-top-URLs-ecs",
"type": "visualization",
},
Object {
"id": "Apache-access-logs-ecs",
"type": "search",
},
Object {
"id": "Apache-errors-log-ecs",
"type": "search",
},
Object {
"id": "Apache-HTTPD-ecs",
"type": "search",
},
],
"installed_kibana_space_id": "default",
"name": "apache",
"package_assets": Array [
Object {
"id": "2f1ab9c0-8cf6-5e83-afcd-0d12851c8108",
"type": "epm-packages-assets",
},
Object {
"id": "841166f1-6db0-5f7a-a8d9-768e88ddf984",
"type": "epm-packages-assets",
},
Object {
"id": "b12ae5e1-daf2-51a7-99d8-0888d1f13b5b",
"type": "epm-packages-assets",
},
Object {
"id": "2f263b24-c36a-5ea8-a707-76d1f274c888",
"type": "epm-packages-assets",
},
Object {
"id": "bd5ff9ad-ba4a-5215-b5af-cef58a3aa886",
"type": "epm-packages-assets",
},
Object {
"id": "5fc59aa9-1d7e-50ae-8ce5-b875ab44cfc5",
"type": "epm-packages-assets",
},
Object {
"id": "7c850453-346b-5010-a946-28b83fc69e48",
"type": "epm-packages-assets",
},
Object {
"id": "f02f8adb-3e0c-5f2f-b4f2-a04dc645b713",
"type": "epm-packages-assets",
},
Object {
"id": "889d88db-6214-5836-aeff-1a87f8513b27",
"type": "epm-packages-assets",
},
Object {
"id": "06a6b940-a745-563c-abf4-83eb3335926b",
"type": "epm-packages-assets",
},
Object {
"id": "e68fd7ac-302e-5b75-bbbb-d69b441c8848",
"type": "epm-packages-assets",
},
Object {
"id": "2c57fe0f-3b1a-57da-a63b-28f9b9e82bce",
"type": "epm-packages-assets",
},
Object {
"id": "13db43e8-f8f9-57f0-b131-a171c2f2070f",
"type": "epm-packages-assets",
},
Object {
"id": "e8750081-1c0b-5c55-bcab-fa6d47f01a85",
"type": "epm-packages-assets",
},
Object {
"id": "71af57fe-25c4-5935-9879-ca4a2fba730e",
"type": "epm-packages-assets",
},
Object {
"id": "cc287718-9573-5c56-a9ed-6dfef6589506",
"type": "epm-packages-assets",
},
Object {
"id": "8badd8ba-289a-5e60-a1c0-f3d39e15cda3",
"type": "epm-packages-assets",
},
Object {
"id": "20300efc-10eb-5fac-ba90-f6aa9b467e84",
"type": "epm-packages-assets",
},
Object {
"id": "047c89df-33c2-5d74-b0a4-8b441879761c",
"type": "epm-packages-assets",
},
Object {
"id": "9838a13f-1b89-5c54-844e-978620d66a1d",
"type": "epm-packages-assets",
},
Object {
"id": "e105414b-221d-5433-8b24-452625f59b7c",
"type": "epm-packages-assets",
},
Object {
"id": "eb166c25-843b-5271-8d43-6fb005d2df5a",
"type": "epm-packages-assets",
},
Object {
"id": "342dbf4d-d88d-53e8-b365-d3639ebbbb14",
"type": "epm-packages-assets",
},
Object {
"id": "f98c44a3-eaea-505f-8598-3b7f1097ef59",
"type": "epm-packages-assets",
},
Object {
"id": "12da8c6c-d0e3-589c-9244-88d857ea76b6",
"type": "epm-packages-assets",
},
Object {
"id": "e2d151ed-709c-542d-b797-cb95f353b9b3",
"type": "epm-packages-assets",
},
Object {
"id": "f434cffe-0b00-59de-a17f-c1e71bd4ab0f",
"type": "epm-packages-assets",
},
Object {
"id": "5bd0c25f-04a5-5fd0-8298-ba9aa2f6fe5e",
"type": "epm-packages-assets",
},
Object {
"id": "279da3a3-8e9b-589b-86e0-bd7364821bab",
"type": "epm-packages-assets",
},
Object {
"id": "b8758fcb-08bf-50fa-89bd-24398955298a",
"type": "epm-packages-assets",
},
Object {
"id": "96e4eb36-03c3-5856-af44-559fd5133f2b",
"type": "epm-packages-assets",
},
Object {
"id": "a59a79c3-66bd-5cfc-91f5-ee84f7227855",
"type": "epm-packages-assets",
},
Object {
"id": "395143f9-54bf-5b46-b1be-a7b2a6142ad9",
"type": "epm-packages-assets",
},
Object {
"id": "3449b8d2-ffd5-5aec-bb32-4245f2fbcde4",
"type": "epm-packages-assets",
},
Object {
"id": "ab44094e-6c9d-50b8-b5c4-2e518d89912e",
"type": "epm-packages-assets",
},
Object {
"id": "b093bfc0-6e98-5a1b-a502-e838a36f6568",
"type": "epm-packages-assets",
},
Object {
"id": "03d86823-b756-5b91-850d-7ad231d33546",
"type": "epm-packages-assets",
},
Object {
"id": "a76af2f0-049b-5be1-8d20-e87c9d1c2709",
"type": "epm-packages-assets",
},
Object {
"id": "bc2f0c1e-992e-5407-9435-fedb39ff74ea",
"type": "epm-packages-assets",
},
Object {
"id": "84668ac1-d5ef-545b-88f3-1e49f8f1c8ad",
"type": "epm-packages-assets",
},
Object {
"id": "69b41271-91a0-5a2e-a62c-60364d5a9c8f",
"type": "epm-packages-assets",
},
Object {
"id": "8e4ec555-5fbf-55d3-bea3-3af12c9aca3f",
"type": "epm-packages-assets",
},
Object {
"id": "aa18f3f9-f62a-5ab8-9b34-75696efa5c48",
"type": "epm-packages-assets",
},
Object {
"id": "71c8c6b1-2116-5817-b65f-7a87ef5ef2b7",
"type": "epm-packages-assets",
},
Object {
"id": "8f6d7a1f-1e7f-5a60-8fe7-ce19115ed460",
"type": "epm-packages-assets",
},
Object {
"id": "c115dbbf-edad-59f2-b046-c65a0373a81c",
"type": "epm-packages-assets",
},
Object {
"id": "b7d696c3-8106-585c-9ecc-94a75cf1e3da",
"type": "epm-packages-assets",
},
Object {
"id": "639e6a78-59d8-5ce8-9687-64e8f9af7e71",
"type": "epm-packages-assets",
},
Object {
"id": "ae60c853-7a90-58d2-ab6c-04d3be5f1847",
"type": "epm-packages-assets",
},
Object {
"id": "0cd33163-2ae4-57eb-96f6-c50af6685cab",
"type": "epm-packages-assets",
},
Object {
"id": "39e0f78f-1172-5e61-9446-65ef3c0cb46c",
"type": "epm-packages-assets",
},
Object {
"id": "b08f10ee-6afd-5e89-b9b4-569064fbdd9f",
"type": "epm-packages-assets",
},
Object {
"id": "efcbe1c6-b2d5-521c-b27a-2146f08a604d",
"type": "epm-packages-assets",
},
Object {
"id": "f9422c02-d43f-5ebb-b7c5-9e32f9b77c21",
"type": "epm-packages-assets",
},
Object {
"id": "c276e880-3ba8-58e7-a5d5-c07707dba6b7",
"type": "epm-packages-assets",
},
Object {
"id": "561a3711-c386-541c-9a77-2d0fa256caf6",
"type": "epm-packages-assets",
},
Object {
"id": "1378350d-2e2b-52dd-ab3a-d8b9a09df92f",
"type": "epm-packages-assets",
},
Object {
"id": "94e40729-4aea-59c8-86ba-075137c000dc",
"type": "epm-packages-assets",
},
],
"removable": true,
"version": "0.1.4",
},
"id": "apache",
"namespaces": Array [],
"references": Array [],
"type": "epm-packages",
},
"screenshots": Array [
Object {
"size": "1215x1199",
"src": "/img/kibana-apache-test.png",
"title": "Apache Integration",
"type": "image/png",
},
Object {
"size": "1919x1079",
"src": "/img/apache_httpd_server_status.png",
"title": "Apache HTTPD Server Status",
"type": "image/png",
},
],
"status": "installed",
"title": "Apache",
"type": "integration",
"version": "0.1.4",
}
`;

View file

@ -66,10 +66,10 @@ export default function (providerContext: FtrProviderContext) {
.get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`)
.expect(200);
const packageInfo = res.body.item;
// 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);
// Get package info always return data from the registry
expect(packageInfo.description).to.not.equal('Apache Uploaded Test Integration');
// download property exist on uploaded packages
expect(packageInfo.download).to.not.equal(undefined);
await uninstallPackage(testPkgName, testPkgVersion);
});
it('returns correct package info from registry if a different version is installed by upload', async function () {

View file

@ -87,20 +87,6 @@ export default function (providerContext: FtrProviderContext) {
.send(buf)
.expect(200);
expect(res.body.items.length).to.be(27);
const packageInfoRes = await supertest
.get(`/api/fleet/epm/packages/${testPkgName}/${testPkgVersion}`)
.set('kbn-xsrf', 'xxxx')
.expect(200);
delete packageInfoRes.body.item.latestVersion;
delete packageInfoRes.body.item.savedObject.attributes.install_started_at;
delete packageInfoRes.body.item.savedObject.version;
delete packageInfoRes.body.item.savedObject.updated_at;
delete packageInfoRes.body.item.savedObject.coreMigrationVersion;
delete packageInfoRes.body.item.savedObject.migrationVersion;
expectSnapshot(packageInfoRes.body.item).toMatch();
});
it('should throw an error if the archive is zip but content type is gzip', async function () {

View file

@ -52,6 +52,40 @@ export default function (providerContext: FtrProviderContext) {
});
});
it('does not fail when package is no longer compatible in registry', async () => {
await supertest
.post(`/api/fleet/epm/packages/deprecated/0.1.0`)
.set('kbn-xsrf', 'xxxx')
.send({ force: true, ignore_constraints: true })
.expect(200);
const agentPolicyResponse = await supertest
.post(`/api/fleet/agent_policies`)
.set('kbn-xsrf', 'xxxx')
.send({
name: 'deprecated-ap-1',
namespace: 'default',
monitoring_enabled: [],
})
.expect(200);
await supertest
.post(`/api/fleet/package_policies`)
.set('kbn-xsrf', 'xxxx')
.send({
name: 'deprecated-1',
policy_id: agentPolicyResponse.body.item.id,
package: {
name: 'deprecated',
version: '0.1.0',
},
inputs: [],
})
.expect(200);
await supertest.post('/api/fleet/setup').set('kbn-xsrf', 'xxxx').expect(200);
});
it('allows elastic/fleet-server user to call required APIs', async () => {
const {
token,

View file

@ -0,0 +1,16 @@
- name: data_stream.type
type: constant_keyword
description: >
Data stream type.
- name: data_stream.dataset
type: constant_keyword
description: >
Data stream dataset.
- name: data_stream.namespace
type: constant_keyword
description: >
Data stream namespace.
- name: '@timestamp'
type: date
description: >
Event timestamp.

View file

@ -0,0 +1,9 @@
title: Test Dataset
type: logs
elasticsearch:
index_template.mappings:
dynamic: false
index_template.settings:
index.lifecycle.name: reference

View file

@ -0,0 +1,3 @@
# Test package
This is a test package for testing installing or updating to an out-of-date package

View file

@ -0,0 +1,16 @@
format_version: 1.0.0
name: deprecated
title: Package install/update test
description: This is a package for testing deprecated packages
version: 0.1.0
categories: []
release: beta
type: integration
license: basic
conditions:
# Version number is not compatible with current version
elasticsearch:
version: '^1.0.0'
kibana:
version: '^1.0.0'