open-vault/command/token_create.go

263 lines
7.4 KiB
Go
Raw Normal View History

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
2015-04-07 21:20:18 +00:00
package command
import (
"fmt"
"strings"
2017-09-05 04:04:54 +00:00
"time"
2015-04-07 21:20:18 +00:00
"github.com/hashicorp/vault/api"
2017-09-05 04:04:54 +00:00
"github.com/mitchellh/cli"
"github.com/posener/complete"
2015-04-07 21:20:18 +00:00
)
var (
_ cli.Command = (*TokenCreateCommand)(nil)
_ cli.CommandAutocomplete = (*TokenCreateCommand)(nil)
)
2017-09-05 04:04:54 +00:00
2015-04-07 21:20:18 +00:00
type TokenCreateCommand struct {
2017-09-05 04:04:54 +00:00
*BaseCommand
flagID string
flagDisplayName string
flagTTL time.Duration
flagExplicitMaxTTL time.Duration
flagPeriod time.Duration
flagRenewable bool
flagOrphan bool
flagNoDefaultPolicy bool
flagUseLimit int
flagRole string
2018-10-15 16:56:24 +00:00
flagType string
2017-09-05 04:04:54 +00:00
flagMetadata map[string]string
flagPolicies []string
flagEntityAlias string
2015-04-07 21:20:18 +00:00
}
func (c *TokenCreateCommand) Synopsis() string {
2017-09-08 01:58:13 +00:00
return "Create a new token"
2015-04-07 21:20:18 +00:00
}
func (c *TokenCreateCommand) Help() string {
helpText := `
2017-09-08 01:58:13 +00:00
Usage: vault token create [options]
2015-04-07 21:20:18 +00:00
2017-09-05 04:04:54 +00:00
Creates a new token that can be used for authentication. This token will be
created as a child of the currently authenticated token. The generated token
will inherit all policies and permissions of the currently authenticated
token unless you explicitly define a subset list policies to assign to the
token.
2015-04-07 21:20:18 +00:00
2017-09-05 04:04:54 +00:00
A ttl can also be associated with the token. If a ttl is not associated
with the token, then it cannot be renewed. If a ttl is associated with
2015-09-12 01:08:32 +00:00
the token, it will expire after that amount of time unless it is renewed.
2015-04-07 21:20:18 +00:00
2017-09-05 04:04:54 +00:00
Metadata associated with the token (specified with "-metadata") is written
to the audit log when the token is used.
2015-04-07 21:20:18 +00:00
If a role is specified, the role may override parameters specified here.
2017-09-05 04:04:54 +00:00
` + c.Flags().Help()
2015-04-07 21:20:18 +00:00
2017-09-05 04:04:54 +00:00
return strings.TrimSpace(helpText)
}
2017-09-05 04:04:54 +00:00
func (c *TokenCreateCommand) Flags() *FlagSets {
set := c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat)
f := set.NewFlagSet("Command Options")
f.StringVar(&StringVar{
Name: "id",
Target: &c.flagID,
Completion: complete.PredictAnything,
Usage: "Value for the token. By default, this is an auto-generated " +
"string. Specifying this value requires sudo permissions.",
2017-09-05 04:04:54 +00:00
})
f.StringVar(&StringVar{
Name: "display-name",
Target: &c.flagDisplayName,
Completion: complete.PredictAnything,
Usage: "Name to associate with this token. This is a non-sensitive value " +
"that can be used to help identify created secrets (e.g. prefixes).",
})
f.DurationVar(&DurationVar{
Name: "ttl",
Target: &c.flagTTL,
Completion: complete.PredictAnything,
Usage: "Initial TTL to associate with the token. Token renewals may be " +
"able to extend beyond this value, depending on the configured maximum " +
2017-09-05 04:04:54 +00:00
"TTLs. This is specified as a numeric string with suffix like \"30s\" " +
"or \"5m\".",
})
f.DurationVar(&DurationVar{
Name: "explicit-max-ttl",
Target: &c.flagExplicitMaxTTL,
Completion: complete.PredictAnything,
Usage: "Explicit maximum lifetime for the token. Unlike normal TTLs, the " +
"maximum TTL is a hard limit and cannot be exceeded. This is specified " +
"as a numeric string with suffix like \"30s\" or \"5m\".",
})
f.DurationVar(&DurationVar{
Name: "period",
Target: &c.flagPeriod,
Completion: complete.PredictAnything,
Usage: "If specified, every renewal will use the given period. Periodic " +
"tokens do not expire (unless -explicit-max-ttl is also provided). " +
"Setting this value requires sudo permissions. This is specified as a " +
"numeric string with suffix like \"30s\" or \"5m\".",
})
f.BoolVar(&BoolVar{
Name: "renewable",
Target: &c.flagRenewable,
Default: true,
Usage: "Allow the token to be renewed up to it's maximum TTL.",
})
f.BoolVar(&BoolVar{
Name: "orphan",
Target: &c.flagOrphan,
Default: false,
Usage: "Create the token with no parent. This prevents the token from " +
"being revoked when the token which created it expires. Setting this " +
2020-04-13 17:03:05 +00:00
"value requires root or sudo permissions.",
2017-09-05 04:04:54 +00:00
})
f.BoolVar(&BoolVar{
Name: "no-default-policy",
Target: &c.flagNoDefaultPolicy,
Default: false,
Usage: "Detach the \"default\" policy from the policy set for this " +
"token.",
})
f.IntVar(&IntVar{
Name: "use-limit",
Target: &c.flagUseLimit,
Default: 0,
Usage: "Number of times this token can be used. After the last use, the " +
"token is automatically revoked. By default, tokens can be used an " +
"unlimited number of times until their expiration.",
})
f.StringVar(&StringVar{
Name: "role",
Target: &c.flagRole,
Default: "",
Usage: "Name of the role to create the token against. Specifying -role " +
"may override other arguments. The locally authenticated Vault token " +
"must have permission for \"auth/token/create/<role>\".",
})
2018-10-15 16:56:24 +00:00
f.StringVar(&StringVar{
Name: "type",
Target: &c.flagType,
Default: "service",
Usage: `The type of token to create. Can be "service" or "batch".`,
})
2017-09-05 04:04:54 +00:00
f.StringMapVar(&StringMapVar{
Name: "metadata",
Target: &c.flagMetadata,
Completion: complete.PredictAnything,
2017-09-08 01:58:13 +00:00
Usage: "Arbitrary key=value metadata to associate with the token. " +
2017-09-05 04:04:54 +00:00
"This metadata will show in the audit log when the token is used. " +
"This can be specified multiple times to add multiple pieces of " +
"metadata.",
})
f.StringSliceVar(&StringSliceVar{
Name: "policy",
Target: &c.flagPolicies,
Completion: c.PredictVaultPolicies(),
Usage: "Name of a policy to associate with this token. This can be " +
"specified multiple times to attach multiple policies.",
})
f.StringVar(&StringVar{
Name: "entity-alias",
Target: &c.flagEntityAlias,
Default: "",
Usage: "Name of the entity alias to associate with during token creation. " +
"Only works in combination with -role argument and used entity alias " +
"must be listed in allowed_entity_aliases. If this has been specified, " +
"the entity will not be inherited from the parent.",
})
2017-09-05 04:04:54 +00:00
return set
}
2017-09-05 04:04:54 +00:00
func (c *TokenCreateCommand) AutocompleteArgs() complete.Predictor {
return nil
}
2015-04-07 21:20:18 +00:00
2017-09-05 04:04:54 +00:00
func (c *TokenCreateCommand) AutocompleteFlags() complete.Flags {
return c.Flags().Completions()
}
2017-09-05 04:04:54 +00:00
func (c *TokenCreateCommand) Run(args []string) int {
f := c.Flags()
2017-09-05 04:04:54 +00:00
if err := f.Parse(args); err != nil {
c.UI.Error(err.Error())
return 1
}
2017-09-05 04:04:54 +00:00
args = f.Args()
if len(args) > 0 {
c.UI.Error(fmt.Sprintf("Too many arguments (expected 0, got %d)", len(args)))
return 1
}
2015-04-07 21:20:18 +00:00
2018-10-15 16:56:24 +00:00
if c.flagType == "batch" {
c.flagRenewable = false
}
2017-09-05 04:04:54 +00:00
client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
return 2
}
2017-09-05 04:04:54 +00:00
tcr := &api.TokenCreateRequest{
ID: c.flagID,
Policies: c.flagPolicies,
Metadata: c.flagMetadata,
TTL: c.flagTTL.String(),
NoParent: c.flagOrphan,
NoDefaultPolicy: c.flagNoDefaultPolicy,
DisplayName: c.flagDisplayName,
NumUses: c.flagUseLimit,
Renewable: &c.flagRenewable,
ExplicitMaxTTL: c.flagExplicitMaxTTL.String(),
Period: c.flagPeriod.String(),
2018-10-15 16:56:24 +00:00
Type: c.flagType,
EntityAlias: c.flagEntityAlias,
2017-09-05 04:04:54 +00:00
}
2015-04-07 21:20:18 +00:00
2017-09-05 04:04:54 +00:00
var secret *api.Secret
if c.flagRole != "" {
secret, err = client.Auth().Token().CreateWithRole(tcr, c.flagRole)
} else {
secret, err = client.Auth().Token().Create(tcr)
}
if err != nil {
c.UI.Error(fmt.Sprintf("Error creating token: %s", err))
return 2
}
2017-09-05 04:04:54 +00:00
if c.flagField != "" {
return PrintRawField(c.UI, secret, c.flagField)
}
CLI Enhancements (#3897) * Use Colored UI if stdout is a tty * Add format options to operator unseal * Add format test on operator unseal * Add -no-color output flag, and use BasicUi if no-color flag is provided * Move seal status formatting logic to OutputSealStatus * Apply no-color to warnings from DeprecatedCommands as well * Add OutputWithFormat to support arbitrary data, add format option to auth list * Add ability to output arbitrary list data on TableFormatter * Clear up switch logic on format * Add format option for list-related commands * Add format option to rest of commands that returns a client API response * Remove initOutputYAML and initOutputJSON, and use OutputWithFormat instead * Remove outputAsYAML and outputAsJSON, and use OutputWithFormat instead * Remove -no-color flag, use env var exclusively to toggle colored output * Fix compile * Remove -no-color flag in main.go * Add missing FlagSetOutputFormat * Fix generate-root/decode test * Migrate init functions to main.go * Add no-color flag back as hidden * Handle non-supported data types for TableFormatter.OutputList * Pull formatting much further up to remove the need to use c.flagFormat (#3950) * Pull formatting much further up to remove the need to use c.flagFormat Also remove OutputWithFormat as the logic can cause issues. * Use const for env var * Minor updates * Remove unnecessary check * Fix SSH output and some tests * Fix tests * Make race detector not run on generate root since it kills Travis these days * Update docs * Update docs * Address review feedback * Handle --format as well as -format
2018-02-12 23:12:16 +00:00
return OutputSecret(c.UI, secret)
2015-04-07 21:20:18 +00:00
}