diff --git a/server/config_check_test.go b/server/config_check_test.go index 3bfcea45..d629c0ad 100644 --- a/server/config_check_test.go +++ b/server/config_check_test.go @@ -36,6 +36,9 @@ func TestConfigCheck(t *testing.T) { // errorLine is the location of the error. errorLine int + + // warning errors also include a reason optionally + reason string }{ { name: "when unknown field is used at top level", @@ -446,6 +449,26 @@ func TestConfigCheck(t *testing.T) { defaultErr: nil, pedanticErr: nil, }, + { + name: "when setting permissions within cluster authorization block", + config: ` + cluster { + authorization { + permissions = { + publish = { allow = ["foo", "bar"] } + } + } + + permissions = { + publish = { deny = ["foo", "bar"] } + } + } + `, + defaultErr: nil, + pedanticErr: errors.New(`invalid use of field "authorization"`), + errorLine: 7, + reason: `setting "permissions" within cluster authorization block is deprecated`, + }, } checkConfig := func(config string, pedantic bool) error { @@ -476,6 +499,9 @@ func TestConfigCheck(t *testing.T) { expectedErr := test.pedanticErr if err != nil && expectedErr != nil { msg := fmt.Sprintf("%s in %s:%d", expectedErr.Error(), conf, test.errorLine) + if test.reason != "" { + msg += ": " + test.reason + } if err.Error() != msg { t.Errorf("Expected %q, got %q", msg, err.Error()) } diff --git a/server/opts.go b/server/opts.go index 9f29f9da..a7efa8b1 100644 --- a/server/opts.go +++ b/server/opts.go @@ -210,6 +210,22 @@ func (e *unknownConfigFieldErr) Error() string { return msg } +type configWarningErr struct { + field string + token token + configFile string + reason string +} + +func (e *configWarningErr) Error() string { + msg := fmt.Sprintf("invalid use of field %q", e.field) + if e.token != nil { + msg += fmt.Sprintf(" in %s:%d", e.configFile, e.token.Line()) + } + msg += ": " + e.reason + return msg +} + // ProcessConfigFile processes a configuration file. // FIXME(dlc): Hacky func ProcessConfigFile(configFile string) (*Options, error) { @@ -489,9 +505,21 @@ func parseCluster(v interface{}, opts *Options) error { opts.Cluster.Username = auth.user opts.Cluster.Password = auth.pass opts.Cluster.AuthTimeout = auth.timeout - // Do not set permissions if they were specified in top-level cluster block. - if auth.defaultPermissions != nil && opts.Cluster.Permissions == nil { - setClusterPermissions(&opts.Cluster, auth.defaultPermissions) + + if auth.defaultPermissions != nil { + if pedantic { + return &configWarningErr{ + field: mk, + token: tk, + reason: `setting "permissions" within cluster authorization block is deprecated`, + configFile: tk.SourceFile(), + } + } + + // Do not set permissions if they were specified in top-level cluster block. + if opts.Cluster.Permissions == nil { + setClusterPermissions(&opts.Cluster, auth.defaultPermissions) + } } case "routes": ra := mv.([]interface{}) @@ -534,11 +562,7 @@ func parseCluster(v interface{}, opts *Options) error { case "connect_retries": opts.Cluster.ConnectRetries = int(mv.(int64)) case "permissions": - pm, ok := mv.(map[string]interface{}) - if !ok { - return fmt.Errorf("Expected permissions to be a map/struct, got %+v", mv) - } - perms, err := parseUserPermissions(pm, opts) + perms, err := parseUserPermissions(mv, opts) if err != nil { return err }