Merge pull request #16961 from influxdata/cli_secret_ui
fix(cmd/influx): ui change for secretpull/17039/head
commit
6387ecc9f4
|
@ -16,6 +16,7 @@
|
||||||
1. [16992](https://github.com/influxdata/influxdb/pull/16992): Query Builder now groups on column values, not tag values
|
1. [16992](https://github.com/influxdata/influxdb/pull/16992): Query Builder now groups on column values, not tag values
|
||||||
1. [17013](https://github.com/influxdata/influxdb/pull/17013): Scatterplots can once again render the tooltip correctly
|
1. [17013](https://github.com/influxdata/influxdb/pull/17013): Scatterplots can once again render the tooltip correctly
|
||||||
1. [17027](https://github.com/influxdata/influxdb/pull/17027): Drop pkger gauge chart requirement for color threshold type
|
1. [17027](https://github.com/influxdata/influxdb/pull/17027): Drop pkger gauge chart requirement for color threshold type
|
||||||
|
1. [16961](https://github.com/influxdata/influxdb/pull/16961): Remove cli confirmation of secret, add an optional parameter of secret value
|
||||||
|
|
||||||
## v2.0.0-beta.4 [2020-02-14]
|
## v2.0.0-beta.4 [2020-02-14]
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,9 @@ type cmdSecretBuilder struct {
|
||||||
|
|
||||||
svcFn secretSVCsFn
|
svcFn secretSVCsFn
|
||||||
|
|
||||||
key string
|
key string
|
||||||
org organization
|
value string
|
||||||
|
org organization
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCmdSecretBuilder(svcsFn secretSVCsFn, opt genericCLIOpts) *cmdSecretBuilder {
|
func newCmdSecretBuilder(svcsFn secretSVCsFn, opt genericCLIOpts) *cmdSecretBuilder {
|
||||||
|
@ -51,6 +52,7 @@ func (b *cmdSecretBuilder) cmdUpdate() *cobra.Command {
|
||||||
cmd := b.newCmd("update", b.cmdUpdateRunEFn)
|
cmd := b.newCmd("update", b.cmdUpdateRunEFn)
|
||||||
cmd.Short = "Update secret"
|
cmd.Short = "Update secret"
|
||||||
cmd.Flags().StringVarP(&b.key, "key", "k", "", "The secret key (required)")
|
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 exposed the secret to your local history")
|
||||||
cmd.MarkFlagRequired("key")
|
cmd.MarkFlagRequired("key")
|
||||||
b.org.register(cmd, false)
|
b.org.register(cmd, false)
|
||||||
|
|
||||||
|
@ -84,7 +86,12 @@ func (b *cmdSecretBuilder) cmdUpdateRunEFn(cmd *cobra.Command, args []string) er
|
||||||
Writer: b.genericCLIOpts.w,
|
Writer: b.genericCLIOpts.w,
|
||||||
Reader: b.genericCLIOpts.in,
|
Reader: b.genericCLIOpts.in,
|
||||||
}
|
}
|
||||||
secret := getSecretFn(ui)
|
var secret string
|
||||||
|
if b.value != "" {
|
||||||
|
secret = b.value
|
||||||
|
} else {
|
||||||
|
secret = getSecretFn(ui)
|
||||||
|
}
|
||||||
|
|
||||||
if err := scrSVC.PatchSecrets(ctx, orgID, map[string]string{b.key: secret}); err != nil {
|
if err := scrSVC.PatchSecrets(ctx, orgID, map[string]string{b.key: secret}); err != nil {
|
||||||
return fmt.Errorf("failed to update secret with key %q: %v", b.key, err)
|
return fmt.Errorf("failed to update secret with key %q: %v", b.key, err)
|
||||||
|
|
|
@ -159,11 +159,23 @@ func TestCmdSecret(t *testing.T) {
|
||||||
"--org=org name", "--key=key1",
|
"--org=org name", "--key=key1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "with key and value",
|
||||||
|
expectedKey: "key1",
|
||||||
|
flags: []string{
|
||||||
|
"--org=org name", "--key=key1", "--value=v1",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "shorts",
|
name: "shorts",
|
||||||
expectedKey: "key1",
|
expectedKey: "key1",
|
||||||
flags: []string{"-o=" + orgID.String(), "-k=key1"},
|
flags: []string{"-o=" + orgID.String(), "-k=key1"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "shorts with value",
|
||||||
|
expectedKey: "key1",
|
||||||
|
flags: []string{"-o=" + orgID.String(), "-k=key1", "-v=v1"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdFn := func(expectedKey string) func(*globalFlags, genericCLIOpts) *cobra.Command {
|
cmdFn := func(expectedKey string) func(*globalFlags, genericCLIOpts) *cobra.Command {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/influxdata/influxdb"
|
|
||||||
platform "github.com/influxdata/influxdb"
|
platform "github.com/influxdata/influxdb"
|
||||||
"github.com/influxdata/influxdb/cmd/influx/internal"
|
"github.com/influxdata/influxdb/cmd/influx/internal"
|
||||||
"github.com/influxdata/influxdb/http"
|
"github.com/influxdata/influxdb/http"
|
||||||
|
@ -234,42 +233,50 @@ You have entered:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func errSecretIsNotMatch(title string) error {
|
var errPasswordNotMatch = fmt.Errorf("passwords do not match")
|
||||||
return fmt.Errorf(title + "s do not match")
|
|
||||||
}
|
|
||||||
|
|
||||||
func errSecretIsTooShort(title string) error {
|
var errPasswordIsTooShort error = fmt.Errorf("password is too short")
|
||||||
return &influxdb.Error{
|
|
||||||
Code: influxdb.EUnprocessableEntity,
|
|
||||||
Msg: title + " is too short",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSecret(ui *input.UI) (secret string) {
|
func getSecret(ui *input.UI) (secret string) {
|
||||||
return getSecretInput(ui, false, "secret")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPassword(ui *input.UI, showNew bool) (password string) {
|
|
||||||
return getSecretInput(ui, showNew, "password")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getSecretInput(ui *input.UI, showNew bool, title string) (secret string) {
|
|
||||||
newStr := ""
|
|
||||||
if showNew {
|
|
||||||
newStr = " new"
|
|
||||||
}
|
|
||||||
var err error
|
var err error
|
||||||
enterSecret:
|
query := string(promptWithColor("Please type your secret", colorCyan))
|
||||||
query := string(promptWithColor("Please type your"+newStr+" "+title, colorCyan))
|
|
||||||
for {
|
for {
|
||||||
secret, err = ui.Ask(query, &input.Options{
|
secret, err = ui.Ask(query, &input.Options{
|
||||||
Required: true,
|
Required: true,
|
||||||
HideOrder: true,
|
HideOrder: true,
|
||||||
Hide: true,
|
Hide: true,
|
||||||
Mask: false,
|
Mask: false,
|
||||||
|
})
|
||||||
|
switch err {
|
||||||
|
case input.ErrInterrupted:
|
||||||
|
os.Exit(1)
|
||||||
|
default:
|
||||||
|
if secret = strings.TrimSpace(secret); secret == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return secret
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPassword(ui *input.UI, showNew bool) (password string) {
|
||||||
|
newStr := ""
|
||||||
|
if showNew {
|
||||||
|
newStr = " new"
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
enterPassword:
|
||||||
|
query := string(promptWithColor("Please type your"+newStr+" password", colorCyan))
|
||||||
|
for {
|
||||||
|
password, err = ui.Ask(query, &input.Options{
|
||||||
|
Required: true,
|
||||||
|
HideOrder: true,
|
||||||
|
Hide: true,
|
||||||
|
Mask: false,
|
||||||
ValidateFunc: func(s string) error {
|
ValidateFunc: func(s string) error {
|
||||||
if len(s) < 8 {
|
if len(s) < 8 {
|
||||||
return errSecretIsTooShort(title)
|
return errPasswordIsTooShort
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -277,25 +284,25 @@ enterSecret:
|
||||||
switch err {
|
switch err {
|
||||||
case input.ErrInterrupted:
|
case input.ErrInterrupted:
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
case errPasswordIsTooShort:
|
||||||
|
ui.Writer.Write(promptWithColor("Password too short - minimum length is 8 characters!\n\r", colorRed))
|
||||||
|
continue
|
||||||
default:
|
default:
|
||||||
if influxdb.ErrorCode(err) == influxdb.EUnprocessableEntity {
|
if password = strings.TrimSpace(password); password == "" {
|
||||||
ui.Writer.Write(promptWithColor(strings.ToTitle(title)+" too short - minimum length is 8 characters!\n\r", colorRed))
|
|
||||||
goto enterSecret
|
|
||||||
} else if secret = strings.TrimSpace(secret); secret == "" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
query = string(promptWithColor("Please type your"+newStr+" "+title+" again", colorCyan))
|
query = string(promptWithColor("Please type your"+newStr+" password again", colorCyan))
|
||||||
for {
|
for {
|
||||||
_, err = ui.Ask(query, &input.Options{
|
_, err = ui.Ask(query, &input.Options{
|
||||||
Required: true,
|
Required: true,
|
||||||
HideOrder: true,
|
HideOrder: true,
|
||||||
Hide: true,
|
Hide: true,
|
||||||
ValidateFunc: func(s string) error {
|
ValidateFunc: func(s string) error {
|
||||||
if s != secret {
|
if s != password {
|
||||||
return errSecretIsNotMatch(title)
|
return errPasswordNotMatch
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@ -306,12 +313,12 @@ enterSecret:
|
||||||
case nil:
|
case nil:
|
||||||
// Nothing.
|
// Nothing.
|
||||||
default:
|
default:
|
||||||
ui.Writer.Write(promptWithColor(strings.ToTitle(title)+"s do not match!\n", colorRed))
|
ui.Writer.Write(promptWithColor("Passwords do not match!\n", colorRed))
|
||||||
goto enterSecret
|
goto enterPassword
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return secret
|
return password
|
||||||
}
|
}
|
||||||
|
|
||||||
func getInput(ui *input.UI, prompt, defaultValue string) string {
|
func getInput(ui *input.UI, prompt, defaultValue string) string {
|
||||||
|
|
Loading…
Reference in New Issue