Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Adds validations for Saved Object types when calling create or bulkCreate. #118969

Merged
merged 15 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/development/core/server/kibana-plugin-core-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [SavedObjectsRepository](./kibana-plugin-core-server.savedobjectsrepository.md) | |
| [SavedObjectsSerializer](./kibana-plugin-core-server.savedobjectsserializer.md) | A serializer that can be used to manually convert [raw](./kibana-plugin-core-server.savedobjectsrawdoc.md) or [sanitized](./kibana-plugin-core-server.savedobjectsanitizeddoc.md) documents to the other kind. |
| [SavedObjectsUtils](./kibana-plugin-core-server.savedobjectsutils.md) | |
| [SavedObjectsValidationError](./kibana-plugin-core-server.savedobjectsvalidationerror.md) | Error to return when the validation is not successful. |
| [SavedObjectTypeRegistry](./kibana-plugin-core-server.savedobjecttyperegistry.md) | Registry holding information about all the registered [saved object types](./kibana-plugin-core-server.savedobjectstype.md)<!-- -->. |

## Enumerations
Expand Down Expand Up @@ -217,6 +218,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [SavedObjectsUpdateObjectsSpacesResponseObject](./kibana-plugin-core-server.savedobjectsupdateobjectsspacesresponseobject.md) | Details about a specific object's update result. |
| [SavedObjectsUpdateOptions](./kibana-plugin-core-server.savedobjectsupdateoptions.md) | |
| [SavedObjectsUpdateResponse](./kibana-plugin-core-server.savedobjectsupdateresponse.md) | |
| [SavedObjectsValidationMap](./kibana-plugin-core-server.savedobjectsvalidationmap.md) | A map of [validation specs](./kibana-plugin-core-server.savedobjectsvalidationspec.md) to be used for a given type. The map's keys must be valid semver versions.<!-- -->Any time you change the schema of a [SavedObjectsType](./kibana-plugin-core-server.savedobjectstype.md)<!-- -->, you should add a new entry to this map for the Kibana version the change was introduced in. |
| [SearchResponse](./kibana-plugin-core-server.searchresponse.md) | |
| [ServiceStatus](./kibana-plugin-core-server.servicestatus.md) | The current status of a service at a point in time. |
| [SessionCookieValidationResult](./kibana-plugin-core-server.sessioncookievalidationresult.md) | Return type from a function to validate cookie contents. |
Expand Down Expand Up @@ -320,6 +322,8 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [SavedObjectsImportHook](./kibana-plugin-core-server.savedobjectsimporthook.md) | A hook associated with a specific saved object type, that will be invoked during the import process. The hook will have access to the objects of the registered type.<!-- -->Currently, the only supported feature for import hooks is to return warnings to be displayed in the UI when the import succeeds. The only interactions the hook can have with the import process is via the hook's response. Mutating the objects inside the hook's code will have no effect. |
| [SavedObjectsImportWarning](./kibana-plugin-core-server.savedobjectsimportwarning.md) | Composite type of all the possible types of import warnings.<!-- -->See [SavedObjectsImportSimpleWarning](./kibana-plugin-core-server.savedobjectsimportsimplewarning.md) and [SavedObjectsImportActionRequiredWarning](./kibana-plugin-core-server.savedobjectsimportactionrequiredwarning.md) for more details. |
| [SavedObjectsNamespaceType](./kibana-plugin-core-server.savedobjectsnamespacetype.md) | The namespace type dictates how a saved object can be interacted in relation to namespaces. Each type is mutually exclusive: \* single (default): This type of saved object is namespace-isolated, e.g., it exists in only one namespace. \* multiple: This type of saved object is shareable, e.g., it can exist in one or more namespaces. \* multiple-isolated: This type of saved object is namespace-isolated, e.g., it exists in only one namespace, but object IDs must be unique across all namespaces. This is intended to be an intermediate step when objects with a "single" namespace type are being converted to a "multiple" namespace type. In other words, objects with a "multiple-isolated" namespace type will be \*share-capable\*, but will not actually be shareable until the namespace type is changed to "multiple". \* agnostic: This type of saved object is global. |
| [SavedObjectsValidationFunction](./kibana-plugin-core-server.savedobjectsvalidationfunction.md) | The custom validation function if @<!-- -->kbn/config-schema is not a valid solution for your specific plugin requirements.<!-- -->Be careful not to mutate the provided attributes. |
| [SavedObjectsValidationSpec](./kibana-plugin-core-server.savedobjectsvalidationspec.md) | Allowed property validation options: either @<!-- -->kbn/config-schema validations or custom validation functions.<!-- -->See [SavedObjectsValidationFunction](./kibana-plugin-core-server.savedobjectsvalidationfunction.md) for custom validation. |
| [SavedObjectTypeExcludeFromUpgradeFilterHook](./kibana-plugin-core-server.savedobjecttypeexcludefromupgradefilterhook.md) | If defined, allows a type to run a search query and return a query filter that may match any documents which may be excluded from the next migration upgrade process. Useful for cleaning up large numbers of old documents which are no longer needed and may slow the migration process.<!-- -->If this hook fails, the migration will proceed without these documents having been filtered out, so this should not be used as a guarantee that these documents have been deleted.<!-- -->Experimental and subject to change |
| [SavedObjectUnsanitizedDoc](./kibana-plugin-core-server.savedobjectunsanitizeddoc.md) | Describes Saved Object documents from Kibana &lt; 7.0.0 which don't have a <code>references</code> root property defined. This type should only be used in migrations. |
| [ScopeableRequest](./kibana-plugin-core-server.scopeablerequest.md) | A user credentials container. It accommodates the necessary auth credentials to impersonate the current user.<!-- -->See [KibanaRequest](./kibana-plugin-core-server.kibanarequest.md)<!-- -->. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ export class Plugin() {
| --- | --- | --- |
| [addClientWrapper](./kibana-plugin-core-server.savedobjectsservicesetup.addclientwrapper.md) | (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) =&gt; void | Add a [client wrapper factory](./kibana-plugin-core-server.savedobjectsclientwrapperfactory.md) with the given priority. |
| [getKibanaIndex](./kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md) | () =&gt; string | Returns the default index used for saved objects. |
| [registerType](./kibana-plugin-core-server.savedobjectsservicesetup.registertype.md) | &lt;Attributes = any&gt;(type: SavedObjectsType&lt;Attributes&gt;) =&gt; void | Register a [savedObjects type](./kibana-plugin-core-server.savedobjectstype.md) definition.<!-- -->See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) and [migration format](./kibana-plugin-core-server.savedobjectmigrationmap.md) for more details about these. |
| [registerType](./kibana-plugin-core-server.savedobjectsservicesetup.registertype.md) | &lt;Attributes extends SavedObjectAttributes = any&gt;(type: SavedObjectsType&lt;Attributes&gt;) =&gt; void | Register a [savedObjects type](./kibana-plugin-core-server.savedobjectstype.md) definition.<!-- -->See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) and [migration format](./kibana-plugin-core-server.savedobjectmigrationmap.md) for more details about these. |
| [setClientFactoryProvider](./kibana-plugin-core-server.savedobjectsservicesetup.setclientfactoryprovider.md) | (clientFactoryProvider: SavedObjectsClientFactoryProvider) =&gt; void | Set the default [factory provider](./kibana-plugin-core-server.savedobjectsclientfactoryprovider.md) for creating Saved Objects clients. Only one provider can be set, subsequent calls to this method will fail. |

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdef
<b>Signature:</b>

