Example #1
0
// 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
}
Example #2
0
// 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
}