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

Remove pinned builtin plugin versions from storage #18051

Merged
merged 9 commits into from
Nov 23, 2022

Conversation

tomhjp
Copy link
Contributor

@tomhjp tomhjp commented Nov 18, 2022

Addresses bug described in the 1.12 upgrade guide: https://developer.hashicorp.com/vault/docs/upgrading/upgrade-to-1.12.x#pinning-to-builtin-plugin-versions-may-cause-failure-on-upgrade.

In a nutshell, when we try to start a plugin after upgrading, if it has a builtin version stored in the mount table and that version subsequently disappeared from catalog due to the upgrade, we won't be able to mount it. To fix this, the main idea is to stop storing version information for builtin plugins, and rely on the pre-existing behaviour that not specifying a version selects the builtin (unless it's been shadowed by an unversioned external plugin).

2 main changes, that need to be done for each of the 3 plugin types:

  • Stop storing the builtin version for newly mounted plugins
  • Clean up storage in existing mounts where we stored the builtin version

Stopping storage for new mounts is easy enough. Cleaning up existing auth and secrets mounts also seems relatively straightforward thanks to some existing logic for upgrading their storage.

Unfortunately, database plugins don't seem to have any such existing capability, instead this relies on fixing storage whenever it's next written to for each db plugin. That means databases also need an extra shim to stop mounting from failing, because we may mount a plugin before the config has been fixed in storage. We also delete builtin plugin versions from a config read response, so the out of date storage is invisible to users unless they poke around in raw endpoints.

The approach also means users who have a builtin version pinned, and an unversioned plugin of the same name registered, will start running the unversioned plugin on upgrading. That deserves a callout in the changelog, but I don't expect it to be problematic for many people, as most people using versions for builtins will probably also use versions for externals. Plus it's still a very new feature, and the delta between the builtin and external versions is likely small.

I've also updated the plugin catalog to not return a builtin if it has been shadowed by an unversioned external plugin of the same name.

@tomhjp
Copy link
Contributor Author

tomhjp commented Nov 18, 2022

One other thought for database plugins, I could iterate through all of the connection configs during the call to Factory and upgrade the storage at that point, guarded by a check similar to the check we do for the initQueue function:

if (conf.System.LocalMount() || !replicationState.HasState(consts.ReplicationPerformanceSecondary)) &&
!replicationState.HasState(consts.ReplicationDRSecondary) &&
!replicationState.HasState(consts.ReplicationPerformanceStandby) {

It feels like that may end up cleaner, but I also worry whether that could cause an unacceptable increase to startup time for users with a very large number of databases.

@tomhjp tomhjp marked this pull request as ready for review November 22, 2022 15:23
@tomhjp tomhjp requested a review from a team November 22, 2022 15:23
Copy link
Contributor

@benashz benashz left a comment

Choose a reason for hiding this comment

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

Looking good. I had a few comments/suggestions.

builtin/logical/database/path_config_connection.go Outdated Show resolved Hide resolved
builtin/logical/database/version_wrapper.go Show resolved Hide resolved
helper/versions/version.go Show resolved Hide resolved
helper/versions/version.go Show resolved Hide resolved
helper/versions/version.go Outdated Show resolved Hide resolved
@benashz benashz self-requested a review November 22, 2022 19:45
Copy link
Contributor

@benashz benashz left a comment

Choose a reason for hiding this comment

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

Sorry, for some reason I missed a few files in my first pass.

vault/logical_system.go Show resolved Hide resolved
vault/logical_system_test.go Outdated Show resolved Hide resolved
vault/plugin_catalog.go Outdated Show resolved Hide resolved
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/version"
)

const (
BuiltinMetadata = "builtin"
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

builtin/logical/database/path_config_connection.go Outdated Show resolved Hide resolved
@benashz benashz self-requested a review November 23, 2022 13:34
Copy link
Contributor

@benashz benashz left a comment

Choose a reason for hiding this comment

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

LGTM!

@benashz benashz self-requested a review November 23, 2022 14:21
Copy link
Collaborator

@ncabatoff ncabatoff left a comment

Choose a reason for hiding this comment

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

This seems reasonable to me, based on the little I know about how plugins work.

Copy link
Contributor

@benashz benashz left a comment

Choose a reason for hiding this comment

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

👍 for the extended test coverage. I added a few comment/suggestions.

vault/logical_system_test.go Show resolved Hide resolved
vault/logical_system_test.go Show resolved Hide resolved
vault/logical_system_test.go Show resolved Hide resolved
vault/logical_system_test.go Outdated Show resolved Hide resolved
vault/logical_system_test.go Show resolved Hide resolved
Copy link
Contributor

@benashz benashz left a comment

Choose a reason for hiding this comment

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

LGTM!

@tomhjp
Copy link
Contributor Author

tomhjp commented Nov 23, 2022

Thanks!

@tomhjp tomhjp merged commit 3c95f15 into main Nov 23, 2022
@tomhjp tomhjp deleted the remove-builtin-version-info-from-mount-table branch November 23, 2022 18:36
tomhjp added a commit that referenced this pull request Nov 23, 2022
* Removes _builtin_ versions from mount storage where it already exists
* Stops new builtin versions being put into storage on mount creation/tuning
* Stops the plugin catalog from returning a builtin plugin that has been overridden, so it more accurately reflects the plugins that are available to actually run
 Conflicts:
	vault/mount.go
tomhjp added a commit that referenced this pull request Nov 23, 2022
* Removes _builtin_ versions from mount storage where it already exists
* Stops new builtin versions being put into storage on mount creation/tuning
* Stops the plugin catalog from returning a builtin plugin that has been overridden, so it more accurately reflects the plugins that are available to actually run
 Conflicts:
	vault/mount.go

Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants