250 lines
5.3 KiB
Go
250 lines
5.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/influxdata/influxdb/v2"
|
|
"github.com/influxdata/influxdb/v2/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, f, opt)
|
|
return builder.cmd()
|
|
}
|
|
|
|
type cmdSecretBuilder struct {
|
|
genericCLIOpts
|
|
*globalFlags
|
|
|
|
svcFn secretSVCsFn
|
|
|
|
json bool
|
|
hideHeaders bool
|
|
key string
|
|
value string
|
|
org organization
|
|
}
|
|
|
|
func newCmdSecretBuilder(svcsFn secretSVCsFn, f *globalFlags, opt genericCLIOpts) *cmdSecretBuilder {
|
|
return &cmdSecretBuilder{
|
|
genericCLIOpts: opt,
|
|
globalFlags: f,
|
|
svcFn: svcsFn,
|
|
}
|
|
}
|
|
|
|
func (b *cmdSecretBuilder) cmd() *cobra.Command {
|
|
cmd := b.genericCLIOpts.newCmd("secret", nil, false)
|
|
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)
|
|
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")
|
|
cmd.MarkFlagRequired("key")
|
|
b.org.register(cmd, false)
|
|
b.registerPrintFlags(cmd)
|
|
|
|
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
|
|
if b.value != "" {
|
|
secretVal = b.value
|
|
} else {
|
|
secretVal = getSecretFn(ui)
|
|
}
|
|
|
|
err = scrSVC.PatchSecrets(ctx, orgID, map[string]string{
|
|
b.key: secretVal,
|
|
})
|
|
if err != nil {
|
|
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,
|
|
},
|
|
})
|
|
}
|
|
|
|
func (b *cmdSecretBuilder) cmdDelete() *cobra.Command {
|
|
cmd := b.newCmd("delete", b.cmdDeleteRunEFn)
|
|
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
|
|
}
|
|
|
|
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,
|
|
},
|
|
})
|
|
}
|
|
|
|
func (b *cmdSecretBuilder) cmdFind() *cobra.Command {
|
|
cmd := b.newCmd("list", b.cmdFindRunEFn)
|
|
cmd.Short = "List secrets"
|
|
cmd.Aliases = []string{"find", "ls"}
|
|
|
|
b.org.register(cmd, false)
|
|
b.registerPrintFlags(cmd)
|
|
|
|
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)
|
|
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,
|
|
})
|
|
}
|
|
|
|
return b.printSecrets(secretPrintOpt{
|
|
secrets: secrets,
|
|
})
|
|
}
|
|
|
|
func (b *cmdSecretBuilder) newCmd(use string, runE func(*cobra.Command, []string) error) *cobra.Command {
|
|
cmd := b.genericCLIOpts.newCmd(use, runE, true)
|
|
b.globalFlags.registerFlags(cmd)
|
|
return cmd
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type (
|
|
secretPrintOpt struct {
|
|
deleted bool
|
|
secret secret
|
|
secrets []secret
|
|
}
|
|
|
|
secret struct {
|
|
key string
|
|
orgID influxdb.ID
|
|
}
|
|
)
|
|
|
|
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
|
|
}
|