Skip to content

Commit

Permalink
[Fleet] Add latest package flag and remove force flag (#97289) (#97333)
Browse files Browse the repository at this point in the history
* [Fleet] Add latest package flag and remove force flag

* Fix installing latest package when old package is still installed
  • Loading branch information
Zacqary authored Apr 16, 2021
1 parent 84d8a7d commit 7b7e25d
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 65 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/fleet/common/constants/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@

export const PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE =
'fleet-preconfiguration-deletion-record';

export const PRECONFIGURATION_LATEST_KEYWORD = 'latest';
4 changes: 1 addition & 3 deletions x-pack/plugins/fleet/common/types/models/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,4 @@ export interface PreconfiguredAgentPolicy extends Omit<NewAgentPolicy, 'namespac
>;
}

export interface PreconfiguredPackage extends Omit<PackagePolicyPackage, 'title'> {
force?: boolean;
}
export type PreconfiguredPackage = Omit<PackagePolicyPackage, 'title'>;
1 change: 1 addition & 0 deletions x-pack/plugins/fleet/server/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ export {
ENROLLMENT_API_KEYS_INDEX,
AGENTS_INDEX,
PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE,
PRECONFIGURATION_LATEST_KEYWORD,
} from '../../common';
77 changes: 25 additions & 52 deletions x-pack/plugins/fleet/server/services/epm/packages/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
import { PACKAGES_SAVED_OBJECT_TYPE, MAX_TIME_COMPLETE_INSTALL } from '../../../constants';
import type { KibanaAssetType } from '../../../types';
import type {
AssetReference,
Installation,
AssetType,
EsAssetReference,
Expand All @@ -46,29 +45,6 @@ import { removeInstallation } from './remove';
import { getPackageSavedObjects } from './get';
import { _installPackage } from './_install_package';

export async function installLatestPackage(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
esClient: ElasticsearchClient;
}): Promise<AssetReference[]> {
const { savedObjectsClient, pkgName, esClient } = options;
try {
const latestPackage = await Registry.fetchFindLatestPackage(pkgName);
const pkgkey = Registry.pkgToPkgKey({
name: latestPackage.name,
version: latestPackage.version,
});
return installPackage({
installSource: 'registry',
savedObjectsClient,
pkgkey,
esClient,
}).then(({ assets }) => assets);
} catch (err) {
throw err;
}
}

export async function ensureInstalledDefaultPackages(
savedObjectsClient: SavedObjectsClientContract,
esClient: ElasticsearchClient
Expand Down Expand Up @@ -97,14 +73,17 @@ export async function ensureInstalledDefaultPackages(
});
}

export async function isPackageVersionInstalled(options: {
async function isPackageVersionOrLaterInstalled(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
pkgVersion?: string;
pkgVersion: string;
}): Promise<Installation | false> {
const { savedObjectsClient, pkgName, pkgVersion } = options;
const installedPackage = await getInstallation({ savedObjectsClient, pkgName });
if (installedPackage && (!pkgVersion || installedPackage.version === pkgVersion)) {
if (
installedPackage &&
(installedPackage.version === pkgVersion || semverLt(pkgVersion, installedPackage.version))
) {
return installedPackage;
}
return false;
Expand All @@ -115,37 +94,31 @@ export async function ensureInstalledPackage(options: {
pkgName: string;
esClient: ElasticsearchClient;
pkgVersion?: string;
force?: boolean;
}): Promise<Installation> {
const { savedObjectsClient, pkgName, esClient, pkgVersion, force } = options;
const installedPackage = await isPackageVersionInstalled({
const { savedObjectsClient, pkgName, esClient, pkgVersion } = options;

// If pkgVersion isn't specified, find the latest package version
const pkgKeyProps = pkgVersion
? { name: pkgName, version: pkgVersion }
: await Registry.fetchFindLatestPackage(pkgName);

const installedPackage = await isPackageVersionOrLaterInstalled({
savedObjectsClient,
pkgName,
pkgVersion,
pkgName: pkgKeyProps.name,
pkgVersion: pkgKeyProps.version,
});
if (installedPackage) {
return installedPackage;
}
// if the requested packaged was not found to be installed, install
if (pkgVersion) {
const pkgkey = Registry.pkgToPkgKey({
name: pkgName,
version: pkgVersion,
});
await installPackage({
installSource: 'registry',
savedObjectsClient,
pkgkey,
esClient,
force,
});
} else {
await installLatestPackage({
savedObjectsClient,
pkgName,
esClient,
});
}
const pkgkey = Registry.pkgToPkgKey(pkgKeyProps);
await installPackage({
installSource: 'registry',
savedObjectsClient,
pkgkey,
esClient,
force: true, // Always force outdated packages to be installed if a later version isn't installed
});

const installation = await getInstallation({ savedObjectsClient, pkgName });
if (!installation) throw new Error(`could not get installation ${pkgName}`);
return installation;
Expand Down
16 changes: 9 additions & 7 deletions x-pack/plugins/fleet/server/services/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import type {
PreconfiguredAgentPolicy,
PreconfiguredPackage,
} from '../../common';
import { PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE } from '../constants';
import {
PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE,
PRECONFIGURATION_LATEST_KEYWORD,
} from '../constants';

import { escapeSearchQueryPhrase } from './saved_object';

Expand Down Expand Up @@ -64,8 +67,8 @@ export async function ensurePreconfiguredPackagesAndPolicies(

// Preinstall packages specified in Kibana config
const preconfiguredPackages = await Promise.all(
packages.map(({ name, version, force }) =>
ensureInstalledPreconfiguredPackage(soClient, esClient, name, version, force)
packages.map(({ name, version }) =>
ensureInstalledPreconfiguredPackage(soClient, esClient, name, version)
)
);

Expand Down Expand Up @@ -202,15 +205,14 @@ async function ensureInstalledPreconfiguredPackage(
soClient: SavedObjectsClientContract,
esClient: ElasticsearchClient,
pkgName: string,
pkgVersion: string,
force?: boolean
pkgVersion: string
) {
const isLatest = pkgVersion === PRECONFIGURATION_LATEST_KEYWORD;
return ensureInstalledPackage({
savedObjectsClient: soClient,
pkgName,
esClient,
pkgVersion,
force,
pkgVersion: isLatest ? undefined : pkgVersion,
});
}

Expand Down
7 changes: 4 additions & 3 deletions x-pack/plugins/fleet/server/types/models/preconfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import semverValid from 'semver/functions/valid';

import { PRECONFIGURATION_LATEST_KEYWORD } from '../../constants';

import { AgentPolicyBaseSchema } from './agent_policy';
import { NamespaceSchema } from './package_policy';

Expand All @@ -27,14 +29,13 @@ export const PreconfiguredPackagesSchema = schema.arrayOf(
name: schema.string(),
version: schema.string({
validate: (value) => {
if (!semverValid(value)) {
if (value !== PRECONFIGURATION_LATEST_KEYWORD && !semverValid(value)) {
return i18n.translate('xpack.fleet.config.invalidPackageVersionError', {
defaultMessage: 'must be a valid semver',
defaultMessage: 'must be a valid semver, or the keyword `latest`',
});
}
},
}),
force: schema.maybe(schema.boolean()),
})
);

Expand Down

0 comments on commit 7b7e25d

Please sign in to comment.