chef-golang icon indicating copy to clipboard operation
chef-golang copied to clipboard

merged node attribute access

Open josephholsten opened this issue 10 years ago • 0 comments

For clients that want to access node attributes, it's nice to be able to access the merged value instead of traversing default, normal and automatic. I'm accessing search results, so this is what I'm using atm:

// take a node with default, normal and automatic attributes
// and return a single merged map of the highest precedence values
func mergeNodeAttrs(node map[string]interface{}) map[string]interface{} {
    // default is a keyword, dfault will have to do
    dfault, _ := node["default"].(map[string]interface{})
    normal, _ := node["normal"].(map[string]interface{})
    automatic, _ := node["automatic"].(map[string]interface{})
    // merge together attributes with automatic at highest precedence,
    // followed by normal, followed by default
    result := mergeAttrMap(mergeAttrMap(dfault, normal), automatic)
    return result
}

// merge n into m, preferring values from n
func mergeAttrMap(m, n map[string]interface{}) map[string]interface{} {
    result := m
    for k := range n {
        mmap, mok := m[k].(map[string]interface{})
        nmap, nok := n[k].(map[string]interface{})
        if mok && nok {
            result[k] = mergeAttrMap(mmap, nmap)
        } else {
            result[k] = n[k]
        }
    }
    return result
}

I also use a shorthand query syntax:

// query a node attribute map using a query string with simplified
// syntax, so that foo.bar.baz is equivalent to node["foo"]["bar"]["baz"],
// and returning nil in the event of invalid access
func getAttr(node map[string]interface{}, query string) interface{} {
    segments := strings.Split(query, ".")
    current := node
    var result interface{}
    for _, seg := range segments {
        result = current[seg]
        // descent into empty map doesn't matter, it
        // correctly returns null regardless
        current, _ = current[seg].(map[string]interface{})
    }
    return result
}

josephholsten avatar May 13 '14 03:05 josephholsten