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

Add deprecation warning when unknown SO types are present #111268

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented Sep 6, 2021

Summary

Fix #105272

Checklist

Copy link
Contributor Author

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

@Bamieh @lukeelmers this is still in POC state.

Just to be sure we're all on the same page regarding the approach, could you take a quick look, to make sure I took the correct direction?

Comment on lines +57 to +60
const { body } = await esClient.asInternalUser.search<SavedObjectsRawDocSource>({
index: targetIndices,
body: {
size: 10000,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

What should I do if this throws? Should I just not register the deprecation?

Copy link
Member

@Bamieh Bamieh Sep 6, 2021

Choose a reason for hiding this comment

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

i think the deprecation service needs to support sending an error inside the returned array from the getDeprecation function.

Currently if the whole getDeprecation throws then the service will show failed to fetch deprecation for x feature. We might need to mimic this behavior inside the array entries just like we do for the whole function.

Maybe until we support this we are OK with throwing everything (es connectivity issue usually means ES is unreachable or something).

}),
level: 'critical',
requireRestart: false,
deprecationType: undefined, // not config nor feature...
Copy link
Member

Choose a reason for hiding this comment

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

Do you have in ind a specific deprecation type we can add or are you comfortable with undefined?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As suggested by the UA team in another issue, I think we should have this field mandatory and at least add an other category

Copy link
Member

@Bamieh Bamieh left a comment

Choose a reason for hiding this comment

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

Approach LGTM aligned with what I had in mind.

Comment on lines +57 to +60
const { body } = await esClient.asInternalUser.search<SavedObjectsRawDocSource>({
index: targetIndices,
body: {
size: 10000,
Copy link
Member

@Bamieh Bamieh Sep 6, 2021

Choose a reason for hiding this comment

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

i think the deprecation service needs to support sending an error inside the returned array from the getDeprecation function.

Currently if the whole getDeprecation throws then the service will show failed to fetch deprecation for x feature. We might need to mimic this behavior inside the array entries just like we do for the whole function.

Maybe until we support this we are OK with throwing everything (es connectivity issue usually means ES is unreachable or something).

@joshdover
Copy link
Contributor

Did we already reach a decision on the long-term support for unknown types in 8.0 #107678?

@pgayvallet
Copy link
Contributor Author

@joshdover

Did we already reach a decision on the long-term support for unknown types in 8.0 #107678?

@rudolf @kobelb @lukeelmers please correct me if I'm wrong here, but from our last conversations, the consensus was that due to both the timeframe and the complexity of introducing a quarantine mechanism, the target solution for 8.0 was to have Kibana fail to start when unknown types are encountered, if this option was considered acceptable by all parties.

@pgayvallet pgayvallet marked this pull request as ready for review September 7, 2021 10:51
@pgayvallet pgayvallet requested a review from a team as a code owner September 7, 2021 10:51
@pgayvallet pgayvallet added Feature:Saved Objects Feature:Upgrade Assistant release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.16.0 v8.0.0 labels Sep 7, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

Copy link
Contributor Author

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

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

self review

Comment on lines 116 to 123
manualSteps: [
i18n.translate('core.savedObjects.deprecations.unknownTypes.manualSteps.1', {
defaultMessage: 'If plugins are disabled, re-enable the, then restart Kibana.',
}),
i18n.translate('core.savedObjects.deprecations.unknownTypes.manualSteps.2', {
defaultMessage:
'If no plugins are disabled, or if enabling them does not fix the issue, delete the documents.',
}),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really sure what to put in the manualSteps, as we're mostly expecting the user to use the automated resolve instead.

We could potentially list all the faulty objects as we're doing in the checkForUnknownDocs migration task's warning, but that really don't work well in the UA UI.

Copy link
Member

Choose a reason for hiding this comment

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

The steps make sense to me. Maybe we can specify how to find these document ids by checking the server logs.

Comment on lines +25 to +29
router.post(
{
path: '/deprecations/_delete_unknown_types',
validate: false,
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A small security concern here: as we can't leverage the SOR to perform the cleanup, we're using the internal ES client instead (which also make sense, because we want to be able to delete all the unknown docs anyway, and because the SO security does not work with unknown types...).

However, this means that any authenticated user can potentially hit this endpoint, and cause the removal of the unknown docs. We could restrict the route with a access: tag, however this endpoint needs to be reachable by anyone having access to the UA management section to resolve the deprecation.

I don't think this is that big of a deal, but still worth a comment: are we fine with this?

Copy link
Contributor

Choose a reason for hiding this comment

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

The likelihood is low that this gets abused and in most cases the impact will be low, it will probably just delete unused data.

But as a pattern this feels wrong, it feels like something that will crop up for other teams too that have destructive correctiveActions e.g. https://github.com/elastic/kibana/blob/master/x-pack/plugins/reporting/server/routes/deprecations.ts#L100

In reporting's case, security is enforced by Elasticsearch. So there's some precedent that just because you're able to use the upgrade assistant doesn't mean you'll automatically be able to perform all corrective actions.

I wonder if it wouldn't be fine to require the kibana_admin to perform these upgrade assistant fixes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder if it wouldn't be fine to require the kibana_admin to perform these upgrade assistant fixes?

we could use the scoped client instead of the internal one, that would do it, but then other users would still see the deprecation, and clicking the button would throw a server error... I don't really like it either to be honest.

Comment on lines +92 to +98
const afterDelete = await fetchIndexContent();
// we're deleting with `wait_for_completion: false` and we don't surface
// the task ID in the API, so we're forced to use pooling for the FTR tests
if (afterDelete.map((obj) => obj.type).includes('unknown-type') && i < 10) {
await delay(1000);
continue;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As explained in the comment, we're deleting with wait_for_completion: false, and the API does not surface the taskId. I could have added it to the deleteUnknownTypeObjects return value and to the HTTP endpoint's response, but that didn't felt right, as the only need was for FTR tests, so I'm using a dumb loop instead.

src/core/server/saved_objects/saved_objects_service.ts Outdated Show resolved Hide resolved
Comment on lines 104 to 111
title: i18n.translate('core.savedObjects.deprecations.unknownTypes.title', {
defaultMessage: 'Saved objects with unknown types are present in Kibana system indices',
}),
message: i18n.translate('core.savedObjects.deprecations.unknownTypes.message', {
defaultMessage:
'Upgrades will fail for 8.0+ because documents were found for unknown saved object types.' +
`To ensure that upgrades will succeed in the future, either re-enable plugins or delete these documents from the Kibana indices`,
}),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we surface the number of unknown docs, of their types, in the deprecation's message?

Copy link
Member

Choose a reason for hiding this comment

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

In the deprecation guide we recommend not writing upgrade will fail in version x.x

Copy link
Member

Choose a reason for hiding this comment

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

If we already have the number of unknown docs i think it makes sense to surface them here.

@joshdover
Copy link
Contributor

please correct me if I'm wrong here, but from our last conversations, the consensus was that due to both the timeframe and the complexity of introducing a quarantine mechanism, the target solution for 8.0 was to have Kibana fail to start when unknown types are encountered, if this option was considered acceptable by all parties.

Thank you for the clarification!

Comment on lines 104 to 111
title: i18n.translate('core.savedObjects.deprecations.unknownTypes.title', {
defaultMessage: 'Saved objects with unknown types are present in Kibana system indices',
}),
message: i18n.translate('core.savedObjects.deprecations.unknownTypes.message', {
defaultMessage:
'Upgrades will fail for 8.0+ because documents were found for unknown saved object types.' +
`To ensure that upgrades will succeed in the future, either re-enable plugins or delete these documents from the Kibana indices`,
}),
Copy link
Member

Choose a reason for hiding this comment

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

In the deprecation guide we recommend not writing upgrade will fail in version x.x

Comment on lines 104 to 111
title: i18n.translate('core.savedObjects.deprecations.unknownTypes.title', {
defaultMessage: 'Saved objects with unknown types are present in Kibana system indices',
}),
message: i18n.translate('core.savedObjects.deprecations.unknownTypes.message', {
defaultMessage:
'Upgrades will fail for 8.0+ because documents were found for unknown saved object types.' +
`To ensure that upgrades will succeed in the future, either re-enable plugins or delete these documents from the Kibana indices`,
}),
Copy link
Member

Choose a reason for hiding this comment

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

If we already have the number of unknown docs i think it makes sense to surface them here.

Comment on lines 116 to 123
manualSteps: [
i18n.translate('core.savedObjects.deprecations.unknownTypes.manualSteps.1', {
defaultMessage: 'If plugins are disabled, re-enable the, then restart Kibana.',
}),
i18n.translate('core.savedObjects.deprecations.unknownTypes.manualSteps.2', {
defaultMessage:
'If no plugins are disabled, or if enabling them does not fix the issue, delete the documents.',
}),
Copy link
Member

Choose a reason for hiding this comment

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

The steps make sense to me. Maybe we can specify how to find these document ids by checking the server logs.

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Member

@Bamieh Bamieh left a comment

Choose a reason for hiding this comment

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

lgtm

@pgayvallet pgayvallet added the auto-backport Deprecated - use backport:version if exact versions are needed label Sep 14, 2021
@pgayvallet pgayvallet merged commit 138371e into elastic:master Sep 14, 2021
@kibanamachine
Copy link
Contributor

💔 Backport failed

Status Branch Result
7.x Commit could not be cherrypicked due to conflicts

To backport manually run:
node scripts/backport --pr 111268

pgayvallet added a commit to pgayvallet/kibana that referenced this pull request Sep 14, 2021
…1268)

* Add deprecation warning when unknown types are present

* fix and add service tests

* remove export

* plug deprecation route

* add integration test for new route

* add unit test for getIndexForType

* add unit tests

* improve deprecation messages

* add FTR test

* fix things due to merge

* change the name of the deprecation provider

* improve message

* improve message again
# Conflicts:
#	src/core/server/saved_objects/saved_objects_service.ts
pgayvallet added a commit that referenced this pull request Sep 15, 2021
) (#112112)

* Add deprecation warning when unknown SO types are present (#111268)

* Add deprecation warning when unknown types are present

* fix and add service tests

* remove export

* plug deprecation route

* add integration test for new route

* add unit test for getIndexForType

* add unit tests

* improve deprecation messages

* add FTR test

* fix things due to merge

* change the name of the deprecation provider

* improve message

* improve message again
# Conflicts:
#	src/core/server/saved_objects/saved_objects_service.ts

* fix types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:Saved Objects Feature:Upgrade Assistant release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.16.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Upgrade Assistant deprecation warning for unknown Saved Object types
6 participants