2018-05-24 17:34:39 +00:00
package main
import (
2019-01-22 18:19:26 +00:00
"context"
2018-05-24 17:34:39 +00:00
"fmt"
2018-11-02 02:34:22 +00:00
"io/ioutil"
2018-05-24 17:34:39 +00:00
"os"
2018-11-02 02:34:22 +00:00
"path/filepath"
2018-05-24 17:34:39 +00:00
2019-02-19 23:47:19 +00:00
"github.com/influxdata/influxdb"
2019-03-28 08:42:38 +00:00
"github.com/influxdata/influxdb/bolt"
2019-01-22 18:19:26 +00:00
"github.com/influxdata/influxdb/cmd/influx/internal"
"github.com/influxdata/influxdb/http"
2019-01-08 00:37:16 +00:00
"github.com/influxdata/influxdb/internal/fs"
2019-03-28 08:42:38 +00:00
"github.com/influxdata/influxdb/kv"
2018-05-24 17:34:39 +00:00
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
2019-10-24 19:20:49 +00:00
const maxTCPConnections = 128
2019-10-09 21:01:23 +00:00
2019-11-21 00:38:12 +00:00
type httpClientOpts struct {
token , addr string
skipVerify bool
}
2019-11-20 00:55:36 +00:00
func main ( ) {
influxCmd := influxCmd ( )
if err := influxCmd . Execute ( ) ; err != nil {
os . Exit ( 1 )
}
}
func influxCmd ( ) * cobra . Command {
cmd := & cobra . Command {
Use : "influx" ,
Short : "Influx Client" ,
Run : func ( cmd * cobra . Command , args [ ] string ) {
if err := checkSetup ( flags . host ) ; err != nil {
fmt . Printf ( "Note: %v\n" , internal . ErrorFmt ( err ) )
}
cmd . Usage ( )
} ,
}
cmd . AddCommand (
2019-11-15 18:23:24 +00:00
authCmd ( ) ,
2019-10-24 19:20:49 +00:00
bucketCmd ,
deleteCmd ,
organizationCmd ,
pingCmd ,
2019-11-18 18:50:45 +00:00
pkgCmd ( newPkgerSVC ) ,
2019-10-24 19:20:49 +00:00
queryCmd ,
replCmd ,
setupCmd ,
taskCmd ,
2019-11-20 00:55:36 +00:00
userCmd ( ) ,
2019-10-24 19:20:49 +00:00
writeCmd ,
)
viper . SetEnvPrefix ( "INFLUX" )
2019-11-20 00:55:36 +00:00
cmd . PersistentFlags ( ) . StringVarP ( & flags . token , "token" , "t" , "" , "API token to be used throughout client calls" )
2019-10-24 19:20:49 +00:00
viper . BindEnv ( "TOKEN" )
if h := viper . GetString ( "TOKEN" ) ; h != "" {
flags . token = h
} else if tok , err := getTokenFromDefaultPath ( ) ; err == nil {
flags . token = tok
}
2019-11-20 00:55:36 +00:00
cmd . PersistentFlags ( ) . StringVar ( & flags . host , "host" , "http://localhost:9999" , "HTTP address of Influx" )
2019-10-24 19:20:49 +00:00
viper . BindEnv ( "HOST" )
if h := viper . GetString ( "HOST" ) ; h != "" {
flags . host = h
}
2019-11-20 00:55:36 +00:00
cmd . PersistentFlags ( ) . BoolVar ( & flags . local , "local" , false , "Run commands locally against the filesystem" )
2019-10-24 19:20:49 +00:00
2019-11-20 00:55:36 +00:00
cmd . PersistentFlags ( ) . BoolVar ( & flags . skipVerify , "skip-verify" , false , "SkipVerify controls whether a client verifies the server's certificate chain and host name." )
2019-11-14 23:28:43 +00:00
2019-10-24 19:20:49 +00:00
// Override help on all the commands tree
2019-11-20 00:55:36 +00:00
walk ( cmd , func ( c * cobra . Command ) {
2019-10-24 19:20:49 +00:00
c . Flags ( ) . BoolP ( "help" , "h" , false , fmt . Sprintf ( "Help for the %s command " , c . Name ( ) ) )
} )
2019-11-20 00:55:36 +00:00
return cmd
2018-05-24 17:34:39 +00:00
}
// Flags contains all the CLI flag values for influx.
type Flags struct {
2019-11-14 23:28:43 +00:00
token string
host string
local bool
skipVerify bool
2018-05-24 17:34:39 +00:00
}
2019-11-18 18:50:45 +00:00
func ( f Flags ) httpClientOpts ( ) httpClientOpts {
return httpClientOpts {
addr : f . host ,
token : f . token ,
skipVerify : f . skipVerify ,
}
}
2018-05-24 17:34:39 +00:00
var flags Flags
2019-03-05 21:51:46 +00:00
func defaultTokenPath ( ) ( string , string , error ) {
2018-11-02 02:34:22 +00:00
dir , err := fs . InfluxDir ( )
if err != nil {
2019-03-05 21:51:46 +00:00
return "" , "" , err
2018-11-02 02:34:22 +00:00
}
2019-03-05 21:51:46 +00:00
return filepath . Join ( dir , "credentials" ) , dir , nil
2018-11-02 02:34:22 +00:00
}
2019-03-05 21:51:46 +00:00
func getTokenFromDefaultPath ( ) ( string , error ) {
path , _ , err := defaultTokenPath ( )
if err != nil {
return "" , err
}
2018-11-02 02:34:22 +00:00
b , err := ioutil . ReadFile ( path )
if err != nil {
return "" , err
}
return string ( b ) , nil
}
2019-03-05 21:51:46 +00:00
func writeTokenToPath ( tok , path , dir string ) error {
if err := os . MkdirAll ( dir , os . ModePerm ) ; err != nil {
return err
}
2018-11-02 02:34:22 +00:00
return ioutil . WriteFile ( path , [ ] byte ( tok ) , 0600 )
}
2019-01-22 18:19:26 +00:00
func checkSetup ( host string ) error {
s := & http . SetupService {
2019-11-14 23:28:43 +00:00
Addr : flags . host ,
InsecureSkipVerify : flags . skipVerify ,
2019-01-22 18:19:26 +00:00
}
2019-10-24 19:20:49 +00:00
isOnboarding , err := s . IsOnboarding ( context . Background ( ) )
2019-01-22 18:19:26 +00:00
if err != nil {
return err
}
if isOnboarding {
return fmt . Errorf ( "the instance at %q has not been setup. Please run `influx setup` before issuing any additional commands" , host )
}
return nil
}
func wrapCheckSetup ( fn func ( * cobra . Command , [ ] string ) error ) func ( * cobra . Command , [ ] string ) error {
2019-01-22 19:34:01 +00:00
return wrapErrorFmt ( func ( cmd * cobra . Command , args [ ] string ) error {
2019-01-22 18:19:26 +00:00
err := fn ( cmd , args )
if err == nil {
return nil
}
2019-02-19 23:47:19 +00:00
if setupErr := checkSetup ( flags . host ) ; setupErr != nil && influxdb . EUnauthorized != influxdb . ErrorCode ( setupErr ) {
2019-01-22 19:34:01 +00:00
return setupErr
}
return err
} )
}
func wrapErrorFmt ( fn func ( * cobra . Command , [ ] string ) error ) func ( * cobra . Command , [ ] string ) error {
return func ( cmd * cobra . Command , args [ ] string ) error {
err := fn ( cmd , args )
if err == nil {
return nil
2019-01-22 18:19:26 +00:00
}
return internal . ErrorFmt ( err )
}
}
2019-01-14 18:53:37 +00:00
// walk calls f for c and all of its children.
func walk ( c * cobra . Command , f func ( * cobra . Command ) ) {
f ( c )
for _ , c := range c . Commands ( ) {
walk ( c , f )
}
}
2019-03-28 08:42:38 +00:00
func newLocalKVService ( ) ( * kv . Service , error ) {
boltFile , err := fs . BoltFile ( )
if err != nil {
return nil , err
}
store := bolt . NewKVStore ( boltFile )
if err := store . Open ( context . Background ( ) ) ; err != nil {
return nil , err
}
return kv . NewService ( store ) , nil
}