influxdb/cmd/influx/secret.go

244 lines
5.1 KiB
Go
Raw Normal View History

2020-02-06 19:58:58 +00:00
package main
import (
"context"
"fmt"
"github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/http"
"github.com/spf13/cobra"
input "github.com/tcnksm/go-input"
)
type secretSVCsFn func() (influxdb.SecretService, influxdb.OrganizationService, func(*input.UI) string, error)
func cmdSecret(f *globalFlags, opt genericCLIOpts) *cobra.Command {
builder := newCmdSecretBuilder(newSecretSVCs, opt)
builder.globalFlags = f
return builder.cmd()
2020-02-06 19:58:58 +00:00
}
type cmdSecretBuilder struct {
genericCLIOpts
*globalFlags
2020-02-06 19:58:58 +00:00
svcFn secretSVCsFn
json bool
hideHeaders bool
key string
value string
org organization
2020-02-06 19:58:58 +00:00
}
func newCmdSecretBuilder(svcsFn secretSVCsFn, opt genericCLIOpts) *cmdSecretBuilder {
2020-02-06 19:58:58 +00:00
return &cmdSecretBuilder{
genericCLIOpts: opt,
svcFn: svcsFn,
}
}
func (b *cmdSecretBuilder) cmd() *cobra.Command {
cmd := b.newCmd("secret", nil, false)
2020-02-06 19:58:58 +00:00
cmd.Short = "Secret management commands"
cmd.Run = seeHelp
cmd.AddCommand(
b.cmdDelete(),
b.cmdFind(),
b.cmdUpdate(),
)
return cmd
}
func (b *cmdSecretBuilder) cmdUpdate() *cobra.Command {
cmd := b.newCmd("update", b.cmdUpdateRunEFn, true)
2020-02-06 19:58:58 +00:00
cmd.Short = "Update secret"
cmd.Flags().StringVarP(&b.key, "key", "k", "", "The secret key (required)")
cmd.Flags().StringVarP(&b.value, "value", "v", "", "Optional secret value for scripting convenience, using this might expose the secret to your local history")
2020-02-06 19:58:58 +00:00
cmd.MarkFlagRequired("key")
b.org.register(cmd, false)
b.registerPrintFlags(cmd)
2020-02-06 19:58:58 +00:00
return cmd
}
func (b *cmdSecretBuilder) cmdUpdateRunEFn(cmd *cobra.Command, args []string) error {
scrSVC, orgSVC, getSecretFn, err := b.svcFn()
if err != nil {
return err
}
orgID, err := b.org.getID(orgSVC)
if err != nil {
return err
}
ctx := context.Background()
ui := &input.UI{
Writer: b.genericCLIOpts.w,
Reader: b.genericCLIOpts.in,
}
var secretVal string
2020-02-21 15:06:07 +00:00
if b.value != "" {
secretVal = b.value
2020-02-21 15:06:07 +00:00
} else {
secretVal = getSecretFn(ui)
2020-02-21 15:06:07 +00:00
}
2020-02-06 19:58:58 +00:00
err = scrSVC.PatchSecrets(ctx, orgID, map[string]string{
b.key: secretVal,
})
if err != nil {
2020-02-06 19:58:58 +00:00
return fmt.Errorf("failed to update secret with key %q: %v", b.key, err)
}
return b.printSecrets(secretPrintOpt{
secret: secret{
key: b.key,
orgID: orgID,
},
2020-02-06 19:58:58 +00:00
})
}
2020-02-06 19:58:58 +00:00
func (b *cmdSecretBuilder) cmdDelete() *cobra.Command {
cmd := b.newCmd("delete", b.cmdDeleteRunEFn, true)
cmd.Short = "Delete secret"
cmd.Flags().StringVarP(&b.key, "key", "k", "", "The secret key (required)")
cmd.MarkFlagRequired("key")
b.org.register(cmd, false)
b.registerPrintFlags(cmd)
return cmd
2020-02-06 19:58:58 +00:00
}
func (b *cmdSecretBuilder) cmdDeleteRunEFn(cmd *cobra.Command, args []string) error {
scrSVC, orgSVC, _, err := b.svcFn()
if err != nil {
return err
}
orgID, err := b.org.getID(orgSVC)
if err != nil {
return err
}
ctx := context.Background()
if err := scrSVC.DeleteSecret(ctx, orgID, b.key); err != nil {
return fmt.Errorf("failed to delete secret with key %q: %v", b.key, err)
}
return b.printSecrets(secretPrintOpt{
deleted: true,
secret: secret{
key: b.key,
orgID: orgID,
},
2020-02-06 19:58:58 +00:00
})
}
func (b *cmdSecretBuilder) cmdFind() *cobra.Command {
cmd := b.newCmd("list", b.cmdFindRunEFn, true)
cmd.Short = "List secrets"
cmd.Aliases = []string{"find", "ls"}
2020-02-06 19:58:58 +00:00
b.org.register(cmd, false)
b.registerPrintFlags(cmd)
2020-02-06 19:58:58 +00:00
return cmd
}
func (b *cmdSecretBuilder) cmdFindRunEFn(cmd *cobra.Command, args []string) error {
scrSVC, orgSVC, _, err := b.svcFn()
if err != nil {
return err
}
orgID, err := b.org.getID(orgSVC)
if err != nil {
return err
}
platformSecrets, err := scrSVC.GetSecretKeys(context.Background(), orgID)
2020-02-06 19:58:58 +00:00
if err != nil {
return fmt.Errorf("failed to retrieve secret keys: %s", err)
}
secrets := make([]secret, 0, len(platformSecrets))
for _, key := range platformSecrets {
secrets = append(secrets, secret{
key: key,
orgID: orgID,
2020-02-06 19:58:58 +00:00
})
}
return b.printSecrets(secretPrintOpt{
secrets: secrets,
})
}
func (b *cmdSecretBuilder) registerPrintFlags(cmd *cobra.Command) {
registerPrintOptions(cmd, &b.hideHeaders, &b.json)
}
func (b *cmdSecretBuilder) printSecrets(opt secretPrintOpt) error {
if b.json {
var v interface{} = opt.secrets
if opt.secrets == nil {
v = opt.secret
}
return b.writeJSON(v)
}
w := b.newTabWriter()
defer w.Flush()
w.HideHeaders(b.hideHeaders)
headers := []string{"Key", "Organization ID"}
if opt.deleted {
headers = append(headers, "Deleted")
}
w.WriteHeaders(headers...)
if opt.secrets == nil {
opt.secrets = append(opt.secrets, opt.secret)
}
for _, s := range opt.secrets {
m := map[string]interface{}{
"Key": s.key,
"Organization ID": s.orgID.String(),
}
if opt.deleted {
m["Deleted"] = true
}
w.Write(m)
}
2020-02-06 19:58:58 +00:00
return nil
}
type (
secretPrintOpt struct {
deleted bool
secret secret
secrets []secret
}
secret struct {
key string
orgID influxdb.ID
}
)
2020-02-06 19:58:58 +00:00
func newSecretSVCs() (influxdb.SecretService, influxdb.OrganizationService, func(*input.UI) string, error) {
httpClient, err := newHTTPClient()
if err != nil {
return nil, nil, nil, err
}
orgSvc := &http.OrganizationService{Client: httpClient}
return &http.SecretService{Client: httpClient}, orgSvc, getSecret, nil
}