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.
This commit is contained in:
Mitchell Hashimoto
2015-03-19 23:11:42 +01:00
parent 163bfa62a6
commit e6ab3a3771
17 changed files with 217 additions and 306 deletions

View File

@@ -44,7 +44,7 @@ type Backend struct {
}
// OperationFunc is the callback called for an operation on a path.
type OperationFunc func(*Request) (*logical.Response, error)
type OperationFunc func(*logical.Request, *FieldData) (*logical.Response, error)
// logical.Backend impl.
func (b *Backend) HandleRequest(req *logical.Request) (*logical.Response, error) {
@@ -92,13 +92,9 @@ func (b *Backend) HandleRequest(req *logical.Request) (*logical.Response, error)
}
// Call the callback with the request and the data
return callback(&Request{
Backend: b,
LogicalRequest: req,
Data: &FieldData{
Raw: raw,
Schema: path.Fields,
},
return callback(req, &FieldData{
Raw: raw,
Schema: path.Fields,
})
}
@@ -161,18 +157,16 @@ func (b *Backend) route(path string) (*Path, map[string]string) {
func (b *Backend) handleRevokeRenew(
req *logical.Request) (*logical.Response, error) {
leaseRaw, ok := req.Data["previous_lease"]
if !ok {
return nil, fmt.Errorf("no previous lease for revoke")
if req.Secret == nil {
return nil, fmt.Errorf("request has no secret")
}
lease, ok := leaseRaw.(*logical.Lease)
rawSecretType, ok := req.Secret.InternalData["secret_type"]
if !ok {
return nil, fmt.Errorf("previous_lease is now *logical.Lease")
return nil, fmt.Errorf("secret is unsupported by this backend")
}
secretType, secretId := SecretType(lease.VaultID)
if secretType == "" {
secretType, ok := rawSecretType.(string)
if !ok {
return nil, fmt.Errorf("secret is unsupported by this backend")
}
@@ -201,17 +195,9 @@ func (b *Backend) handleRevokeRenew(
data = raw.(map[string]interface{})
}
return fn(&Request{
Backend: b,
LogicalRequest: req,
Data: &FieldData{
Raw: data,
Schema: secret.Fields,
},
SecretType: secretType,
SecretId: secretId,
return fn(req, &FieldData{
Raw: data,
Schema: secret.Fields,
})
}