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

Resolve filter index references when importing saved objects #42974

Merged
merged 5 commits into from
Aug 30, 2019

Conversation

rudolf
Copy link
Contributor

@rudolf rudolf commented Aug 8, 2019

Summary

Fixes #42343 Resolve filter index references when importing saved objects.

Checklist

Use strikethroughs to remove checklist items you don't feel are applicable to this PR.

For maintainers

Release notes:
When importing Saved Objects from a JSON file using the Kibana Management UI, Kibana will detect references to missing indexes in these objects and prompt the user to re-map these to any existing index. However, when importing Saved Objects from Kibana < 7.0.0 that contain filters, Kibana did not detect missing index references in these filters. Kibana will now correctly detect missing index references and prompt users to re-map these to existing indexes.

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@rudolf rudolf marked this pull request as ready for review August 23, 2019 19:40
@rudolf rudolf requested a review from a team as a code owner August 23, 2019 19:40
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@rudolf rudolf added the Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc label Aug 27, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform

},
_serialize: () => { return { references: [{ id: 'MyIndexPattern*' }, { id: 'filterIndex' }] };},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a bit confusing that _serialize returns an object instead of a string. is it okay?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mocks the saved_object._serialize() function which returns an object that can be JSON.stringified. https://github.com/rudolf/kibana/blob/fix-42343-resolve-filter-imports/src/legacy/ui/public/saved_objects/saved_object.js#L309

return { doc, obj: obj._serialize() };
}).forEach(({ doc, obj }) =>
obj.references.forEach(ref => {
byId[ref.id] = byId[ref.id] != null ? byId[ref.id].concat({ doc, obj }) : [{ doc, obj }];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not add conflictedIndexPatternsById as a part of resolveSavedObjects api? this logic is not related to the component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it makes a lot of sense to move it, but when I do a lot of tests break :( because there's so much business logic in _serialize() it's not so easy to stub out.

}

resolution = resolutions.find(({ oldId }) => oldId === filter.meta.index);
return resolution ? ({ ...filter, ...{ meta: { ...filter.meta, index: resolution.newId } } }) : filter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also not super clear why management changes saved object internal content and mutate it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm not sure if this was implemented before we had migrations, but we're essentially performing migrations in the frontend which is rather brittle :( We use this code path when importing JSON files, but newer exports are made in NDJSON and if you importing NDJSON we'll do all the migrations server-side with a much cleaner architecture. Unfortunately JSON support will probably have to stay till 8.0.0.

@@ -326,7 +326,7 @@ export function SavedObjectProvider(Promise, Private, confirmModalPromise, index
references.push({
name: refName,
type: 'index-pattern',
id: indexId,
id: indexId || searchSourceFields.index,
Copy link
Contributor

@mshustov mshustov Aug 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it a necessary change? anyway we read id later https://github.com/elastic/kibana/pull/42974/files#diff-e8fcd698a977c19072c4c82d0d4eb40bR149
probably we should throw if id is not present?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the source code comments when hydrateIndexPattern() is called index can be either a string or an IndexPattern, but after the call it's converted to an IndexPattern. So I think this can happen if a Saved Object is created and then _serialize() is called before hydrateIndexPattern is called. This might happen here https://github.com/elastic/kibana/pull/42974/files#diff-28408d72ee9bcd7cf7c986c55a9212d7R279

But I'll take a deeper look and also refactor this a bit (if it's necessary).

const indexId = typeof(searchSourceFields.index) == 'string' : searchSourceFields.index : searchSourceFields.index.id;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comment above wasn't 100% accurate...

group by ID https://github.com/elastic/kibana/pull/42974/files#diff-28408d72ee9bcd7cf7c986c55a9212d7L276 used to use obj.searchSource.getOwnField('index') (a string) which would only group by searchSource indexes and not other referenced indexes. To get access to the other referenced indexes I need to call _serialize(). When serialize() is called searchSource.getFields('index') is a string because these index patterns don't exist so they never get resolved to an IndexPattern object in hydrateIndexPattern().

I think this behaviour change makes sense, when a saved object is serialized (which normally happens before saving) we should persist the id of referenced indexes even if these don't exist in Elasticsearch.

Copy link
Contributor

@mikecote mikecote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took a quick look at the code (excluding tests) and it looks good to me.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@rudolf rudolf merged commit 901a54e into elastic:master Aug 30, 2019
@rudolf rudolf deleted the fix-42343-resolve-filter-imports branch August 30, 2019 10:11
@rudolf rudolf added the v7.3.2 label Aug 30, 2019
rudolf added a commit to rudolf/kibana that referenced this pull request Aug 30, 2019
…#42974)

* Resolve filter index references when importing saved objects

* Tests for filter index resolution

* saved_object.js test for serialization of non-existing searchSource indexes
rudolf added a commit to rudolf/kibana that referenced this pull request Aug 30, 2019
…#42974)

* Resolve filter index references when importing saved objects

* Tests for filter index resolution

* saved_object.js test for serialization of non-existing searchSource indexes
rudolf added a commit to rudolf/kibana that referenced this pull request Aug 30, 2019
…#42974)

* Resolve filter index references when importing saved objects

* Tests for filter index resolution

* saved_object.js test for serialization of non-existing searchSource indexes
rudolf added a commit that referenced this pull request Aug 30, 2019
…#44480)

* Resolve filter index references when importing saved objects

* Tests for filter index resolution

* saved_object.js test for serialization of non-existing searchSource indexes
rudolf added a commit that referenced this pull request Aug 30, 2019
…#44481)

* Resolve filter index references when importing saved objects

* Tests for filter index resolution

* saved_object.js test for serialization of non-existing searchSource indexes
rudolf added a commit that referenced this pull request Aug 30, 2019
…#44482)

* Resolve filter index references when importing saved objects

* Tests for filter index resolution

* saved_object.js test for serialization of non-existing searchSource indexes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release_note:fix Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.3.2 v7.4.0 v7.5.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Importing Saved Objects using JSON doesn't resolve filter index references
4 participants