Skip to content

Commit

Permalink
Merge branch 'master' into feature-102623-improve-settings-port
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Jun 22, 2021
2 parents 998ffa7 + b386ce1 commit f390be5
Show file tree
Hide file tree
Showing 130 changed files with 3,201 additions and 2,692 deletions.
5 changes: 5 additions & 0 deletions docs/api/saved-objects/bulk_create.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ experimental[] Create multiple {kib} saved objects.
(Optional, string array) Identifiers for the <<xpack-spaces,spaces>> in which this object is created. If this is provided, the
object is created only in the explicitly defined spaces. If this is not provided, the object is created in the current space
(default behavior).
* For shareable object types (registered with `namespaceType: 'multiple'`): this option can be used to specify one or more spaces, including
the "All spaces" identifier (`'*'`).
* For isolated object types (registered with `namespaceType: 'single'` or `namespaceType: 'multiple-isolated'`): this option can only be
used to specify a single space, and the "All spaces" identifier (`'*'`) is not allowed.
* For global object types (registered with `namespaceType: 'agnostic'`): this option cannot be used.

`version`::
(Optional, number) Specifies the version.
Expand Down
5 changes: 5 additions & 0 deletions docs/api/saved-objects/create.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ any data that you send to the API is properly formed.
(Optional, string array) Identifiers for the <<xpack-spaces,spaces>> in which this object is created. If this is provided, the
object is created only in the explicitly defined spaces. If this is not provided, the object is created in the current space
(default behavior).
* For shareable object types (registered with `namespaceType: 'multiple'`): this option can be used to specify one or more spaces, including
the "All spaces" identifier (`'*'`).
* For isolated object types (registered with `namespaceType: 'single'` or `namespaceType: 'multiple-isolated'`): this option can only be
used to specify a single space, and the "All spaces" identifier (`'*'`) is not allowed.
* For global object types (registered with `namespaceType: 'agnostic'): this option cannot be used.

[[saved-objects-api-create-request-codes]]
==== Response code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md)<!-- -->.

Note: this can only be used for multi-namespace object types.
\* For shareable object types (registered with `namespaceType: 'multiple'`<!-- -->): this option can be used to specify one or more spaces, including the "All spaces" identifier (`'*'`<!-- -->). \* For isolated object types (registered with `namespaceType: 'single'` or `namespaceType: 'multiple-isolated'`<!-- -->): this option can only be used to specify a single space, and the "All spaces" identifier (`'*'`<!-- -->) is not allowed. \* For global object types (registered with `namespaceType: 'agnostic'`<!-- -->): this option cannot be used.

<b>Signature:</b>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface SavedObjectsBulkCreateObject<T = unknown>
| [attributes](./kibana-plugin-core-server.savedobjectsbulkcreateobject.attributes.md) | <code>T</code> | |
| [coreMigrationVersion](./kibana-plugin-core-server.savedobjectsbulkcreateobject.coremigrationversion.md) | <code>string</code> | A semver value that is used when upgrading objects between Kibana versions. If undefined, this will be automatically set to the current Kibana version when the object is created. If this is set to a non-semver value, or it is set to a semver value greater than the current Kibana version, it will result in an error. |
| [id](./kibana-plugin-core-server.savedobjectsbulkcreateobject.id.md) | <code>string</code> | |
| [initialNamespaces](./kibana-plugin-core-server.savedobjectsbulkcreateobject.initialnamespaces.md) | <code>string[]</code> | Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md)<!-- -->.<!-- -->Note: this can only be used for multi-namespace object types. |
| [initialNamespaces](./kibana-plugin-core-server.savedobjectsbulkcreateobject.initialnamespaces.md) | <code>string[]</code> | Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md)<!-- -->.<!-- -->\* For shareable object types (registered with <code>namespaceType: 'multiple'</code>): this option can be used to specify one or more spaces, including the "All spaces" identifier (<code>'*'</code>). \* For isolated object types (registered with <code>namespaceType: 'single'</code> or <code>namespaceType: 'multiple-isolated'</code>): this option can only be used to specify a single space, and the "All spaces" identifier (<code>'*'</code>) is not allowed. \* For global object types (registered with <code>namespaceType: 'agnostic'</code>): this option cannot be used. |
| [migrationVersion](./kibana-plugin-core-server.savedobjectsbulkcreateobject.migrationversion.md) | <code>SavedObjectsMigrationVersion</code> | Information about the migrations that have been applied to this SavedObject. When Kibana starts up, KibanaMigrator detects outdated documents and migrates them based on this value. For each migration that has been applied, the plugin's name is used as a key and the latest migration version as the value. |
| [originId](./kibana-plugin-core-server.savedobjectsbulkcreateobject.originid.md) | <code>string</code> | Optional ID of the original saved object, if this object's <code>id</code> was regenerated |
| [references](./kibana-plugin-core-server.savedobjectsbulkcreateobject.references.md) | <code>SavedObjectReference[]</code> | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md)<!-- -->.

Note: this can only be used for multi-namespace object types.
\* For shareable object types (registered with `namespaceType: 'multiple'`<!-- -->): this option can be used to specify one or more spaces, including the "All spaces" identifier (`'*'`<!-- -->). \* For isolated object types (registered with `namespaceType: 'single'` or `namespaceType: 'multiple-isolated'`<!-- -->): this option can only be used to specify a single space, and the "All spaces" identifier (`'*'`<!-- -->) is not allowed. \* For global object types (registered with `namespaceType: 'agnostic'`<!-- -->): this option cannot be used.

<b>Signature:</b>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions
| --- | --- | --- |
| [coreMigrationVersion](./kibana-plugin-core-server.savedobjectscreateoptions.coremigrationversion.md) | <code>string</code> | A semver value that is used when upgrading objects between Kibana versions. If undefined, this will be automatically set to the current Kibana version when the object is created. If this is set to a non-semver value, or it is set to a semver value greater than the current Kibana version, it will result in an error. |
| [id](./kibana-plugin-core-server.savedobjectscreateoptions.id.md) | <code>string</code> | (not recommended) Specify an id for the document |
| [initialNamespaces](./kibana-plugin-core-server.savedobjectscreateoptions.initialnamespaces.md) | <code>string[]</code> | Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md)<!-- -->.<!-- -->Note: this can only be used for multi-namespace object types. |
| [initialNamespaces](./kibana-plugin-core-server.savedobjectscreateoptions.initialnamespaces.md) | <code>string[]</code> | Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md)<!-- -->.<!-- -->\* For shareable object types (registered with <code>namespaceType: 'multiple'</code>): this option can be used to specify one or more spaces, including the "All spaces" identifier (<code>'*'</code>). \* For isolated object types (registered with <code>namespaceType: 'single'</code> or <code>namespaceType: 'multiple-isolated'</code>): this option can only be used to specify a single space, and the "All spaces" identifier (<code>'*'</code>) is not allowed. \* For global object types (registered with <code>namespaceType: 'agnostic'</code>): this option cannot be used. |
| [migrationVersion](./kibana-plugin-core-server.savedobjectscreateoptions.migrationversion.md) | <code>SavedObjectsMigrationVersion</code> | Information about the migrations that have been applied to this SavedObject. When Kibana starts up, KibanaMigrator detects outdated documents and migrates them based on this value. For each migration that has been applied, the plugin's name is used as a key and the latest migration version as the value. |
| [originId](./kibana-plugin-core-server.savedobjectscreateoptions.originid.md) | <code>string</code> | Optional ID of the original saved object, if this object's <code>id</code> was regenerated |
| [overwrite](./kibana-plugin-core-server.savedobjectscreateoptions.overwrite.md) | <code>boolean</code> | Overwrite existing documents (defaults to false) |
Expand Down
145 changes: 106 additions & 39 deletions src/core/server/saved_objects/service/lib/repository.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,22 @@ describe('SavedObjectsRepository', () => {
const ns2 = 'bar-namespace';
const ns3 = 'baz-namespace';
const objects = [
{ ...obj1, type: MULTI_NAMESPACE_TYPE, initialNamespaces: [ns2] },
{ ...obj2, type: MULTI_NAMESPACE_TYPE, initialNamespaces: [ns3] },
{ ...obj1, type: 'dashboard', initialNamespaces: [ns2] },
{ ...obj1, type: MULTI_NAMESPACE_ISOLATED_TYPE, initialNamespaces: [ns2] },
{ ...obj1, type: MULTI_NAMESPACE_TYPE, initialNamespaces: [ns2, ns3] },
];
await bulkCreateSuccess(objects, { namespace, overwrite: true });
const body = [
expect.any(Object),
{ index: expect.objectContaining({ _id: `${ns2}:dashboard:${obj1.id}` }) },
expect.objectContaining({ namespace: ns2 }),
{
index: expect.objectContaining({
_id: `${MULTI_NAMESPACE_ISOLATED_TYPE}:${obj1.id}`,
}),
},
expect.objectContaining({ namespaces: [ns2] }),
expect.any(Object),
expect.objectContaining({ namespaces: [ns3] }),
{ index: expect.objectContaining({ _id: `${MULTI_NAMESPACE_TYPE}:${obj1.id}` }) },
expect.objectContaining({ namespaces: [ns2, ns3] }),
];
expect(client.bulk).toHaveBeenCalledWith(
expect.objectContaining({ body }),
Expand Down Expand Up @@ -649,24 +656,19 @@ describe('SavedObjectsRepository', () => {
).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"'));
});

it(`returns error when initialNamespaces is used with a non-shareable object`, async () => {
const test = async (objType) => {
const obj = { ...obj3, type: objType, initialNamespaces: [] };
await bulkCreateError(
it(`returns error when initialNamespaces is used with a space-agnostic object`, async () => {
const obj = { ...obj3, type: NAMESPACE_AGNOSTIC_TYPE, initialNamespaces: [] };
await bulkCreateError(
obj,
undefined,
expectErrorResult(
obj,
undefined,
expectErrorResult(
obj,
createBadRequestError('"initialNamespaces" can only be used on multi-namespace types')
)
);
};
await test('dashboard');
await test(NAMESPACE_AGNOSTIC_TYPE);
await test(MULTI_NAMESPACE_ISOLATED_TYPE);
createBadRequestError('"initialNamespaces" cannot be used on space-agnostic types')
)
);
});

it(`throws when options.initialNamespaces is used with a shareable type and is empty`, async () => {
it(`returns error when initialNamespaces is empty`, async () => {
const obj = { ...obj3, type: MULTI_NAMESPACE_TYPE, initialNamespaces: [] };
await bulkCreateError(
obj,
Expand All @@ -678,6 +680,26 @@ describe('SavedObjectsRepository', () => {
);
});

it(`returns error when initialNamespaces is used with a space-isolated object and does not specify a single space`, async () => {
const doTest = async (objType, initialNamespaces) => {
const obj = { ...obj3, type: objType, initialNamespaces };
await bulkCreateError(
obj,
undefined,
expectErrorResult(
obj,
createBadRequestError(
'"initialNamespaces" can only specify a single space when used with space-isolated types'
)
)
);
};
await doTest('dashboard', ['spacex', 'spacey']);
await doTest('dashboard', ['*']);
await doTest(MULTI_NAMESPACE_ISOLATED_TYPE, ['spacex', 'spacey']);
await doTest(MULTI_NAMESPACE_ISOLATED_TYPE, ['*']);
});

it(`returns error when type is invalid`, async () => {
const obj = { ...obj3, type: 'unknownType' };
await bulkCreateError(obj, undefined, expectErrorInvalidType(obj));
Expand Down Expand Up @@ -1865,12 +1887,46 @@ describe('SavedObjectsRepository', () => {
});

it(`adds initialNamespaces instead of namespace`, async () => {
const options = { id, namespace, initialNamespaces: ['bar-namespace', 'baz-namespace'] };
await createSuccess(MULTI_NAMESPACE_TYPE, attributes, options);
expect(client.create).toHaveBeenCalledWith(
const ns2 = 'bar-namespace';
const ns3 = 'baz-namespace';
await savedObjectsRepository.create('dashboard', attributes, {
id,
namespace,
initialNamespaces: [ns2],
});
await savedObjectsRepository.create(MULTI_NAMESPACE_ISOLATED_TYPE, attributes, {
id,
namespace,
initialNamespaces: [ns2],
});
await savedObjectsRepository.create(MULTI_NAMESPACE_TYPE, attributes, {
id,
namespace,
initialNamespaces: [ns2, ns3],
});

expect(client.create).toHaveBeenCalledTimes(3);
expect(client.create).toHaveBeenNthCalledWith(
1,
expect.objectContaining({
id: `${ns2}:dashboard:${id}`,
body: expect.objectContaining({ namespace: ns2 }),
}),
expect.anything()
);
expect(client.create).toHaveBeenNthCalledWith(
2,
expect.objectContaining({
id: `${MULTI_NAMESPACE_ISOLATED_TYPE}:${id}`,
body: expect.objectContaining({ namespaces: [ns2] }),
}),
expect.anything()
);
expect(client.create).toHaveBeenNthCalledWith(
3,
expect.objectContaining({
id: `${MULTI_NAMESPACE_TYPE}:${id}`,
body: expect.objectContaining({ namespaces: options.initialNamespaces }),
body: expect.objectContaining({ namespaces: [ns2, ns3] }),
}),
expect.anything()
);
Expand All @@ -1892,29 +1948,40 @@ describe('SavedObjectsRepository', () => {
});

describe('errors', () => {
it(`throws when options.initialNamespaces is used with a non-shareable object`, async () => {
const test = async (objType) => {
await expect(
savedObjectsRepository.create(objType, attributes, { initialNamespaces: [namespace] })
).rejects.toThrowError(
createBadRequestError(
'"options.initialNamespaces" can only be used on multi-namespace types'
)
);
};
await test('dashboard');
await test(MULTI_NAMESPACE_ISOLATED_TYPE);
await test(NAMESPACE_AGNOSTIC_TYPE);
it(`throws when options.initialNamespaces is used with a space-agnostic object`, async () => {
await expect(
savedObjectsRepository.create(NAMESPACE_AGNOSTIC_TYPE, attributes, {
initialNamespaces: [namespace],
})
).rejects.toThrowError(
createBadRequestError('"initialNamespaces" cannot be used on space-agnostic types')
);
});

it(`throws when options.initialNamespaces is used with a shareable type and is empty`, async () => {
it(`throws when options.initialNamespaces is empty`, async () => {
await expect(
savedObjectsRepository.create(MULTI_NAMESPACE_TYPE, attributes, { initialNamespaces: [] })
).rejects.toThrowError(
createBadRequestError('"options.initialNamespaces" must be a non-empty array of strings')
createBadRequestError('"initialNamespaces" must be a non-empty array of strings')
);
});

it(`throws when options.initialNamespaces is used with a space-isolated object and does not specify a single space`, async () => {
const doTest = async (objType, initialNamespaces) => {
await expect(
savedObjectsRepository.create(objType, attributes, { initialNamespaces })
).rejects.toThrowError(
createBadRequestError(
'"initialNamespaces" can only specify a single space when used with space-isolated types'
)
);
};
await doTest('dashboard', ['spacex', 'spacey']);
await doTest('dashboard', ['*']);
await doTest(MULTI_NAMESPACE_ISOLATED_TYPE, ['spacex', 'spacey']);
await doTest(MULTI_NAMESPACE_ISOLATED_TYPE, ['*']);
});

it(`throws when options.namespace is '*'`, async () => {
await expect(
savedObjectsRepository.create(type, attributes, { namespace: ALL_NAMESPACES_STRING })
Expand Down
Loading

0 comments on commit f390be5

Please sign in to comment.