open-vault/builtin/credential/aws/path_tidy_identity_accesslist.go
Jim Kalafut 1785b1bd00
Replace deprecated terms in AWS Auth (#10997)
* Replace deprecated terms in AWS Auth

This PR is part of an effort to remove non-inclusive language throughout
Vault. The AWS Auth backend uses the "whitelist" and "blacklist" term
extensively, and these are the focus of the PR:

* Add new API endpoints that use the preferred terminology, while
  deprecating the old endpoints. These endpoints offer identical
  functionality and are basically aliases. This is the only functional
  change in the PR except for terms in error messages.
* Replace "whitelist" -> "access list", "blacklist" -> "deny list" in
  variable names, comments, etc.

Note that storage locations were *not* changed at this time, as that is
a more complex process involving versioning that we may tackle in a future
revision. We have reduced the occurrences of non-inclusive language,
however.

Reviewers should be sure to "Ignore Whitespace" in diffs, especially for
the tests, which were basically indented one level as part of looping
over the tests with both the old and new names.
2021-02-25 23:23:34 -08:00

128 lines
4.1 KiB
Go

package awsauth
import (
"context"
"fmt"
"net/http"
"sync/atomic"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/logical"
)
func (b *backend) pathTidyIdentityAccessList() *framework.Path {
return &framework.Path{
Pattern: "tidy/identity-accesslist$",
Fields: map[string]*framework.FieldSchema{
"safety_buffer": {
Type: framework.TypeDurationSecond,
Default: 259200,
Description: `The amount of extra time that must have passed beyond the identity's
expiration, before it is removed from the backend storage.`,
},
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.UpdateOperation: &framework.PathOperation{
Callback: b.pathTidyIdentityAccessListUpdate,
},
},
HelpSynopsis: pathTidyIdentityAccessListSyn,
HelpDescription: pathTidyIdentityAccessListDesc,
}
}
// tidyAccessListIdentity is used to delete entries in the access list that are expired.
func (b *backend) tidyAccessListIdentity(ctx context.Context, req *logical.Request, safetyBuffer int) (*logical.Response, error) {
// If we are a performance standby forward the request to the active node
if b.System().ReplicationState().HasState(consts.ReplicationPerformanceStandby) {
return nil, logical.ErrReadOnly
}
if !atomic.CompareAndSwapUint32(b.tidyAccessListCASGuard, 0, 1) {
resp := &logical.Response{}
resp.AddWarning("Tidy operation already in progress.")
return resp, nil
}
s := req.Storage
go func() {
defer atomic.StoreUint32(b.tidyAccessListCASGuard, 0)
// Don't cancel when the original client request goes away
ctx = context.Background()
logger := b.Logger().Named("wltidy")
bufferDuration := time.Duration(safetyBuffer) * time.Second
doTidy := func() error {
identities, err := s.List(ctx, identityAccessListStorage)
if err != nil {
return err
}
for _, instanceID := range identities {
identityEntry, err := s.Get(ctx, identityAccessListStorage+instanceID)
if err != nil {
return errwrap.Wrapf(fmt.Sprintf("error fetching identity of instanceID %q: {{err}}", instanceID), err)
}
if identityEntry == nil {
return fmt.Errorf("identity entry for instanceID %q is nil", instanceID)
}
if identityEntry.Value == nil || len(identityEntry.Value) == 0 {
return fmt.Errorf("found identity entry for instanceID %q but actual identity is empty", instanceID)
}
var result accessListIdentity
if err := identityEntry.DecodeJSON(&result); err != nil {
return err
}
if time.Now().After(result.ExpirationTime.Add(bufferDuration)) {
if err := s.Delete(ctx, identityAccessListStorage+instanceID); err != nil {
return errwrap.Wrapf(fmt.Sprintf("error deleting identity of instanceID %q from storage: {{err}}", instanceID), err)
}
}
}
return nil
}
if err := doTidy(); err != nil {
logger.Error("error running access list tidy", "error", err)
return
}
}()
resp := &logical.Response{}
resp.AddWarning("Tidy operation successfully started. Any information from the operation will be printed to Vault's server logs.")
return logical.RespondWithStatusCode(resp, req, http.StatusAccepted)
}
// pathTidyIdentityAccessListUpdate is used to delete entries in the access list that are expired.
func (b *backend) pathTidyIdentityAccessListUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
return b.tidyAccessListIdentity(ctx, req, data.Get("safety_buffer").(int))
}
const pathTidyIdentityAccessListSyn = `
Clean-up the access list instance identity entries.
`
const pathTidyIdentityAccessListDesc = `
When an instance identity is in the access list, the expiration time of the access list
entry is set based on the maximum 'max_ttl' value set on: the role, the role tag
and the backend's mount.
When this endpoint is invoked, all the entries that are expired will be deleted.
A 'safety_buffer' (duration in seconds) can be provided, to ensure deletion of
only those entries that are expired before 'safety_buffer' seconds.
`