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
"github.com/influxdata/platform"
"github.com/influxdata/platform/cmd/influx/internal"
"github.com/influxdata/platform/http"
"github.com/spf13/cobra"
2018-10-11 22:02:58 +00:00
"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 ) {
// 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" ,
"Token" ,
)
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 ,
"Token" : result . Auth . Token ,
} )
w . Flush ( )
}
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 )
req . Org = getInput ( ui , "Please type your primary organization name." , "" )
req . Bucket = getInput ( ui , "Please type your primary bucket name." , "" )
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 (
keyEscape = byte ( 27 )
colorBlack = [ ] byte { keyEscape , '[' , '3' , '0' , 'm' }
colorRed = [ ] byte { keyEscape , '[' , '3' , '1' , 'm' }
colorGreen = [ ] byte { keyEscape , '[' , '3' , '2' , 'm' }
colorYellow = [ ] byte { keyEscape , '[' , '3' , '3' , 'm' }
colorBlue = [ ] byte { keyEscape , '[' , '3' , '4' , 'm' }
colorMagenta = [ ] byte { keyEscape , '[' , '3' , '5' , 'm' }
colorCyan = [ ] byte { keyEscape , '[' , '3' , '6' , 'm' }
colorWhite = [ ] byte { keyEscape , '[' , '3' , '7' , 'm' }
keyReset = [ ] byte { keyEscape , '[' , '0' , 'm' }
)
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 :
break
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
}