Improve the way config store transforms a value to string

This commit provide a better way to transform the value to string when
they are loaded from the driver.
Fixes #14074
However the way the config driver loaded config values and configstore
stores it back and forth seems repetitive and should be optimized.

Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
Daniel Jiang 2021-01-25 21:35:04 +08:00 committed by Ziming
parent fbfc943e8f
commit ea76594469
2 changed files with 72 additions and 1 deletions

View File

@ -2,12 +2,15 @@
package store
import (
"encoding/json"
"errors"
"fmt"
"github.com/goharbor/harbor/src/common/config/metadata"
"github.com/goharbor/harbor/src/common/config/store/driver"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/lib/log"
"reflect"
"strconv"
"sync"
)
@ -60,8 +63,12 @@ func (c *ConfigStore) Load() error {
return err
}
for key, value := range cfgs {
strValue, err := toString(value)
if err != nil {
log.Errorf("failed to transform the value from driver to string, key: %s, value: %v, error: %v", key, value, err)
continue
}
cfgValue := metadata.ConfigureValue{}
strValue := fmt.Sprintf("%v", value)
err = cfgValue.Set(key, strValue)
if err != nil {
log.Errorf("error when loading data item, key %v, value %v, error %v", key, value, err)
@ -110,3 +117,26 @@ func (c *ConfigStore) Update(cfgMap map[string]interface{}) error {
// Update to driver
return c.cfgDriver.Save(cfgMap)
}
func toString(value interface{}) (string, error) {
if value == nil {
return "nil", nil
}
v := reflect.ValueOf(value)
switch v.Kind() {
case reflect.Map, reflect.Array, reflect.Slice, reflect.Struct:
d, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(d), nil
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(v.Int(), 10), nil
case reflect.Bool:
return strconv.FormatBool(v.Bool()), nil
case reflect.String:
return value.(string), nil
default:
return fmt.Sprintf("%v", value), nil
}
}

View File

@ -50,3 +50,44 @@ func TestConfigStore_Load(t *testing.T) {
assert.Equal(t, "ldap://ldap.vmware.com", cfgValue.GetString())
}
func TestToString(t *testing.T) {
cases := []struct {
name string
value interface{}
expect string
}{
{
name: "transform int",
value: 999,
expect: "999",
},
{
name: "transform slice",
value: []int{0, 1, 2},
expect: "[0,1,2]",
},
{
name: "transform map",
value: map[string]string{"k": "v"},
expect: "{\"k\":\"v\"}",
},
{
name: "transform bool",
value: false,
expect: "false",
},
{
name: "transform nil",
value: nil,
expect: "nil",
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
s, err := toString(c.value)
assert.Nil(t, err)
assert.Equal(t, c.expect, s)
})
}
}