Files
vault/logical/request.go
Mitchell Hashimoto e6ab3a3771 vault: clean up VaultID duplications, make secret responses clearer
/cc @armon - This is a reasonably major refactor that I think cleans up
a lot of the logic with secrets in responses. The reason for the
refactor is that while implementing Renew/Revoke in logical/framework I
found the existing API to be really awkward to work with.

Primarily, we needed a way to send down internal data for Vault core to
store since not all the data you need to revoke a key is always sent
down to the user (for example the user than AWS key belongs to).

At first, I was doing this manually in logical/framework with
req.Storage, but this is going to be such a common event that I think
its something core should assist with. Additionally, I think the added
context for secrets will be useful in the future when we have a Vault
API for returning orphaned out keys: we can also return the internal
data that might help an operator.

So this leads me to this refactor. I've removed most of the fields in
`logical.Response` and replaced it with a single `*Secret` pointer. If
this is non-nil, then the response represents a secret. The Secret
struct encapsulates all the lease info and such.

It also has some fields on it that are only populated at _request_ time
for Revoke/Renew operations. There is precedent for this sort of
behavior in the Go stdlib where http.Request/http.Response have fields
that differ based on client/server. I copied this style.

All core unit tests pass. The APIs fail for obvious reasons but I'll fix
that up in the next commit.
2015-03-19 23:11:42 +01:00

98 lines
2.6 KiB
Go

package logical
import (
"errors"
)
// Request is a struct that stores the parameters and context
// of a request being made to Vault. It is used to abstract
// the details of the higher level request protocol from the handlers.
type Request struct {
// Operation is the requested operation type
Operation Operation
// Path is the part of the request path not consumed by the
// routing. As an example, if the original request path is "prod/aws/foo"
// and the AWS logical backend is mounted at "prod/aws/", then the
// final path is "foo" since the mount prefix is trimmed.
Path string
// Request data is an opaque map that must have string keys.
Data map[string]interface{}
// Storage can be used to durably store and retrieve state.
Storage Storage
// Secret will be non-nil only for Revoke and Renew operations
// to represent the secret that was returned prior.
Secret *Secret
}
// Get returns a data field and guards for nil Data
func (r *Request) Get(key string) interface{} {
if r.Data == nil {
return nil
}
return r.Data[key]
}
// GetString returns a data field as a string
func (r *Request) GetString(key string) string {
raw := r.Get(key)
s, _ := raw.(string)
return s
}
// RenewRequest creates the structure of the renew request.
func RenewRequest(
path string, secret *Secret, data map[string]interface{}) *Request {
return &Request{
Operation: RenewOperation,
Path: path,
Data: data,
Secret: secret,
}
}
// RevokeRequest creates the structure of the revoke request.
func RevokeRequest(
path string, secret *Secret, data map[string]interface{}) *Request {
return &Request{
Operation: RevokeOperation,
Path: path,
Data: data,
Secret: secret,
}
}
// Operation is an enum that is used to specify the type
// of request being made
type Operation string
const (
// The operations below are called per path
ReadOperation Operation = "read"
WriteOperation = "write"
DeleteOperation = "delete"
ListOperation = "list"
HelpOperation = "help"
// The operations below are called globally, the path is less relevant.
RevokeOperation Operation = "revoke"
RenewOperation = "renew"
RollbackOperation = "rollback"
)
var (
// ErrUnsupportedOperation is returned if the operation is not supported
// by the logical backend.
ErrUnsupportedOperation = errors.New("unsupported operation")
// ErrUnsupportedPath is returned if the path is not supported
// by the logical backend.
ErrUnsupportedPath = errors.New("unsupported path")
// ErrInvalidRequest is returned if the request is invalid
ErrInvalidRequest = errors.New("invalid request")
)