Skip to content

Commit

Permalink
feat(upgrade): upgrade command basic skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
vlastahajek committed Oct 1, 2020
1 parent 8fea0cd commit ea8f608
Show file tree
Hide file tree
Showing 16 changed files with 930 additions and 261 deletions.
5 changes: 3 additions & 2 deletions cmd/influx/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/cmd/internal"
"github.com/influxdata/influxdb/v2/http"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -88,7 +89,7 @@ func (b *cmdBucketBuilder) cmdCreateRunEFn(*cobra.Command, []string) error {
return err
}

dur, err := rawDurationToTimeDuration(b.retention)
dur, err := internal.RawDurationToTimeDuration(b.retention)
if err != nil {
return err
}
Expand Down Expand Up @@ -273,7 +274,7 @@ func (b *cmdBucketBuilder) cmdUpdateRunEFn(cmd *cobra.Command, args []string) er
update.Description = &b.description
}

dur, err := rawDurationToTimeDuration(b.retention)
dur, err := internal.RawDurationToTimeDuration(b.retention)
if err != nil {
return err
}
Expand Down
49 changes: 0 additions & 49 deletions cmd/influx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -21,7 +20,6 @@ import (
"github.com/influxdata/influxdb/v2/internal/fs"
"github.com/influxdata/influxdb/v2/kit/cli"
"github.com/influxdata/influxdb/v2/pkg/httpc"
"github.com/influxdata/influxdb/v2/task/options"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -614,50 +612,3 @@ func newBucketService() (influxdb.BucketService, error) {
Client: client,
}, nil
}

func rawDurationToTimeDuration(raw string) (time.Duration, error) {
if raw == "" {
return 0, nil
}

if dur, err := time.ParseDuration(raw); err == nil {
return dur, nil
}

retention, err := options.ParseSignedDuration(raw)
if err != nil {
return 0, err
}

const (
day = 24 * time.Hour
week = 7 * day
)

var dur time.Duration
for _, d := range retention.Values {
if d.Magnitude < 0 {
return 0, errors.New("must be greater than 0")
}
mag := time.Duration(d.Magnitude)
switch d.Unit {
case "w":
dur += mag * week
case "d":
dur += mag * day
case "m":
dur += mag * time.Minute
case "s":
dur += mag * time.Second
case "ms":
dur += mag * time.Minute
case "us":
dur += mag * time.Microsecond
case "ns":
dur += mag * time.Nanosecond
default:
return 0, errors.New("duration must be week(w), day(d), hour(h), min(m), sec(s), millisec(ms), microsec(us), or nanosec(ns)")
}
}
return dur, nil
}
5 changes: 3 additions & 2 deletions cmd/influx/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import (
"fmt"

"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/cmd/internal"
"github.com/influxdata/influxdb/v2/http"
"github.com/spf13/cobra"
input "github.com/tcnksm/go-input"
"github.com/tcnksm/go-input"
)

type secretSVCsFn func() (influxdb.SecretService, influxdb.OrganizationService, func(*input.UI) string, error)
Expand Down Expand Up @@ -245,5 +246,5 @@ func newSecretSVCs() (influxdb.SecretService, influxdb.OrganizationService, func
}
orgSvc := &http.OrganizationService{Client: httpClient}

return &http.SecretService{Client: httpClient}, orgSvc, getSecret, nil
return &http.SecretService{Client: httpClient}, orgSvc, internal.GetSecret, nil
}
197 changes: 25 additions & 172 deletions cmd/influx/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/influxdata/influxdb/v2"
"github.com/influxdata/influxdb/v2/cmd/influx/config"
"github.com/influxdata/influxdb/v2/cmd/influx/internal"
internal2 "github.com/influxdata/influxdb/v2/cmd/internal"
"github.com/influxdata/influxdb/v2/tenant"
"github.com/spf13/cobra"
input "github.com/tcnksm/go-input"
"github.com/tcnksm/go-input"
)