```typescript
registerType: <Attributes = any>(type: SavedObjectsType<Attributes>) => void;
registerType: <Attributes extends SavedObjectAttributes = any>(type: SavedObjectsType<Attributes>) => void;
```

## Example
Expand All @@ -21,6 +21,7 @@ registerType: <Attributes = any>(type: SavedObjectsType<Attributes>) => void;
// src/plugins/my_plugin/server/saved_objects/my_type.ts
import { SavedObjectsType } from 'src/core/server';
import * as migrations from './migrations';
import * as schemas from './schemas';

export const myType: SavedObjectsType = {
name: 'MyType',
Expand All @@ -40,6 +41,10 @@ export const myType: SavedObjectsType = {
'2.0.0': migrations.migrateToV2,
'2.1.0': migrations.migrateToV2_1
},
schemas: {
'2.0.0': schemas.v2,
'2.1.0': schemas.v2_1,
},
};

// src/plugins/my_plugin/server/plugin.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@

## SavedObjectsType interface


<b>Signature:</b>

```typescript
export interface SavedObjectsType<Attributes = any>
```

## Remarks

This is only internal for now, and will only be public when we expose the registerType API

## Properties

| Property | Type | Description |
Expand Down Expand Up @@ -57,4 +54,5 @@ Note: migration function(s) can be optionally specified for any of these version
| [migrations?](./kibana-plugin-core-server.savedobjectstype.migrations.md) | SavedObjectMigrationMap \| (() =&gt; SavedObjectMigrationMap) | <i>(Optional)</i> An optional map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) or a function returning a map of [migrations](./kibana-plugin-core-server.savedobjectmigrationfn.md) to be used to migrate the type. |
| [name](./kibana-plugin-core-server.savedobjectstype.name.md) | string | The name of the type, which is also used as the internal id. |
| [namespaceType](./kibana-plugin-core-server.savedobjectstype.namespacetype.md) | SavedObjectsNamespaceType | The [namespace type](./kibana-plugin-core-server.savedobjectsnamespacetype.md) for the type. |
| [schemas?](./kibana-plugin-core-server.savedobjectstype.schemas.md) | SavedObjectsValidationMap \| (() =&gt; SavedObjectsValidationMap) | <i>(Optional)</i> An optional schema that can be used to validate the attributes of the type.<!-- -->When provided, calls to [create](./kibana-plugin-core-server.savedobjectsclient.create.md) will be validated against this schema.<!-- -->See [SavedObjectsValidationMap](./kibana-plugin-core-server.savedobjectsvalidationmap.md) for more details. |

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsType](./kibana-plugin-core-server.savedobjectstype.md) &gt; [schemas](./kibana-plugin-core-server.savedobjectstype.schemas.md)

