[data views] Fix overwrite param for create (#160953)

## Summary

Under some circumstances passing `override` to `POST
/api/data_views/data_view` would fail. Its now fixed.

To test - Try using the override param from the Kibana dev console. I
found it reproduced the problem before the fix and shows its resolved
after the fix. The problem did not appear in the integration tests.

I suspect the problem had to do with how quickly the delete was
performed - if it completed before the create command then everything
was fine. If it didn't then the error would appear. Passing the
overwrite param to the saved object client eliminates the possibility of
the delete failing to complete.

Closes https://github.com/elastic/kibana/issues/161016
This commit is contained in:
Matthew Kime 2023-07-04 15:35:40 -05:00 committed by GitHub
parent 6731eb3008
commit 803d139adc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 14 additions and 6 deletions

View file

@ -54,6 +54,7 @@ const dataViewSavedObjectSchema = savedObjectSchema(dataViewAttributesSchema);
const dataViewCreateOptionsSchema = schema.object({
id: createOptionsSchemas.id,
initialNamespaces: createOptionsSchemas.initialNamespaces,
overwrite: schema.maybe(createOptionsSchemas.overwrite),
});
const dataViewSearchOptionsSchema = schema.object({

View file

@ -18,6 +18,7 @@ import { DataViewContentType } from './constants';
interface DataViewCreateOptions {
id?: SavedObjectCreateOptions['id'];
initialNamespaces?: SavedObjectCreateOptions['initialNamespaces'];
overwrite?: SavedObjectCreateOptions['overwrite'];
}
interface DataViewUpdateOptions {

View file

@ -167,7 +167,7 @@ export interface DataViewsServicePublicMethods {
*/
createSavedObject: (
indexPattern: DataView,
override?: boolean,
overwrite?: boolean,
displayErrors?: boolean
) => Promise<DataView>;
/**
@ -964,12 +964,16 @@ export class DataViewsService {
async createAndSave(
spec: DataViewSpec,
override = false,
overwrite = false,
skipFetchFields = false,
displayErrors = true
) {
const indexPattern = await this.createFromSpec(spec, skipFetchFields, displayErrors);
const createdIndexPattern = await this.createSavedObject(indexPattern, override, displayErrors);
const createdIndexPattern = await this.createSavedObject(
indexPattern,
overwrite,
displayErrors
);
await this.setDefault(createdIndexPattern.id!);
return createdIndexPattern!;
}
@ -981,14 +985,14 @@ export class DataViewsService {
* @param displayErrors - If set false, API consumer is responsible for displaying and handling errors.
*/
async createSavedObject(dataView: DataView, override = false, displayErrors = true) {
async createSavedObject(dataView: DataView, overwrite = false, displayErrors = true) {
if (!(await this.getCanSave())) {
throw new DataViewInsufficientAccessError();
}
const dupe = await findByName(this.savedObjectsClient, dataView.getName());
if (dupe) {
if (override) {
if (overwrite) {
await this.delete(dupe.id);
} else {
throw new DuplicateDataViewError(`Duplicate data view: ${dataView.getName()}`);
@ -1000,6 +1004,7 @@ export class DataViewsService {
const response: SavedObject<DataViewAttributes> = (await this.savedObjectsClient.create(body, {
id: dataView.id,
initialNamespaces: dataView.namespaces.length > 0 ? dataView.namespaces : undefined,
overwrite,
})) as SavedObject<DataViewAttributes>;
const createdIndexPattern = await this.initFromSavedObject(response, displayErrors);

View file

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

View file

@ -437,6 +437,7 @@ export default function ({ getService }: FtrProviderContext) {
const title = indexPattern.title;
await supertest.delete(`${config.path}/${indexPattern.id}`);
const response1 = await supertest.post(config.path).send({
override: true,
[config.serviceKey]: {
title,
fields: {