From d107d0845ec90f2b661c7f55fff1417fbf8bd21b Mon Sep 17 00:00:00 2001 From: Larry Gregory Date: Thu, 1 Aug 2019 13:55:26 -0400 Subject: [PATCH] [7.x] Expose saved object import/export from core (#42022) (#42458) * expose saved object import/export from core * additional tests * removing unused mock * updater snapshots * add objectLimit to saved objects service * don't export the import/export functionality from core; only types * documenting exported types * export missing type --- .../core/server/kibana-plugin-server.md | 15 +- ...sclientprovideroptions.excludedwrappers.md | 11 + ...erver.savedobjectsclientprovideroptions.md | 20 + ...server.savedobjectsclientwrapperfactory.md | 2 + ...server.savedobjectsclientwrapperoptions.md | 2 + ...vedobjectsexportoptions.exportsizelimit.md | 11 + ...ectsexportoptions.includereferencesdeep.md | 11 + ...plugin-server.savedobjectsexportoptions.md | 25 + ...ver.savedobjectsexportoptions.namespace.md | 11 + ...erver.savedobjectsexportoptions.objects.md | 14 + ...objectsexportoptions.savedobjectsclient.md | 11 + ...-server.savedobjectsexportoptions.types.md | 11 + ...-server.savedobjectsimportconflicterror.md | 20 + ...er.savedobjectsimportconflicterror.type.md | 11 + ...in-server.savedobjectsimporterror.error.md | 11 + ...lugin-server.savedobjectsimporterror.id.md | 11 + ...a-plugin-server.savedobjectsimporterror.md | 23 + ...in-server.savedobjectsimporterror.title.md | 11 + ...gin-server.savedobjectsimporterror.type.md | 11 + ...tsimportmissingreferenceserror.blocking.md | 14 + ...avedobjectsimportmissingreferenceserror.md | 22 + ...importmissingreferenceserror.references.md | 14 + ...bjectsimportmissingreferenceserror.type.md | 11 + ...plugin-server.savedobjectsimportoptions.md | 25 + ...ver.savedobjectsimportoptions.namespace.md | 11 + ...r.savedobjectsimportoptions.objectlimit.md | 11 + ...ver.savedobjectsimportoptions.overwrite.md | 11 + ...er.savedobjectsimportoptions.readstream.md | 11 + ...objectsimportoptions.savedobjectsclient.md | 11 + ...avedobjectsimportoptions.supportedtypes.md | 11 + ...erver.savedobjectsimportresponse.errors.md | 11 + ...lugin-server.savedobjectsimportresponse.md | 22 + ...rver.savedobjectsimportresponse.success.md | 11 + ...savedobjectsimportresponse.successcount.md | 11 + ...lugin-server.savedobjectsimportretry.id.md | 11 + ...a-plugin-server.savedobjectsimportretry.md | 23 + ...erver.savedobjectsimportretry.overwrite.md | 11 + ...vedobjectsimportretry.replacereferences.md | 15 + ...gin-server.savedobjectsimportretry.type.md | 11 + ...n-server.savedobjectsimportunknownerror.md | 22 + ....savedobjectsimportunknownerror.message.md | 11 + ...vedobjectsimportunknownerror.statuscode.md | 11 + ...ver.savedobjectsimportunknownerror.type.md | 11 + ....savedobjectsimportunsupportedtypeerror.md | 20 + ...dobjectsimportunsupportedtypeerror.type.md | 11 + ....savedobjectsresolveimporterrorsoptions.md | 25 + ...ctsresolveimporterrorsoptions.namespace.md | 11 + ...sresolveimporterrorsoptions.objectlimit.md | 11 + ...tsresolveimporterrorsoptions.readstream.md | 11 + ...jectsresolveimporterrorsoptions.retries.md | 11 + ...eimporterrorsoptions.savedobjectsclient.md | 11 + ...solveimporterrorsoptions.supportedtypes.md | 11 + ...server.savedobjectsservice.importexport.md | 16 + ...ibana-plugin-server.savedobjectsservice.md | 2 + ...lugin-server.savedobjectsservice.schema.md | 11 + src/core/server/index.ts | 11 + .../get_sorted_objects_for_export.test.ts | 345 ++++++---- .../export/get_sorted_objects_for_export.ts | 30 +- src/core/server/saved_objects/export/index.ts | 5 +- .../inject_nested_depdendencies.test.ts | 412 ++++++------ .../export/inject_nested_depdendencies.ts | 5 +- .../import/collect_saved_objects.ts | 4 +- .../import/create_objects_filter.ts | 4 +- .../saved_objects/import/extract_errors.ts | 4 +- .../import/import_saved_objects.test.ts | 632 ++++++++++-------- .../import/import_saved_objects.ts | 31 +- src/core/server/saved_objects/import/index.ts | 11 + .../import/resolve_import_errors.test.ts | 444 ++++++------ .../import/resolve_import_errors.ts | 35 +- .../saved_objects/import/split_overwrites.ts | 4 +- src/core/server/saved_objects/import/types.ts | 81 ++- .../import/validate_references.test.ts | 9 + .../import/validate_references.ts | 15 +- src/core/server/saved_objects/index.ts | 4 + .../server/saved_objects/service/index.ts | 15 + .../server/saved_objects/service/lib/index.ts | 1 + .../service/lib/scoped_client_provider.ts | 16 + src/core/server/server.api.md | 151 ++++- src/legacy/server/kbn_server.d.ts | 3 +- .../saved_objects/routes/import.test.ts | 3 + .../routes/resolve_import_errors.test.ts | 200 +++--- .../saved_objects/saved_objects_mixin.js | 12 +- 82 files changed, 2241 insertions(+), 972 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.excludedwrappers.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.exportsizelimit.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.includereferencesdeep.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.namespace.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.objects.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.savedobjectsclient.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.types.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.type.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.error.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.id.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.title.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.type.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.blocking.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.references.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.type.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.namespace.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.objectlimit.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.overwrite.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.readstream.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.savedobjectsclient.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.supportedtypes.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.errors.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.success.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.successcount.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.id.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.overwrite.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.replacereferences.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.type.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.message.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.statuscode.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.type.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.type.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.namespace.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.objectlimit.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.readstream.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.retries.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.savedobjectsclient.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.supportedtypes.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsservice.importexport.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectsservice.schema.md diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index bd4ef84723057..0b1ab7e005a0a 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -58,12 +58,23 @@ The plugin integrates with the core system via lifecycle events: `setup` | [SavedObjectsBulkCreateObject](./kibana-plugin-server.savedobjectsbulkcreateobject.md) | | | [SavedObjectsBulkGetObject](./kibana-plugin-server.savedobjectsbulkgetobject.md) | | | [SavedObjectsBulkResponse](./kibana-plugin-server.savedobjectsbulkresponse.md) | | -| [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) | | +| [SavedObjectsClientProviderOptions](./kibana-plugin-server.savedobjectsclientprovideroptions.md) | Options to control the creation of the Saved Objects Client. | +| [SavedObjectsClientWrapperOptions](./kibana-plugin-server.savedobjectsclientwrapperoptions.md) | Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. | | [SavedObjectsCreateOptions](./kibana-plugin-server.savedobjectscreateoptions.md) | | +| [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) | Options controlling the export operation. | | [SavedObjectsFindOptions](./kibana-plugin-server.savedobjectsfindoptions.md) | | | [SavedObjectsFindResponse](./kibana-plugin-server.savedobjectsfindresponse.md) | | +| [SavedObjectsImportConflictError](./kibana-plugin-server.savedobjectsimportconflicterror.md) | Represents a failure to import due to a conflict. | +| [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) | Represents a failure to import. | +| [SavedObjectsImportMissingReferencesError](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.md) | Represents a failure to import due to missing references. | +| [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) | Options to control the import operation. | +| [SavedObjectsImportResponse](./kibana-plugin-server.savedobjectsimportresponse.md) | The response describing the result of an import. | +| [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) | Describes a retry operation for importing a saved object. | +| [SavedObjectsImportUnknownError](./kibana-plugin-server.savedobjectsimportunknownerror.md) | Represents a failure to import due to an unknown reason. | +| [SavedObjectsImportUnsupportedTypeError](./kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md) | Represents a failure to import due to having an unsupported saved object type. | | [SavedObjectsMigrationVersion](./kibana-plugin-server.savedobjectsmigrationversion.md) | A dictionary of saved object type -> version used to determine what migrations need to be applied to a saved object. | | [SavedObjectsRawDoc](./kibana-plugin-server.savedobjectsrawdoc.md) | A raw document as represented directly in the saved object index. | +| [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) | Options to control the "resolve import" operation. | | [SavedObjectsService](./kibana-plugin-server.savedobjectsservice.md) | | | [SavedObjectsUpdateOptions](./kibana-plugin-server.savedobjectsupdateoptions.md) | | | [SavedObjectsUpdateResponse](./kibana-plugin-server.savedobjectsupdateresponse.md) | | @@ -89,5 +100,5 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ResponseError](./kibana-plugin-server.responseerror.md) | Error message and optional data send to the client in case of error. | | [RouteMethod](./kibana-plugin-server.routemethod.md) | The set of common HTTP methods supported by Kibana routing. | | [SavedObjectsClientContract](./kibana-plugin-server.savedobjectsclientcontract.md) | \#\# SavedObjectsClient errorsSince the SavedObjectsClient has its hands in everything we are a little paranoid about the way we present errors back to to application code. Ideally, all errors will be either:1. Caused by bad implementation (ie. undefined is not a function) and as such unpredictable 2. An error that has been classified and decorated appropriately by the decorators in [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md)Type 1 errors are inevitable, but since all expected/handle-able errors should be Type 2 the isXYZError() helpers exposed at SavedObjectsErrorHelpers should be used to understand and manage error responses from the SavedObjectsClient.Type 2 errors are decorated versions of the source error, so if the elasticsearch client threw an error it will be decorated based on its type. That means that rather than looking for error.body.error.type or doing substring checks on error.body.error.reason, just use the helpers to understand the meaning of the error:\`\`\`js if (SavedObjectsErrorHelpers.isNotFoundError(error)) { // handle 404 }if (SavedObjectsErrorHelpers.isNotAuthorizedError(error)) { // 401 handling should be automatic, but in case you wanted to know }// always rethrow the error unless you handle it throw error; \`\`\`\#\#\# 404s from missing indexFrom the perspective of application code and APIs the SavedObjectsClient is a black box that persists objects. One of the internal details that users have no control over is that we use an elasticsearch index for persistance and that index might be missing.At the time of writing we are in the process of transitioning away from the operating assumption that the SavedObjects index is always available. Part of this transition is handling errors resulting from an index missing. These used to trigger a 500 error in most cases, and in others cause 404s with different error messages.From my (Spencer) perspective, a 404 from the SavedObjectsApi is a 404; The object the request/call was targeting could not be found. This is why \#14141 takes special care to ensure that 404 errors are generic and don't distinguish between index missing or document missing.\#\#\# 503s from missing indexUnlike all other methods, create requests are supposed to succeed even when the Kibana index does not exist because it will be automatically created by elasticsearch. When that is not the case it is because Elasticsearch's action.auto_create_index setting prevents it from being created automatically so we throw a special 503 with the intention of informing the user that their Elasticsearch settings need to be updated.See [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | -| [SavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) | | +| [SavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) | Describes the factory used to create instances of Saved Objects Client Wrappers. | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.excludedwrappers.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.excludedwrappers.md new file mode 100644 index 0000000000000..9eb036c01e26e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.excludedwrappers.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientProviderOptions](./kibana-plugin-server.savedobjectsclientprovideroptions.md) > [excludedWrappers](./kibana-plugin-server.savedobjectsclientprovideroptions.excludedwrappers.md) + +## SavedObjectsClientProviderOptions.excludedWrappers property + +Signature: + +```typescript +excludedWrappers?: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.md new file mode 100644 index 0000000000000..29b872a30a373 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclientprovideroptions.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsClientProviderOptions](./kibana-plugin-server.savedobjectsclientprovideroptions.md) + +## SavedObjectsClientProviderOptions interface + +Options to control the creation of the Saved Objects Client. + +Signature: + +```typescript +export interface SavedObjectsClientProviderOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [excludedWrappers](./kibana-plugin-server.savedobjectsclientprovideroptions.excludedwrappers.md) | string[] | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperfactory.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperfactory.md index 321aefcba0ffd..3ef2fac727b01 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperfactory.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperfactory.md @@ -4,6 +4,8 @@ ## SavedObjectsClientWrapperFactory type +Describes the factory used to create instances of Saved Objects Client Wrappers. + Signature: ```typescript diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md index 1a096fd9e5264..65e7cfa64c2a6 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsclientwrapperoptions.md @@ -4,6 +4,8 @@ ## SavedObjectsClientWrapperOptions interface +Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. + Signature: ```typescript diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.exportsizelimit.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.exportsizelimit.md new file mode 100644 index 0000000000000..d8ff7b4c9e2ed --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.exportsizelimit.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) > [exportSizeLimit](./kibana-plugin-server.savedobjectsexportoptions.exportsizelimit.md) + +## SavedObjectsExportOptions.exportSizeLimit property + +Signature: + +```typescript +exportSizeLimit: number; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.includereferencesdeep.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.includereferencesdeep.md new file mode 100644 index 0000000000000..1972cc6634b75 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.includereferencesdeep.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) > [includeReferencesDeep](./kibana-plugin-server.savedobjectsexportoptions.includereferencesdeep.md) + +## SavedObjectsExportOptions.includeReferencesDeep property + +Signature: + +```typescript +includeReferencesDeep?: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.md new file mode 100644 index 0000000000000..66f501a0f1433 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) + +## SavedObjectsExportOptions interface + +Options controlling the export operation. + +Signature: + +```typescript +export interface SavedObjectsExportOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [exportSizeLimit](./kibana-plugin-server.savedobjectsexportoptions.exportsizelimit.md) | number | | +| [includeReferencesDeep](./kibana-plugin-server.savedobjectsexportoptions.includereferencesdeep.md) | boolean | | +| [namespace](./kibana-plugin-server.savedobjectsexportoptions.namespace.md) | string | | +| [objects](./kibana-plugin-server.savedobjectsexportoptions.objects.md) | Array<{
id: string;
type: string;
}> | | +| [savedObjectsClient](./kibana-plugin-server.savedobjectsexportoptions.savedobjectsclient.md) | SavedObjectsClientContract | | +| [types](./kibana-plugin-server.savedobjectsexportoptions.types.md) | string[] | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.namespace.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.namespace.md new file mode 100644 index 0000000000000..b5abfba7f6910 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.namespace.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) > [namespace](./kibana-plugin-server.savedobjectsexportoptions.namespace.md) + +## SavedObjectsExportOptions.namespace property + +Signature: + +```typescript +namespace?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.objects.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.objects.md new file mode 100644 index 0000000000000..46cb62841d46c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.objects.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) > [objects](./kibana-plugin-server.savedobjectsexportoptions.objects.md) + +## SavedObjectsExportOptions.objects property + +Signature: + +```typescript +objects?: Array<{ + id: string; + type: string; + }>; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.savedobjectsclient.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.savedobjectsclient.md new file mode 100644 index 0000000000000..fc206d0f7e877 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.savedobjectsclient.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) > [savedObjectsClient](./kibana-plugin-server.savedobjectsexportoptions.savedobjectsclient.md) + +## SavedObjectsExportOptions.savedObjectsClient property + +Signature: + +```typescript +savedObjectsClient: SavedObjectsClientContract; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.types.md b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.types.md new file mode 100644 index 0000000000000..204402fe355e3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsexportoptions.types.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsExportOptions](./kibana-plugin-server.savedobjectsexportoptions.md) > [types](./kibana-plugin-server.savedobjectsexportoptions.types.md) + +## SavedObjectsExportOptions.types property + +Signature: + +```typescript +types?: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.md new file mode 100644 index 0000000000000..485500da504a9 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportConflictError](./kibana-plugin-server.savedobjectsimportconflicterror.md) + +## SavedObjectsImportConflictError interface + +Represents a failure to import due to a conflict. + +Signature: + +```typescript +export interface SavedObjectsImportConflictError +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [type](./kibana-plugin-server.savedobjectsimportconflicterror.type.md) | 'conflict' | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.type.md new file mode 100644 index 0000000000000..bd85de140674a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportconflicterror.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportConflictError](./kibana-plugin-server.savedobjectsimportconflicterror.md) > [type](./kibana-plugin-server.savedobjectsimportconflicterror.type.md) + +## SavedObjectsImportConflictError.type property + +Signature: + +```typescript +type: 'conflict'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.error.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.error.md new file mode 100644 index 0000000000000..0828ca9e01c34 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.error.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) > [error](./kibana-plugin-server.savedobjectsimporterror.error.md) + +## SavedObjectsImportError.error property + +Signature: + +```typescript +error: SavedObjectsImportConflictError | SavedObjectsImportUnsupportedTypeError | SavedObjectsImportMissingReferencesError | SavedObjectsImportUnknownError; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.id.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.id.md new file mode 100644 index 0000000000000..0791d668f4626 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) > [id](./kibana-plugin-server.savedobjectsimporterror.id.md) + +## SavedObjectsImportError.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.md new file mode 100644 index 0000000000000..0d734c21c3151 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) + +## SavedObjectsImportError interface + +Represents a failure to import. + +Signature: + +```typescript +export interface SavedObjectsImportError +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [error](./kibana-plugin-server.savedobjectsimporterror.error.md) | SavedObjectsImportConflictError | SavedObjectsImportUnsupportedTypeError | SavedObjectsImportMissingReferencesError | SavedObjectsImportUnknownError | | +| [id](./kibana-plugin-server.savedobjectsimporterror.id.md) | string | | +| [title](./kibana-plugin-server.savedobjectsimporterror.title.md) | string | | +| [type](./kibana-plugin-server.savedobjectsimporterror.type.md) | string | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.title.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.title.md new file mode 100644 index 0000000000000..bd0beeb4d79dd --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.title.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) > [title](./kibana-plugin-server.savedobjectsimporterror.title.md) + +## SavedObjectsImportError.title property + +Signature: + +```typescript +title?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.type.md new file mode 100644 index 0000000000000..0b48cc4bbaecf --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimporterror.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportError](./kibana-plugin-server.savedobjectsimporterror.md) > [type](./kibana-plugin-server.savedobjectsimporterror.type.md) + +## SavedObjectsImportError.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.blocking.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.blocking.md new file mode 100644 index 0000000000000..bbbd499ea5844 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.blocking.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportMissingReferencesError](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.md) > [blocking](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.blocking.md) + +## SavedObjectsImportMissingReferencesError.blocking property + +Signature: + +```typescript +blocking: Array<{ + type: string; + id: string; + }>; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.md new file mode 100644 index 0000000000000..fb4e997fe17ba --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportMissingReferencesError](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.md) + +## SavedObjectsImportMissingReferencesError interface + +Represents a failure to import due to missing references. + +Signature: + +```typescript +export interface SavedObjectsImportMissingReferencesError +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [blocking](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.blocking.md) | Array<{
type: string;
id: string;
}> | | +| [references](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.references.md) | Array<{
type: string;
id: string;
}> | | +| [type](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.type.md) | 'missing_references' | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.references.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.references.md new file mode 100644 index 0000000000000..593d2b48d456c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.references.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportMissingReferencesError](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.md) > [references](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.references.md) + +## SavedObjectsImportMissingReferencesError.references property + +Signature: + +```typescript +references: Array<{ + type: string; + id: string; + }>; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.type.md new file mode 100644 index 0000000000000..3e6e80f77c447 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportmissingreferenceserror.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportMissingReferencesError](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.md) > [type](./kibana-plugin-server.savedobjectsimportmissingreferenceserror.type.md) + +## SavedObjectsImportMissingReferencesError.type property + +Signature: + +```typescript +type: 'missing_references'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.md new file mode 100644 index 0000000000000..a1ea33e11b14f --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) + +## SavedObjectsImportOptions interface + +Options to control the import operation. + +Signature: + +```typescript +export interface SavedObjectsImportOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [namespace](./kibana-plugin-server.savedobjectsimportoptions.namespace.md) | string | | +| [objectLimit](./kibana-plugin-server.savedobjectsimportoptions.objectlimit.md) | number | | +| [overwrite](./kibana-plugin-server.savedobjectsimportoptions.overwrite.md) | boolean | | +| [readStream](./kibana-plugin-server.savedobjectsimportoptions.readstream.md) | Readable | | +| [savedObjectsClient](./kibana-plugin-server.savedobjectsimportoptions.savedobjectsclient.md) | SavedObjectsClientContract | | +| [supportedTypes](./kibana-plugin-server.savedobjectsimportoptions.supportedtypes.md) | string[] | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.namespace.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.namespace.md new file mode 100644 index 0000000000000..600a4dc1176f3 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.namespace.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) > [namespace](./kibana-plugin-server.savedobjectsimportoptions.namespace.md) + +## SavedObjectsImportOptions.namespace property + +Signature: + +```typescript +namespace?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.objectlimit.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.objectlimit.md new file mode 100644 index 0000000000000..bb040a560b89b --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.objectlimit.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) > [objectLimit](./kibana-plugin-server.savedobjectsimportoptions.objectlimit.md) + +## SavedObjectsImportOptions.objectLimit property + +Signature: + +```typescript +objectLimit: number; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.overwrite.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.overwrite.md new file mode 100644 index 0000000000000..4586a93568588 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.overwrite.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) > [overwrite](./kibana-plugin-server.savedobjectsimportoptions.overwrite.md) + +## SavedObjectsImportOptions.overwrite property + +Signature: + +```typescript +overwrite: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.readstream.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.readstream.md new file mode 100644 index 0000000000000..4b54f931797cf --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.readstream.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) > [readStream](./kibana-plugin-server.savedobjectsimportoptions.readstream.md) + +## SavedObjectsImportOptions.readStream property + +Signature: + +```typescript +readStream: Readable; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.savedobjectsclient.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.savedobjectsclient.md new file mode 100644 index 0000000000000..f0d439aedc005 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.savedobjectsclient.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) > [savedObjectsClient](./kibana-plugin-server.savedobjectsimportoptions.savedobjectsclient.md) + +## SavedObjectsImportOptions.savedObjectsClient property + +Signature: + +```typescript +savedObjectsClient: SavedObjectsClientContract; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.supportedtypes.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.supportedtypes.md new file mode 100644 index 0000000000000..0359c53d8fcf1 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportoptions.supportedtypes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportOptions](./kibana-plugin-server.savedobjectsimportoptions.md) > [supportedTypes](./kibana-plugin-server.savedobjectsimportoptions.supportedtypes.md) + +## SavedObjectsImportOptions.supportedTypes property + +Signature: + +```typescript +supportedTypes: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.errors.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.errors.md new file mode 100644 index 0000000000000..c59390c6d45e0 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.errors.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportResponse](./kibana-plugin-server.savedobjectsimportresponse.md) > [errors](./kibana-plugin-server.savedobjectsimportresponse.errors.md) + +## SavedObjectsImportResponse.errors property + +Signature: + +```typescript +errors?: SavedObjectsImportError[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.md new file mode 100644 index 0000000000000..23f6526dc6367 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportResponse](./kibana-plugin-server.savedobjectsimportresponse.md) + +## SavedObjectsImportResponse interface + +The response describing the result of an import. + +Signature: + +```typescript +export interface SavedObjectsImportResponse +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [errors](./kibana-plugin-server.savedobjectsimportresponse.errors.md) | SavedObjectsImportError[] | | +| [success](./kibana-plugin-server.savedobjectsimportresponse.success.md) | boolean | | +| [successCount](./kibana-plugin-server.savedobjectsimportresponse.successcount.md) | number | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.success.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.success.md new file mode 100644 index 0000000000000..5fd76959c556c --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.success.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportResponse](./kibana-plugin-server.savedobjectsimportresponse.md) > [success](./kibana-plugin-server.savedobjectsimportresponse.success.md) + +## SavedObjectsImportResponse.success property + +Signature: + +```typescript +success: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.successcount.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.successcount.md new file mode 100644 index 0000000000000..4b49f57e8367d --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportresponse.successcount.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportResponse](./kibana-plugin-server.savedobjectsimportresponse.md) > [successCount](./kibana-plugin-server.savedobjectsimportresponse.successcount.md) + +## SavedObjectsImportResponse.successCount property + +Signature: + +```typescript +successCount: number; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.id.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.id.md new file mode 100644 index 0000000000000..568185b2438b7 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) > [id](./kibana-plugin-server.savedobjectsimportretry.id.md) + +## SavedObjectsImportRetry.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.md new file mode 100644 index 0000000000000..dc842afbf9f29 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) + +## SavedObjectsImportRetry interface + +Describes a retry operation for importing a saved object. + +Signature: + +```typescript +export interface SavedObjectsImportRetry +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-server.savedobjectsimportretry.id.md) | string | | +| [overwrite](./kibana-plugin-server.savedobjectsimportretry.overwrite.md) | boolean | | +| [replaceReferences](./kibana-plugin-server.savedobjectsimportretry.replacereferences.md) | Array<{
type: string;
from: string;
to: string;
}> | | +| [type](./kibana-plugin-server.savedobjectsimportretry.type.md) | string | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.overwrite.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.overwrite.md new file mode 100644 index 0000000000000..36a31e836aebc --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.overwrite.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) > [overwrite](./kibana-plugin-server.savedobjectsimportretry.overwrite.md) + +## SavedObjectsImportRetry.overwrite property + +Signature: + +```typescript +overwrite: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.replacereferences.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.replacereferences.md new file mode 100644 index 0000000000000..c3439bb554e13 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.replacereferences.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) > [replaceReferences](./kibana-plugin-server.savedobjectsimportretry.replacereferences.md) + +## SavedObjectsImportRetry.replaceReferences property + +Signature: + +```typescript +replaceReferences: Array<{ + type: string; + from: string; + to: string; + }>; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.type.md new file mode 100644 index 0000000000000..8f0408dcbc11e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportretry.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportRetry](./kibana-plugin-server.savedobjectsimportretry.md) > [type](./kibana-plugin-server.savedobjectsimportretry.type.md) + +## SavedObjectsImportRetry.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.md new file mode 100644 index 0000000000000..913038c5bc67d --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportUnknownError](./kibana-plugin-server.savedobjectsimportunknownerror.md) + +## SavedObjectsImportUnknownError interface + +Represents a failure to import due to an unknown reason. + +Signature: + +```typescript +export interface SavedObjectsImportUnknownError +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [message](./kibana-plugin-server.savedobjectsimportunknownerror.message.md) | string | | +| [statusCode](./kibana-plugin-server.savedobjectsimportunknownerror.statuscode.md) | number | | +| [type](./kibana-plugin-server.savedobjectsimportunknownerror.type.md) | 'unknown' | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.message.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.message.md new file mode 100644 index 0000000000000..96b8b98bf6a9f --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.message.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportUnknownError](./kibana-plugin-server.savedobjectsimportunknownerror.md) > [message](./kibana-plugin-server.savedobjectsimportunknownerror.message.md) + +## SavedObjectsImportUnknownError.message property + +Signature: + +```typescript +message: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.statuscode.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.statuscode.md new file mode 100644 index 0000000000000..9cdef84ff4ea7 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.statuscode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportUnknownError](./kibana-plugin-server.savedobjectsimportunknownerror.md) > [statusCode](./kibana-plugin-server.savedobjectsimportunknownerror.statuscode.md) + +## SavedObjectsImportUnknownError.statusCode property + +Signature: + +```typescript +statusCode: number; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.type.md new file mode 100644 index 0000000000000..cf31166157ab7 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunknownerror.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportUnknownError](./kibana-plugin-server.savedobjectsimportunknownerror.md) > [type](./kibana-plugin-server.savedobjectsimportunknownerror.type.md) + +## SavedObjectsImportUnknownError.type property + +Signature: + +```typescript +type: 'unknown'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md new file mode 100644 index 0000000000000..cc775b20bb8f2 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportUnsupportedTypeError](./kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md) + +## SavedObjectsImportUnsupportedTypeError interface + +Represents a failure to import due to having an unsupported saved object type. + +Signature: + +```typescript +export interface SavedObjectsImportUnsupportedTypeError +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [type](./kibana-plugin-server.savedobjectsimportunsupportedtypeerror.type.md) | 'unsupported_type' | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.type.md b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.type.md new file mode 100644 index 0000000000000..ae69911020c18 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsimportunsupportedtypeerror.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsImportUnsupportedTypeError](./kibana-plugin-server.savedobjectsimportunsupportedtypeerror.md) > [type](./kibana-plugin-server.savedobjectsimportunsupportedtypeerror.type.md) + +## SavedObjectsImportUnsupportedTypeError.type property + +Signature: + +```typescript +type: 'unsupported_type'; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md new file mode 100644 index 0000000000000..e3542714d96bb --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) + +## SavedObjectsResolveImportErrorsOptions interface + +Options to control the "resolve import" operation. + +Signature: + +```typescript +export interface SavedObjectsResolveImportErrorsOptions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [namespace](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.namespace.md) | string | | +| [objectLimit](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.objectlimit.md) | number | | +| [readStream](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.readstream.md) | Readable | | +| [retries](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.retries.md) | SavedObjectsImportRetry[] | | +| [savedObjectsClient](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.savedobjectsclient.md) | SavedObjectsClientContract | | +| [supportedTypes](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.supportedtypes.md) | string[] | | + diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.namespace.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.namespace.md new file mode 100644 index 0000000000000..6175e75a4bbec --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.namespace.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) > [namespace](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.namespace.md) + +## SavedObjectsResolveImportErrorsOptions.namespace property + +Signature: + +```typescript +namespace?: string; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.objectlimit.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.objectlimit.md new file mode 100644 index 0000000000000..d5616851e1386 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.objectlimit.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) > [objectLimit](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.objectlimit.md) + +## SavedObjectsResolveImportErrorsOptions.objectLimit property + +Signature: + +```typescript +objectLimit: number; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.readstream.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.readstream.md new file mode 100644 index 0000000000000..e4b5d92d7b05a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.readstream.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) > [readStream](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.readstream.md) + +## SavedObjectsResolveImportErrorsOptions.readStream property + +Signature: + +```typescript +readStream: Readable; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.retries.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.retries.md new file mode 100644 index 0000000000000..7dc825f762fe9 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.retries.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) > [retries](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.retries.md) + +## SavedObjectsResolveImportErrorsOptions.retries property + +Signature: + +```typescript +retries: SavedObjectsImportRetry[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.savedobjectsclient.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.savedobjectsclient.md new file mode 100644 index 0000000000000..ae5edc98d3a9e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.savedobjectsclient.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) > [savedObjectsClient](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.savedobjectsclient.md) + +## SavedObjectsResolveImportErrorsOptions.savedObjectsClient property + +Signature: + +```typescript +savedObjectsClient: SavedObjectsClientContract; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.supportedtypes.md b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.supportedtypes.md new file mode 100644 index 0000000000000..5a92a8d0a9936 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsresolveimporterrorsoptions.supportedtypes.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsResolveImportErrorsOptions](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.md) > [supportedTypes](./kibana-plugin-server.savedobjectsresolveimporterrorsoptions.supportedtypes.md) + +## SavedObjectsResolveImportErrorsOptions.supportedTypes property + +Signature: + +```typescript +supportedTypes: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservice.importexport.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservice.importexport.md new file mode 100644 index 0000000000000..f9b4e46712f4a --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservice.importexport.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsService](./kibana-plugin-server.savedobjectsservice.md) > [importExport](./kibana-plugin-server.savedobjectsservice.importexport.md) + +## SavedObjectsService.importExport property + +Signature: + +```typescript +importExport: { + objectLimit: number; + importSavedObjects(options: SavedObjectsImportOptions): Promise; + resolveImportErrors(options: SavedObjectsResolveImportErrorsOptions): Promise; + getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise; + }; +``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservice.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservice.md index ad281002854b3..d9e23e6f15928 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectsservice.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservice.md @@ -17,7 +17,9 @@ export interface SavedObjectsService | --- | --- | --- | | [addScopedSavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsservice.addscopedsavedobjectsclientwrapperfactory.md) | ScopedSavedObjectsClientProvider<Request>['addClientWrapperFactory'] | | | [getScopedSavedObjectsClient](./kibana-plugin-server.savedobjectsservice.getscopedsavedobjectsclient.md) | ScopedSavedObjectsClientProvider<Request>['getClient'] | | +| [importExport](./kibana-plugin-server.savedobjectsservice.importexport.md) | {
objectLimit: number;
importSavedObjects(options: SavedObjectsImportOptions): Promise<SavedObjectsImportResponse>;
resolveImportErrors(options: SavedObjectsResolveImportErrorsOptions): Promise<SavedObjectsImportResponse>;
getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise<Readable>;
} | | | [SavedObjectsClient](./kibana-plugin-server.savedobjectsservice.savedobjectsclient.md) | typeof SavedObjectsClient | | +| [schema](./kibana-plugin-server.savedobjectsservice.schema.md) | SavedObjectsSchema | | | [types](./kibana-plugin-server.savedobjectsservice.types.md) | string[] | | ## Methods diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectsservice.schema.md b/docs/development/core/server/kibana-plugin-server.savedobjectsservice.schema.md new file mode 100644 index 0000000000000..be5682e6f034e --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectsservice.schema.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectsService](./kibana-plugin-server.savedobjectsservice.md) > [schema](./kibana-plugin-server.savedobjectsservice.schema.md) + +## SavedObjectsService.schema property + +Signature: + +```typescript +schema: SavedObjectsSchema; +``` diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 2bbcaa58f6af5..426364d344961 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -99,6 +99,7 @@ export { SavedObjectsClient, SavedObjectsClientContract, SavedObjectsCreateOptions, + SavedObjectsClientProviderOptions, SavedObjectsClientWrapperFactory, SavedObjectsClientWrapperOptions, SavedObjectsErrorHelpers, @@ -111,6 +112,16 @@ export { SavedObjectsService, SavedObjectsUpdateOptions, SavedObjectsUpdateResponse, + SavedObjectsExportOptions, + SavedObjectsImportError, + SavedObjectsImportConflictError, + SavedObjectsImportMissingReferencesError, + SavedObjectsImportUnknownError, + SavedObjectsImportUnsupportedTypeError, + SavedObjectsImportOptions, + SavedObjectsImportResponse, + SavedObjectsImportRetry, + SavedObjectsResolveImportErrorsOptions, } from './saved_objects'; export { RecursiveReadonly } from '../utils'; diff --git a/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts b/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts index 385de5b14565d..618a83b0fb68b 100644 --- a/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts +++ b/src/core/server/saved_objects/export/get_sorted_objects_for_export.test.ts @@ -74,50 +74,134 @@ describe('getSortedObjectsForExport()', () => { const response = await readStreamToCompletion(exportStream); expect(response).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "name", - "type": "index-pattern", - }, - ], - "type": "search", - }, -] -`); + Array [ + Object { + "attributes": Object {}, + "id": "1", + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object {}, + "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "name", + "type": "index-pattern", + }, + ], + "type": "search", + }, + ] + `); expect(savedObjectsClient.find).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Object { - "perPage": 500, - "sortField": "_id", - "sortOrder": "asc", - "type": Array [ - "index-pattern", - "search", + [MockFunction] { + "calls": Array [ + Array [ + Object { + "namespace": undefined, + "perPage": 500, + "sortField": "_id", + "sortOrder": "asc", + "type": Array [ + "index-pattern", + "search", + ], + }, + ], ], - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); + }); + + test('exports from the provided namespace when present', async () => { + savedObjectsClient.find.mockResolvedValueOnce({ + total: 2, + saved_objects: [ + { + id: '2', + type: 'search', + attributes: {}, + references: [ + { + name: 'name', + type: 'index-pattern', + id: '1', + }, + ], + }, + { + id: '1', + type: 'index-pattern', + attributes: {}, + references: [], + }, + ], + per_page: 1, + page: 0, + }); + const exportStream = await getSortedObjectsForExport({ + savedObjectsClient, + exportSizeLimit: 500, + types: ['index-pattern', 'search'], + namespace: 'foo', + }); + + const response = await readStreamToCompletion(exportStream); + + expect(response).toMatchInlineSnapshot(` + Array [ + Object { + "attributes": Object {}, + "id": "1", + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object {}, + "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "name", + "type": "index-pattern", + }, + ], + "type": "search", + }, + ] + `); + expect(savedObjectsClient.find).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Object { + "namespace": "foo", + "perPage": 500, + "sortField": "_id", + "sortOrder": "asc", + "type": Array [ + "index-pattern", + "search", + ], + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('export selected types throws error when exceeding exportSizeLimit', async () => { @@ -195,51 +279,54 @@ Array [ }); const response = await readStreamToCompletion(exportStream); expect(response).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "name", - "type": "index-pattern", - }, - ], - "type": "search", - }, -] -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ Array [ Object { + "attributes": Object {}, "id": "1", + "references": Array [], "type": "index-pattern", }, Object { + "attributes": Object {}, "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "name", + "type": "index-pattern", + }, + ], "type": "search", }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ] + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "id": "1", + "type": "index-pattern", + }, + Object { + "id": "2", + "type": "search", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('includes nested dependencies when passed in', async () => { @@ -283,59 +370,65 @@ Array [ }); const response = await readStreamToCompletion(exportStream); expect(response).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "name", - "type": "index-pattern", - }, - ], - "type": "search", - }, -] -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "id": "2", - "type": "search", - }, - ], - ], - Array [ Array [ Object { + "attributes": Object {}, "id": "1", + "references": Array [], "type": "index-pattern", }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + Object { + "attributes": Object {}, + "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "name", + "type": "index-pattern", + }, + ], + "type": "search", + }, + ] + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "id": "2", + "type": "search", + }, + ], + Object { + "namespace": undefined, + }, + ], + Array [ + Array [ + Object { + "id": "1", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('export selected objects throws error when exceeding exportSizeLimit', async () => { diff --git a/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts b/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts index e09780574a25c..d8513bcfe72d3 100644 --- a/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts +++ b/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts @@ -23,17 +23,20 @@ import { SavedObjectsClientContract } from '../'; import { injectNestedDependencies } from './inject_nested_depdendencies'; import { sortObjects } from './sort_objects'; -interface ObjectToExport { - id: string; - type: string; -} - -interface ExportObjectsOptions { +/** + * Options controlling the export operation. + * @public + */ +export interface SavedObjectsExportOptions { types?: string[]; - objects?: ObjectToExport[]; + objects?: Array<{ + id: string; + type: string; + }>; savedObjectsClient: SavedObjectsClientContract; exportSizeLimit: number; includeReferencesDeep?: boolean; + namespace?: string; } async function fetchObjectsToExport({ @@ -41,17 +44,19 @@ async function fetchObjectsToExport({ types, exportSizeLimit, savedObjectsClient, + namespace, }: { - objects?: ObjectToExport[]; + objects?: SavedObjectsExportOptions['objects']; types?: string[]; exportSizeLimit: number; savedObjectsClient: SavedObjectsClientContract; + namespace?: string; }) { if (objects) { if (objects.length > exportSizeLimit) { throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`); } - const bulkGetResult = await savedObjectsClient.bulkGet(objects); + const bulkGetResult = await savedObjectsClient.bulkGet(objects, { namespace }); const erroredObjects = bulkGetResult.saved_objects.filter(obj => !!obj.error); if (erroredObjects.length) { const err = Boom.badRequest(); @@ -67,6 +72,7 @@ async function fetchObjectsToExport({ sortField: '_id', sortOrder: 'asc', perPage: exportSizeLimit, + namespace, }); if (findResponse.total > exportSizeLimit) { throw Boom.badRequest(`Can't export more than ${exportSizeLimit} objects`); @@ -80,17 +86,19 @@ export async function getSortedObjectsForExport({ savedObjectsClient, exportSizeLimit, includeReferencesDeep = false, -}: ExportObjectsOptions) { + namespace, +}: SavedObjectsExportOptions) { const objectsToExport = await fetchObjectsToExport({ types, objects, savedObjectsClient, exportSizeLimit, + namespace, }); const exportedObjects = sortObjects( includeReferencesDeep - ? await injectNestedDependencies(objectsToExport, savedObjectsClient) + ? await injectNestedDependencies(objectsToExport, savedObjectsClient, namespace) : objectsToExport ); diff --git a/src/core/server/saved_objects/export/index.ts b/src/core/server/saved_objects/export/index.ts index eb52fcbecfda8..d994df2af627c 100644 --- a/src/core/server/saved_objects/export/index.ts +++ b/src/core/server/saved_objects/export/index.ts @@ -17,4 +17,7 @@ * under the License. */ -export { getSortedObjectsForExport } from './get_sorted_objects_for_export'; +export { + getSortedObjectsForExport, + SavedObjectsExportOptions, +} from './get_sorted_objects_for_export'; diff --git a/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts b/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts index 9a2548952de3d..2fa06550727f0 100644 --- a/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts +++ b/src/core/server/saved_objects/export/inject_nested_depdendencies.test.ts @@ -70,13 +70,13 @@ describe('getObjectReferencesToFetch()', () => { }); const result = getObjectReferencesToFetch(map); expect(result).toMatchInlineSnapshot(` -Array [ - Object { - "id": "1", - "type": "index-pattern", - }, -] -`); + Array [ + Object { + "id": "1", + "type": "index-pattern", + }, + ] + `); }); test(`doesn't deal with circular dependencies`, () => { @@ -137,15 +137,15 @@ describe('injectNestedDependencies', () => { ]; const result = await injectNestedDependencies(savedObjects, savedObjectsClient); expect(result).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, -] -`); + Array [ + Object { + "attributes": Object {}, + "id": "1", + "references": Array [], + "type": "index-pattern", + }, + ] + `); }); test(`doesn't fetch references that are already fetched`, async () => { @@ -171,27 +171,27 @@ Array [ ]; const result = await injectNestedDependencies(savedObjects, savedObjectsClient); expect(result).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "ref_0", - "type": "index-pattern", - }, - ], - "type": "search", - }, -] -`); + Array [ + Object { + "attributes": Object {}, + "id": "1", + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object {}, + "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "ref_0", + "type": "index-pattern", + }, + ], + "type": "search", + }, + ] + `); }); test('fetches dependencies at least one level deep', async () => { @@ -221,47 +221,50 @@ Array [ }); const result = await injectNestedDependencies(savedObjects, savedObjectsClient); expect(result).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "ref_0", - "type": "index-pattern", - }, - ], - "type": "search", - }, - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, -] -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ Array [ Object { + "attributes": Object {}, + "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "ref_0", + "type": "index-pattern", + }, + ], + "type": "search", + }, + Object { + "attributes": Object {}, "id": "1", + "references": Array [], "type": "index-pattern", }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ] + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "id": "1", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('fetches dependencies multiple levels deep', async () => { @@ -336,108 +339,114 @@ Array [ }); const result = await injectNestedDependencies(savedObjects, savedObjectsClient); expect(result).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "5", - "references": Array [ - Object { - "id": "4", - "name": "panel_0", - "type": "visualization", - }, - Object { - "id": "3", - "name": "panel_1", - "type": "visualization", - }, - ], - "type": "dashboard", - }, - Object { - "attributes": Object {}, - "id": "4", - "references": Array [ - Object { - "id": "2", - "name": "ref_0", - "type": "search", - }, - ], - "type": "visualization", - }, - Object { - "attributes": Object {}, - "id": "3", - "references": Array [ - Object { - "id": "1", - "name": "ref_0", - "type": "index-pattern", - }, - ], - "type": "visualization", - }, - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "ref_0", - "type": "index-pattern", - }, - ], - "type": "search", - }, - Object { - "attributes": Object {}, - "id": "1", - "references": Array [], - "type": "index-pattern", - }, -] -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ Array [ Object { + "attributes": Object {}, + "id": "5", + "references": Array [ + Object { + "id": "4", + "name": "panel_0", + "type": "visualization", + }, + Object { + "id": "3", + "name": "panel_1", + "type": "visualization", + }, + ], + "type": "dashboard", + }, + Object { + "attributes": Object {}, "id": "4", + "references": Array [ + Object { + "id": "2", + "name": "ref_0", + "type": "search", + }, + ], "type": "visualization", }, Object { + "attributes": Object {}, "id": "3", + "references": Array [ + Object { + "id": "1", + "name": "ref_0", + "type": "index-pattern", + }, + ], "type": "visualization", }, - ], - ], - Array [ - Array [ Object { + "attributes": Object {}, "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "ref_0", + "type": "index-pattern", + }, + ], "type": "search", }, Object { + "attributes": Object {}, "id": "1", + "references": Array [], "type": "index-pattern", }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ] + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "id": "4", + "type": "visualization", + }, + Object { + "id": "3", + "type": "visualization", + }, + ], + Object { + "namespace": undefined, + }, + ], + Array [ + Array [ + Object { + "id": "2", + "type": "search", + }, + Object { + "id": "1", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('throws error when bulkGet returns an error', async () => { @@ -505,52 +514,55 @@ Array [ }); const result = await injectNestedDependencies(savedObjects, savedObjectsClient); expect(result).toMatchInlineSnapshot(` -Array [ - Object { - "attributes": Object {}, - "id": "2", - "references": Array [ - Object { - "id": "1", - "name": "ref_0", - "type": "index-pattern", - }, - ], - "type": "search", - }, - Object { - "attributes": Object {}, - "id": "1", - "references": Array [ - Object { - "id": "2", - "name": "ref_0", - "type": "search", - }, - ], - "type": "index-pattern", - }, -] -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ Array [ Object { + "attributes": Object {}, + "id": "2", + "references": Array [ + Object { + "id": "1", + "name": "ref_0", + "type": "index-pattern", + }, + ], + "type": "search", + }, + Object { + "attributes": Object {}, "id": "1", + "references": Array [ + Object { + "id": "2", + "name": "ref_0", + "type": "search", + }, + ], "type": "index-pattern", }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ] + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "id": "1", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); }); diff --git a/src/core/server/saved_objects/export/inject_nested_depdendencies.ts b/src/core/server/saved_objects/export/inject_nested_depdendencies.ts index ee9ce781ef9a5..82cb3e3cfe115 100644 --- a/src/core/server/saved_objects/export/inject_nested_depdendencies.ts +++ b/src/core/server/saved_objects/export/inject_nested_depdendencies.ts @@ -34,7 +34,8 @@ export function getObjectReferencesToFetch(savedObjectsMap: Map(); for (const savedObject of savedObjects) { @@ -42,7 +43,7 @@ export async function injectNestedDependencies( } let objectsToFetch = getObjectReferencesToFetch(savedObjectsMap); while (objectsToFetch.length > 0) { - const bulkGetResponse = await savedObjectsClient.bulkGet(objectsToFetch); + const bulkGetResponse = await savedObjectsClient.bulkGet(objectsToFetch, { namespace }); // Check for errors const erroredObjects = bulkGetResponse.saved_objects.filter(obj => !!obj.error); if (erroredObjects.length) { diff --git a/src/core/server/saved_objects/import/collect_saved_objects.ts b/src/core/server/saved_objects/import/collect_saved_objects.ts index 11add36e54fb6..fa2938109f6e7 100644 --- a/src/core/server/saved_objects/import/collect_saved_objects.ts +++ b/src/core/server/saved_objects/import/collect_saved_objects.ts @@ -26,7 +26,7 @@ import { } from '../../../../legacy/utils/streams'; import { SavedObject } from '../service'; import { createLimitStream } from './create_limit_stream'; -import { ImportError } from './types'; +import { SavedObjectsImportError } from './types'; interface CollectSavedObjectsOptions { readStream: Readable; @@ -41,7 +41,7 @@ export async function collectSavedObjects({ filter, supportedTypes, }: CollectSavedObjectsOptions) { - const errors: ImportError[] = []; + const errors: SavedObjectsImportError[] = []; const collectedObjects: SavedObject[] = await createPromiseFromStreams([ readStream, createLimitStream(objectLimit), diff --git a/src/core/server/saved_objects/import/create_objects_filter.ts b/src/core/server/saved_objects/import/create_objects_filter.ts index aacf8112f255a..684e44944002b 100644 --- a/src/core/server/saved_objects/import/create_objects_filter.ts +++ b/src/core/server/saved_objects/import/create_objects_filter.ts @@ -18,9 +18,9 @@ */ import { SavedObject } from '../service'; -import { Retry } from './types'; +import { SavedObjectsImportRetry } from './types'; -export function createObjectsFilter(retries: Retry[]) { +export function createObjectsFilter(retries: SavedObjectsImportRetry[]) { const retryKeys = new Set(retries.map(retry => `${retry.type}:${retry.id}`)); return (obj: SavedObject) => { return retryKeys.has(`${obj.type}:${obj.id}`); diff --git a/src/core/server/saved_objects/import/extract_errors.ts b/src/core/server/saved_objects/import/extract_errors.ts index 6ae9562a1f3aa..4c001cf8acf64 100644 --- a/src/core/server/saved_objects/import/extract_errors.ts +++ b/src/core/server/saved_objects/import/extract_errors.ts @@ -18,13 +18,13 @@ */ import { SavedObject } from '../service'; -import { ImportError } from './types'; +import { SavedObjectsImportError } from './types'; export function extractErrors( savedObjectResults: SavedObject[], savedObjectsToImport: SavedObject[] ) { - const errors: ImportError[] = []; + const errors: SavedObjectsImportError[] = []; const originalSavedObjectsMap = new Map(); for (const savedObject of savedObjectsToImport) { originalSavedObjectsMap.set(`${savedObject.type}:${savedObject.id}`, savedObject); diff --git a/src/core/server/saved_objects/import/import_saved_objects.test.ts b/src/core/server/saved_objects/import/import_saved_objects.test.ts index 80e5cc9a306f0..6ba4304574f49 100644 --- a/src/core/server/saved_objects/import/import_saved_objects.test.ts +++ b/src/core/server/saved_objects/import/import_saved_objects.test.ts @@ -86,11 +86,11 @@ describe('importSavedObjects()', () => { supportedTypes: [], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 0, -} -`); + Object { + "success": true, + "successCount": 0, + } + `); }); test('calls bulkCreate without overwrite', async () => { @@ -113,66 +113,151 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 4, -} -`); + Object { + "success": true, + "successCount": 4, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "My Index Pattern", - }, - "id": "1", - "migrationVersion": Object {}, - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object { - "title": "My Search", - }, - "id": "2", - "migrationVersion": Object {}, - "references": Array [], - "type": "search", - }, - Object { - "attributes": Object { - "title": "My Visualization", - }, - "id": "3", - "migrationVersion": Object {}, - "references": Array [], - "type": "visualization", - }, - Object { - "attributes": Object { - "title": "My Dashboard", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Index Pattern", + }, + "id": "1", + "migrationVersion": Object {}, + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object { + "title": "My Search", + }, + "id": "2", + "migrationVersion": Object {}, + "references": Array [], + "type": "search", + }, + Object { + "attributes": Object { + "title": "My Visualization", + }, + "id": "3", + "migrationVersion": Object {}, + "references": Array [], + "type": "visualization", + }, + Object { + "attributes": Object { + "title": "My Dashboard", + }, + "id": "4", + "migrationVersion": Object {}, + "references": Array [], + "type": "dashboard", + }, + ], + Object { + "namespace": undefined, + "overwrite": false, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "4", - "migrationVersion": Object {}, - "references": Array [], - "type": "dashboard", - }, - ], - Object { - "overwrite": false, + ], + } + `); + }); + + test('uses the provided namespace when present', async () => { + const readStream = new Readable({ + objectMode: true, + read() { + savedObjects.forEach(obj => this.push(obj)); + this.push(null); }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + }); + savedObjectsClient.find.mockResolvedValueOnce({ saved_objects: [] }); + savedObjectsClient.bulkCreate.mockResolvedValue({ + saved_objects: savedObjects, + }); + const result = await importSavedObjects({ + readStream, + objectLimit: 4, + overwrite: false, + savedObjectsClient, + supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], + namespace: 'foo', + }); + expect(result).toMatchInlineSnapshot(` + Object { + "success": true, + "successCount": 4, + } + `); + expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Index Pattern", + }, + "id": "1", + "migrationVersion": Object {}, + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object { + "title": "My Search", + }, + "id": "2", + "migrationVersion": Object {}, + "references": Array [], + "type": "search", + }, + Object { + "attributes": Object { + "title": "My Visualization", + }, + "id": "3", + "migrationVersion": Object {}, + "references": Array [], + "type": "visualization", + }, + Object { + "attributes": Object { + "title": "My Dashboard", + }, + "id": "4", + "migrationVersion": Object {}, + "references": Array [], + "type": "dashboard", + }, + ], + Object { + "namespace": "foo", + "overwrite": false, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('calls bulkCreate with overwrite', async () => { @@ -195,66 +280,67 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 4, -} -`); + Object { + "success": true, + "successCount": 4, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "My Index Pattern", - }, - "id": "1", - "migrationVersion": Object {}, - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object { - "title": "My Search", - }, - "id": "2", - "migrationVersion": Object {}, - "references": Array [], - "type": "search", - }, - Object { - "attributes": Object { - "title": "My Visualization", - }, - "id": "3", - "migrationVersion": Object {}, - "references": Array [], - "type": "visualization", - }, - Object { - "attributes": Object { - "title": "My Dashboard", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Index Pattern", + }, + "id": "1", + "migrationVersion": Object {}, + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object { + "title": "My Search", + }, + "id": "2", + "migrationVersion": Object {}, + "references": Array [], + "type": "search", + }, + Object { + "attributes": Object { + "title": "My Visualization", + }, + "id": "3", + "migrationVersion": Object {}, + "references": Array [], + "type": "visualization", + }, + Object { + "attributes": Object { + "title": "My Dashboard", + }, + "id": "4", + "migrationVersion": Object {}, + "references": Array [], + "type": "dashboard", + }, + ], + Object { + "namespace": undefined, + "overwrite": true, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "4", - "migrationVersion": Object {}, - "references": Array [], - "type": "dashboard", - }, - ], - Object { - "overwrite": true, - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + } + `); }); test('extracts errors for conflicts', async () => { @@ -284,45 +370,45 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "errors": Array [ - Object { - "error": Object { - "type": "conflict", - }, - "id": "1", - "title": "My Index Pattern", - "type": "index-pattern", - }, - Object { - "error": Object { - "type": "conflict", - }, - "id": "2", - "title": "My Search", - "type": "search", - }, - Object { - "error": Object { - "type": "conflict", - }, - "id": "3", - "title": "My Visualization", - "type": "visualization", - }, - Object { - "error": Object { - "type": "conflict", - }, - "id": "4", - "title": "My Dashboard", - "type": "dashboard", - }, - ], - "success": false, - "successCount": 0, -} -`); + Object { + "errors": Array [ + Object { + "error": Object { + "type": "conflict", + }, + "id": "1", + "title": "My Index Pattern", + "type": "index-pattern", + }, + Object { + "error": Object { + "type": "conflict", + }, + "id": "2", + "title": "My Search", + "type": "search", + }, + Object { + "error": Object { + "type": "conflict", + }, + "id": "3", + "title": "My Visualization", + "type": "visualization", + }, + Object { + "error": Object { + "type": "conflict", + }, + "id": "4", + "title": "My Dashboard", + "type": "dashboard", + }, + ], + "success": false, + "successCount": 0, + } + `); }); test('validates references', async () => { @@ -380,56 +466,59 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "errors": Array [ - Object { - "error": Object { - "blocking": Array [ + Object { + "errors": Array [ Object { - "id": "3", - "type": "visualization", + "error": Object { + "blocking": Array [ + Object { + "id": "3", + "type": "visualization", + }, + ], + "references": Array [ + Object { + "id": "2", + "type": "index-pattern", + }, + ], + "type": "missing_references", + }, + "id": "1", + "title": "My Search", + "type": "search", }, ], - "references": Array [ + "success": false, + "successCount": 0, + } + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "fields": Array [ + "id", + ], + "id": "2", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ Object { - "id": "2", - "type": "index-pattern", + "type": "return", + "value": Promise {}, }, ], - "type": "missing_references", - }, - "id": "1", - "title": "My Search", - "type": "search", - }, - ], - "success": false, - "successCount": 0, -} -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "fields": Array [ - "id", - ], - "id": "2", - "type": "index-pattern", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + } + `); }); test('validates supported types', async () => { @@ -453,75 +542,76 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "errors": Array [ - Object { - "error": Object { - "type": "unsupported_type", - }, - "id": "1", - "title": "my title", - "type": "wigwags", - }, - ], - "success": false, - "successCount": 4, -} -`); - expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "My Index Pattern", - }, - "id": "1", - "migrationVersion": Object {}, - "references": Array [], - "type": "index-pattern", - }, - Object { - "attributes": Object { - "title": "My Search", - }, - "id": "2", - "migrationVersion": Object {}, - "references": Array [], - "type": "search", - }, - Object { - "attributes": Object { - "title": "My Visualization", + Object { + "errors": Array [ + Object { + "error": Object { + "type": "unsupported_type", + }, + "id": "1", + "title": "my title", + "type": "wigwags", }, - "id": "3", - "migrationVersion": Object {}, - "references": Array [], - "type": "visualization", - }, - Object { - "attributes": Object { - "title": "My Dashboard", + ], + "success": false, + "successCount": 4, + } + `); + expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Index Pattern", + }, + "id": "1", + "migrationVersion": Object {}, + "references": Array [], + "type": "index-pattern", + }, + Object { + "attributes": Object { + "title": "My Search", + }, + "id": "2", + "migrationVersion": Object {}, + "references": Array [], + "type": "search", + }, + Object { + "attributes": Object { + "title": "My Visualization", + }, + "id": "3", + "migrationVersion": Object {}, + "references": Array [], + "type": "visualization", + }, + Object { + "attributes": Object { + "title": "My Dashboard", + }, + "id": "4", + "migrationVersion": Object {}, + "references": Array [], + "type": "dashboard", + }, + ], + Object { + "namespace": undefined, + "overwrite": false, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "4", - "migrationVersion": Object {}, - "references": Array [], - "type": "dashboard", - }, - ], - Object { - "overwrite": false, - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + } + `); }); }); diff --git a/src/core/server/saved_objects/import/import_saved_objects.ts b/src/core/server/saved_objects/import/import_saved_objects.ts index 10c1350c4c579..ef3b4a214c2c2 100644 --- a/src/core/server/saved_objects/import/import_saved_objects.ts +++ b/src/core/server/saved_objects/import/import_saved_objects.ts @@ -17,26 +17,14 @@ * under the License. */ -import { Readable } from 'stream'; import { collectSavedObjects } from './collect_saved_objects'; import { extractErrors } from './extract_errors'; -import { ImportError } from './types'; +import { + SavedObjectsImportError, + SavedObjectsImportResponse, + SavedObjectsImportOptions, +} from './types'; import { validateReferences } from './validate_references'; -import { SavedObjectsClientContract } from '../'; - -interface ImportSavedObjectsOptions { - readStream: Readable; - objectLimit: number; - overwrite: boolean; - savedObjectsClient: SavedObjectsClientContract; - supportedTypes: string[]; -} - -interface ImportResponse { - success: boolean; - successCount: number; - errors?: ImportError[]; -} export async function importSavedObjects({ readStream, @@ -44,8 +32,9 @@ export async function importSavedObjects({ overwrite, savedObjectsClient, supportedTypes, -}: ImportSavedObjectsOptions): Promise { - let errorAccumulator: ImportError[] = []; + namespace, +}: SavedObjectsImportOptions): Promise { + let errorAccumulator: SavedObjectsImportError[] = []; // Get the objects to import const { @@ -57,7 +46,8 @@ export async function importSavedObjects({ // Validate references const { filteredObjects, errors: validationErrors } = await validateReferences( objectsFromStream, - savedObjectsClient + savedObjectsClient, + namespace ); errorAccumulator = [...errorAccumulator, ...validationErrors]; @@ -73,6 +63,7 @@ export async function importSavedObjects({ // Create objects in bulk const bulkCreateResult = await savedObjectsClient.bulkCreate(filteredObjects, { overwrite, + namespace, }); errorAccumulator = [ ...errorAccumulator, diff --git a/src/core/server/saved_objects/import/index.ts b/src/core/server/saved_objects/import/index.ts index aad06931c330e..95fa8aa192f3e 100644 --- a/src/core/server/saved_objects/import/index.ts +++ b/src/core/server/saved_objects/import/index.ts @@ -19,3 +19,14 @@ export { importSavedObjects } from './import_saved_objects'; export { resolveImportErrors } from './resolve_import_errors'; +export { + SavedObjectsImportResponse, + SavedObjectsImportError, + SavedObjectsImportOptions, + SavedObjectsImportConflictError, + SavedObjectsImportMissingReferencesError, + SavedObjectsImportUnknownError, + SavedObjectsImportUnsupportedTypeError, + SavedObjectsResolveImportErrorsOptions, + SavedObjectsImportRetry, +} from './types'; diff --git a/src/core/server/saved_objects/import/resolve_import_errors.test.ts b/src/core/server/saved_objects/import/resolve_import_errors.test.ts index d3f36852fd796..783b0d6a61be6 100644 --- a/src/core/server/saved_objects/import/resolve_import_errors.test.ts +++ b/src/core/server/saved_objects/import/resolve_import_errors.test.ts @@ -96,11 +96,11 @@ describe('resolveImportErrors()', () => { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 0, -} -`); + Object { + "success": true, + "successCount": 0, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(`[MockFunction]`); }); @@ -130,36 +130,39 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 1, -} -`); + Object { + "success": true, + "successCount": 1, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "My Visualization", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Visualization", + }, + "id": "3", + "migrationVersion": Object {}, + "references": Array [], + "type": "visualization", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "3", - "migrationVersion": Object {}, - "references": Array [], - "type": "visualization", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + } + `); }); test('works with overwrites', async () => { @@ -188,39 +191,40 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 1, -} -`); + Object { + "success": true, + "successCount": 1, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "My Index Pattern", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Index Pattern", + }, + "id": "1", + "migrationVersion": Object {}, + "references": Array [], + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + "overwrite": true, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "1", - "migrationVersion": Object {}, - "references": Array [], - "type": "index-pattern", - }, - ], - Object { - "overwrite": true, - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + } + `); }); test('works wtih replaceReferences', async () => { @@ -255,42 +259,45 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "success": true, - "successCount": 1, -} -`); + Object { + "success": true, + "successCount": 1, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "My Dashboard", - }, - "id": "4", - "migrationVersion": Object {}, - "references": Array [ + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "My Dashboard", + }, + "id": "4", + "migrationVersion": Object {}, + "references": Array [ + Object { + "id": "13", + "name": "panel_0", + "type": "visualization", + }, + ], + "type": "dashboard", + }, + ], Object { - "id": "13", - "name": "panel_0", - "type": "visualization", + "namespace": undefined, }, ], - "type": "dashboard", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); test('extracts errors for conflicts', async () => { @@ -324,45 +331,45 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "errors": Array [ - Object { - "error": Object { - "type": "conflict", - }, - "id": "1", - "title": "My Index Pattern", - "type": "index-pattern", - }, - Object { - "error": Object { - "type": "conflict", - }, - "id": "2", - "title": "My Search", - "type": "search", - }, - Object { - "error": Object { - "type": "conflict", - }, - "id": "3", - "title": "My Visualization", - "type": "visualization", - }, - Object { - "error": Object { - "type": "conflict", - }, - "id": "4", - "title": "My Dashboard", - "type": "dashboard", - }, - ], - "success": false, - "successCount": 0, -} -`); + Object { + "errors": Array [ + Object { + "error": Object { + "type": "conflict", + }, + "id": "1", + "title": "My Index Pattern", + "type": "index-pattern", + }, + Object { + "error": Object { + "type": "conflict", + }, + "id": "2", + "title": "My Search", + "type": "search", + }, + Object { + "error": Object { + "type": "conflict", + }, + "id": "3", + "title": "My Visualization", + "type": "visualization", + }, + Object { + "error": Object { + "type": "conflict", + }, + "id": "4", + "title": "My Dashboard", + "type": "dashboard", + }, + ], + "success": false, + "successCount": 0, + } + `); }); test('validates references', async () => { @@ -433,56 +440,59 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "errors": Array [ - Object { - "error": Object { - "blocking": Array [ + Object { + "errors": Array [ Object { - "id": "3", - "type": "visualization", + "error": Object { + "blocking": Array [ + Object { + "id": "3", + "type": "visualization", + }, + ], + "references": Array [ + Object { + "id": "2", + "type": "index-pattern", + }, + ], + "type": "missing_references", + }, + "id": "1", + "title": "My Search", + "type": "search", }, ], - "references": Array [ + "success": false, + "successCount": 0, + } + `); + expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "fields": Array [ + "id", + ], + "id": "2", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ Object { - "id": "2", - "type": "index-pattern", + "type": "return", + "value": Promise {}, }, ], - "type": "missing_references", - }, - "id": "1", - "title": "My Search", - "type": "search", - }, - ], - "success": false, - "successCount": 0, -} -`); - expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "fields": Array [ - "id", - ], - "id": "2", - "type": "index-pattern", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + } + `); }); test('validates object types', async () => { @@ -512,21 +522,67 @@ Object { supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], }); expect(result).toMatchInlineSnapshot(` -Object { - "errors": Array [ - Object { - "error": Object { - "type": "unsupported_type", - }, - "id": "1", - "title": "my title", - "type": "wigwags", - }, - ], - "success": false, - "successCount": 0, -} -`); + Object { + "errors": Array [ + Object { + "error": Object { + "type": "unsupported_type", + }, + "id": "1", + "title": "my title", + "type": "wigwags", + }, + ], + "success": false, + "successCount": 0, + } + `); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(`[MockFunction]`); }); + + test('uses namespace when provided', async () => { + const readStream = new Readable({ + objectMode: true, + read() { + savedObjects.forEach(obj => this.push(obj)); + this.push(null); + }, + }); + savedObjectsClient.bulkCreate.mockResolvedValue({ + saved_objects: savedObjects.filter(obj => obj.type === 'index-pattern' && obj.id === '1'), + }); + const result = await resolveImportErrors({ + readStream, + objectLimit: 4, + retries: [ + { + type: 'index-pattern', + id: '1', + overwrite: true, + replaceReferences: [], + }, + ], + savedObjectsClient, + supportedTypes: ['index-pattern', 'search', 'visualization', 'dashboard'], + namespace: 'foo', + }); + expect(result).toMatchInlineSnapshot(` + Object { + "success": true, + "successCount": 1, + } + `); + expect(savedObjectsClient.bulkCreate).toHaveBeenCalledWith( + [ + { + attributes: { title: 'My Index Pattern' }, + id: '1', + migrationVersion: {}, + references: [], + type: 'index-pattern', + }, + ], + { namespace: 'foo', overwrite: true } + ); + }); }); diff --git a/src/core/server/saved_objects/import/resolve_import_errors.ts b/src/core/server/saved_objects/import/resolve_import_errors.ts index 5cd4d2fca740c..c04827dc98ab5 100644 --- a/src/core/server/saved_objects/import/resolve_import_errors.ts +++ b/src/core/server/saved_objects/import/resolve_import_errors.ts @@ -17,38 +17,27 @@ * under the License. */ -import { Readable } from 'stream'; -import { SavedObjectsClientContract } from '../'; import { collectSavedObjects } from './collect_saved_objects'; import { createObjectsFilter } from './create_objects_filter'; import { extractErrors } from './extract_errors'; import { splitOverwrites } from './split_overwrites'; -import { ImportError, Retry } from './types'; +import { + SavedObjectsImportError, + SavedObjectsImportResponse, + SavedObjectsResolveImportErrorsOptions, +} from './types'; import { validateReferences } from './validate_references'; -interface ResolveImportErrorsOptions { - readStream: Readable; - objectLimit: number; - savedObjectsClient: SavedObjectsClientContract; - retries: Retry[]; - supportedTypes: string[]; -} - -interface ImportResponse { - success: boolean; - successCount: number; - errors?: ImportError[]; -} - export async function resolveImportErrors({ readStream, objectLimit, retries, savedObjectsClient, supportedTypes, -}: ResolveImportErrorsOptions): Promise { + namespace, +}: SavedObjectsResolveImportErrorsOptions): Promise { let successCount = 0; - let errorAccumulator: ImportError[] = []; + let errorAccumulator: SavedObjectsImportError[] = []; const filter = createObjectsFilter(retries); // Get the objects to resolve errors @@ -89,7 +78,8 @@ export async function resolveImportErrors({ // Validate references const { filteredObjects, errors: validationErrors } = await validateReferences( objectsToResolve, - savedObjectsClient + savedObjectsClient, + namespace ); errorAccumulator = [...errorAccumulator, ...validationErrors]; @@ -98,6 +88,7 @@ export async function resolveImportErrors({ if (objectsToOverwrite.length) { const bulkCreateResult = await savedObjectsClient.bulkCreate(objectsToOverwrite, { overwrite: true, + namespace, }); errorAccumulator = [ ...errorAccumulator, @@ -106,7 +97,9 @@ export async function resolveImportErrors({ successCount += bulkCreateResult.saved_objects.filter(obj => !obj.error).length; } if (objectsToNotOverwrite.length) { - const bulkCreateResult = await savedObjectsClient.bulkCreate(objectsToNotOverwrite); + const bulkCreateResult = await savedObjectsClient.bulkCreate(objectsToNotOverwrite, { + namespace, + }); errorAccumulator = [ ...errorAccumulator, ...extractErrors(bulkCreateResult.saved_objects, objectsToNotOverwrite), diff --git a/src/core/server/saved_objects/import/split_overwrites.ts b/src/core/server/saved_objects/import/split_overwrites.ts index 5609308f755f3..f49b634c8d9f2 100644 --- a/src/core/server/saved_objects/import/split_overwrites.ts +++ b/src/core/server/saved_objects/import/split_overwrites.ts @@ -18,9 +18,9 @@ */ import { SavedObject } from '../service'; -import { Retry } from './types'; +import { SavedObjectsImportRetry } from './types'; -export function splitOverwrites(savedObjects: SavedObject[], retries: Retry[]) { +export function splitOverwrites(savedObjects: SavedObject[], retries: SavedObjectsImportRetry[]) { const objectsToOverwrite: SavedObject[] = []; const objectsToNotOverwrite: SavedObject[] = []; const overwrites = retries diff --git a/src/core/server/saved_objects/import/types.ts b/src/core/server/saved_objects/import/types.ts index ccefe178f38d5..cc16a1697d9a0 100644 --- a/src/core/server/saved_objects/import/types.ts +++ b/src/core/server/saved_objects/import/types.ts @@ -17,7 +17,14 @@ * under the License. */ -export interface Retry { +import { Readable } from 'stream'; +import { SavedObjectsClientContract } from '../service'; + +/** + * Describes a retry operation for importing a saved object. + * @public + */ +export interface SavedObjectsImportRetry { type: string; id: string; overwrite: boolean; @@ -28,21 +35,37 @@ export interface Retry { }>; } -export interface ConflictError { +/** + * Represents a failure to import due to a conflict. + * @public + */ +export interface SavedObjectsImportConflictError { type: 'conflict'; } -export interface UnsupportedTypeError { +/** + * Represents a failure to import due to having an unsupported saved object type. + * @public + */ +export interface SavedObjectsImportUnsupportedTypeError { type: 'unsupported_type'; } -export interface UnknownError { +/** + * Represents a failure to import due to an unknown reason. + * @public + */ +export interface SavedObjectsImportUnknownError { type: 'unknown'; message: string; statusCode: number; } -export interface MissingReferencesError { +/** + * Represents a failure to import due to missing references. + * @public + */ +export interface SavedObjectsImportMissingReferencesError { type: 'missing_references'; references: Array<{ type: string; @@ -54,9 +77,53 @@ export interface MissingReferencesError { }>; } -export interface ImportError { +/** + * Represents a failure to import. + * @public + */ +export interface SavedObjectsImportError { id: string; type: string; title?: string; - error: ConflictError | UnsupportedTypeError | MissingReferencesError | UnknownError; + error: + | SavedObjectsImportConflictError + | SavedObjectsImportUnsupportedTypeError + | SavedObjectsImportMissingReferencesError + | SavedObjectsImportUnknownError; +} + +/** + * The response describing the result of an import. + * @public + */ +export interface SavedObjectsImportResponse { + success: boolean; + successCount: number; + errors?: SavedObjectsImportError[]; +} + +/** + * Options to control the import operation. + * @public + */ +export interface SavedObjectsImportOptions { + readStream: Readable; + objectLimit: number; + overwrite: boolean; + savedObjectsClient: SavedObjectsClientContract; + supportedTypes: string[]; + namespace?: string; +} + +/** + * Options to control the "resolve import" operation. + * @public + */ +export interface SavedObjectsResolveImportErrorsOptions { + readStream: Readable; + objectLimit: number; + savedObjectsClient: SavedObjectsClientContract; + retries: SavedObjectsImportRetry[]; + supportedTypes: string[]; + namespace?: string; } diff --git a/src/core/server/saved_objects/import/validate_references.test.ts b/src/core/server/saved_objects/import/validate_references.test.ts index e69ca99fb10f2..1a558b3d82b32 100644 --- a/src/core/server/saved_objects/import/validate_references.test.ts +++ b/src/core/server/saved_objects/import/validate_references.test.ts @@ -107,6 +107,9 @@ describe('getNonExistingReferenceAsKeys()', () => { "type": "index-pattern", }, ], + Object { + "namespace": undefined, + }, ], ], "results": Array [ @@ -206,6 +209,9 @@ describe('getNonExistingReferenceAsKeys()', () => { "type": "search", }, ], + Object { + "namespace": undefined, + }, ], ], "results": Array [ @@ -434,6 +440,9 @@ Object { "type": "search", }, ], + Object { + "namespace": undefined, + }, ], ], "results": Array [ diff --git a/src/core/server/saved_objects/import/validate_references.ts b/src/core/server/saved_objects/import/validate_references.ts index 2e3c1ef5293b3..ad3f73b68f6e0 100644 --- a/src/core/server/saved_objects/import/validate_references.ts +++ b/src/core/server/saved_objects/import/validate_references.ts @@ -19,7 +19,7 @@ import Boom from 'boom'; import { SavedObject, SavedObjectsClientContract } from '../'; -import { ImportError } from './types'; +import { SavedObjectsImportError } from './types'; const REF_TYPES_TO_VLIDATE = ['index-pattern', 'search']; @@ -29,7 +29,8 @@ function filterReferencesToValidate({ type }: { type: string }) { export async function getNonExistingReferenceAsKeys( savedObjects: SavedObject[], - savedObjectsClient: SavedObjectsClientContract + savedObjectsClient: SavedObjectsClientContract, + namespace?: string ) { const collector = new Map(); // Collect all references within objects @@ -50,7 +51,7 @@ export async function getNonExistingReferenceAsKeys( // Fetch references to see if they exist const bulkGetOpts = Array.from(collector.values()).map(obj => ({ ...obj, fields: ['id'] })); - const bulkGetResponse = await savedObjectsClient.bulkGet(bulkGetOpts); + const bulkGetResponse = await savedObjectsClient.bulkGet(bulkGetOpts, { namespace }); // Error handling const erroredObjects = bulkGetResponse.saved_objects.filter( @@ -77,12 +78,14 @@ export async function getNonExistingReferenceAsKeys( export async function validateReferences( savedObjects: SavedObject[], - savedObjectsClient: SavedObjectsClientContract + savedObjectsClient: SavedObjectsClientContract, + namespace?: string ) { - const errorMap: { [key: string]: ImportError } = {}; + const errorMap: { [key: string]: SavedObjectsImportError } = {}; const nonExistingReferenceKeys = await getNonExistingReferenceAsKeys( savedObjects, - savedObjectsClient + savedObjectsClient, + namespace ); // Filter out objects with missing references, add to error object diff --git a/src/core/server/saved_objects/index.ts b/src/core/server/saved_objects/index.ts index 623c722eb95b1..ef0362e0eb915 100644 --- a/src/core/server/saved_objects/index.ts +++ b/src/core/server/saved_objects/index.ts @@ -23,4 +23,8 @@ export { SavedObjectsSchema } from './schema'; export { SavedObjectsManagement } from './management'; +export * from './import'; + +export { getSortedObjectsForExport, SavedObjectsExportOptions } from './export'; + export { SavedObjectsSerializer, RawDoc as SavedObjectsRawDoc } from './serialization'; diff --git a/src/core/server/saved_objects/service/index.ts b/src/core/server/saved_objects/service/index.ts index 697e1d2d41471..386539e755d9a 100644 --- a/src/core/server/saved_objects/service/index.ts +++ b/src/core/server/saved_objects/service/index.ts @@ -17,8 +17,13 @@ * under the License. */ +import { Readable } from 'stream'; import { ScopedSavedObjectsClientProvider } from './lib'; import { SavedObjectsClient } from './saved_objects_client'; +import { SavedObjectsExportOptions } from '../export'; +import { SavedObjectsImportOptions, SavedObjectsImportResponse } from '../import'; +import { SavedObjectsSchema } from '../schema'; +import { SavedObjectsResolveImportErrorsOptions } from '../import/types'; /** * @public @@ -31,12 +36,22 @@ export interface SavedObjectsService { getScopedSavedObjectsClient: ScopedSavedObjectsClientProvider['getClient']; SavedObjectsClient: typeof SavedObjectsClient; types: string[]; + schema: SavedObjectsSchema; getSavedObjectsRepository(...rest: any[]): any; + importExport: { + objectLimit: number; + importSavedObjects(options: SavedObjectsImportOptions): Promise; + resolveImportErrors( + options: SavedObjectsResolveImportErrorsOptions + ): Promise; + getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise; + }; } export { SavedObjectsRepository, ScopedSavedObjectsClientProvider, + SavedObjectsClientProviderOptions, SavedObjectsClientWrapperFactory, SavedObjectsClientWrapperOptions, SavedObjectsErrorHelpers, diff --git a/src/core/server/saved_objects/service/lib/index.ts b/src/core/server/saved_objects/service/lib/index.ts index 19fdc3d75f603..d987737c2ffa0 100644 --- a/src/core/server/saved_objects/service/lib/index.ts +++ b/src/core/server/saved_objects/service/lib/index.ts @@ -22,6 +22,7 @@ export { SavedObjectsClientWrapperFactory, SavedObjectsClientWrapperOptions, ScopedSavedObjectsClientProvider, + SavedObjectsClientProviderOptions, } from './scoped_client_provider'; export { SavedObjectsErrorHelpers } from './errors'; diff --git a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts index fc0a3ea64c7a4..e0ca16e254e18 100644 --- a/src/core/server/saved_objects/service/lib/scoped_client_provider.ts +++ b/src/core/server/saved_objects/service/lib/scoped_client_provider.ts @@ -19,21 +19,37 @@ import { PriorityCollection } from './priority_collection'; import { SavedObjectsClientContract } from '..'; +/** + * Options passed to each SavedObjectsClientWrapperFactory to aid in creating the wrapper instance. + * @public + */ export interface SavedObjectsClientWrapperOptions { client: SavedObjectsClientContract; request: Request; } +/** + * Describes the factory used to create instances of Saved Objects Client Wrappers. + * @public + */ export type SavedObjectsClientWrapperFactory = ( options: SavedObjectsClientWrapperOptions ) => SavedObjectsClientContract; +/** + * Describes the factory used to create instances of the Saved Objects Client. + * @public + */ export type SavedObjectsClientFactory = ({ request, }: { request: Request; }) => SavedObjectsClientContract; +/** + * Options to control the creation of the Saved Objects Client. + * @public + */ export interface SavedObjectsClientProviderOptions { excludedWrappers?: string[]; } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 6ab535a66cb36..b4871fc5cd381 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -12,6 +12,7 @@ import { Duration } from 'moment'; import { IncomingHttpHeaders } from 'http'; import { ObjectType } from '@kbn/config-schema'; import { Observable } from 'rxjs'; +import { Readable } from 'stream'; import { Request } from 'hapi'; import { ResponseObject } from 'hapi'; import { ResponseToolkit } from 'hapi'; @@ -533,14 +534,16 @@ export class SavedObjectsClient { // @public export type SavedObjectsClientContract = Pick; -// Warning: (ae-missing-release-tag) "SavedObjectsClientWrapperFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export interface SavedObjectsClientProviderOptions { + // (undocumented) + excludedWrappers?: string[]; +} + +// @public export type SavedObjectsClientWrapperFactory = (options: SavedObjectsClientWrapperOptions) => SavedObjectsClientContract; -// Warning: (ae-missing-release-tag) "SavedObjectsClientWrapperOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface SavedObjectsClientWrapperOptions { // (undocumented) client: SavedObjectsClientContract; @@ -608,6 +611,25 @@ export class SavedObjectsErrorHelpers { static isSavedObjectsClientError(error: any): error is DecoratedError; } +// @public +export interface SavedObjectsExportOptions { + // (undocumented) + exportSizeLimit: number; + // (undocumented) + includeReferencesDeep?: boolean; + // (undocumented) + namespace?: string; + // (undocumented) + objects?: Array<{ + id: string; + type: string; + }>; + // (undocumented) + savedObjectsClient: SavedObjectsClientContract; + // (undocumented) + types?: string[]; +} + // @public (undocumented) export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions { // (undocumented) @@ -646,6 +668,98 @@ export interface SavedObjectsFindResponse total: number; } +// @public +export interface SavedObjectsImportConflictError { + // (undocumented) + type: 'conflict'; +} + +// @public +export interface SavedObjectsImportError { + // (undocumented) + error: SavedObjectsImportConflictError | SavedObjectsImportUnsupportedTypeError | SavedObjectsImportMissingReferencesError | SavedObjectsImportUnknownError; + // (undocumented) + id: string; + // (undocumented) + title?: string; + // (undocumented) + type: string; +} + +// @public +export interface SavedObjectsImportMissingReferencesError { + // (undocumented) + blocking: Array<{ + type: string; + id: string; + }>; + // (undocumented) + references: Array<{ + type: string; + id: string; + }>; + // (undocumented) + type: 'missing_references'; +} + +// @public +export interface SavedObjectsImportOptions { + // (undocumented) + namespace?: string; + // (undocumented) + objectLimit: number; + // (undocumented) + overwrite: boolean; + // (undocumented) + readStream: Readable; + // (undocumented) + savedObjectsClient: SavedObjectsClientContract; + // (undocumented) + supportedTypes: string[]; +} + +// @public +export interface SavedObjectsImportResponse { + // (undocumented) + errors?: SavedObjectsImportError[]; + // (undocumented) + success: boolean; + // (undocumented) + successCount: number; +} + +// @public +export interface SavedObjectsImportRetry { + // (undocumented) + id: string; + // (undocumented) + overwrite: boolean; + // (undocumented) + replaceReferences: Array<{ + type: string; + from: string; + to: string; + }>; + // (undocumented) + type: string; +} + +// @public +export interface SavedObjectsImportUnknownError { + // (undocumented) + message: string; + // (undocumented) + statusCode: number; + // (undocumented) + type: 'unknown'; +} + +// @public +export interface SavedObjectsImportUnsupportedTypeError { + // (undocumented) + type: 'unsupported_type'; +} + // @public export interface SavedObjectsMigrationVersion { // (undocumented) @@ -668,6 +782,22 @@ export interface SavedObjectsRawDoc { _type?: string; } +// @public +export interface SavedObjectsResolveImportErrorsOptions { + // (undocumented) + namespace?: string; + // (undocumented) + objectLimit: number; + // (undocumented) + readStream: Readable; + // (undocumented) + retries: SavedObjectsImportRetry[]; + // (undocumented) + savedObjectsClient: SavedObjectsClientContract; + // (undocumented) + supportedTypes: string[]; +} + // Warning: (ae-missing-release-tag) "SavedObjectsSchema" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -704,11 +834,20 @@ export interface SavedObjectsService { getSavedObjectsRepository(...rest: any[]): any; // (undocumented) getScopedSavedObjectsClient: ScopedSavedObjectsClientProvider['getClient']; + // (undocumented) + importExport: { + objectLimit: number; + importSavedObjects(options: SavedObjectsImportOptions): Promise; + resolveImportErrors(options: SavedObjectsResolveImportErrorsOptions): Promise; + getSortedObjectsForExport(options: SavedObjectsExportOptions): Promise; + }; // Warning: (ae-incompatible-release-tags) The symbol "SavedObjectsClient" is marked as @public, but its signature references "SavedObjectsClient" which is marked as @internal // // (undocumented) SavedObjectsClient: typeof SavedObjectsClient; // (undocumented) + schema: SavedObjectsSchema; + // (undocumented) types: string[]; } diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts index dff649227adfe..36a0e423e1660 100644 --- a/src/legacy/server/kbn_server.d.ts +++ b/src/legacy/server/kbn_server.d.ts @@ -19,6 +19,7 @@ import { ResponseObject, Server } from 'hapi'; +import { SavedObjectsClientProviderOptions } from 'src/core/server'; import { ConfigService, ElasticsearchServiceSetup, @@ -74,7 +75,7 @@ declare module 'hapi' { } interface Request { - getSavedObjectsClient(): SavedObjectsClientContract; + getSavedObjectsClient(options?: SavedObjectsClientProviderOptions): SavedObjectsClientContract; getBasePath(): string; getUiSettingsService(): any; getCapabilities(): Promise; diff --git a/src/legacy/server/saved_objects/routes/import.test.ts b/src/legacy/server/saved_objects/routes/import.test.ts index 5530170472f1c..5e859e7a57d8c 100644 --- a/src/legacy/server/saved_objects/routes/import.test.ts +++ b/src/legacy/server/saved_objects/routes/import.test.ts @@ -301,6 +301,9 @@ describe('POST /api/saved_objects/_import', () => { "type": "index-pattern", }, ], + Object { + "namespace": undefined, + }, ], ], "results": Array [ diff --git a/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts b/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts index 64261f15a2e78..32adf18f7481c 100644 --- a/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts +++ b/src/legacy/server/saved_objects/routes/resolve_import_errors.test.ts @@ -161,29 +161,32 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => { expect(statusCode).toBe(200); expect(response).toEqual({ success: true, successCount: 1 }); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "Look at my dashboard", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "Look at my dashboard", + }, + "id": "my-dashboard", + "migrationVersion": Object {}, + "type": "dashboard", + }, + ], + Object { + "namespace": undefined, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "my-dashboard", - "migrationVersion": Object {}, - "type": "dashboard", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + } + `); }); test('resolves conflicts for dashboard', async () => { @@ -224,32 +227,33 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => { expect(statusCode).toBe(200); expect(response).toEqual({ success: true, successCount: 1 }); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "Look at my dashboard", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "Look at my dashboard", + }, + "id": "my-dashboard", + "migrationVersion": Object {}, + "type": "dashboard", + }, + ], + Object { + "namespace": undefined, + "overwrite": true, + }, + ], + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, }, - "id": "my-dashboard", - "migrationVersion": Object {}, - "type": "dashboard", - }, - ], - Object { - "overwrite": true, - }, - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + } + `); }); test('resolves conflicts by replacing the visualization references', async () => { @@ -306,58 +310,64 @@ describe('POST /api/saved_objects/_resolve_import_errors', () => { expect(statusCode).toBe(200); expect(response).toEqual({ success: true, successCount: 1 }); expect(savedObjectsClient.bulkCreate).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "attributes": Object { - "title": "Look at my visualization", - }, - "id": "my-vis", - "migrationVersion": Object {}, - "references": Array [ + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "attributes": Object { + "title": "Look at my visualization", + }, + "id": "my-vis", + "migrationVersion": Object {}, + "references": Array [ + Object { + "id": "existing", + "name": "ref_0", + "type": "index-pattern", + }, + ], + "type": "visualization", + }, + ], Object { - "id": "existing", - "name": "ref_0", - "type": "index-pattern", + "namespace": undefined, }, ], - "type": "visualization", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); expect(savedObjectsClient.bulkGet).toMatchInlineSnapshot(` -[MockFunction] { - "calls": Array [ - Array [ - Array [ - Object { - "fields": Array [ - "id", + [MockFunction] { + "calls": Array [ + Array [ + Array [ + Object { + "fields": Array [ + "id", + ], + "id": "existing", + "type": "index-pattern", + }, + ], + Object { + "namespace": undefined, + }, ], - "id": "existing", - "type": "index-pattern", - }, - ], - ], - ], - "results": Array [ - Object { - "type": "return", - "value": Promise {}, - }, - ], -} -`); + ], + "results": Array [ + Object { + "type": "return", + "value": Promise {}, + }, + ], + } + `); }); }); diff --git a/src/legacy/server/saved_objects/saved_objects_mixin.js b/src/legacy/server/saved_objects/saved_objects_mixin.js index 29e2cb356da8e..d6ca2698395f3 100644 --- a/src/legacy/server/saved_objects/saved_objects_mixin.js +++ b/src/legacy/server/saved_objects/saved_objects_mixin.js @@ -27,7 +27,10 @@ import { SavedObjectsClient, SavedObjectsRepository, ScopedSavedObjectsClientProvider, -} from '../../../core/server/saved_objects/service'; + getSortedObjectsForExport, + importSavedObjects, + resolveImportErrors, +} from '../../../core/server/saved_objects'; import { getRootPropertiesObjects } from '../../../core/server/saved_objects/mappings'; import { SavedObjectsManagement } from '../../../core/server/saved_objects/management'; @@ -144,6 +147,13 @@ export function savedObjectsMixin(kbnServer, server) { setScopedSavedObjectsClientFactory: (...args) => provider.setClientFactory(...args), addScopedSavedObjectsClientWrapperFactory: (...args) => provider.addClientWrapperFactory(...args), + importExport: { + objectLimit: server.config().get('savedObjects.maxImportExportSize'), + importSavedObjects, + resolveImportErrors, + getSortedObjectsForExport, + }, + schema, }; server.decorate('server', 'savedObjects', service);