## SavedObjectsType.schemas property

An optional schema that can be used to validate the attributes of the type.

When provided, calls to [create](./kibana-plugin-core-server.savedobjectsclient.create.md) will be validated against this schema.

See [SavedObjectsValidationMap](./kibana-plugin-core-server.savedobjectsvalidationmap.md) for more details.

<b>Signature:</b>

```typescript
schemas?: SavedObjectsValidationMap | (() => SavedObjectsValidationMap);
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsValidationError](./kibana-plugin-core-server.savedobjectsvalidationerror.md) &gt; [(constructor)](./kibana-plugin-core-server.savedobjectsvalidationerror._constructor_.md)

## SavedObjectsValidationError.(constructor)

Constructs a new instance of the `SavedObjectsValidationError` class

<b>Signature:</b>

```typescript
constructor(error: Error | string, path?: string[]);
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| error | Error \| string | |
| path | string\[\] | |

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsValidationError](./kibana-plugin-core-server.savedobjectsvalidationerror.md)

## SavedObjectsValidationError class

Error to return when the validation is not successful.

<b>Signature:</b>

```typescript
export declare class SavedObjectsValidationError extends SchemaTypeError
```
<b>Extends:</b> SchemaTypeError

## Constructors

| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(error, path)](./kibana-plugin-core-server.savedobjectsvalidationerror._constructor_.md) | | Constructs a new instance of the <code>SavedObjectsValidationError</code> class |

Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsValidationFunction](./kibana-plugin-core-server.savedobjectsvalidationfunction.md)

## SavedObjectsValidationFunction type

The custom validation function if @<!-- -->kbn/config-schema is not a valid solution for your specific plugin requirements.

Be careful not to mutate the provided attributes.

<b>Signature:</b>

```typescript
export declare type SavedObjectsValidationFunction = (data: {
attributes: unknown;
}) => void;
```

## Example

The validation should look something like:

