docker / docker/secrets-engine
Improve plugin interface
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 91
- Forks
- 16
- Avg merge
- 9h 3m
- Merged PRs (30d)
- 24
Description
Plugins in the secrets engine were built and tailored around the concept of a Resolver interface which has a singular function to retrieve a secret from a provider based on a pattern.
A request might look as follows:
POST http://localhost/resolver.v1.ResolverService/GetSecret -H "Content-Type: application/json" -d '{"pattern": "foo"}'
-> http.Handler
-> protobuf handler
-> `engine.regResolver`
-> `engine.regResolver.GetSecrets()`
-> list all registered providers from `engine.regResolver.registry.GetAll()`
-> `engine.runtime.GetSecrets()`
-> resolver service
-> resolver.GetSecret
-> builtin plugin GetSecret
As shown above, this is a high-level call trace for a built-in plugin. We implement the secrets.Resolver interface in multiple places instead of just for a specific plugin type. We tightly coupled the handler endpoint with the underlying plugin.
A built-in plugin gets defined inside the engine/builtins/<plugin> directory, where they implement the engine.Plugin interface.
https://github.com/docker/secrets-engine/blob/main/engine/adaptation.go#L42-L46
Plugins are created individually inside the daemon func main and passed along to the engine.New function. Here they are eventually managed the wrapBuiltins function.
https://github.com/docker/secrets-engine/blob/main/engine/builtin.go#L114-L122
This translates into a call to newInternalRuntime which accepts the engine.Plugin interface.
https://github.com/docker/secrets-engine/blob/main/engine/builtin.go#L22
The engine.Plugin interface is tightly coupled with the plugin.Resolver interface which is an alias of secrets.Resolver.
This makes it difficult to create a plugin that is not a resolver. Creating plugins that could by of another plugin type would mean adding a new internalRuntime type which implements the runtime interface. The runtime interface also depends upon the secrets.Resolver interface. Which means we would need to simplify the runtime interface and remove the hard dependency upon secrets.Resolver. A more general resolver service is needed to instead of just specifying GetSecrets it needs to be dynamic, based upon the underlying type (i.e. it cannot just accept a secrets.Resolver type).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with engine/adaptation.go, engine/builtin.go, and the daemon's main function to trace plugin creation through engine.New, wrapBuiltins, and newInternalRuntime. Read the runtime, engine.Plugin, and plugin.Resolver interfaces and map their dependencies on secrets.Resolver. Done means the design supports plugin types beyond resolvers without coupling the runtime to secrets.Resolver.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100