Skip to content

Commit

Permalink
feat: error out when config file contains 1.x config values (#22996)
Browse files Browse the repository at this point in the history
* feat: error out when config file contains invalid options

* feat: debug logging when loading a config file

* fix: only detect flags from 1.x

* test: update tests to use toml configs
  • Loading branch information
williamhbaker authored Dec 16, 2021
1 parent 6023496 commit c51a0df
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 0 deletions.
69 changes: 69 additions & 0 deletions cmd/influxd/launcher/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/influxdata/influxdb/v2/bolt"
Expand All @@ -31,6 +32,14 @@ const (
MaxInt = 1<<uint(strconv.IntSize-1) - 1
)

func errInvalidFlags(flags []string, configFile string) error {
return fmt.Errorf(
"error: found flags from an InfluxDB 1.x configuration in config file at %s - see https://docs.influxdata.com/influxdb/latest/reference/config-options/ for flags supported on this version of InfluxDB: %s",
configFile,
strings.Join(flags, ","),
)
}

// NewInfluxdCommand constructs the root of the influxd CLI, along with a `run` subcommand.
// The `run` subcommand is set as the default to execute.
func NewInfluxdCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, error) {
Expand All @@ -46,6 +55,11 @@ func NewInfluxdCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, err
return nil, err
}

// Error out if invalid flags are found in the config file. This may indicate trying to launch 2.x using a 1.x config.
if invalidFlags := invalidFlags(v); len(invalidFlags) > 0 {
return nil, errInvalidFlags(invalidFlags, v.ConfigFileUsed())
}

runCmd := &cobra.Command{
Use: "run",
RunE: cmd.RunE,
Expand All @@ -67,6 +81,17 @@ func NewInfluxdCommand(ctx context.Context, v *viper.Viper) (*cobra.Command, err
return cmd, nil
}

func invalidFlags(v *viper.Viper) []string {
var invalid []string
for _, k := range v.AllKeys() {
if inOneDotExFlagsList(k) {
invalid = append(invalid, k)
}
}

return invalid
}

func setCmdDescriptions(cmd *cobra.Command) {
cmd.Short = "Start the influxd server"
cmd.Long = `
Expand Down Expand Up @@ -610,3 +635,47 @@ func (o *InfluxdOpts) BindCliOpts() []cli.Opt {
},
}
}

var (
oneDotExFlagsList = []string{
// "reporting-disabled" is valid in both 1x and 2x configs
"bind-address", // global setting is called "http-bind-address" on 2x

// Remaining flags, when parsed from a 1.x config file, will be in sub-sections prefixed by these headers:
"collectd.",
"continuous_queries.",
"coordinator.",
"data.",
"graphite.",
"http.",
"logging.",
"meta.",
"monitor.",
"opentsdb.",
"retention.",
"shard-precreation.",
"subscriber.",
"tls.",
"udp.",
}
)

// compareFlags checks if a given flag from the read configuration matches one from the list. If the value from the list
// ends in a ".", the given flag is check for that prefix. Otherwise, the flag is checked for equality.
func compareFlags(key, fromList string) bool {
if strings.HasSuffix(fromList, ".") {
return strings.HasPrefix(key, fromList)
}

return strings.EqualFold(key, fromList)
}

func inOneDotExFlagsList(key string) bool {
for _, f := range oneDotExFlagsList {
if compareFlags(key, f) {
return true
}
}

return false
}
69 changes: 69 additions & 0 deletions cmd/influxd/launcher/cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package launcher

import (
"strings"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)

func TestInvalidFlags(t *testing.T) {
t.Parallel()

v2config := `
bolt-path = "/db/.influxdbv2/influxd.bolt"
engine-path = "/db/.influxdbv2/engine"
http-bind-address = ":8086"
`

v1config := `
reporting-disabled = false
# Bind address to use for the RPC service for backup and restore.
bind-address = "127.0.0.1:8088"
[http]
flux-enabled = false
[data]
index-version = "inmem"`

tests := []struct {
name string
config string
want []string
}{
{
name: "empty config",
config: "",
want: []string(nil),
},
{
name: "v2 config",
config: v2config,
want: []string(nil),
},
{
name: "v1 config",
config: v1config,
want: []string{"http.flux-enabled", "data.index-version", "bind-address"},
},
{
name: "mixed config",
config: v2config + v1config,
want: []string{"http.flux-enabled", "data.index-version", "bind-address"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := strings.NewReader(tt.config)
v := viper.GetViper()
v.SetConfigType("toml")
require.NoError(t, v.ReadConfig(r))
got := invalidFlags(v)
require.ElementsMatch(t, tt.want, got)
})
}
}
4 changes: 4 additions & 0 deletions cmd/influxd/launcher/launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ func (m *Launcher) run(ctx context.Context, opts *InfluxdOpts) (err error) {
)
m.initTracing(opts)

if p := opts.Viper.ConfigFileUsed(); p != "" {
m.log.Debug("loaded config file", zap.String("path", p))
}

// Parse feature flags.
// These flags can be used to modify the remaining setup logic in this method.
// They will also be injected into the contexts of incoming HTTP requests at runtime,
Expand Down

0 comments on commit c51a0df

Please sign in to comment.