Export command prints turned-off sub-sys as comments (#8594)

This PR also tries to

- Preserve the order of keys printed in export command
- Fix cache to be enabled with _STATE env to keep
  backward compatibility
This commit is contained in:
Harshavardhana
2019-12-03 10:50:20 -08:00
committed by kannappanr
parent 2ab8d5e47f
commit 794eb54da8
7 changed files with 133 additions and 120 deletions

View File

@@ -51,11 +51,7 @@ func (adm *AdminClient) DelConfigKV(k string) (err error) {
// SetConfigKV - set key value config to server.
func (adm *AdminClient) SetConfigKV(kv string) (err error) {
targets, err := ParseSubSysTarget([]byte(kv))
if err != nil {
return err
}
econfigBytes, err := EncryptData(adm.secretAccessKey, []byte(targets.String()))
econfigBytes, err := EncryptData(adm.secretAccessKey, []byte(kv))
if err != nil {
return err
}

View File

@@ -59,22 +59,33 @@ func (kvs KVS) Lookup(key string) (string, bool) {
return "", false
}
// Targets sub-system targets
type Targets map[string]map[string]KVS
// Target signifies an individual target
type Target struct {
SubSystem string `json:"subSys"`
KVS KVS `json:"kvs"`
}
// Targets sub-system targets
type Targets []Target
// Standard config keys and values.
const (
stateKey = "state"
commentKey = "comment"
StateKey = "state"
CommentKey = "comment"
// State values
StateOn = "on"
StateOff = "off"
)
func (kvs KVS) String() string {
var s strings.Builder
for _, kv := range kvs {
// Do not need to print state
if kv.Key == stateKey {
// Do not need to print state which is on.
if kv.Key == StateKey && kv.Value == StateOn {
continue
}
if kv.Key == commentKey && kv.Value == "" {
if kv.Key == CommentKey && kv.Value == "" {
continue
}
s.WriteString(kv.Key)
@@ -94,13 +105,7 @@ func (kvs KVS) String() string {
// Count - returns total numbers of target
func (t Targets) Count() int {
var count int
for _, targetKV := range t {
for range targetKV {
count++
}
}
return count
return len(t)
}
func hasSpace(s string) bool {
@@ -115,19 +120,15 @@ func hasSpace(s string) bool {
func (t Targets) String() string {
var s strings.Builder
count := t.Count()
for subSys, targetKV := range t {
for target, kv := range targetKV {
count--
s.WriteString(subSys)
if target != Default {
s.WriteString(SubSystemSeparator)
s.WriteString(target)
}
s.WriteString(KvSpaceSeparator)
s.WriteString(kv.String())
if (len(t) > 1 || len(targetKV) > 1) && count > 0 {
s.WriteString(KvNewline)
}
// Print all "on" states entries
for _, targetKV := range t {
kv := targetKV.KVS
count--
s.WriteString(targetKV.SubSystem)
s.WriteString(KvSpaceSeparator)
s.WriteString(kv.String())
if len(t) > 1 && count > 0 {
s.WriteString(KvNewline)
}
}
return s.String()
@@ -137,6 +138,7 @@ func (t Targets) String() string {
const (
SubSystemSeparator = `:`
KvSeparator = `=`
KvComment = `#`
KvSpaceSeparator = ` `
KvNewline = "\n"
KvDoubleQuote = `"`
@@ -145,13 +147,14 @@ const (
Default = `_`
)
// This function is needed, to trim off single or double quotes, creeping into the values.
func sanitizeValue(v string) string {
// SanitizeValue - this function is needed, to trim off single or double quotes, creeping into the values.
func SanitizeValue(v string) string {
v = strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(v), KvDoubleQuote), KvDoubleQuote)
return strings.TrimSuffix(strings.TrimPrefix(v, KvSingleQuote), KvSingleQuote)
}
func convertTargets(s string, targets Targets) error {
// AddTarget - adds new targets, by parsing the input string s.
func (t *Targets) AddTarget(s string) error {
inputs := strings.SplitN(s, KvSpaceSeparator, 2)
if len(inputs) <= 1 {
return fmt.Errorf("invalid number of arguments '%s'", s)
@@ -170,7 +173,7 @@ func convertTargets(s string, targets Targets) error {
if len(kv) == 1 && prevK != "" {
kvs = append(kvs, KV{
Key: prevK,
Value: strings.Join([]string{kvs.Get(prevK), sanitizeValue(kv[0])}, KvSpaceSeparator),
Value: strings.Join([]string{kvs.Get(prevK), SanitizeValue(kv[0])}, KvSpaceSeparator),
})
continue
}
@@ -180,28 +183,24 @@ func convertTargets(s string, targets Targets) error {
prevK = kv[0]
kvs = append(kvs, KV{
Key: kv[0],
Value: sanitizeValue(kv[1]),
Value: SanitizeValue(kv[1]),
})
}
_, ok := targets[subSystemValue[0]]
if !ok {
targets[subSystemValue[0]] = map[string]KVS{}
}
if len(subSystemValue) == 2 {
targets[subSystemValue[0]][subSystemValue[1]] = kvs
} else {
targets[subSystemValue[0]][Default] = kvs
}
*t = append(*t, Target{
SubSystem: inputs[0],
KVS: kvs,
})
return nil
}
// ParseSubSysTarget - parse sub-system target
func ParseSubSysTarget(buf []byte) (Targets, error) {
targets := make(map[string]map[string]KVS)
var targets Targets
bio := bufio.NewScanner(bytes.NewReader(buf))
for bio.Scan() {
if err := convertTargets(bio.Text(), targets); err != nil {
if err := targets.AddTarget(bio.Text()); err != nil {
return nil, err
}
}