2018-10-02 17:21:36 +00:00
package main
import (
"context"
"fmt"
"os"
2018-10-18 19:09:25 +00:00
"strconv"
2018-10-04 22:13:24 +00:00
"strings"
2018-10-02 17:21:36 +00:00
2019-01-08 00:37:16 +00:00
platform "github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/cmd/influx/internal"
"github.com/influxdata/influxdb/http"
2018-10-02 17:21:36 +00:00
"github.com/spf13/cobra"
2019-01-08 20:58:31 +00:00
input "github.com/tcnksm/go-input"
2018-10-02 17:21:36 +00:00
)
// setup Command
var setupCmd = & cobra . Command {
Use : "setup" ,
Short : "Create default username, password, org, bucket..." ,
Run : setupF ,
}
func setupF ( cmd * cobra . Command , args [ ] string ) {
2018-10-25 19:28:33 +00:00
if flags . local {
fmt . Println ( "Local flag not supported for setup command" )
os . Exit ( 1 )
}
2018-10-02 17:21:36 +00:00
// check if setup is allowed
s := & http . SetupService {
Addr : flags . host ,
}
allowed , err := s . IsOnboarding ( context . Background ( ) )
if err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
if ! allowed {
fmt . Println ( "Initialization has been already completed" )
2018-10-05 15:34:39 +00:00
os . Exit ( 0 )
2018-10-02 17:21:36 +00:00
}
2018-10-18 19:09:25 +00:00
req := getOnboardingRequest ( )
2018-10-02 17:21:36 +00:00
2018-10-18 19:09:25 +00:00
result , err := s . Generate ( context . Background ( ) , req )
2018-10-02 17:21:36 +00:00
if err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
w := internal . NewTabWriter ( os . Stdout )
w . WriteHeaders (
"UserID" ,
2018-10-11 22:02:58 +00:00
"Username" ,
2018-10-02 17:21:36 +00:00
"Organization" ,
"Bucket" ,
)
w . Write ( map [ string ] interface { } {
"UserID" : result . User . ID . String ( ) ,
2018-10-11 22:02:58 +00:00
"Username" : result . User . Name ,
2018-10-02 17:21:36 +00:00
"Organization" : result . Org . Name ,
"Bucket" : result . Bucket . Name ,
} )
2018-11-02 02:34:22 +00:00
writeTokenToPath ( result . Auth . Token , defaultTokenPath ( ) )
2018-10-02 17:21:36 +00:00
w . Flush ( )
2019-01-08 20:58:31 +00:00
fmt . Println ( promptWithColor ( "Your token has been stored in " + defaultTokenPath ( ) , colorCyan ) )
2018-10-02 17:21:36 +00:00
}
2018-10-18 19:09:25 +00:00
func getOnboardingRequest ( ) ( req * platform . OnboardingRequest ) {
2018-10-11 22:02:58 +00:00
ui := & input . UI {
Writer : os . Stdout ,
Reader : os . Stdin ,
}
2018-10-18 19:09:25 +00:00
req = new ( platform . OnboardingRequest )
2018-10-12 00:49:00 +00:00
fmt . Println ( promptWithColor ( ` Welcome to InfluxDB 2.0! ` , colorYellow ) )
2018-10-18 19:09:25 +00:00
req . User = getInput ( ui , "Please type your primary username" , "" )
req . Password = getPassword ( ui )
2019-01-14 15:04:54 +00:00
req . Org = getInput ( ui , "Please type your primary organization name" , "" )
req . Bucket = getInput ( ui , "Please type your primary bucket name" , "" )
2018-10-18 19:09:25 +00:00
for {
rpStr := getInput ( ui , "Please type your retention period in hours (exp 168 for 1 week).\r\nOr press ENTER for infinite." , strconv . Itoa ( platform . InfiniteRetention ) )
rp , err := strconv . Atoi ( rpStr )
if rp >= 0 && err == nil {
req . RetentionPeriod = uint ( rp )
break
}
}
2018-10-05 15:34:39 +00:00
2018-10-18 19:09:25 +00:00
if confirmed := getConfirm ( ui , req ) ; ! confirmed {
2018-10-12 00:49:00 +00:00
fmt . Println ( "Setup is canceled." )
2018-10-18 17:38:17 +00:00
// user cancel
os . Exit ( 0 )
2018-10-05 15:34:39 +00:00
}
2018-10-03 18:24:42 +00:00
2018-10-18 19:09:25 +00:00
return req
2018-10-03 18:24:42 +00:00
}
2018-10-11 22:02:58 +00:00
// vt100EscapeCodes
var (
2018-11-01 17:02:47 +00:00
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' }
2018-10-11 22:02:58 +00:00
)
func promptWithColor ( s string , color [ ] byte ) string {
return string ( color ) + s + string ( keyReset )
2018-10-05 15:34:39 +00:00
}
2018-10-11 22:02:58 +00:00
func getConfirm ( ui * input . UI , or * platform . OnboardingRequest ) bool {
2018-10-12 00:49:00 +00:00
prompt := promptWithColor ( "Confirm? (y/n)" , colorRed )
for {
2018-10-18 19:09:25 +00:00
rp := "infinite"
if or . RetentionPeriod > 0 {
rp = fmt . Sprintf ( "%d hrs" , or . RetentionPeriod )
}
2018-10-12 00:49:00 +00:00
fmt . Print ( promptWithColor ( fmt . Sprintf ( `
2018-10-11 22:02:58 +00:00
You have entered :
2018-10-18 19:09:25 +00:00
Username : % s
Organization : % s
Bucket : % s
Retention Period : % s
` , or . User , or . Org , or . Bucket , rp ) , colorCyan ) )
2018-10-12 00:49:00 +00:00
result , err := ui . Ask ( prompt , & input . Options {
HideOrder : true ,
} )
if err != nil {
2018-10-18 17:38:17 +00:00
// interrupt
2018-10-12 00:49:00 +00:00
os . Exit ( 1 )
}
switch result {
case "y" :
return true
case "n" :
return false
default :
continue
}
2018-10-05 15:34:39 +00:00
}
}
2018-10-11 22:02:58 +00:00
var errPasswordIsNotMatch = fmt . Errorf ( "passwords do not match" )
2018-10-03 18:24:42 +00:00
2018-10-11 22:02:58 +00:00
func getPassword ( ui * input . UI ) ( password string ) {
var err error
enterPasswd :
query := promptWithColor ( "Please type your password" , colorCyan )
for {
password , err = ui . Ask ( query , & input . Options {
Required : true ,
HideOrder : true ,
Hide : true ,
} )
switch err {
case input . ErrInterrupted :
os . Exit ( 1 )
default :
if password = strings . TrimSpace ( password ) ; password == "" {
2018-10-02 17:21:36 +00:00
continue
}
}
2018-10-11 22:02:58 +00:00
break
2018-10-02 17:21:36 +00:00
}
2018-10-11 22:02:58 +00:00
query = promptWithColor ( "Please type your password again" , colorCyan )
2018-10-04 22:13:24 +00:00
for {
2018-10-11 22:02:58 +00:00
_ , err = ui . Ask ( query , & input . Options {
Required : true ,
HideOrder : true ,
Hide : true ,
ValidateFunc : func ( s string ) error {
if s != password {
return errPasswordIsNotMatch
}
return nil
} ,
} )
switch err {
case input . ErrInterrupted :
os . Exit ( 1 )
case nil :
2018-11-01 17:02:47 +00:00
// Nothing.
2018-10-11 22:02:58 +00:00
default :
fmt . Println ( promptWithColor ( "Passwords do not match!" , colorRed ) )
goto enterPasswd
2018-10-04 22:13:24 +00:00
}
2018-10-11 22:02:58 +00:00
break
2018-10-02 17:21:36 +00:00
}
2018-10-11 22:02:58 +00:00
return password
}
2018-10-04 22:13:24 +00:00
2018-10-11 22:02:58 +00:00
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 = 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
}
2018-10-03 18:24:42 +00:00
}
2018-10-02 17:21:36 +00:00
}