Update help text and comments
This commit is contained in:
parent
c85b7be22f
commit
128f25c13d
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/hashicorp/vault/helper/pluginutil"
|
||||
)
|
||||
|
||||
// DatabasePluginClient embeds a databasePluginRPCClient and wraps it's close
|
||||
// DatabasePluginClient embeds a databasePluginRPCClient and wraps it's Close
|
||||
// method to also call Kill() on the plugin.Client.
|
||||
type DatabasePluginClient struct {
|
||||
client *plugin.Client
|
||||
|
@ -64,7 +64,7 @@ func newPluginClient(sys pluginutil.Wrapper, pluginRunner *pluginutil.PluginRunn
|
|||
|
||||
// ---- RPC client domain ----
|
||||
|
||||
// databasePluginRPCClient impliments DatabaseType and is used on the client to
|
||||
// databasePluginRPCClient implements DatabaseType and is used on the client to
|
||||
// make RPC calls to a plugin.
|
||||
type databasePluginRPCClient struct {
|
||||
client *rpc.Client
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
|
||||
// ---- Tracing Middleware Domain ----
|
||||
|
||||
// databaseTracingMiddleware wraps a implementation of DatabaseType and executes
|
||||
// trace logging on function call.
|
||||
type databaseTracingMiddleware struct {
|
||||
next DatabaseType
|
||||
logger log.Logger
|
||||
|
@ -77,6 +79,8 @@ func (mw *databaseTracingMiddleware) Close() (err error) {
|
|||
|
||||
// ---- Metrics Middleware Domain ----
|
||||
|
||||
// databaseMetricsMiddleware wraps an implementation of DatabaseTypes and on
|
||||
// function call logs metrics about this instance.
|
||||
type databaseMetricsMiddleware struct {
|
||||
next DatabaseType
|
||||
|
||||
|
|
|
@ -40,11 +40,13 @@ func PluginFactory(pluginName string, sys pluginutil.LookWrapper, logger log.Log
|
|||
return nil, ErrEmptyPluginName
|
||||
}
|
||||
|
||||
// Look for plugin in the plugin catalog
|
||||
pluginMeta, err := sys.LookupPlugin(pluginName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create a DatabasePluginClient instance
|
||||
db, err := newPluginClient(sys, pluginMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -76,6 +78,8 @@ var handshakeConfig = plugin.HandshakeConfig{
|
|||
MagicCookieValue: "926a0820-aea2-be28-51d6-83cdf00e8edb",
|
||||
}
|
||||
|
||||
// DatabasePlugin implements go-plugin's Plugin interface. It has methods for
|
||||
// retrieving a server and a client instance of the plugin.
|
||||
type DatabasePlugin struct {
|
||||
impl DatabaseType
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// NewPluginServer is called from within a plugin and wraps the provided
|
||||
// DatabaseType implimentation in a databasePluginRPCServer object and starts a
|
||||
// DatabaseType implementation in a databasePluginRPCServer object and starts a
|
||||
// RPC server.
|
||||
func NewPluginServer(db DatabaseType) {
|
||||
dbPlugin := &DatabasePlugin{
|
||||
|
@ -35,7 +35,8 @@ func NewPluginServer(db DatabaseType) {
|
|||
|
||||
// ---- RPC server domain ----
|
||||
|
||||
// databasePluginRPCServer impliments DatabaseType and is run inside a plugin
|
||||
// databasePluginRPCServer implements an RPC version of DatabaseType and is run
|
||||
// inside a plugin. It wraps an underlying implementation of DatabaseType.
|
||||
type databasePluginRPCServer struct {
|
||||
impl DatabaseType
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/hashicorp/vault/logical/framework"
|
||||
)
|
||||
|
||||
// pathResetConnection configures a path to reset a plugin.
|
||||
func pathResetConnection(b *databaseBackend) *framework.Path {
|
||||
return &framework.Path{
|
||||
Pattern: fmt.Sprintf("reset/%s", framework.GenericNameRegex("name")),
|
||||
|
@ -20,15 +21,18 @@ func pathResetConnection(b *databaseBackend) *framework.Path {
|
|||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.UpdateOperation: b.pathConnectionReset,
|
||||
logical.UpdateOperation: b.pathConnectionReset(),
|
||||
},
|
||||
|
||||
HelpSynopsis: pathConfigConnectionHelpSyn,
|
||||
HelpDescription: pathConfigConnectionHelpDesc,
|
||||
HelpSynopsis: pathResetConnectionHelpSyn,
|
||||
HelpDescription: pathResetConnectionHelpDesc,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) pathConnectionReset(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
// pathConnectionReset resets a plugin by closing the existing instance and
|
||||
// creating a new one.
|
||||
func (b *databaseBackend) pathConnectionReset() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
name := data.Get("name").(string)
|
||||
if name == "" {
|
||||
return logical.ErrorResponse("Empty name attribute given"), nil
|
||||
|
@ -47,6 +51,7 @@ func (b *databaseBackend) pathConnectionReset(req *logical.Request, data *framew
|
|||
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// pathConfigurePluginConnection returns a configured framework.Path setup to
|
||||
// operate on plugins.
|
||||
|
@ -62,13 +67,15 @@ func pathConfigurePluginConnection(b *databaseBackend) *framework.Path {
|
|||
"verify_connection": &framework.FieldSchema{
|
||||
Type: framework.TypeBool,
|
||||
Default: true,
|
||||
Description: `If set, connection_url is verified by actually connecting to the database`,
|
||||
Description: `If set, the connection details are verified by
|
||||
actually connecting to the database`,
|
||||
},
|
||||
|
||||
"plugin_name": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
Description: `Maximum amount of time a connection may be reused;
|
||||
a zero or negative value reuses connections forever.`,
|
||||
Description: `The name of a builtin or previously registered
|
||||
plugin known to vault. This endpoint will create an instance of
|
||||
that plugin type.`,
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -198,16 +205,32 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
|
|||
}
|
||||
|
||||
const pathConfigConnectionHelpSyn = `
|
||||
Configure the connection string to talk to PostgreSQL.
|
||||
Configure connection details to a database plugin.
|
||||
`
|
||||
|
||||
const pathConfigConnectionHelpDesc = `
|
||||
This path configures the connection string used to connect to PostgreSQL.
|
||||
The value of the string can be a URL, or a PG style string in the
|
||||
format of "user=foo host=bar" etc.
|
||||
This path configures the connection details used to connect to a particular
|
||||
database. This path runs the provided plugin name and passes the configured
|
||||
connection details to the plugin. See the documentation for the plugin specified
|
||||
for a full list of accepted connection details.
|
||||
|
||||
The URL looks like:
|
||||
"postgresql://user:pass@host:port/dbname"
|
||||
In addition to the database specific connection details, this endpoing also
|
||||
accepts:
|
||||
|
||||
When configuring the connection string, the backend will verify its validity.
|
||||
* "plugin_name" (required) - The name of a builtin or previously registered
|
||||
plugin known to vault. This endpoint will create an instance of that
|
||||
plugin type.
|
||||
|
||||
* "verify_connection" - A boolean value denoting if the plugin should verify
|
||||
it is able to connect to the database using the provided connection
|
||||
details.
|
||||
`
|
||||
|
||||
const pathResetConnectionHelpSyn = `
|
||||
Resets a database plugin.
|
||||
`
|
||||
|
||||
const pathResetConnectionHelpDesc = `
|
||||
This path resets the database connection by closing the existing database plugin
|
||||
instance and running a new one.
|
||||
`
|
||||
|
|
|
@ -19,7 +19,7 @@ func pathRoleCreate(b *databaseBackend) *framework.Path {
|
|||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.ReadOperation: b.pathRoleCreateRead,
|
||||
logical.ReadOperation: b.pathRoleCreateRead(),
|
||||
},
|
||||
|
||||
HelpSynopsis: pathRoleCreateReadHelpSyn,
|
||||
|
@ -27,7 +27,8 @@ func pathRoleCreate(b *databaseBackend) *framework.Path {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) pathRoleCreateRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) pathRoleCreateRead() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
name := data.Get("name").(string)
|
||||
|
||||
// Get the role
|
||||
|
@ -67,6 +68,7 @@ func (b *databaseBackend) pathRoleCreateRead(req *logical.Request, data *framewo
|
|||
resp.Secret.TTL = role.DefaultTTL
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
||||
const pathRoleCreateReadHelpSyn = `
|
||||
Request database credentials for a certain role.
|
||||
|
|
|
@ -14,7 +14,7 @@ func pathListRoles(b *databaseBackend) *framework.Path {
|
|||
Pattern: "roles/?$",
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.ListOperation: b.pathRoleList,
|
||||
logical.ListOperation: b.pathRoleList(),
|
||||
},
|
||||
|
||||
HelpSynopsis: pathRoleHelpSyn,
|
||||
|
@ -35,12 +35,13 @@ func pathRoles(b *databaseBackend) *framework.Path {
|
|||
Type: framework.TypeString,
|
||||
Description: "Name of the database this role acts on.",
|
||||
},
|
||||
|
||||
"creation_statements": {
|
||||
Type: framework.TypeString,
|
||||
Description: "SQL string to create a user. See help for more info.",
|
||||
Description: `Statements to be executed to create a user. Must be a semicolon-separated
|
||||
string, a base64-encoded semicolon-separated string, a serialized JSON string
|
||||
array, or a base64-encoded serialized JSON string array. The '{{name}}',
|
||||
'{{password}}', and '{{expiration}}' values will be substituted.`,
|
||||
},
|
||||
|
||||
"revocation_statements": {
|
||||
Type: framework.TypeString,
|
||||
Description: `Statements to be executed to revoke a user. Must be a semicolon-separated
|
||||
|
@ -75,9 +76,9 @@ func pathRoles(b *databaseBackend) *framework.Path {
|
|||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.ReadOperation: b.pathRoleRead,
|
||||
logical.UpdateOperation: b.pathRoleCreate,
|
||||
logical.DeleteOperation: b.pathRoleDelete,
|
||||
logical.ReadOperation: b.pathRoleRead(),
|
||||
logical.UpdateOperation: b.pathRoleCreate(),
|
||||
logical.DeleteOperation: b.pathRoleDelete(),
|
||||
},
|
||||
|
||||
HelpSynopsis: pathRoleHelpSyn,
|
||||
|
@ -85,7 +86,8 @@ func pathRoles(b *databaseBackend) *framework.Path {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) pathRoleDelete(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) pathRoleDelete() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
err := req.Storage.Delete("role/" + data.Get("name").(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -93,8 +95,10 @@ func (b *databaseBackend) pathRoleDelete(req *logical.Request, data *framework.F
|
|||
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) pathRoleRead(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) pathRoleRead() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
role, err := b.Role(req.Storage, data.Get("name").(string))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -114,8 +118,10 @@ func (b *databaseBackend) pathRoleRead(req *logical.Request, data *framework.Fie
|
|||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) pathRoleList(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) pathRoleList() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
entries, err := req.Storage.List("role/")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -123,8 +129,10 @@ func (b *databaseBackend) pathRoleList(req *logical.Request, d *framework.FieldD
|
|||
|
||||
return logical.ListResponse(entries), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) pathRoleCreate(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) pathRoleCreate() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
name := data.Get("name").(string)
|
||||
if name == "" {
|
||||
return logical.ErrorResponse("Empty role name attribute given"), nil
|
||||
|
@ -163,8 +171,6 @@ func (b *databaseBackend) pathRoleCreate(req *logical.Request, data *framework.F
|
|||
RenewStatements: renewStmts,
|
||||
}
|
||||
|
||||
// TODO: Think about preparing the statments to test.
|
||||
|
||||
// Store it
|
||||
entry, err := logical.StorageEntryJSON("role/"+name, &roleEntry{
|
||||
DBName: dbName,
|
||||
|
@ -181,6 +187,7 @@ func (b *databaseBackend) pathRoleCreate(req *logical.Request, data *framework.F
|
|||
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
type roleEntry struct {
|
||||
DBName string `json:"db_name" mapstructure:"db_name" structs:"db_name"`
|
||||
|
@ -196,10 +203,14 @@ Manage the roles that can be created with this backend.
|
|||
const pathRoleHelpDesc = `
|
||||
This path lets you manage the roles that can be created with this backend.
|
||||
|
||||
The "sql" parameter customizes the SQL string used to create the role.
|
||||
This can be a sequence of SQL queries. Some substitution will be done to the
|
||||
SQL string for certain keys. The names of the variables must be surrounded
|
||||
by "{{" and "}}" to be replaced.
|
||||
The "db_name" parameter is required and configures the name of the database
|
||||
connection to use.
|
||||
|
||||
The "creation_statements" parameter customizes the string used to create the
|
||||
credentials. This can be a sequence of SQL queries, or other statement formats
|
||||
for a particular database type. Some substitution will be done to the statement
|
||||
strings for certain keys. The names of the variables must be surrounded by "{{"
|
||||
and "}}" to be replaced.
|
||||
|
||||
* "name" - The random username generated for the DB user.
|
||||
|
||||
|
@ -207,7 +218,7 @@ by "{{" and "}}" to be replaced.
|
|||
|
||||
* "expiration" - The timestamp when this user will expire.
|
||||
|
||||
Example of a decent SQL query to use:
|
||||
Example of a decent creation_statements for a postgresql database plugin:
|
||||
|
||||
CREATE ROLE "{{name}}" WITH
|
||||
LOGIN
|
||||
|
@ -215,14 +226,17 @@ Example of a decent SQL query to use:
|
|||
VALID UNTIL '{{expiration}}';
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "{{name}}";
|
||||
|
||||
Note the above user would be able to access everything in schema public.
|
||||
For more complex GRANT clauses, see the PostgreSQL manual.
|
||||
|
||||
The "revocation_sql" parameter customizes the SQL string used to revoke a user.
|
||||
Example of a decent revocation SQL query to use:
|
||||
The "revocation_statements" parameter customizes the statement string used to
|
||||
revoke a user. Example of a decent revocation_statements for a postgresql
|
||||
database plugin:
|
||||
|
||||
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM {{name}};
|
||||
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM {{name}};
|
||||
REVOKE USAGE ON SCHEMA public FROM {{name}};
|
||||
DROP ROLE IF EXISTS {{name}};
|
||||
|
||||
The "renew_statements" parameter customizes the statement string used to renew a
|
||||
user.
|
||||
The "rollback_statements' parameter customizes the statement string used to
|
||||
rollback a change if needed.
|
||||
`
|
||||
|
|
|
@ -14,12 +14,13 @@ func secretCreds(b *databaseBackend) *framework.Secret {
|
|||
Type: SecretCredsType,
|
||||
Fields: map[string]*framework.FieldSchema{},
|
||||
|
||||
Renew: b.secretCredsRenew,
|
||||
Revoke: b.secretCredsRevoke,
|
||||
Renew: b.secretCredsRenew(),
|
||||
Revoke: b.secretCredsRevoke(),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) secretCredsRenew(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) secretCredsRenew() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
// Get the username from the internal data
|
||||
usernameRaw, ok := req.Secret.InternalData["username"]
|
||||
if !ok {
|
||||
|
@ -41,7 +42,7 @@ func (b *databaseBackend) secretCredsRenew(req *logical.Request, d *framework.Fi
|
|||
}
|
||||
|
||||
f := framework.LeaseExtend(role.DefaultTTL, role.MaxTTL, b.System())
|
||||
resp, err := f(req, d)
|
||||
resp, err := f(req, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -66,8 +67,10 @@ func (b *databaseBackend) secretCredsRenew(req *logical.Request, d *framework.Fi
|
|||
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (b *databaseBackend) secretCredsRevoke(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
func (b *databaseBackend) secretCredsRevoke() framework.OperationFunc {
|
||||
return func(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
// Get the username from the internal data
|
||||
usernameRaw, ok := req.Secret.InternalData["username"]
|
||||
if !ok {
|
||||
|
@ -123,3 +126,4 @@ func (b *databaseBackend) secretCredsRevoke(req *logical.Request, d *framework.F
|
|||
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,11 +88,11 @@ func (d StaticSystemView) ReplicationState() consts.ReplicationState {
|
|||
}
|
||||
|
||||
func (d StaticSystemView) ResponseWrapData(data map[string]interface{}, ttl time.Duration, jwt bool) (string, error) {
|
||||
return "", errors.New("ResponseWrapData is not implimented in StaticSystemView")
|
||||
return "", errors.New("ResponseWrapData is not implemented in StaticSystemView")
|
||||
}
|
||||
|
||||
func (d StaticSystemView) LookupPlugin(name string) (*pluginutil.PluginRunner, error) {
|
||||
return nil, errors.New("LookupPlugin is not implimented in StaticSystemView")
|
||||
return nil, errors.New("LookupPlugin is not implemented in StaticSystemView")
|
||||
}
|
||||
|
||||
func (d StaticSystemView) MlockDisabled() bool {
|
||||
|
|
Loading…
Reference in a new issue