diff --git a/command/commands.go b/command/commands.go index 81d70674ad..5e5dba90cf 100644 --- a/command/commands.go +++ b/command/commands.go @@ -296,6 +296,16 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) { BaseCommand: getBaseCommand(), }, nil }, + "license": func() (cli.Command, error) { + return &LicenseCommand{ + BaseCommand: getBaseCommand(), + }, nil + }, + "license get": func() (cli.Command, error) { + return &LicenseGetCommand{ + BaseCommand: getBaseCommand(), + }, nil + }, "list": func() (cli.Command, error) { return &ListCommand{ BaseCommand: getBaseCommand(), diff --git a/command/license.go b/command/license.go new file mode 100644 index 0000000000..95c021be46 --- /dev/null +++ b/command/license.go @@ -0,0 +1,37 @@ +package command + +import ( + "strings" + + "github.com/mitchellh/cli" +) + +var _ cli.Command = (*LicenseCommand)(nil) + +type LicenseCommand struct { + *BaseCommand +} + +func (c *LicenseCommand) Synopsis() string { + return "Interact with licenses" +} + +func (c *LicenseCommand) Help() string { + helpText := ` +Usage: vault license [options] [args] + + This command groups subcommands for interacting with Vault licenses. + + Get the current Vault license: + + $ vault license get + + Please see the individual subcommand help for detailed usage information. +` + + return strings.TrimSpace(helpText) +} + +func (c *LicenseCommand) Run(args []string) int { + return cli.RunResultHelp +} diff --git a/command/license_get.go b/command/license_get.go new file mode 100644 index 0000000000..147c751964 --- /dev/null +++ b/command/license_get.go @@ -0,0 +1,108 @@ +package command + +import ( + "fmt" + "strconv" + "strings" + + "github.com/mitchellh/cli" + "github.com/posener/complete" +) + +var ( + _ cli.Command = (*LicenseGetCommand)(nil) + _ cli.CommandAutocomplete = (*LicenseGetCommand)(nil) +) + +type LicenseGetCommand struct { + *BaseCommand + + signed bool +} + +func (c *LicenseGetCommand) Synopsis() string { + return "Get an existing license" +} + +func (c *LicenseGetCommand) Help() string { + helpText := ` +Usage: vault license get [options] + + Get the currently installed license, if any: + + $ vault license get + + Get the currently installed license, if any, and output its contents as a signed blob: + + $ vault license get -signed + +` + c.Flags().Help() + + return strings.TrimSpace(helpText) +} + +func (c *LicenseGetCommand) Flags() *FlagSets { + set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat) + + f := set.NewFlagSet("License Options") + f.BoolVar(&BoolVar{ + Name: "signed", + Target: &c.signed, + Usage: "Whether to return a signed blob from the API.", + }) + + return set +} + +func (c *LicenseGetCommand) AutocompleteArgs() complete.Predictor { + return complete.PredictNothing +} + +func (c *LicenseGetCommand) AutocompleteFlags() complete.Flags { + return c.Flags().Completions() +} + +func (c *LicenseGetCommand) Run(args []string) int { + f := c.Flags() + + if err := f.Parse(args); err != nil { + c.UI.Error(err.Error()) + return 1 + } + + args = f.Args() + if len(args) > 0 { + c.UI.Error(fmt.Sprintf("Too many arguments (expected 0, got %d)", len(args))) + return 1 + } + + client, err := c.Client() + if err != nil { + c.UI.Error(err.Error()) + return 2 + } + + secret, err := client.Logical().ReadWithData("sys/license", map[string][]string{"signed": {strconv.FormatBool(c.signed)}}) + if err != nil { + c.UI.Error(fmt.Sprintf("Error retrieving license: %s", err)) + return 2 + } + + if secret == nil { + c.UI.Error("License not found") + return 2 + } + + if c.signed { + blob := secret.Data["signed"].(string) + if blob == "" { + c.UI.Output("License not found or using a temporary license.") + return 2 + } else { + c.UI.Output(blob) + return 0 + } + } else { + return OutputSecret(c.UI, secret) + } +}