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

Run all builtins as plugins #5536

Merged
merged 54 commits into from
Nov 7, 2018
Merged

Conversation

tyrannosaurus-becks
Copy link
Contributor

@tyrannosaurus-becks tyrannosaurus-becks commented Oct 17, 2018

This PR is to allow Vault to run all builtins as plugins. This PR is ready for review.

Overview

To understand how this is helpful, consider this scenario:

  • You are running the aws auth builtin
  • You wish to run a custom version while still otherwise remaining on the current version of Vault

To achieve this given this code, you would:

  • Customize the aws builtin
  • Run $ go build on main.go in its directory to make a binary
  • Place this binary in your configured plugin directory
  • Add it to the plugin catalog as per normal
  • Run $ auth enable aws
  • Vault would then give precedence to enabling your custom plugin over the builtin version of the aws plugin

This hopefully illustrates the new behavior this PR introduces:

  • All builtins are plugins
  • Plugins in the plugin directory are preferred over builtin versions

Because of possible naming clashes across plugins, we had to introduce the concept of a plugin type. This prevents the aws secrets plugin's name from clashing with the aws auth plugin's name.

Other side effects of these actions include:

  • The plugin catalog used to be a LIST /sys/plugins/catalog which is DEPRECATED by this PR
  • The same functionality, by plugin type, will now be at /sys/plugins/catalog/database, /sys/plugins/catalog/auth, and /sys/plugins/catalog/secret
  • The plugin catalog now has READ at /sys/plugins/catalog which, under "data", returns a map of plugin type to the names of the plugins that fall into that type
  • The syntax of $ vault secrets enable -plugin-name='ad' plugin will now be DEPRECATED (though still supported) and now all plugins will be enabled via $ vault secrets enable ad

TODO

  • I will create a follow-up PR immediately after this is merged updating all docs to correspond with these changes

@tyrannosaurus-becks tyrannosaurus-becks changed the title Early reviews: Run all builtins as plugins Run all builtins as plugins Oct 18, 2018
vault/auth.go Outdated Show resolved Hide resolved
@briankassouf briankassouf added this to the 0.12 milestone Oct 19, 2018
@tyrannosaurus-becks tyrannosaurus-becks force-pushed the run-all-buitins-as-plugins branch from 74a052f to 97c24d7 Compare October 23, 2018 16:35
@tyrannosaurus-becks tyrannosaurus-becks changed the title Run all builtins as plugins Not Ready: Run all builtins as plugins Oct 23, 2018
@tyrannosaurus-becks tyrannosaurus-becks changed the title Not Ready: Run all builtins as plugins Run all builtins as plugins Oct 23, 2018
// backend is a thin wrapper around plugin.BackendPluginClient
type backend struct {
// PluginBackend is a thin wrapper around plugin.BackendPluginClient
type PluginBackend struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this have to be exported? The func Backend factory func above returns an interface so having this as backend seems to be fine (and follows the pattern on how other backends are laid out, e.g. credentials/aws having its own internal type backend struct).

Copy link
Contributor Author

@tyrannosaurus-becks tyrannosaurus-becks Oct 30, 2018

Choose a reason for hiding this comment

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

This is exported so it can be used in the plugin_test package residing in the same directory, here.

The reason that was changed to its own package was to resolve an extremely persistent import cycle. This is the import cycle that results if I revert it:

$ make test
==> Checking that build is using go version >= 1.10...
==> Using go version 1.11...
# github.com/hashicorp/vault/builtin/plugin
import cycle not allowed in test
package github.com/hashicorp/vault/builtin/plugin (test)
	imports github.com/hashicorp/vault/http
	imports github.com/hashicorp/vault/vault
	imports github.com/hashicorp/vault/builtin/plugin
FAIL	github.com/hashicorp/vault/builtin/plugin [setup failed]

I experimented with multiple ways of breaking this import cycle, ultimately selecting this one because it was the least code change.

I'm open to taking other approaches, or adding a comment to that effect.

@@ -1,4 +1,4 @@
package plugin
package plugin_test
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason why this has to be broken out to its own package?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replied to this one in the above comment.

command/plugin.go Outdated Show resolved Hide resolved
command/plugin.go Outdated Show resolved Hide resolved
Copy link
Contributor

@briankassouf briankassouf left a comment

Choose a reason for hiding this comment

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

I think we need to think through some of the upgrade cases still, i worry that existing plugins mounts wont upgrade correctly. Also i think the catalog's storage needs to be broken out by type.

command/auth_enable.go Outdated Show resolved Hide resolved
i := 0
for pluginName := range pluginNames {
plugins[i] = pluginName
i++
Copy link
Contributor

Choose a reason for hiding this comment

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

Feels like the dedup should be happening in the API

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 agree - and the sorting of the list too. So, I added this commit and what that does is re-add the ability to list all plugins at sys/plugins/catalog. At that endpoint, it sorts and dedupes them.

There's a catch, though. I can't move all the sorting and deduping to the API because when I re-add path prediction for the secret mounts, I need to predict all database and secrets plugins. So there need to be two API calls - one listing each type, and then some logic sorting and deduping them.

command/commands.go Outdated Show resolved Hide resolved
command/secrets_enable.go Outdated Show resolved Hide resolved
vault/auth.go Outdated Show resolved Hide resolved
vault/logical_system.go Outdated Show resolved Hide resolved
vault/logical_system.go Outdated Show resolved Hide resolved
vault/mount.go Show resolved Hide resolved
vault/plugin_catalog.go Show resolved Hide resolved
@@ -77,8 +75,7 @@ func (c *Core) reloadMatchingPlugin(ctx context.Context, pluginName string) erro
if ns.ID != entry.Namespace().ID {
continue
}

if entry.Config.PluginName == pluginName && entry.Type == "plugin" {
if entry.Type == pluginName {
Copy link
Contributor

Choose a reason for hiding this comment

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

What does entry.Type equal now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the command, $ vault auth enable my-custom-plugin, the entry.Type == "my-custom-plugin".

command/plugin_info.go Outdated Show resolved Hide resolved
"database": logicalDb.Factory,
// This is also available in the plugin catalog, but is here due to the need to
// automatically mount it.
"kv": logicalKv.Factory,
Copy link
Contributor

Choose a reason for hiding this comment

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

Was this necessary to add?

Becca Petrin and others added 8 commits November 6, 2018 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants