Skip to content

Commit

Permalink
[EPM] Change PACKAGES_SAVED_OBJECT_TYPE id (#62818)
Browse files Browse the repository at this point in the history
* changed PACKAGES_SAVED_OBJECT_TYPE id from packageName-version to packageName

* change references to keys to package and version

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
neptunian and elasticmachine authored Apr 9, 2020
1 parent 6985478 commit a0c247b
Show file tree
Hide file tree
Showing 14 changed files with 118 additions and 139 deletions.
4 changes: 3 additions & 1 deletion x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ export const getInfoHandler: RequestHandler<TypeOf<typeof GetInfoRequestSchema.p
try {
const { pkgkey } = request.params;
const savedObjectsClient = context.core.savedObjects.client;
const res = await getPackageInfo({ savedObjectsClient, pkgkey });
// TODO: change epm API to /packageName/version so we don't need to do this
const [pkgName, pkgVersion] = pkgkey.split('-');
const res = await getPackageInfo({ savedObjectsClient, pkgName, pkgVersion });
const body: GetInfoResponse = {
response: res,
success: true,
Expand Down
10 changes: 4 additions & 6 deletions x-pack/plugins/ingest_manager/server/services/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DeleteDatasourcesResponse, packageToConfigDatasource } from '../../comm
import { DATASOURCE_SAVED_OBJECT_TYPE } from '../constants';
import { NewDatasource, Datasource, ListWithKuery } from '../types';
import { agentConfigService } from './agent_config';
import { findInstalledPackageByName, getPackageInfo } from './epm/packages';
import { getPackageInfo, getInstallation } from './epm/packages';
import { outputService } from './output';

const SAVED_OBJECT_TYPE = DATASOURCE_SAVED_OBJECT_TYPE;
Expand Down Expand Up @@ -172,15 +172,13 @@ class DatasourceService {
soClient: SavedObjectsClientContract,
pkgName: string
): Promise<NewDatasource | undefined> {
const pkgInstall = await findInstalledPackageByName({
savedObjectsClient: soClient,
pkgName,
});
const pkgInstall = await getInstallation({ savedObjectsClient: soClient, pkgName });
if (pkgInstall) {
const [pkgInfo, defaultOutputId] = await Promise.all([
getPackageInfo({
savedObjectsClient: soClient,
pkgkey: `${pkgInstall.name}-${pkgInstall.version}`,
pkgName: pkgInstall.name,
pkgVersion: pkgInstall.version,
}),
outputService.getDefaultOutputId(soClient),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
import { CallESAsCurrentUser, ElasticsearchAssetType } from '../../../../types';
import * as Registry from '../../registry';

export async function installILMPolicy(pkgkey: string, callCluster: CallESAsCurrentUser) {
const ilmPaths = await Registry.getArchiveInfo(pkgkey, (entry: Registry.ArchiveEntry) =>
isILMPolicy(entry)
export async function installILMPolicy(
pkgName: string,
pkgVersion: string,
callCluster: CallESAsCurrentUser
) {
const ilmPaths = await Registry.getArchiveInfo(
pkgName,
pkgVersion,
(entry: Registry.ArchiveEntry) => isILMPolicy(entry)
);
if (!ilmPaths.length) return;
await Promise.all(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ export const installPipelines = async (
if (dataset.ingest_pipeline) {
acc.push(
installPipelinesForDataset({
pkgkey: Registry.pkgToPkgKey(registryPackage),
dataset,
callCluster,
packageName: registryPackage.name,
packageVersion: registryPackage.version,
pkgName: registryPackage.name,
pkgVersion: registryPackage.version,
})
);
}
Expand Down Expand Up @@ -68,19 +67,19 @@ export function rewriteIngestPipeline(

export async function installPipelinesForDataset({
callCluster,
pkgkey,
pkgName,
pkgVersion,
dataset,
packageName,
packageVersion,
}: {
callCluster: CallESAsCurrentUser;
pkgkey: string;
pkgName: string;
pkgVersion: string;
dataset: Dataset;
packageName: string;
packageVersion: string;
}): Promise<AssetReference[]> {
const pipelinePaths = await Registry.getArchiveInfo(pkgkey, (entry: Registry.ArchiveEntry) =>
isDatasetPipeline(entry, dataset.path)
const pipelinePaths = await Registry.getArchiveInfo(
pkgName,
pkgVersion,
(entry: Registry.ArchiveEntry) => isDatasetPipeline(entry, dataset.path)
);
let pipelines: any[] = [];
const substitutions: RewriteSubstitution[] = [];
Expand All @@ -90,7 +89,7 @@ export async function installPipelinesForDataset({
const nameForInstallation = getPipelineNameForInstallation({
pipelineName: name,
dataset,
packageVersion,
packageVersion: pkgVersion,
});
const content = Registry.getAsset(path).toString('utf-8');
pipelines.push({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import * as Registry from '../../registry';
export const installTemplates = async (
registryPackage: RegistryPackage,
callCluster: CallESAsCurrentUser,
pkgkey: string
pkgName: string,
pkgVersion: string
) => {
// install any pre-built index template assets,
// atm, this is only the base package's global template
installPreBuiltTemplates(pkgkey, callCluster);
installPreBuiltTemplates(pkgName, pkgVersion, callCluster);

// build templates per dataset from yml files
const datasets = registryPackage.datasets;
Expand All @@ -45,9 +46,15 @@ export const installTemplates = async (
};

// this is temporary until we update the registry to use index templates v2 structure
const installPreBuiltTemplates = async (pkgkey: string, callCluster: CallESAsCurrentUser) => {
const templatePaths = await Registry.getArchiveInfo(pkgkey, (entry: Registry.ArchiveEntry) =>
isTemplate(entry)
const installPreBuiltTemplates = async (
pkgName: string,
pkgVersion: string,
callCluster: CallESAsCurrentUser
) => {
const templatePaths = await Registry.getArchiveInfo(
pkgName,
pkgVersion,
(entry: Registry.ArchiveEntry) => isTemplate(entry)
);
templatePaths.forEach(async path => {
const { file } = Registry.pathParts(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,32 @@ export enum IndexPatternType {
metrics = 'metrics',
events = 'events',
}

// TODO: use a function overload and make pkgName and pkgVersion required for install/update
// and not for an update removal. or separate out the functions
export async function installIndexPatterns(
savedObjectsClient: SavedObjectsClientContract,
pkgkey?: string
pkgName?: string,
pkgVersion?: string
) {
// get all user installed packages
const installedPackages = await getPackageKeysByStatus(
savedObjectsClient,
InstallationStatus.installed
);
// add this package to the array if it doesn't already exist
// this should not happen because a user can't "reinstall" a package
// if it does because the install endpoint is called directly, the install continues
if (pkgkey && !installedPackages.includes(pkgkey)) {
installedPackages.push(pkgkey);
if (pkgName && pkgVersion) {
// add this package to the array if it doesn't already exist
const foundPkg = installedPackages.find(pkg => pkg.pkgName === pkgName);
// this may be removed if we add the packged to saved objects before installing index patterns
// otherwise this is a first time install
// TODO: handle update case when versions are different
if (!foundPkg) {
installedPackages.push({ pkgName, pkgVersion });
}
}

// get each package's registry info
const installedPackagesFetchInfoPromise = installedPackages.map(pkg => Registry.fetchInfo(pkg));
const installedPackagesFetchInfoPromise = installedPackages.map(pkg =>
Registry.fetchInfo(pkg.pkgName, pkg.pkgVersion)
);
const installedPackagesInfo = await Promise.all(installedPackagesFetchInfoPromise);

// for each index pattern type, create an index pattern
Expand All @@ -97,7 +104,7 @@ export async function installIndexPatterns(
];
indexPatternTypes.forEach(async indexPatternType => {
// if this is an update because a package is being unisntalled (no pkgkey argument passed) and no other packages are installed, remove the index pattern
if (!pkgkey && installedPackages.length === 0) {
if (!pkgName && installedPackages.length === 0) {
try {
await savedObjectsClient.delete(INDEX_PATTERN_SAVED_OBJECT_TYPE, `${indexPatternType}-*`);
} catch (err) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function getAssetsData(
): Promise<Registry.ArchiveEntry[]> {
// TODO: Needs to be called to fill the cache but should not be required
const pkgkey = packageInfo.name + '-' + packageInfo.version;
if (!cacheHas(pkgkey)) await Registry.getArchiveInfo(pkgkey);
if (!cacheHas(pkgkey)) await Registry.getArchiveInfo(packageInfo.name, packageInfo.version);

// Gather all asset data
const assets = getAssets(packageInfo, filter, datasetName);
Expand Down
40 changes: 13 additions & 27 deletions x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export async function getPackages(
.map(item =>
createInstallableFrom(
item,
savedObjectsVisible.find(({ attributes }) => attributes.name === item.name)
savedObjectsVisible.find(({ id }) => id === item.name)
)
)
.sort(sortByName);
Expand All @@ -53,23 +53,24 @@ export async function getPackageKeysByStatus(
status: InstallationStatus
) {
const allPackages = await getPackages({ savedObjectsClient });
return allPackages.reduce<string[]>((acc, pkg) => {
return allPackages.reduce<Array<{ pkgName: string; pkgVersion: string }>>((acc, pkg) => {
if (pkg.status === status) {
acc.push(`${pkg.name}-${pkg.version}`);
acc.push({ pkgName: pkg.name, pkgVersion: pkg.version });
}
return acc;
}, []);
}

export async function getPackageInfo(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgkey: string;
pkgName: string;
pkgVersion: string;
}): Promise<PackageInfo> {
const { savedObjectsClient, pkgkey } = options;
const { savedObjectsClient, pkgName, pkgVersion } = options;
const [item, savedObject] = await Promise.all([
Registry.fetchInfo(pkgkey),
getInstallationObject({ savedObjectsClient, pkgkey }),
Registry.getArchiveInfo(pkgkey),
Registry.fetchInfo(pkgName, pkgVersion),
getInstallationObject({ savedObjectsClient, pkgName }),
Registry.getArchiveInfo(pkgName, pkgVersion),
] as const);
// adding `as const` due to regression in TS 3.7.2
// see https://github.com/microsoft/TypeScript/issues/34925#issuecomment-550021453
Expand All @@ -86,37 +87,22 @@ export async function getPackageInfo(options: {

export async function getInstallationObject(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgkey: string;
pkgName: string;
}) {
const { savedObjectsClient, pkgkey } = options;
const { savedObjectsClient, pkgName } = options;
return savedObjectsClient
.get<Installation>(PACKAGES_SAVED_OBJECT_TYPE, pkgkey)
.get<Installation>(PACKAGES_SAVED_OBJECT_TYPE, pkgName)
.catch(e => undefined);
}

export async function getInstallation(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgkey: string;
pkgName: string;
}) {
const savedObject = await getInstallationObject(options);
return savedObject?.attributes;
}

export async function findInstalledPackageByName(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
}): Promise<Installation | undefined> {
const { savedObjectsClient, pkgName } = options;

const res = await savedObjectsClient.find<Installation>({
type: PACKAGES_SAVED_OBJECT_TYPE,
search: pkgName,
searchFields: ['name'],
});
if (res.saved_objects.length) return res.saved_objects[0].attributes;
return undefined;
}

function sortByName(a: { name: string }, b: { name: string }) {
if (a.name > b.name) {
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,6 @@ import * as Registry from '../registry';
type ArchiveAsset = Pick<SavedObject, 'attributes' | 'migrationVersion' | 'references'>;
type SavedObjectToBe = Required<SavedObjectsBulkCreateObject> & { type: AssetType };

export async function getObjects(
pkgkey: string,
filter = (entry: Registry.ArchiveEntry): boolean => true
): Promise<SavedObjectToBe[]> {
// Create a Map b/c some values, especially index-patterns, are referenced multiple times
const objects: Map<string, SavedObjectToBe> = new Map();

// Get paths which match the given filter
const paths = await Registry.getArchiveInfo(pkgkey, filter);

// Get all objects which matched filter. Add them to the Map
const rootObjects = await Promise.all(paths.map(getObject));
rootObjects.forEach(obj => objects.set(obj.id, obj));

// Each of those objects might have `references` property like [{id, type, name}]
for (const object of rootObjects) {
// For each of those objects, if they have references
for (const reference of object.references) {
// Get the referenced objects. Call same function with a new filter
const referencedObjects = await getObjects(pkgkey, (entry: Registry.ArchiveEntry) => {
// Skip anything we've already stored
if (objects.has(reference.id)) return false;

// Is the archive entry the reference we want?
const { type, file } = Registry.pathParts(entry.path);
const isType = type === reference.type;
const isJson = file === `${reference.id}.json`;

return isType && isJson;
});

// Add referenced objects to the Map
referencedObjects.forEach(ro => objects.set(ro.id, ro));
}
}

// return the array of unique objects
return Array.from(objects.values());
}

export async function getObject(key: string) {
const buffer = Registry.getAsset(key);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export {
getPackageInfo,
getPackages,
SearchParams,
findInstalledPackageByName,
} from './get';

export { installKibanaAssets, installPackage, ensureInstalledPackage } from './install';
Expand Down
Loading

0 comments on commit a0c247b

Please sign in to comment.