2020-02-06 19:58:58 +00:00
package main
import (
"context"
"fmt"
2020-04-03 17:39:20 +00:00
"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/http"
2020-02-06 19:58:58 +00:00
"github.com/spf13/cobra"
input "github.com/tcnksm/go-input"
)
type secretSVCsFn func ( ) ( influxdb . SecretService , influxdb . OrganizationService , func ( * input . UI ) string , error )
2020-02-19 20:43:06 +00:00
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
2020-02-19 20:43:06 +00:00
* globalFlags
2020-02-06 19:58:58 +00:00
svcFn secretSVCsFn
2020-03-27 17:31:26 +00:00
json bool
hideHeaders bool
key string
value string
org organization
2020-02-06 19:58:58 +00:00
}
2020-02-19 20:43:06 +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 {
2020-03-25 18:54:49 +00:00
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 {
2020-03-25 18:54:49 +00:00
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)" )
2020-03-27 17:31:26 +00:00
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 )
2020-03-27 17:31:26 +00:00
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 ,
}
2020-03-27 17:31:26 +00:00
var secretVal string
2020-02-21 15:06:07 +00:00
if b . value != "" {
2020-03-27 17:31:26 +00:00
secretVal = b . value
2020-02-21 15:06:07 +00:00
} else {
2020-03-27 17:31:26 +00:00
secretVal = getSecretFn ( ui )
2020-02-21 15:06:07 +00:00
}
2020-02-06 19:58:58 +00:00
2020-03-27 17:31:26 +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 )
}
2020-03-27 17:31:26 +00:00
return b . printSecrets ( secretPrintOpt {
secret : secret {
key : b . key ,
orgID : orgID ,
} ,
2020-02-06 19:58:58 +00:00
} )
2020-03-27 17:31:26 +00:00
}
2020-02-06 19:58:58 +00:00
2020-03-27 17:31:26 +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 )
}
2020-03-27 17:31:26 +00:00
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 {
2020-03-25 18:54:49 +00:00
cmd := b . newCmd ( "list" , b . cmdFindRunEFn , true )
2020-03-04 23:39:04 +00:00
cmd . Short = "List secrets"
cmd . Aliases = [ ] string { "find" , "ls" }
2020-03-27 17:31:26 +00:00
2020-02-06 19:58:58 +00:00
b . org . register ( cmd , false )
2020-03-27 17:31:26 +00:00
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
}
2020-03-27 17:31:26 +00:00
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 )
}
2020-03-27 17:31:26 +00:00
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
} )
}
2020-03-27 17:31:26 +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
}
2020-03-27 17:31:26 +00:00
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
}