diff --git a/cmd/influx/main.go b/cmd/influx/main.go index 76b223b..7ee115d 100644 --- a/cmd/influx/main.go +++ b/cmd/influx/main.go @@ -25,6 +25,14 @@ var ( date = "" ) +func init() { + if len(date) == 0 { + date = time.Now().UTC().Format(time.RFC3339) + } + + cli.VersionFlag = nil +} + var ( tokenFlag = "token" hostFlag = "host" @@ -37,6 +45,46 @@ var ( hideHeadersFlag = "hide-headers" ) +// NOTE: urfave/cli has dedicated support for global flags, but it only parses those flags +// if they're specified before any command names. This is incompatible with the old influx +// CLI, which repeatedly registered common flags on every "leaf" command, forcing the flags +// to be specified after _all_ command names were given. +// +// We replicate the pattern from the old CLI so existing scripts and docs stay valid. + +// Some commands (i.e. `setup` use custom help-text for the token flag). +var commonFlagsNoToken = []cli.Flag{ + &cli.StringFlag{ + Name: hostFlag, + Usage: "HTTP address of InfluxDB", + EnvVars: []string{"INFLUX_HOST"}, + }, + &cli.BoolFlag{ + Name: skipVerifyFlag, + Usage: "Skip TLS certificate chain and host name verification", + }, + &cli.PathFlag{ + Name: configPathFlag, + Usage: "Path to the influx CLI configurations", + EnvVars: []string{"INFLUX_CLI_CONFIGS_PATH"}, + }, + &cli.StringFlag{ + Name: configNameFlag, + Usage: "Config name to use for command", + Aliases: []string{"c"}, + EnvVars: []string{"INFLUX_ACTIVE_CONFIG"}, + }, + &cli.StringFlag{ + Name: traceIdFlag, + Hidden: true, + EnvVars: []string{"INFLUX_TRACE_DEBUG_ID"}, + }, + &cli.BoolFlag{ + Name: httpDebugFlag, + Hidden: true, + }, +} + // newCli builds a CLI core that reads from stdin, writes to stdout/stderr, manages a local config store, // and optionally tracks a trace ID specified over the CLI. func newCli(ctx *cli.Context) (*internal.CLI, error) { @@ -108,173 +156,18 @@ func standardCtx(ctx *cli.Context) context.Context { return signals.WithStandardSignals(ctx.Context) } +var app = cli.App{ + Name: "influx", + Usage: "Influx Client", + UsageText: "influx [command]", + Commands: []*cli.Command{ + &versionCmd, + &pingCmd, + &setupCmd, + }, +} + func main() { - if len(date) == 0 { - date = time.Now().UTC().Format(time.RFC3339) - } - - cli.VersionFlag = nil - - // NOTE: urfave/cli has dedicated support for global flags, but it only parses those flags - // if they're specified before any command names. This is incompatible with the old influx - // CLI, which repeatedly registered common flags on every "leaf" command, forcing the flags - // to be specified after _all_ command names were given. - // - // We replicate the pattern from the old CLI so existing scripts and docs stay valid. - - // Some commands (i.e. `setup` use custom help-text for the token flag). - commonFlagsNoToken := []cli.Flag{ - &cli.StringFlag{ - Name: hostFlag, - Usage: "HTTP address of InfluxDB", - EnvVars: []string{"INFLUX_HOST"}, - }, - &cli.BoolFlag{ - Name: skipVerifyFlag, - Usage: "Skip TLS certificate chain and host name verification", - }, - &cli.PathFlag{ - Name: configPathFlag, - Usage: "Path to the influx CLI configurations", - EnvVars: []string{"INFLUX_CLI_CONFIGS_PATH"}, - }, - &cli.StringFlag{ - Name: configNameFlag, - Usage: "Config name to use for command", - Aliases: []string{"c"}, - EnvVars: []string{"INFLUX_ACTIVE_CONFIG"}, - }, - &cli.StringFlag{ - Name: traceIdFlag, - Hidden: true, - EnvVars: []string{"INFLUX_TRACE_DEBUG_ID"}, - }, - &cli.BoolFlag{ - Name: httpDebugFlag, - Hidden: true, - }, - } - - // Most commands use this form of the token flag. - //commonFlags := append(commonFlagsNoToken, &cli.StringFlag{ - // Name: tokenFlag, - // Usage: "Authentication token", - // Aliases: []string{"t"}, - // EnvVars: []string{"INFLUX_TOKEN"}, - //}) - - app := cli.App{ - Name: "influx", - Usage: "Influx Client", - UsageText: "influx [command]", - Commands: []*cli.Command{ - { - Name: "version", - Usage: "Print the influx CLI version", - Action: func(*cli.Context) error { - fmt.Printf("Influx CLI %s (git: %s) build_date: %s\n", version, commit, date) - return nil - }, - }, - { - Name: "ping", - Usage: "Check the InfluxDB /health endpoint", - Flags: commonFlagsNoToken, - Action: func(ctx *cli.Context) error { - cli, err := newCli(ctx) - if err != nil { - return err - } - client, err := newApiClient(ctx, cli, false) - if err != nil { - return err - } - return cli.Ping(standardCtx(ctx), client.HealthApi) - }, - }, - { - Name: "setup", - Usage: "Setup instance with initial user, org, bucket", - Flags: append( - commonFlagsNoToken, - &cli.StringFlag{ - Name: "username", - Usage: "Name of initial user to create", - Aliases: []string{"u"}, - }, - &cli.StringFlag{ - Name: "password", - Usage: "Password to set on initial user", - Aliases: []string{"p"}, - }, - &cli.StringFlag{ - Name: tokenFlag, - Usage: "Auth token to set on the initial user", - Aliases: []string{"t"}, - EnvVars: []string{"INFLUX_TOKEN"}, - DefaultText: "auto-generated", - }, - &cli.StringFlag{ - Name: "org", - Usage: "Name of initial organization to create", - Aliases: []string{"o"}, - }, - &cli.StringFlag{ - Name: "bucket", - Usage: "Name of initial bucket to create", - Aliases: []string{"b"}, - }, - &cli.StringFlag{ - Name: "retention", - Usage: "Duration initial bucket will retain data, or 0 for infinite", - Aliases: []string{"r"}, - DefaultText: "infinite", - }, - &cli.BoolFlag{ - Name: "force", - Usage: "Skip confirmation prompt", - Aliases: []string{"f"}, - }, - &cli.StringFlag{ - Name: "name", - Usage: "Name to set on CLI config generated for the InfluxDB instance, required if other configs exist", - Aliases: []string{"n"}, - }, - &cli.BoolFlag{ - Name: printJsonFlag, - Usage: "Output data as JSON", - EnvVars: []string{"INFLUX_OUTPUT_JSON"}, - }, - &cli.BoolFlag{ - Name: hideHeadersFlag, - Usage: "Hide the table headers in output data", - EnvVars: []string{"INFLUX_HIDE_HEADERS"}, - }, - ), - Action: func(ctx *cli.Context) error { - cli, err := newCli(ctx) - if err != nil { - return err - } - client, err := newApiClient(ctx, cli, false) - if err != nil { - return err - } - return cli.Setup(standardCtx(ctx), client.SetupApi, &internal.SetupParams{ - Username: ctx.String("username"), - Password: ctx.String("password"), - AuthToken: ctx.String(tokenFlag), - Org: ctx.String("org"), - Bucket: ctx.String("bucket"), - Retention: ctx.String("retention"), - Force: ctx.Bool("force"), - ConfigName: ctx.String("name"), - }) - }, - }, - }, - } - if err := app.Run(os.Args); err != nil { _, _ = fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) diff --git a/cmd/influx/ping.go b/cmd/influx/ping.go new file mode 100644 index 0000000..b9652db --- /dev/null +++ b/cmd/influx/ping.go @@ -0,0 +1,20 @@ +package main + +import "github.com/urfave/cli/v2" + +var pingCmd = cli.Command{ + Name: "ping", + Usage: "Check the InfluxDB /health endpoint", + Flags: commonFlagsNoToken, + Action: func(ctx *cli.Context) error { + cli, err := newCli(ctx) + if err != nil { + return err + } + client, err := newApiClient(ctx, cli, false) + if err != nil { + return err + } + return cli.Ping(standardCtx(ctx), client.HealthApi) + }, +} diff --git a/cmd/influx/setup.go b/cmd/influx/setup.go new file mode 100644 index 0000000..daf763c --- /dev/null +++ b/cmd/influx/setup.go @@ -0,0 +1,87 @@ +package main + +import ( + "github.com/influxdata/influx-cli/v2/internal" + "github.com/urfave/cli/v2" +) + +var setupCmd = cli.Command{ + Name: "setup", + Usage: "Setup instance with initial user, org, bucket", + Flags: append( + commonFlagsNoToken, + &cli.StringFlag{ + Name: "username", + Usage: "Name of initial user to create", + Aliases: []string{"u"}, + }, + &cli.StringFlag{ + Name: "password", + Usage: "Password to set on initial user", + Aliases: []string{"p"}, + }, + &cli.StringFlag{ + Name: tokenFlag, + Usage: "Auth token to set on the initial user", + Aliases: []string{"t"}, + EnvVars: []string{"INFLUX_TOKEN"}, + DefaultText: "auto-generated", + }, + &cli.StringFlag{ + Name: "org", + Usage: "Name of initial organization to create", + Aliases: []string{"o"}, + }, + &cli.StringFlag{ + Name: "bucket", + Usage: "Name of initial bucket to create", + Aliases: []string{"b"}, + }, + &cli.StringFlag{ + Name: "retention", + Usage: "Duration initial bucket will retain data, or 0 for infinite", + Aliases: []string{"r"}, + DefaultText: "infinite", + }, + &cli.BoolFlag{ + Name: "force", + Usage: "Skip confirmation prompt", + Aliases: []string{"f"}, + }, + &cli.StringFlag{ + Name: "name", + Usage: "Name to set on CLI config generated for the InfluxDB instance, required if other configs exist", + Aliases: []string{"n"}, + }, + &cli.BoolFlag{ + Name: printJsonFlag, + Usage: "Output data as JSON", + EnvVars: []string{"INFLUX_OUTPUT_JSON"}, + }, + &cli.BoolFlag{ + Name: hideHeadersFlag, + Usage: "Hide the table headers in output data", + EnvVars: []string{"INFLUX_HIDE_HEADERS"}, + }, + ), + Action: func(ctx *cli.Context) error { + cli, err := newCli(ctx) + if err != nil { + return err + } + client, err := newApiClient(ctx, cli, false) + if err != nil { + return err + } + return cli.Setup(standardCtx(ctx), client.SetupApi, &internal.SetupParams{ + Username: ctx.String("username"), + Password: ctx.String("password"), + AuthToken: ctx.String(tokenFlag), + Org: ctx.String("org"), + Bucket: ctx.String("bucket"), + Retention: ctx.String("retention"), + Force: ctx.Bool("force"), + ConfigName: ctx.String("name"), + }) + }, +} diff --git a/cmd/influx/version.go b/cmd/influx/version.go new file mode 100644 index 0000000..adb28db --- /dev/null +++ b/cmd/influx/version.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + + "github.com/urfave/cli/v2" +) + +var versionCmd = cli.Command{ + Name: "version", + Usage: "Print the influx CLI version", + Action: func(*cli.Context) error { + fmt.Printf("Influx CLI %s (git: %s) build_date: %s\n", version, commit, date) + return nil + }, +}