Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Saved Objects] Allow exporting and importing hidden types #90178

Merged
merged 22 commits into from
Feb 14, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
dcf79c6
initial implementation
Bamieh Feb 3, 2021
70796b2
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 3, 2021
c6c6719
revert testing changes
Bamieh Feb 3, 2021
9823639
some code review fixes
Bamieh Feb 5, 2021
d5a6ffa
remove unused types
Bamieh Feb 5, 2021
6a23d63
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 6, 2021
cd3d2c3
pr review updates + cleanup
Bamieh Feb 6, 2021
7f8aa13
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 8, 2021
36143d1
update all SOM routes to show includedHiddenTypes
Bamieh Feb 8, 2021
55a6974
fix tests
Bamieh Feb 8, 2021
96d7096
Merge branch 'master' into saved_objects/export_import_hidden_types
kibanamachine Feb 8, 2021
497b322
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 9, 2021
a3f8db3
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 10, 2021
34fc8d4
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 11, 2021
3b83707
add ftr tests
Bamieh Feb 11, 2021
74d32ff
return this.client if options undefined
Bamieh Feb 11, 2021
9581554
move to tests to plugin_functional
Bamieh Feb 11, 2021
3c2bef4
self codereview
Bamieh Feb 11, 2021
fcce36a
fix typo
Bamieh Feb 11, 2021
c437d55
tidying up things
Bamieh Feb 11, 2021
9b603aa
Merge branch 'master' of github.com:elastic/kibana into saved_objects…
Bamieh Feb 14, 2021
f8cf3fb
add FTR test for SOM UI
Bamieh Feb 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ core: {
savedObjects: {
client: SavedObjectsClientContract;
typeRegistry: ISavedObjectTypeRegistry;
exporter: ISavedObjectsExporter;
importer: ISavedObjectsImporter;
getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract;
getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter;
getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter;
};
elasticsearch: {
client: IScopedClusterClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export interface RequestHandlerContext

| Property | Type | Description |
| --- | --- | --- |
| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | <code>{</code><br/><code> savedObjects: {</code><br/><code> client: SavedObjectsClientContract;</code><br/><code> typeRegistry: ISavedObjectTypeRegistry;</code><br/><code> exporter: ISavedObjectsExporter;</code><br/><code> importer: ISavedObjectsImporter;</code><br/><code> };</code><br/><code> elasticsearch: {</code><br/><code> client: IScopedClusterClient;</code><br/><code> legacy: {</code><br/><code> client: ILegacyScopedClusterClient;</code><br/><code> };</code><br/><code> };</code><br/><code> uiSettings: {</code><br/><code> client: IUiSettingsClient;</code><br/><code> };</code><br/><code> }</code> | |
| [core](./kibana-plugin-core-server.requesthandlercontext.core.md) | <code>{</code><br/><code> savedObjects: {</code><br/><code> client: SavedObjectsClientContract;</code><br/><code> typeRegistry: ISavedObjectTypeRegistry;</code><br/><code> getClient: (options?: SavedObjectsClientProviderOptions) =&gt; SavedObjectsClientContract;</code><br/><code> getExporter: (client: SavedObjectsClientContract) =&gt; ISavedObjectsExporter;</code><br/><code> getImporter: (client: SavedObjectsClientContract) =&gt; ISavedObjectsImporter;</code><br/><code> };</code><br/><code> elasticsearch: {</code><br/><code> client: IScopedClusterClient;</code><br/><code> legacy: {</code><br/><code> client: ILegacyScopedClusterClient;</code><br/><code> };</code><br/><code> };</code><br/><code> uiSettings: {</code><br/><code> client: IUiSettingsClient;</code><br/><code> };</code><br/><code> }</code> | |

17 changes: 11 additions & 6 deletions src/core/server/core_route_handler_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
ISavedObjectTypeRegistry,
ISavedObjectsExporter,
ISavedObjectsImporter,
SavedObjectsClientProviderOptions,
} from './saved_objects';
import {
InternalElasticsearchServiceStart,
Expand Down Expand Up @@ -75,19 +76,23 @@ class CoreSavedObjectsRouteHandlerContext {
return this.#typeRegistry;
}

public get exporter() {
public getClient = (options?: SavedObjectsClientProviderOptions) => {
return this.savedObjectsStart.getScopedClient(this.request, options);
};
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

public getExporter = (client: SavedObjectsClientContract) => {
if (this.#exporter == null) {
this.#exporter = this.savedObjectsStart.createExporter(this.client);
this.#exporter = this.savedObjectsStart.createExporter(client);
}
return this.#exporter;
}
};
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

public get importer() {
public getImporter = (client: SavedObjectsClientContract) => {
if (this.#importer == null) {
this.#importer = this.savedObjectsStart.createImporter(this.client);
this.#importer = this.savedObjectsStart.createImporter(client);
}
return this.#importer;
}
};
}

class CoreUiSettingsRouteHandlerContext {
Expand Down
6 changes: 4 additions & 2 deletions src/core/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
SavedObjectsServiceStart,
ISavedObjectsExporter,
ISavedObjectsImporter,
SavedObjectsClientProviderOptions,
} from './saved_objects';
import { CapabilitiesSetup, CapabilitiesStart } from './capabilities';
import { MetricsServiceSetup, MetricsServiceStart } from './metrics';
Expand Down Expand Up @@ -409,8 +410,9 @@ export interface RequestHandlerContext {
savedObjects: {
client: SavedObjectsClientContract;
typeRegistry: ISavedObjectTypeRegistry;
exporter: ISavedObjectsExporter;
importer: ISavedObjectsImporter;
getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract;
getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter;
getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter;
};
elasticsearch: {
client: IScopedClusterClient;
Expand Down
11 changes: 10 additions & 1 deletion src/core/server/saved_objects/routes/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,20 @@ export const registerDeleteRoute = (router: IRouter, { coreUsageData }: RouteDep
router.handleLegacyErrors(async (context, req, res) => {
const { type, id } = req.params;
const { force } = req.query;
const { getClient, typeRegistry } = context.core.savedObjects;

const usageStatsClient = coreUsageData.getClient();
usageStatsClient.incrementSavedObjectsDelete({ request: req }).catch(() => {});

const result = await context.core.savedObjects.client.delete(type, id, { force });
const includedHiddenTypes = [type].filter(
(supportedType) =>
typeRegistry.isHidden(supportedType) &&
typeRegistry.isImportableAndExportable(supportedType)
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
);

const client = getClient({ includedHiddenTypes });

const result = await client.delete(type, id, { force });
return res.ok({ body: result });
})
);
Expand Down
13 changes: 9 additions & 4 deletions src/core/server/saved_objects/routes/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ export const registerExportRoute = (
},
router.handleLegacyErrors(async (context, req, res) => {
const cleaned = cleanOptions(req.body);
const supportedTypes = context.core.savedObjects.typeRegistry
.getImportableAndExportableTypes()
.map((t) => t.name);
const { typeRegistry, getExporter, getClient } = context.core.savedObjects;
const supportedTypes = typeRegistry.getImportableAndExportableTypes().map((t) => t.name);

let options: EitherExportOptions;
try {
options = validateOptions(cleaned, {
Expand All @@ -181,7 +181,12 @@ export const registerExportRoute = (
});
}

const exporter = context.core.savedObjects.exporter;
const includedHiddenTypes = supportedTypes.filter((supportedType) =>
typeRegistry.isHidden(supportedType)
);

const client = getClient({ includedHiddenTypes });
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
const exporter = getExporter(client);

const usageStatsClient = coreUsageData.getClient();
usageStatsClient
Expand Down
11 changes: 10 additions & 1 deletion src/core/server/saved_objects/routes/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export const registerImportRoute = (
},
router.handleLegacyErrors(async (context, req, res) => {
const { overwrite, createNewCopies } = req.query;
const { getClient, getImporter, typeRegistry } = context.core.savedObjects;

const usageStatsClient = coreUsageData.getClient();
usageStatsClient
Expand All @@ -84,7 +85,15 @@ export const registerImportRoute = (
});
}

const { importer } = context.core.savedObjects;
const supportedTypes = typeRegistry.getImportableAndExportableTypes().map((t) => t.name);

const includedHiddenTypes = supportedTypes.filter((supportedType) =>
typeRegistry.isHidden(supportedType)
);

const client = getClient({ includedHiddenTypes });
const importer = getImporter(client);

try {
const result = await importer.import({
readStream,
Expand Down
13 changes: 12 additions & 1 deletion src/core/server/saved_objects/routes/resolve_import_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,18 @@ export const registerResolveImportErrorsRoute = (
});
}

const { importer } = context.core.savedObjects;
const { getClient, getImporter, typeRegistry } = context.core.savedObjects;

const includedHiddenTypes = req.body.retries
.map((retry) => retry.type)
.filter(
(supportedType) =>
typeRegistry.isHidden(supportedType) &&
typeRegistry.isImportableAndExportable(supportedType)
);
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

const client = getClient({ includedHiddenTypes });
const importer = getImporter(client);

try {
const result = await importer.resolveImportErrors({
Expand Down
5 changes: 3 additions & 2 deletions src/core/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1913,8 +1913,9 @@ export interface RequestHandlerContext {
savedObjects: {
client: SavedObjectsClientContract;
typeRegistry: ISavedObjectTypeRegistry;
exporter: ISavedObjectsExporter;
importer: ISavedObjectsImporter;
getClient: (options?: SavedObjectsClientProviderOptions) => SavedObjectsClientContract;
getExporter: (client: SavedObjectsClientContract) => ISavedObjectsExporter;
getImporter: (client: SavedObjectsClientContract) => ISavedObjectsImporter;
};
elasticsearch: {
client: IScopedClusterClient;
Expand Down
14 changes: 11 additions & 3 deletions src/plugins/home/server/services/sample_data/routes/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,15 @@ export function createInstallRoute(

let createResults;
try {
createResults = await context.core.savedObjects.client.bulkCreate(
const { getClient, typeRegistry } = context.core.savedObjects;

const includedHiddenTypes = sampleDataset.savedObjects
.map((object) => object.type)
.filter((supportedType) => typeRegistry.isHidden(supportedType));
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

const client = getClient({ includedHiddenTypes });

createResults = await client.bulkCreate(
sampleDataset.savedObjects.map(({ version, ...savedObject }) => savedObject),
{ overwrite: true }
);
Expand All @@ -156,8 +164,8 @@ export function createInstallRoute(
return Boolean(savedObjectCreateResult.error);
});
if (errors.length > 0) {
const errMsg = `sample_data install errors while loading saved objects. Errors: ${errors.join(
','
const errMsg = `sample_data install errors while loading saved objects. Errors: ${JSON.stringify(
errors
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
)}`;
logger.warn(errMsg);
return res.customError({ body: errMsg, statusCode: 403 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function createUninstallRoute(
client: { callAsCurrentUser },
},
},
savedObjects: { client: savedObjectsClient },
savedObjects: { getClient: getSavedObjectsClient, typeRegistry },
},
},
request,
Expand Down Expand Up @@ -61,6 +61,12 @@ export function createUninstallRoute(
}
}

const includedHiddenTypes = sampleDataset.savedObjects
.map((object) => object.type)
.filter((supportedType) => typeRegistry.isHidden(supportedType));
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

const savedObjectsClient = getSavedObjectsClient({ includedHiddenTypes });

const deletePromises = sampleDataset.savedObjects.map(({ type, id }) =>
savedObjectsClient.delete(type, id)
);
Expand Down
19 changes: 13 additions & 6 deletions src/plugins/saved_objects_management/server/routes/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,24 @@ export const registerFindRoute = (
},
},
router.handleLegacyErrors(async (context, req, res) => {
const { query } = req;
const managementService = await managementServicePromise;
const { client } = context.core.savedObjects;
const searchTypes = Array.isArray(req.query.type) ? req.query.type : [req.query.type];
const includedFields = Array.isArray(req.query.fields)
? req.query.fields
: [req.query.fields];
const { getClient } = context.core.savedObjects;

const searchTypes = Array.isArray(query.type) ? query.type : [query.type];
const includedFields = Array.isArray(query.fields) ? query.fields : [query.fields];

const importAndExportableTypes = searchTypes.filter((type) =>
managementService.isImportAndExportable(type)
);

const includedHiddenTypes = importAndExportableTypes.filter((type) =>
managementService.isHidden(type)
);

const client = getClient({ includedHiddenTypes });
Bamieh marked this conversation as resolved.
Show resolved Hide resolved
const searchFields = new Set<string>();

importAndExportableTypes.forEach((type) => {
const searchField = managementService.getDefaultSearchField(type);
if (searchField) {
Expand All @@ -64,7 +71,7 @@ export const registerFindRoute = (
});

const findResponse = await client.find<any>({
...req.query,
...query,
fields: undefined,
searchFields: [...searchFields],
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class SavedObjectsManagement {
return this.registry.isImportableAndExportable(type);
}

public isHidden(type: string) {
return this.registry.isHidden(type);
}

public getDefaultSearchField(type: string) {
return this.registry.getType(type)?.management?.defaultSearchField;
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/features/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export class Plugin {

private registerOssFeatures(savedObjects: SavedObjectsServiceStart) {
const registry = savedObjects.getTypeRegistry();
const savedObjectTypes = registry.getVisibleTypes().map((t) => t.name);
const savedObjectTypes = registry.getImportableAndExportableTypes().map((t) => t.name);
Bamieh marked this conversation as resolved.
Show resolved Hide resolved

this.logger.debug(
`Registering OSS features with SO types: ${savedObjectTypes.join(', ')}. "includeTimelion": ${
Expand Down