From 07785194c4c064a864d7a17efa9ce4cc4a431dd4 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 1 Dec 2019 12:18:41 -0800 Subject: [PATCH] [#3896bk] Ensure the data types are maintained correctly --- parser/parser.go | 56 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index 8e0efbd..e615965 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -15,6 +15,7 @@ import ( "io/ioutil" "os" "regexp" + "strconv" "strings" ) @@ -121,6 +122,31 @@ func readFileBytes(path string) ([]byte, error) { return ioutil.ReadAll(file) } +// Helper function to set the value of the JSON key item based on the jsonparser value +// type returned. +func setPathway(c *gabs.Container, path string, value []byte, dt jsonparser.ValueType) error { + var err error + + switch dt { + case jsonparser.Number: + { + v, _ := strconv.Atoi(string(value)) + _, err = c.SetP(v, path) + } + break + case jsonparser.Boolean: + { + v, _ := strconv.ParseBool(string(value)) + _, err = c.SetP(v, path) + } + break + default: + _, err = c.SetP(string(value), path) + } + + return err +} + // Iterate over an unstructured JSON/YAML/etc. interface and set all of the required // key/value pairs for the configuration file. // @@ -137,7 +163,7 @@ func (f *ConfigurationFile) IterateOverJson(data []byte) (*gabs.Container, error } for _, v := range f.Replace { - value, err := f.lookupConfigurationValue(v.Value) + value, dt, err := f.lookupConfigurationValue(v) if err != nil { return nil, err } @@ -153,12 +179,12 @@ func (f *ConfigurationFile) IterateOverJson(data []byte) (*gabs.Container, error // If the child is a null value, nothing will happen. Seems reasonable as of the // time this code is being written. for _, child := range parsed.Path(strings.Trim(parts[0], ".")).Children() { - if _, err := child.SetP(value, strings.Trim(parts[1], ".")); err != nil { + if err := setPathway(child, strings.Trim(parts[1], "."), value, dt); err != nil { return nil, err } } } else { - if _, err = parsed.SetP(value, v.Match); err != nil { + if err = setPathway(parsed, v.Match, value, dt); err != nil { return nil, err } } @@ -268,12 +294,12 @@ func (f *ConfigurationFile) parsePropertiesFile(path string) error { } for _, replace := range f.Replace { - v, err := f.lookupConfigurationValue(replace.Value) + data, _, err := f.lookupConfigurationValue(replace) if err != nil { return errors.WithStack(err) } - if _, _, err := p.Set(replace.Match, v); err != nil { + if _, _, err := p.Set(replace.Match, string(data)); err != nil { return errors.WithStack(err) } } @@ -289,38 +315,36 @@ func (f *ConfigurationFile) parsePropertiesFile(path string) error { } // Looks up a configuration value on the Daemon given a dot-notated syntax. -func (f *ConfigurationFile) lookupConfigurationValue(value string) (string, error) { - if !configMatchRegex.Match([]byte(value)) { - return value, nil +func (f *ConfigurationFile) lookupConfigurationValue(cfr ConfigurationFileReplacement) ([]byte, jsonparser.ValueType, error) { + if !configMatchRegex.Match([]byte(cfr.Value)) { + return []byte(cfr.Value), cfr.ValueType, nil } // If there is a match, lookup the value in the configuration for the Daemon. If no key // is found, just return the string representation, otherwise use the value from the // daemon configuration here. - v := configMatchRegex.ReplaceAllString(value, "$1") + huntPath := configMatchRegex.ReplaceAllString(cfr.Value, "$1") var path []string // The camel casing is important here, the configuration for the Daemon does not use // JSON, and as such all of the keys will be generated in CamelCase format, rather than // the expected snake_case from the old Daemon. - for _, value := range strings.Split(v, ".") { + for _, value := range strings.Split(huntPath, ".") { path = append(path, strcase.ToCamel(value)) } // Look for the key in the configuration file, and if found return that value to the // calling function. - match, err := jsonparser.GetString(f.configuration, path...) + match, dt, _, err := jsonparser.Get(f.configuration, path...) if err != nil { if err != jsonparser.KeyPathNotFoundError { - return "", errors.WithStack(err) + return match, dt, errors.WithStack(err) } // If there is no key, keep the original value intact, that way it is obvious there // is a replace issue at play. - v = value + return []byte(cfr.Value), cfr.ValueType, nil } else { - v = match + return match, cfr.ValueType, nil } - - return v, nil }