// UpdateFromJSON updates an existing node with the uploaded JSON. func (n *Node) UpdateFromJSON(jsonNode map[string]interface{}) util.Gerror { /* It's actually totally legitimate to save a node with a different * name than you started with, but we need to get/create a new node for * it is all. */ nodeName, nerr := util.ValidateAsString(jsonNode["name"]) if nerr != nil { return nerr } if n.Name != nodeName { err := util.Errorf("Node name %s and %s from JSON do not match.", n.Name, nodeName) return err } /* Validations */ /* Look for invalid top level elements. *We* don't have to worry about * them, but chef-pedant cares (probably because Chef <=10 stores * json objects directly, dunno about Chef 11). */ validElements := []string{"name", "json_class", "chef_type", "chef_environment", "run_list", "override", "normal", "default", "automatic"} ValidElem: for k := range jsonNode { for _, i := range validElements { if k == i { continue ValidElem } } err := util.Errorf("Invalid key %s in request body", k) return err } var verr util.Gerror jsonNode["run_list"], verr = util.ValidateRunList(jsonNode["run_list"]) if verr != nil { return verr } attrs := []string{"normal", "automatic", "default", "override"} for _, a := range attrs { jsonNode[a], verr = util.ValidateAttributes(a, jsonNode[a]) if verr != nil { return verr } } jsonNode["chef_environment"], verr = util.ValidateAsFieldString(jsonNode["chef_environment"]) if verr != nil { if verr.Error() == "Field 'name' nil" { jsonNode["chef_environment"] = n.ChefEnvironment } else { return verr } } else { if !util.ValidateEnvName(jsonNode["chef_environment"].(string)) { verr = util.Errorf("Field 'chef_environment' invalid") return verr } } jsonNode["json_class"], verr = util.ValidateAsFieldString(jsonNode["json_class"]) if verr != nil { if verr.Error() == "Field 'name' nil" { jsonNode["json_class"] = n.JSONClass } else { return verr } } else { if jsonNode["json_class"].(string) != "Chef::Node" { verr = util.Errorf("Field 'json_class' invalid") return verr } } jsonNode["chef_type"], verr = util.ValidateAsFieldString(jsonNode["chef_type"]) if verr != nil { if verr.Error() == "Field 'name' nil" { jsonNode["chef_type"] = n.ChefType } else { return verr } } else { if jsonNode["chef_type"].(string) != "node" { verr = util.Errorf("Field 'chef_type' invalid") return verr } } /* and setting */ n.ChefEnvironment = jsonNode["chef_environment"].(string) n.ChefType = jsonNode["chef_type"].(string) n.JSONClass = jsonNode["json_class"].(string) n.RunList = jsonNode["run_list"].([]string) n.Normal = jsonNode["normal"].(map[string]interface{}) n.Automatic = jsonNode["automatic"].(map[string]interface{}) n.Default = jsonNode["default"].(map[string]interface{}) n.Override = jsonNode["override"].(map[string]interface{}) return nil }
// UpdateFromJSON updates an existing role with the uploaded JSON. func (r *Role) UpdateFromJSON(jsonRole map[string]interface{}) util.Gerror { /* TODO - this and node.UpdateFromJSON may be generalizeable with * reflect - look into it. */ if r.Name != jsonRole["name"] { err := util.Errorf("Role name %s and %s from JSON do not match.", r.Name, jsonRole["name"]) return err } /* Validations */ /* Look for invalid top level elements. See node/node.go for more * information. */ validElements := []string{"name", "json_class", "chef_type", "run_list", "env_run_lists", "default_attributes", "override_attributes", "description"} ValidElem: for k := range jsonRole { for _, i := range validElements { if k == i { continue ValidElem } } err := util.Errorf("Invalid key %s in request body", k) return err } var verr util.Gerror if jsonRole["run_list"], verr = util.ValidateRunList(jsonRole["run_list"]); verr != nil { return verr } if _, erlExists := jsonRole["env_run_lists"]; erlExists { for k, v := range jsonRole["env_run_lists"].(map[string][]string) { if jsonRole["env_run_lists"].(map[string][]string)[k], verr = util.ValidateRunList(v); verr != nil { return verr } } } else { jsonRole["env_run_lists"] = make(map[string][]string) } attrs := []string{"default_attributes", "override_attributes"} for _, a := range attrs { jsonRole[a], verr = util.ValidateAttributes(a, jsonRole[a]) if verr != nil { return verr } } jsonRole["json_class"], verr = util.ValidateAsFieldString(jsonRole["json_class"]) if verr != nil { if verr.Error() == "Field 'name' nil" { jsonRole["json_class"] = r.JSONClass } else { return verr } } else { if jsonRole["json_class"].(string) != "Chef::Role" { verr = util.Errorf("Field 'json_class' invalid") return verr } } // Roles can be empty, just force it into being a string jsonRole["description"], _ = util.ValidateAsString(jsonRole["description"]) jsonRole["chef_type"], verr = util.ValidateAsFieldString(jsonRole["chef_type"]) if verr != nil { if verr.Error() == "Field 'name' nil" { jsonRole["chef_type"] = r.ChefType } else { return verr } } else { if jsonRole["chef_type"].(string) != "role" { verr = util.Errorf("Field 'chef_type' invalid") return verr } } r.ChefType = jsonRole["chef_type"].(string) r.JSONClass = jsonRole["json_class"].(string) r.Description = jsonRole["description"].(string) r.RunList = jsonRole["run_list"].([]string) r.EnvRunLists = jsonRole["env_run_lists"].(map[string][]string) r.Default = jsonRole["default_attributes"].(map[string]interface{}) r.Override = jsonRole["override_attributes"].(map[string]interface{}) return nil }