// parseCloudConfig parses the provided config into a node structure and logs // any parsing issues into the provided report. Unrecoverable errors are // returned as an error. func parseCloudConfig(cfg []byte, report *Report) (node, error) { yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) { return nameIn } // unmarshal the config into an implicitly-typed form. The yaml library // will implicitly convert types into their normalized form // (e.g. 0744 -> 484, off -> false). var weak map[interface{}]interface{} if err := yaml.Unmarshal(cfg, &weak); err != nil { matches := yamlLineError.FindStringSubmatch(err.Error()) if len(matches) == 3 { line, err := strconv.Atoi(matches[1]) if err != nil { return node{}, err } msg := matches[2] report.Error(line, msg) return node{}, nil } matches = yamlError.FindStringSubmatch(err.Error()) if len(matches) == 2 { report.Error(1, matches[1]) return node{}, nil } return node{}, errors.New("couldn't parse yaml error") } w := NewNode(weak, NewContext(cfg)) w = normalizeNodeNames(w, report) // unmarshal the config into the explicitly-typed form. yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) { return strings.Replace(nameIn, "-", "_", -1) } var strong config.CloudConfig if err := yaml.Unmarshal([]byte(cfg), &strong); err != nil { return node{}, err } s := NewNode(strong, NewContext(cfg)) // coerceNodes weak nodes and strong nodes. strong nodes replace weak nodes // if they are compatible types (this happens when the yaml library // converts the input). // (e.g. weak 484 is replaced by strong 0744, weak 4 is not replaced by // strong false) return coerceNodes(w, s), nil }
// NewCloudConfig instantiates a new CloudConfig from the given contents (a // string of YAML), returning any error encountered. It will ignore unknown // fields but log encountering them. func NewCloudConfig(contents string) (*CloudConfig, error) { yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) { return strings.Replace(nameIn, "-", "_", -1) } var cfg CloudConfig err := yaml.Unmarshal([]byte(contents), &cfg) return &cfg, err }