logical/framework: auto-extend leases if requested
This commit is contained in:
parent
05246433bb
commit
27d33ad9f7
|
@ -181,25 +181,15 @@ func (b *Backend) handleRevokeRenew(
|
|||
return nil, fmt.Errorf("secret is unsupported by this backend")
|
||||
}
|
||||
|
||||
var fn OperationFunc
|
||||
switch req.Operation {
|
||||
case logical.RenewOperation:
|
||||
fn = secret.Renew
|
||||
return secret.HandleRenew(req)
|
||||
case logical.RevokeOperation:
|
||||
fn = secret.Revoke
|
||||
return secret.HandleRevoke(req)
|
||||
default:
|
||||
return nil, fmt.Errorf(
|
||||
"invalid operation for revoke/renew: %s", req.Operation)
|
||||
}
|
||||
|
||||
if fn == nil {
|
||||
return nil, logical.ErrUnsupportedOperation
|
||||
}
|
||||
|
||||
return fn(req, &FieldData{
|
||||
Raw: req.Data,
|
||||
Schema: secret.Fields,
|
||||
})
|
||||
}
|
||||
|
||||
func (b *Backend) handleRollback(
|
||||
|
|
|
@ -162,6 +162,30 @@ func TestBackendHandleRequest_renew(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBackendHandleRequest_renewExtend(t *testing.T) {
|
||||
secret := &Secret{
|
||||
Type: "foo",
|
||||
RenewExtend: true,
|
||||
DefaultDuration: 5 * time.Second,
|
||||
}
|
||||
b := &Backend{
|
||||
Secrets: []*Secret{secret},
|
||||
}
|
||||
|
||||
req := logical.RenewRequest("/foo", secret.Response(nil, nil).Secret, nil)
|
||||
req.Secret.LeaseIncrement = 1 * time.Hour
|
||||
resp, err := b.HandleRequest(req)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
if resp == nil || resp.Secret == nil {
|
||||
t.Fatal("should have secret")
|
||||
}
|
||||
if resp.Secret.Lease != 1*time.Hour {
|
||||
t.Fatalf("bad: %#v", resp.Secret)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackendHandleRequest_revoke(t *testing.T) {
|
||||
var called uint32
|
||||
callback := func(*logical.Request, *FieldData) (*logical.Response, error) {
|
||||
|
|
|
@ -25,15 +25,26 @@ type Secret struct {
|
|||
DefaultDuration time.Duration
|
||||
DefaultGracePeriod time.Duration
|
||||
|
||||
// Below are the operations that can be called on the secret.
|
||||
// Renew is the callback called to renew this secret. If Renew is
|
||||
// not specified and RenewExtend is false, then Renewable is set to
|
||||
// false in the secret.
|
||||
//
|
||||
// Renew, if not set, will mark the secret as not renewable.
|
||||
//
|
||||
// Revoke is required.
|
||||
Renew OperationFunc
|
||||
// RenewExtend, if true, will automatically extend the lease of this
|
||||
// secret type. You can specify RenewExtendMax to specify the max
|
||||
// duration it can be extended, otherwise it will be extended potentially
|
||||
// indefinitely.
|
||||
Renew OperationFunc
|
||||
RenewExtend bool
|
||||
RenewExtendMax time.Duration
|
||||
|
||||
// Revoke is the callback called to revoke this secret. This is required.
|
||||
Revoke OperationFunc
|
||||
}
|
||||
|
||||
func (s *Secret) Renewable() bool {
|
||||
return s.Renew != nil || s.RenewExtend
|
||||
}
|
||||
|
||||
func (s *Secret) Response(
|
||||
data, internal map[string]interface{}) *logical.Response {
|
||||
internalData := make(map[string]interface{})
|
||||
|
@ -44,7 +55,7 @@ func (s *Secret) Response(
|
|||
|
||||
return &logical.Response{
|
||||
Secret: &logical.Secret{
|
||||
Renewable: s.Renew != nil,
|
||||
Renewable: s.Renewable(),
|
||||
Lease: s.DefaultDuration,
|
||||
LeaseGracePeriod: s.DefaultGracePeriod,
|
||||
InternalData: internalData,
|
||||
|
@ -53,3 +64,56 @@ func (s *Secret) Response(
|
|||
Data: data,
|
||||
}
|
||||
}
|
||||
|
||||
// HandleRenew is the request handler for renewing this secret.
|
||||
func (s *Secret) HandleRenew(req *logical.Request) (*logical.Response, error) {
|
||||
if !s.Renewable() {
|
||||
return nil, logical.ErrUnsupportedOperation
|
||||
}
|
||||
|
||||
data := &FieldData{
|
||||
Raw: req.Data,
|
||||
Schema: s.Fields,
|
||||
}
|
||||
|
||||
// If we have a callback, we just call that and that does all the logic.
|
||||
if s.Renew != nil {
|
||||
return s.Renew(req, data)
|
||||
}
|
||||
|
||||
// If we're using RenewExtend, then just automaticaly extend.
|
||||
if s.RenewExtend {
|
||||
return s.HandleRenewExtend(req, data)
|
||||
}
|
||||
|
||||
return nil, logical.ErrUnsupportedOperation
|
||||
}
|
||||
|
||||
// HandleRenewExtend is the OperationFunc that just extends the lease
|
||||
// of the secret.
|
||||
func (s *Secret) HandleRenewExtend(
|
||||
req *logical.Request, data *FieldData) (*logical.Response, error) {
|
||||
// First copy the original secret/data
|
||||
var resp logical.Response
|
||||
resp.Secret = req.Secret
|
||||
resp.Data = req.Data
|
||||
|
||||
// Now extend the lease by the amount specified.
|
||||
resp.Secret.Lease = req.Secret.LeaseIncrement
|
||||
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// HandleRevoke is the request handler for renewing this secret.
|
||||
func (s *Secret) HandleRevoke(req *logical.Request) (*logical.Response, error) {
|
||||
data := &FieldData{
|
||||
Raw: req.Data,
|
||||
Schema: s.Fields,
|
||||
}
|
||||
|
||||
if s.Revoke != nil {
|
||||
return s.Revoke(req, data)
|
||||
}
|
||||
|
||||
return nil, logical.ErrUnsupportedOperation
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue