mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-03 20:40:45 -05:00
Add LIST endpoint to AWS Secrets static roles (#29842)
* Add LIST endpoint to AWS Secrets static roles * add test + changelog * Update website/content/api-docs/secret/aws.mdx Co-authored-by: John-Michael Faircloth <fairclothjm@users.noreply.github.com> * Update website/content/api-docs/secret/aws.mdx Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com> --------- Co-authored-by: John-Michael Faircloth <fairclothjm@users.noreply.github.com> Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com>
This commit is contained in:
parent
404356a805
commit
84fa94c6c1
5 changed files with 115 additions and 0 deletions
|
|
@ -57,6 +57,7 @@ func Backend(_ *logical.BackendConfig) *backend {
|
|||
pathRoles(&b),
|
||||
pathListRoles(&b),
|
||||
pathStaticRoles(&b),
|
||||
pathListStaticRoles(&b),
|
||||
pathStaticCredentials(&b),
|
||||
pathUser(&b),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -94,6 +94,19 @@ func pathStaticRoles(b *backend) *framework.Path {
|
|||
}
|
||||
}
|
||||
|
||||
func pathListStaticRoles(b *backend) *framework.Path {
|
||||
return &framework.Path{
|
||||
Pattern: fmt.Sprintf("%s/?$", pathStaticRole),
|
||||
Operations: map[logical.Operation]framework.OperationHandler{
|
||||
logical.ListOperation: &framework.PathOperation{
|
||||
Callback: b.pathStaticRolesList,
|
||||
},
|
||||
},
|
||||
HelpSynopsis: pathStaticRolesHelpSyn,
|
||||
HelpDescription: pathStaticRolesHelpDesc,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *backend) pathStaticRolesRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
roleName, ok := data.GetOk(paramRoleName)
|
||||
if !ok {
|
||||
|
|
@ -289,6 +302,21 @@ func (b *backend) pathStaticRolesDelete(ctx context.Context, req *logical.Reques
|
|||
return nil, req.Storage.Delete(ctx, formatRoleStoragePath(roleName.(string)))
|
||||
}
|
||||
|
||||
func (b *backend) pathStaticRolesList(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.roleMutex.RLock()
|
||||
defer b.roleMutex.RUnlock()
|
||||
|
||||
roles, err := req.Storage.List(ctx, pathStaticRole+"/")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error listing static roles at %s: %w", pathStaticRole, err)
|
||||
}
|
||||
if len(roles) == 0 {
|
||||
return &logical.Response{Data: map[string]interface{}{}}, nil
|
||||
}
|
||||
|
||||
return logical.ListResponse(roles), nil
|
||||
}
|
||||
|
||||
func (b *backend) validateRoleName(name string) error {
|
||||
if name == "" {
|
||||
return errors.New("empty role name attribute given")
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ package aws
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -533,6 +534,61 @@ func TestStaticRoleDelete(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestStaticRolesList validates that we can list all the static roles in the storage backend.
|
||||
func TestStaticRolesList(t *testing.T) {
|
||||
config := logical.TestBackendConfig()
|
||||
config.StorageView = &logical.InmemStorage{}
|
||||
bgCTX := context.Background()
|
||||
|
||||
staticRoles := []staticRoleEntry{}
|
||||
for i := 1; i <= 10; i++ {
|
||||
roles := staticRoleEntry{
|
||||
Name: "testrole" + strconv.Itoa(i),
|
||||
Username: "jane-doe",
|
||||
RotationPeriod: 24 * time.Hour,
|
||||
}
|
||||
staticRoles = append(staticRoles, roles)
|
||||
}
|
||||
|
||||
for _, role := range staticRoles {
|
||||
entry, err := logical.StorageEntryJSON(formatRoleStoragePath(role.Name), role)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create storage entry for %s: %v", role.Name, err)
|
||||
}
|
||||
err = config.StorageView.Put(bgCTX, entry)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to store role %s: %v", role.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
b := Backend(config)
|
||||
resp, err := b.HandleRequest(bgCTX, &logical.Request{
|
||||
Operation: logical.ListOperation,
|
||||
Path: "static-roles",
|
||||
Storage: config.StorageView,
|
||||
})
|
||||
if err != nil || (resp != nil && resp.IsError()) {
|
||||
t.Fatalf("bad: listing roles failed. resp:%#v\n err:%v", resp, err)
|
||||
}
|
||||
|
||||
if len(resp.Data["keys"].([]string)) != 10 {
|
||||
t.Fatalf("failed to list all 10 roles")
|
||||
}
|
||||
|
||||
resp, err = b.HandleRequest(bgCTX, &logical.Request{
|
||||
Operation: logical.ListOperation,
|
||||
Path: "static-roles/",
|
||||
Storage: config.StorageView,
|
||||
})
|
||||
if err != nil || (resp != nil && resp.IsError()) {
|
||||
t.Fatalf("bad: listing roles failed. resp:%#v\n err:%v", resp, err)
|
||||
}
|
||||
|
||||
if len(resp.Data["keys"].([]string)) != 10 {
|
||||
t.Fatalf("failed to list all 10 roles")
|
||||
}
|
||||
}
|
||||
|
||||
func staticRoleFieldData(data map[string]interface{}) *framework.FieldData {
|
||||
schema := map[string]*framework.FieldSchema{
|
||||
paramRoleName: {
|
||||
|
|
|
|||
3
changelog/29842.txt
Normal file
3
changelog/29842.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
secrets/aws: Add LIST endpoint to the AWS secrets engine static roles.
|
||||
```
|
||||
|
|
@ -777,6 +777,33 @@ $ curl \
|
|||
}
|
||||
```
|
||||
|
||||
## List static roles
|
||||
|
||||
Use the list static roles endpoint to fetch all existing static roles in the secrets engine.
|
||||
|
||||
| Method | Path |
|
||||
| :----- | :------------------ |
|
||||
| `LIST` | `/aws/static-roles` |
|
||||
|
||||
### Sample request
|
||||
|
||||
```shell-session
|
||||
$ curl
|
||||
--header "X-Vault-Token: ..." \
|
||||
--request LIST \
|
||||
http://127.0.0.1:8200/v1/aws/static-roles
|
||||
```
|
||||
|
||||
### Sample response
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"keys": ["example-role"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Delete static role
|
||||
|
||||
This endpoint deletes the static role definition. The user, having been defined externally,
|
||||
|
|
|
|||
Loading…
Reference in a new issue