2023-03-15 16:00:52 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2021-06-02 16:11:30 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"math/rand"
|
2021-06-04 19:25:41 +00:00
|
|
|
"path"
|
2021-06-02 16:11:30 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
uuid "github.com/hashicorp/go-uuid"
|
|
|
|
"github.com/hashicorp/vault/helper/namespace"
|
2021-06-04 19:25:41 +00:00
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
2021-06-02 16:11:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type basicLeaseTestInfo struct {
|
|
|
|
id string
|
|
|
|
mount string
|
|
|
|
expire time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
// add an irrevocable lease for test purposes
|
|
|
|
// returns the lease ID and expire time
|
2021-06-29 21:02:30 +00:00
|
|
|
func (c *Core) AddIrrevocableLease(ctx context.Context, pathPrefix string) (*basicLeaseTestInfo, error) {
|
|
|
|
exp := c.expiration
|
2021-06-02 16:11:30 +00:00
|
|
|
|
|
|
|
uuid, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
2021-06-29 21:02:30 +00:00
|
|
|
return nil, fmt.Errorf("error generating uuid: %w", err)
|
2021-06-02 16:11:30 +00:00
|
|
|
}
|
|
|
|
|
2021-06-29 21:02:30 +00:00
|
|
|
ns, err := namespace.FromContext(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("error getting namespace from context: %w", err)
|
|
|
|
}
|
2021-06-02 16:11:30 +00:00
|
|
|
if ns == nil {
|
|
|
|
ns = namespace.RootNamespace
|
|
|
|
}
|
|
|
|
|
2021-06-04 19:25:41 +00:00
|
|
|
leaseID := path.Join(pathPrefix, "lease"+uuid)
|
|
|
|
|
2021-06-02 16:11:30 +00:00
|
|
|
if ns != namespace.RootNamespace {
|
2021-06-04 19:25:41 +00:00
|
|
|
leaseID = fmt.Sprintf("%s.%s", leaseID, ns.ID)
|
2021-06-02 16:11:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
randomTimeDelta := time.Duration(rand.Int31n(24))
|
|
|
|
le := &leaseEntry{
|
2021-06-04 19:25:41 +00:00
|
|
|
LeaseID: leaseID,
|
|
|
|
Path: pathPrefix,
|
2021-06-02 16:11:30 +00:00
|
|
|
namespace: ns,
|
|
|
|
IssueTime: time.Now(),
|
|
|
|
ExpireTime: time.Now().Add(randomTimeDelta * time.Hour),
|
|
|
|
RevokeErr: "some error message",
|
|
|
|
}
|
|
|
|
|
2021-06-29 21:02:30 +00:00
|
|
|
exp.pendingLock.Lock()
|
|
|
|
defer exp.pendingLock.Unlock()
|
2021-06-02 16:11:30 +00:00
|
|
|
|
2021-06-29 21:02:30 +00:00
|
|
|
if err := exp.persistEntry(context.Background(), le); err != nil {
|
|
|
|
return nil, fmt.Errorf("error persisting irrevocable lease: %w", err)
|
2021-06-02 16:11:30 +00:00
|
|
|
}
|
|
|
|
|
2021-06-29 21:02:30 +00:00
|
|
|
exp.updatePendingInternal(le)
|
2021-06-02 16:11:30 +00:00
|
|
|
|
|
|
|
return &basicLeaseTestInfo{
|
|
|
|
id: le.LeaseID,
|
|
|
|
expire: le.ExpireTime,
|
2021-06-29 21:02:30 +00:00
|
|
|
}, nil
|
2021-06-02 16:11:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// InjectIrrevocableLeases injects `count` irrevocable leases (currently to a
|
|
|
|
// single mount).
|
|
|
|
// It returns a map of the mount accessor to the number of leases stored there
|
2021-06-29 21:02:30 +00:00
|
|
|
func (c *Core) InjectIrrevocableLeases(ctx context.Context, count int) (map[string]int, error) {
|
2021-06-02 16:11:30 +00:00
|
|
|
out := make(map[string]int)
|
|
|
|
for i := 0; i < count; i++ {
|
2021-06-29 21:02:30 +00:00
|
|
|
le, err := c.AddIrrevocableLease(ctx, "foo/")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-06-02 16:11:30 +00:00
|
|
|
|
|
|
|
mountAccessor := c.expiration.getLeaseMountAccessor(ctx, le.id)
|
|
|
|
if _, ok := out[mountAccessor]; !ok {
|
|
|
|
out[mountAccessor] = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
out[mountAccessor]++
|
|
|
|
}
|
|
|
|
|
2021-06-29 21:02:30 +00:00
|
|
|
return out, nil
|
2021-06-02 16:11:30 +00:00
|
|
|
}
|
2021-06-04 19:25:41 +00:00
|
|
|
|
|
|
|
type backend struct {
|
|
|
|
path string
|
|
|
|
ns *namespace.Namespace
|
|
|
|
}
|
|
|
|
|
|
|
|
// set up multiple mounts, and return a mapping of the path to the mount accessor
|
2021-06-29 21:02:30 +00:00
|
|
|
func mountNoopBackends(c *Core, backends []*backend) (map[string]string, error) {
|
2021-06-04 19:25:41 +00:00
|
|
|
// enable the noop backend
|
|
|
|
c.logicalBackends["noop"] = func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) {
|
|
|
|
return &NoopBackend{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
pathToMount := make(map[string]string)
|
|
|
|
for _, backend := range backends {
|
|
|
|
me := &MountEntry{
|
|
|
|
Table: mountTableType,
|
|
|
|
Path: backend.path,
|
|
|
|
Type: "noop",
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCtx := namespace.ContextWithNamespace(context.Background(), backend.ns)
|
2021-06-29 21:02:30 +00:00
|
|
|
if err := c.mount(nsCtx, me); err != nil {
|
|
|
|
return nil, fmt.Errorf("error mounting backend %s: %w", backend.path, err)
|
2021-06-04 19:25:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mount := c.router.MatchingMountEntry(nsCtx, backend.path)
|
|
|
|
if mount == nil {
|
2021-06-29 21:02:30 +00:00
|
|
|
return nil, fmt.Errorf("couldn't find mount for path %s", backend.path)
|
2021-06-04 19:25:41 +00:00
|
|
|
}
|
|
|
|
pathToMount[backend.path] = mount.Accessor
|
|
|
|
}
|
|
|
|
|
2021-06-29 21:02:30 +00:00
|
|
|
return pathToMount, nil
|
2021-06-04 19:25:41 +00:00
|
|
|
}
|
2021-07-06 22:12:24 +00:00
|
|
|
|
|
|
|
func (c *Core) FetchLeaseCountToRevoke() int {
|
|
|
|
c.expiration.pendingLock.RLock()
|
|
|
|
defer c.expiration.pendingLock.RUnlock()
|
|
|
|
return c.expiration.leaseCount
|
|
|
|
}
|