[MM-58003] Allow setting AdvancedLoggingJSON via mmctl (#27388)

This commit is contained in:
Ben Schumacher 2024-07-08 21:20:25 +02:00 committed by GitHub
parent d939c1bd46
commit 3513d310af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 90 additions and 8 deletions

View File

@ -193,12 +193,15 @@ func setValueWithConversion(val reflect.Value, newValue interface{}) error {
val.Set(reflect.ValueOf(newValue))
return nil
case reflect.Slice:
if val.Type().Elem().Kind() != reflect.String {
return errors.New("unsupported type of slice")
}
v := reflect.ValueOf(newValue)
if v.Kind() != reflect.Slice {
return errors.New("target value is of type Array and provided value is not")
// Special case when setting a string to a byte slice
if val.Type().Elem().Kind() == reflect.Uint8 && v.Kind() == reflect.String {
s := newValue.(string)
v = reflect.ValueOf([]byte(s))
} else {
return errors.Errorf("target value is of type %v and provided value is %v", val.Kind(), v.Kind())
}
}
val.Set(v)
return nil
@ -206,7 +209,7 @@ func setValueWithConversion(val reflect.Value, newValue interface{}) error {
bits := val.Type().Bits()
v, err := strconv.ParseInt(newValue.(string), 10, bits)
if err != nil {
return fmt.Errorf("target value is of type %v and provided value is not", val.Kind())
return fmt.Errorf("target value is of type %v and provided value is not, err: %v", val.Kind(), err)
}
val.SetInt(v)
return nil
@ -214,7 +217,7 @@ func setValueWithConversion(val reflect.Value, newValue interface{}) error {
bits := val.Type().Bits()
v, err := strconv.ParseFloat(newValue.(string), bits)
if err != nil {
return fmt.Errorf("target value is of type %v and provided value is not", val.Kind())
return fmt.Errorf("target value is of type %v and provided value is not, err: %v", val.Kind(), err)
}
val.SetFloat(v)
return nil
@ -224,12 +227,12 @@ func setValueWithConversion(val reflect.Value, newValue interface{}) error {
case reflect.Bool:
v, err := strconv.ParseBool(newValue.(string))
if err != nil {
return errors.New("target value is of type Bool and provided value is not")
return fmt.Errorf("target value is of type %v and provided value is not, err: %v", val.Kind(), err)
}
val.SetBool(v)
return nil
default:
return errors.New("target value type is not supported")
return errors.Errorf("value type %v is not supported", val.Kind())
}
}

View File

@ -6,6 +6,7 @@ package commands
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
@ -14,6 +15,7 @@ import (
"github.com/mattermost/mattermost/server/public/model"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
@ -923,3 +925,80 @@ func TestCloudRestricted(t *testing.T) {
require.True(t, cloudRestricted(cfg, parseConfigPath(path)))
})
}
func TestSetConfigValue(t *testing.T) {
tests := map[string]struct {
path string
config *model.Config
args []string
expectedConfig *model.Config
}{
"bool": {
path: "LogSettings.EnableConsole",
args: []string{"true"},
config: &model.Config{LogSettings: model.LogSettings{
EnableConsole: model.NewBool(false),
}},
expectedConfig: &model.Config{LogSettings: model.LogSettings{
EnableConsole: model.NewBool(true),
}},
},
"string": {
path: "LogSettings.ConsoleLevel",
args: []string{"foo"},
config: &model.Config{LogSettings: model.LogSettings{
ConsoleLevel: model.NewString("ConsoleLevel"),
}},
expectedConfig: &model.Config{LogSettings: model.LogSettings{
ConsoleLevel: model.NewString("foo"),
}},
},
"int": {
path: "LogSettings.MaxFieldSize",
args: []string{"123"},
config: &model.Config{LogSettings: model.LogSettings{
MaxFieldSize: model.NewInt(0),
}},
expectedConfig: &model.Config{LogSettings: model.LogSettings{
MaxFieldSize: model.NewInt(123),
}},
},
"int64": {
path: "ServiceSettings.TLSStrictTransportMaxAge",
config: &model.Config{ServiceSettings: model.ServiceSettings{
TLSStrictTransportMaxAge: model.NewInt64(0),
}},
args: []string{"123"},
expectedConfig: &model.Config{ServiceSettings: model.ServiceSettings{
TLSStrictTransportMaxAge: model.NewInt64(123),
}},
},
"string slice": {
path: "SqlSettings.DataSourceReplicas",
args: []string{"abc", "def"},
config: &model.Config{SqlSettings: model.SqlSettings{
DataSourceReplicas: []string{},
}},
expectedConfig: &model.Config{SqlSettings: model.SqlSettings{
DataSourceReplicas: []string{"abc", "def"},
}},
},
"json.RawMessage": {
path: "LogSettings.AdvancedLoggingJSON",
config: &model.Config{LogSettings: model.LogSettings{
AdvancedLoggingJSON: nil,
}},
args: []string{`{"console1":{"Type":"console"}}`},
expectedConfig: &model.Config{LogSettings: model.LogSettings{
AdvancedLoggingJSON: json.RawMessage(`{"console1":{"Type":"console"}}`),
}},
},
}
for name, tc := range tests {
err := setConfigValue(parseConfigPath(tc.path), tc.config, tc.args)
require.NoError(t, err)
assert.Equal(t, tc.expectedConfig, tc.config, name)
}
}