[Data Views] Support "namespaces" param in create data view API (#155815)

## Summary

This work was originally done by @jughosta in #150712, I just added a
couple of integration tests and opened another PR for it.

Fixes #140426.

#### Original PR summary:

This PR adds support for `namespaces` param in create data view API as
per docs
https://www.elastic.co/guide/en/kibana/current/data-views-api-create.html#data-views-api-properties

<img width="300" alt="Screenshot 2023-02-09 at 15 04 55"
src="https://user-images.githubusercontent.com/1415710/217835577-fa4286ff-89f4-4de2-97b0-62c04f756858.png">

Previous functionality is still in place:
* setting "default" space if "namespaces" param is not provided
<img width="300" alt="Screenshot 2023-02-09 at 15 06 55"
src="https://user-images.githubusercontent.com/1415710/217835951-d274c8ba-5bd9-4c36-9487-c2dbd5ce42de.png">

* setting the specified in URL space ID if "namespaces" param is not
provided
<img width="300" alt="Screenshot 2023-02-09 at 15 06 34"
src="https://user-images.githubusercontent.com/1415710/217836019-81f36a16-157f-4ce9-9d19-c5685d633acc.png">

### Checklist

- [ ] ~Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)~
- [ ]
~[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials~
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] ~Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard
accessibility](https://webaim.org/techniques/keyboard/))~
- [ ] ~Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))~
- [ ] ~If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)~
- [ ] ~This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))~
- [ ] ~This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)~

### For maintainers

- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

---------

Co-authored-by: Julia Rechkunova <julia.rechkunova@elastic.co>
This commit is contained in:
Davis McPhee 2023-05-08 10:03:08 -03:00 committed by GitHub
parent b0abcfc202
commit ab2f967ba5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 4 deletions

View file

@ -1011,6 +1011,7 @@ export class DataViewsService {
body,
{
id: dataView.id,
initialNamespaces: dataView.namespaces.length > 0 ? dataView.namespaces : undefined,
}
)) as SavedObject<DataViewAttributes>;

View file

@ -296,7 +296,7 @@ export interface SavedObjectsClientCommon {
create: (
type: string,
attributes: DataViewAttributes,
options: SavedObjectsCreateOptions
options: SavedObjectsCreateOptions & { initialNamespaces?: string[] }
) => Promise<SavedObject>;
/**
* Delete a saved object by id

View file

@ -70,6 +70,7 @@ const dataViewSpecSchema = schema.object({
allowNoIndex: schema.maybe(schema.boolean()),
runtimeFieldMap: schema.maybe(schema.recordOf(schema.string(), runtimeFieldSchema)),
name: schema.maybe(schema.string()),
namespaces: schema.maybe(schema.arrayOf(schema.string())),
});
const registerCreateDataViewRouteFactory =
@ -124,7 +125,10 @@ const registerCreateDataViewRouteFactory =
'content-type': 'application/json',
},
body: {
[serviceKey]: dataView.toSpec(),
[serviceKey]: {
...dataView.toSpec(),
namespaces: dataView.namespaces,
},
},
});
})

View file

@ -8,7 +8,7 @@
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../../../ftr_provider_context';
import { configArray } from '../../constants';
import { configArray, dataViewConfig } from '../../constants';
export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
@ -290,5 +290,59 @@ export default function ({ getService }: FtrProviderContext) {
});
});
});
describe('spaces', () => {
const kibanaServer = getService('kibanaServer');
const fooNamespace = 'foo-namespace';
before(async () => {
await kibanaServer.spaces.create({
id: fooNamespace,
name: fooNamespace,
});
});
after(async () => {
await kibanaServer.spaces.delete(fooNamespace);
});
it('can specify optional namespaces array when creating a data view', async () => {
const title = `foo-${Date.now()}-${Math.random()}*`;
const namespaces = ['default', fooNamespace];
const createResponse = await supertest.post(dataViewConfig.path).send({
[dataViewConfig.serviceKey]: {
title,
namespaces,
},
});
expect(createResponse.status).to.be(200);
expect(createResponse.body[dataViewConfig.serviceKey].namespaces).to.eql(namespaces);
const getResponse = await supertest.get(dataViewConfig.basePath);
const dataView = getResponse.body.data_view.find((dv: any) => dv.title === title);
expect(dataView.namespaces).to.eql(namespaces);
});
it('sets namespaces to the current space if namespaces array is not specified', async () => {
const title = `foo-${Date.now()}-${Math.random()}*`;
const createResponse = await supertest
.post(`/s/${fooNamespace}${dataViewConfig.path}`)
.send({
[dataViewConfig.serviceKey]: {
title,
},
});
expect(createResponse.status).to.be(200);
expect(createResponse.body[dataViewConfig.serviceKey].namespaces).to.eql([fooNamespace]);
const getResponse = await supertest.get(`/s/${fooNamespace}${dataViewConfig.basePath}`);
const dataView = getResponse.body.data_view.find((dv: any) => dv.title === title);
expect(dataView.namespaces).to.eql([fooNamespace]);
});
});
});
}

View file

@ -111,7 +111,7 @@ export default function ({ getService }: FtrProviderContext) {
expect(response6.status).to.be(200);
const recreatedIndexPattern = response6.body.index_pattern;
expect(_.omit(recreatedIndexPattern, 'version')).to.eql(
expect(_.omit(recreatedIndexPattern, 'version', 'namespaces')).to.eql(
_.omit(resultIndexPattern, 'version')
);
});