```typescript
const myAttributesValidation: SavedObjectsValidationFunction = ({ attributes }) => {
if (typeof attributes.bar !== 'string') {
throw new Error(`[bar]: expected value of type [string] but got [${typeof attributes.bar}]`);
}
}
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsValidationMap](./kibana-plugin-core-server.savedobjectsvalidationmap.md)

## SavedObjectsValidationMap interface

A map of [validation specs](./kibana-plugin-core-server.savedobjectsvalidationspec.md) to be used for a given type. The map's keys must be valid semver versions.

Any time you change the schema of a [SavedObjectsType](./kibana-plugin-core-server.savedobjectstype.md)<!-- -->, you should add a new entry to this map for the Kibana version the change was introduced in.

<b>Signature:</b>

```typescript
export interface SavedObjectsValidationMap
```

## Example


```typescript
const validationMap: SavedObjectValidationMap = {
'1.0.0': schema.object({
foo: schema.string(),
}),
'1.1.0': schema.object({
foo: schema.oneOf([schema.string(), schema.boolean()]),
}),
'2.1.0': ({ attributes }) => {
if (typeof attributes.bar !== 'string') {
throw new Error(`[bar]: expected value of type [string] but got [${typeof data.bar}]`);
}
if (typeof attributes.foo !== 'string' && typeof attributes.foo !== 'boolean') {
throw new Error(`[foo]: expected value of type [string,boolean] but got [${typeof attributes.foo}]`);
}
}
}
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [SavedObjectsValidationSpec](./kibana-plugin-core-server.savedobjectsvalidationspec.md)

## SavedObjectsValidationSpec type

Allowed property validation options: either @<!-- -->kbn/config-schema validations or custom validation functions.

See [SavedObjectsValidationFunction](./kibana-plugin-core-server.savedobjectsvalidationfunction.md) for custom validation.

<b>Signature:</b>

```typescript
export declare type SavedObjectsValidationSpec = ObjectType | SavedObjectsValidationFunction;
```
4 changes: 4 additions & 0 deletions src/core/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ export type {
SavedObjectsImportSimpleWarning,
SavedObjectsImportActionRequiredWarning,
SavedObjectsImportWarning,
SavedObjectsValidationError,
SavedObjectsValidationFunction,
SavedObjectsValidationMap,
SavedObjectsValidationSpec,
} from './saved_objects';

export type {
Expand Down
7 changes: 7 additions & 0 deletions src/core/server/saved_objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ export type {
SavedObjectTypeExcludeFromUpgradeFilterHook,
} from './types';

export type {
SavedObjectsValidationMap,
SavedObjectsValidationSpec,
SavedObjectsValidationFunction,
} from './validation';
export { SavedObjectsValidationError } from './validation';

export { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects_config';
export { SavedObjectTypeRegistry } from './saved_objects_type_registry';
export type { ISavedObjectTypeRegistry } from './saved_objects_type_registry';
16 changes: 14 additions & 2 deletions src/core/server/saved_objects/saved_objects_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ import {
SavedObjectConfig,
} from './saved_objects_config';
import { KibanaRequest, InternalHttpServiceSetup } from '../http';
import { SavedObjectsClientContract, SavedObjectsType, SavedObjectStatusMeta } from './types';
import {
SavedObjectsClientContract,
SavedObjectsType,
SavedObjectStatusMeta,
SavedObjectAttributes,
} from './types';
import { ISavedObjectsRepository, SavedObjectsRepository } from './service/lib/repository';
import {
SavedObjectsClientFactoryProvider,
Expand Down Expand Up @@ -112,6 +117,7 @@ export interface SavedObjectsServiceSetup {
* // src/plugins/my_plugin/server/saved_objects/my_type.ts
* import { SavedObjectsType } from 'src/core/server';
* import * as migrations from './migrations';
* import * as schemas from './schemas';
*
* export const myType: SavedObjectsType = {
* name: 'MyType',
Expand All @@ -131,6 +137,10 @@ export interface SavedObjectsServiceSetup {
* '2.0.0': migrations.migrateToV2,
* '2.1.0': migrations.migrateToV2_1
* },
* schemas: {
* '2.0.0': schemas.v2,
* '2.1.0': schemas.v2_1,
* },
* };
*
* // src/plugins/my_plugin/server/plugin.ts
Expand All @@ -144,7 +154,9 @@ export interface SavedObjectsServiceSetup {
* }
* ```
*/
registerType: <Attributes = any>(type: SavedObjectsType<Attributes>) => void;
registerType: <Attributes extends SavedObjectAttributes = any>(
type: SavedObjectsType<Attributes>
) => void;

/**
* Returns the default index used for saved objects.
Expand Down
Loading