var setupFlags struct {
Expand All @@ -31,8 +31,6 @@ var setupFlags struct {
username string
}

const minPasswordLen int = 8

func cmdSetup(f *globalFlags, opt genericCLIOpts) *cobra.Command {
cmd := opt.newCmd("setup", nil, true)
cmd.RunE = setupF
Expand Down Expand Up @@ -182,7 +180,7 @@ func setupF(cmd *cobra.Command, args []string) error {
return fmt.Errorf("failed to write config to path %q: %v", dPath, err)
}

fmt.Println(string(promptWithColor(fmt.Sprintf("Config %s has been stored in %s.", p.Name, dPath), colorCyan)))
fmt.Println(string(internal2.PromptWithColor(fmt.Sprintf("Config %s has been stored in %s.", p.Name, dPath), internal2.ColorCyan)))

w := cmd.OutOrStdout()
if setupFlags.json {
Expand Down Expand Up @@ -224,8 +222,8 @@ func onboardingRequest() (*influxdb.OnboardingRequest, error) {
}

func nonInteractive() (*influxdb.OnboardingRequest, error) {
if len(setupFlags.password) < minPasswordLen {
return nil, errPasswordIsTooShort
if len(setupFlags.password) < internal2.MinPasswordLen {
return nil, internal2.ErrPasswordIsTooShort
}

req := &influxdb.OnboardingRequest{
Expand All @@ -237,7 +235,7 @@ func nonInteractive() (*influxdb.OnboardingRequest, error) {
RetentionPeriod: influxdb.InfiniteRetention,
}

dur, err := rawDurationToTimeDuration(setupFlags.retention)
dur, err := internal2.RawDurationToTimeDuration(setupFlags.retention)
if err != nil {
return nil, err
}
Expand All @@ -253,16 +251,16 @@ func interactive() (req *influxdb.OnboardingRequest, err error) {
Reader: os.Stdin,
}
req = new(influxdb.OnboardingRequest)
fmt.Println(string(promptWithColor(`Welcome to InfluxDB 2.0!`, colorYellow)))
fmt.Println(string(internal2.PromptWithColor(`Welcome to InfluxDB 2.0!`, internal2.ColorYellow)))
if setupFlags.username != "" {
req.User = setupFlags.username
} else {
req.User = getInput(ui, "Please type your primary username", "")
req.User = internal2.GetInput(ui, "Please type your primary username", "")
}
if setupFlags.password != "" && len(setupFlags.password) >= minPasswordLen {
if setupFlags.password != "" && len(setupFlags.password) >= internal2.MinPasswordLen {
req.Password = setupFlags.password
} else {
req.Password = getPassword(ui, false)
req.Password = internal2.GetPassword(ui, false)
}
if setupFlags.token != "" {
req.Token = setupFlags.token
Expand All @@ -271,15 +269,15 @@ func interactive() (req *influxdb.OnboardingRequest, err error) {
if setupFlags.org != "" {
req.Org = setupFlags.org
} else {
req.Org = getInput(ui, "Please type your primary organization name", "")
req.Org = internal2.GetInput(ui, "Please type your primary organization name", "")
}
if setupFlags.bucket != "" {
req.Bucket = setupFlags.bucket
} else {
req.Bucket = getInput(ui, "Please type your primary bucket name", "")
req.Bucket = internal2.GetInput(ui, "Please type your primary bucket name", "")
}

dur, err := rawDurationToTimeDuration(setupFlags.retention)
dur, err := internal2.RawDurationToTimeDuration(setupFlags.retention)
if err != nil {
return nil, err
}
Expand All @@ -288,177 +286,32 @@ func interactive() (req *influxdb.OnboardingRequest, err error) {
req.RetentionPeriod = uint(dur / time.Hour)
} else {
for {
rpStr := getInput(ui, "Please type your retention period in hours.\r\nOr press ENTER for infinite.", strconv.Itoa(influxdb.InfiniteRetention))
rpStr := internal2.GetInput(ui, "Please type your retention period in hours.\r\nOr press ENTER for infinite.", strconv.Itoa(influxdb.InfiniteRetention))
rp, err := strconv.Atoi(rpStr)
if rp >= 0 && err == nil {
req.RetentionPeriod = uint(rp)
req.RetentionPeriod = uint(rp) * uint(time.Hour)
break
}
}
}

if !setupFlags.force {
if confirmed := getConfirm(ui, req); !confirmed {
return nil, fmt.Errorf("setup was canceled")
}
}

return req, nil
}

// vt100EscapeCodes
var (
keyEscape = byte(27)
colorRed = []byte{keyEscape, '[', '3', '1', 'm'}
colorYellow = []byte{keyEscape, '[', '3', '3', 'm'}
colorCyan = []byte{keyEscape, '[', '3', '6', 'm'}
keyReset = []byte{keyEscape, '[', '0', 'm'}
)

func promptWithColor(s string, color []byte) []byte {
bb := append(color, []byte(s)...)
return append(bb, keyReset...)
}

func getConfirm(ui *input.UI, or *influxdb.OnboardingRequest) bool {
prompt := promptWithColor("Confirm? (y/n)", colorRed)
for {
rp := "infinite"
if or.RetentionPeriod > 0 {
rp = fmt.Sprintf("%d hrs", time.Duration(or.RetentionPeriod)/time.Hour)
}
ui.Writer.Write(promptWithColor(fmt.Sprintf(`
if confirmed := internal2.GetConfirm(ui, func() string {
rp := "infinite"
if req.RetentionPeriod > 0 {
rp = fmt.Sprintf("%d hrs", time.Duration(req.RetentionPeriod)/time.Hour)
}
return fmt.Sprintf(`
You have entered:
Username: %s
Organization: %s
Bucket: %s
Retention Period: %s
`, or.User, or.Org, or.Bucket, rp), colorCyan))
result, err := ui.Ask(string(prompt), &input.Options{
HideOrder: true,
})
if err != nil {
return false
}
switch result {
case "y":
return true
case "n":
return false
default:
continue
}
}
}

var errPasswordNotMatch = errors.New("passwords do not match")

var errPasswordIsTooShort error = errors.New("password is too short")

func getSecret(ui *input.UI) (secret string) {
var err error
query := string(promptWithColor("Please type your secret", colorCyan))
for {
secret, err = ui.Ask(query, &input.Options{
Required: true,
HideOrder: true,
Hide: true,
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 {
if len(s) < minPasswordLen {
return errPasswordIsTooShort
}
return nil
},
})
switch err {
case input.ErrInterrupted:
os.Exit(1)
case errPasswordIsTooShort:
ui.Writer.Write(promptWithColor(fmt.Sprintf("Password too short - minimum length is %d characters!\n\r", minPasswordLen), colorRed))
continue
default:
if password = strings.TrimSpace(password); password == "" {
continue
}
}
break
}
query = string(promptWithColor("Please type your"+newStr+" password again", colorCyan))
for {
_, err = ui.Ask(query, &input.Options{
Required: true,
HideOrder: true,
Hide: true,
ValidateFunc: func(s string) error {
if s != password {
return errPasswordNotMatch
}
return nil
},
})
switch err {
case input.ErrInterrupted:
os.Exit(1)
case nil:
// Nothing.
default:
ui.Writer.Write(promptWithColor("Passwords do not match!\n", colorRed))
goto enterPassword
`, req.User, req.Org, req.Bucket, rp)
}); !confirmed {
return nil, fmt.Errorf("setup was canceled")
}
break
}
return password
}

func getInput(ui *input.UI, prompt, defaultValue string) string {
option := &input.Options{
Required: true,
HideOrder: true,
}
if defaultValue != "" {
option.Default = defaultValue
option.HideDefault = true
}
prompt = string(promptWithColor(prompt, colorCyan))
for {
line, err := ui.Ask(prompt, option)
switch err {
case input.ErrInterrupted:
os.Exit(1)
default:
if line = strings.TrimSpace(line); line == "" {
continue
}
return line
}
}
return req, nil
}
Loading

0 comments on commit ea8f608

Please sign in to comment.