vault/builtin/logical/nomad/path_creds_create.go
hashicorp-copywrite[bot] 0b12cdcfd1
[COMPLIANCE] License changes (#22290)
* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package.

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License.

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUS-1.1

* Fix test that expected exact offset on hcl file

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
Co-authored-by: Sarah Thompson <sthompson@hashicorp.com>
Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
2023-08-10 18:14:03 -07:00

108 lines
2.7 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package nomad
import (
"context"
"fmt"
"time"
"github.com/hashicorp/nomad/api"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
// maxTokenNameLength is the maximum length for the name of a Nomad access
// token
const maxTokenNameLength = 256
func pathCredsCreate(b *backend) *framework.Path {
return &framework.Path{
Pattern: "creds/" + framework.GenericNameRegex("name"),
DisplayAttrs: &framework.DisplayAttributes{
OperationPrefix: operationPrefixNomad,
OperationVerb: "generate",
OperationSuffix: "credentials",
},
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeString,
Description: "Name of the role",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathTokenRead,
},
}
}
func (b *backend) pathTokenRead(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("name").(string)
conf, _ := b.readConfigAccess(ctx, req.Storage)
// establish a default
tokenNameLength := maxTokenNameLength
if conf != nil && conf.MaxTokenNameLength > 0 {
tokenNameLength = conf.MaxTokenNameLength
}
role, err := b.Role(ctx, req.Storage, name)
if err != nil {
return nil, fmt.Errorf("error retrieving role: %w", err)
}
if role == nil {
return logical.ErrorResponse(fmt.Sprintf("role %q not found", name)), nil
}
// Determine if we have a lease configuration
leaseConfig, err := b.LeaseConfig(ctx, req.Storage)
if err != nil {
return nil, err
}
if leaseConfig == nil {
leaseConfig = &configLease{}
}
// Get the nomad client
c, err := b.client(ctx, req.Storage)
if err != nil {
return nil, err
}
// Generate a name for the token
tokenName := fmt.Sprintf("vault-%s-%s-%d", name, req.DisplayName, time.Now().UnixNano())
// Note: if the given role name is sufficiently long, the UnixNano() portion
// of the pseudo randomized token name is the part that gets trimmed off,
// weakening it's randomness.
if len(tokenName) > tokenNameLength {
tokenName = tokenName[:tokenNameLength]
}
// Create it
token, _, err := c.ACLTokens().Create(&api.ACLToken{
Name: tokenName,
Type: role.TokenType,
Policies: role.Policies,
Global: role.Global,
}, nil)
if err != nil {
return nil, err
}
// Use the helper to create the secret
resp := b.Secret(SecretTokenType).Response(map[string]interface{}{
"secret_id": token.SecretID,
"accessor_id": token.AccessorID,
}, map[string]interface{}{
"accessor_id": token.AccessorID,
})
resp.Secret.TTL = leaseConfig.TTL
resp.Secret.MaxTTL = leaseConfig.MaxTTL
return resp, nil
}