-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: don't assume bash when displaying interactive CLI prompts #21839
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,15 +4,12 @@ import ( | |
"context" | ||
"errors" | ||
"fmt" | ||
"math" | ||
"path/filepath" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/influxdata/influx-cli/v2/clients" | ||
"github.com/influxdata/influx-cli/v2/clients/setup" | ||
"github.com/influxdata/influx-cli/v2/config" | ||
"github.com/influxdata/influxdb/v2" | ||
"github.com/influxdata/influxdb/v2/cmd/internal" | ||
"github.com/tcnksm/go-input" | ||
"go.uber.org/zap" | ||
) | ||
|
||
|
@@ -25,81 +22,35 @@ func setupAdmin(ctx context.Context, v2 *influxDBv2, req *influxdb.OnboardingReq | |
return res, nil | ||
} | ||
|
||
func onboardingRequest(ui *input.UI, options *options) (*influxdb.OnboardingRequest, error) { | ||
if (options.force || len(options.target.password) > 0) && len(options.target.password) < internal.MinPasswordLen { | ||
return nil, internal.ErrPasswordIsTooShort | ||
} | ||
|
||
req := &influxdb.OnboardingRequest{ | ||
User: options.target.userName, | ||
Password: options.target.password, | ||
Org: options.target.orgName, | ||
Bucket: options.target.bucket, | ||
RetentionPeriodSeconds: influxdb.InfiniteRetention, | ||
Token: options.target.token, | ||
} | ||
|
||
if options.target.retention != "" { | ||
dur, err := internal.RawDurationToTimeDuration(options.target.retention) | ||
if err != nil { | ||
return nil, err | ||
} | ||
secs, nanos := math.Modf(dur.Seconds()) | ||
if nanos > 0 { | ||
return nil, fmt.Errorf("retention policy %q is too precise, must be divisible by 1s", options.target.retention) | ||
} | ||
req.RetentionPeriodSeconds = int64(secs) | ||
} | ||
|
||
if options.force { | ||
return req, nil | ||
} | ||
|
||
fmt.Fprintln(ui.Writer, string(internal.PromptWithColor("Welcome to InfluxDB 2.0!", internal.ColorYellow))) | ||
if req.User == "" { | ||
req.User = internal.GetInput(ui, "Please type your primary username", "") | ||
} | ||
if req.Password == "" { | ||
req.Password = internal.GetPassword(ui, false) | ||
func onboardingRequest(cli clients.CLI, options *options) (*influxdb.OnboardingRequest, error) { | ||
setupClient := setup.Client{CLI: cli} | ||
cliReq, err := setupClient.OnboardingRequest(&setup.Params{ | ||
Username: options.target.userName, | ||
Password: options.target.password, | ||
AuthToken: options.target.token, | ||
Org: options.target.orgName, | ||
Bucket: options.target.bucket, | ||
Retention: options.target.retention, | ||
Force: options.force, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if req.Org == "" { | ||
req.Org = internal.GetInput(ui, "Please type your primary organization name", "") | ||
req := influxdb.OnboardingRequest{ | ||
User: cliReq.Username, | ||
Org: cliReq.Org, | ||
Bucket: cliReq.Bucket, | ||
} | ||
if req.Bucket == "" { | ||
req.Bucket = internal.GetInput(ui, "Please type your primary bucket name", "") | ||
if cliReq.Password != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, a consequence of codegen vs. hand-rolled. The codegen'd models use pointer-fields for every optional field. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Talked on Slack: going to try deleting There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After trying, would prefer to leave it as an adapter layer here. Both |
||
req.Password = *cliReq.Password | ||
} | ||
|
||
// Check the initial opts instead of the req to distinguish not-set from explicit 0 over the CLI. | ||
if options.target.retention == "" { | ||
infiniteStr := strconv.Itoa(influxdb.InfiniteRetention) | ||
for { | ||
rpStr := internal.GetInput(ui, | ||
"Please type your retention period in hours.\nOr press ENTER for infinite", infiniteStr) | ||
rp, err := strconv.Atoi(rpStr) | ||
if rp >= 0 && err == nil { | ||
req.RetentionPeriodSeconds = int64((time.Duration(rp) * time.Hour).Seconds()) | ||
break | ||
} | ||
} | ||
if cliReq.RetentionPeriodSeconds != nil { | ||
req.RetentionPeriodSeconds = *cliReq.RetentionPeriodSeconds | ||
} | ||
|
||
if confirmed := internal.GetConfirm(ui, func() string { | ||
rp := "infinite" | ||
if req.RetentionPeriodSeconds > 0 { | ||
rp = (time.Duration(req.RetentionPeriodSeconds) * time.Second).String() | ||
} | ||
return fmt.Sprintf(` | ||
You have entered: | ||
Username: %s | ||
Organization: %s | ||
Bucket: %s | ||
Retention Period: %s | ||
`, req.User, req.Org, req.Bucket, rp) | ||
}); !confirmed { | ||
return nil, errors.New("setup was canceled") | ||
if cliReq.Token != nil { | ||
req.Token = *cliReq.Token | ||
} | ||
|
||
return req, nil | ||
return &req, nil | ||
} | ||
|
||
func saveLocalConfig(sourceOptions *optionsV1, targetOptions *optionsV2, log *zap.Logger) error { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit confusing that the prompt appears to be for a different kind of string than the options value now? (nanos vs hours?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The help-text isn't very helpful, but I think the behavior is the same before and after this change. Whatever gets passed to
--retention
gets parsed as atime.Duration
I can update the description in the help-text to show examples of durations (i.e.
72h
)