Пример #1
0
// Get gets a client from the data store.
func Get(clientname string) (*Client, util.Gerror) {
	var client *Client
	var err error

	if config.UsingDB() {
		client, err = getClientSQL(clientname)
		if err != nil {
			var gerr util.Gerror
			if err != sql.ErrNoRows {
				gerr = util.Errorf(err.Error())
				gerr.SetStatus(http.StatusInternalServerError)
			} else {
				gerr = util.Errorf("Client %s not found", clientname)
				gerr.SetStatus(http.StatusNotFound)
			}
			return nil, gerr
		}
	} else {
		ds := datastore.New()
		c, found := ds.Get("client", clientname)
		if !found {
			gerr := util.Errorf("Client %s not found", clientname)
			gerr.SetStatus(http.StatusNotFound)
			return nil, gerr
		}
		if c != nil {
			client = c.(*Client)
		}
	}
	return client, nil
}
Пример #2
0
// Get a user.
func Get(name string) (*User, util.Gerror) {
	var user *User
	if config.UsingDB() {
		var err error
		user, err = getUserSQL(name)
		if err != nil {
			var gerr util.Gerror
			if err != sql.ErrNoRows {
				gerr = util.Errorf(err.Error())
				gerr.SetStatus(http.StatusInternalServerError)
			} else {
				gerr = util.Errorf("Client %s not found", name)
				gerr.SetStatus(http.StatusNotFound)
			}
			return nil, gerr
		}
	} else {
		ds := datastore.New()
		u, found := ds.Get("user", name)
		if !found {
			err := util.Errorf("User %s not found", name)
			return nil, err
		}
		if u != nil {
			user = u.(*User)
		}
	}
	return user, nil
}
Пример #3
0
// Get a data bag.
func Get(dbName string) (*DataBag, util.Gerror) {
	var dataBag *DataBag
	var err error
	if config.UsingDB() {
		dataBag, err = getDataBagSQL(dbName)
		if err != nil {
			var gerr util.Gerror
			if err == sql.ErrNoRows {
				gerr = util.Errorf("Cannot load data bag %s", dbName)
				gerr.SetStatus(http.StatusNotFound)
			} else {
				gerr = util.Errorf(err.Error())
				gerr.SetStatus(http.StatusInternalServerError)
			}
			return nil, gerr
		}
	} else {
		ds := datastore.New()
		d, found := ds.Get("data_bag", dbName)
		if !found {
			err := util.Errorf("Cannot load data bag %s", dbName)
			err.SetStatus(http.StatusNotFound)
			return nil, err
		}
		if d != nil {
			dataBag = d.(*DataBag)
			for _, v := range dataBag.DataBagItems {
				z := datastore.WalkMapForNil(v.RawData)
				v.RawData = z.(map[string]interface{})
			}
		}
	}
	return dataBag, nil
}
Пример #4
0
// New creates an empty data bag, and kicks off adding it to the index.
func New(name string) (*DataBag, util.Gerror) {
	var found bool
	var err util.Gerror

	if err = validateDataBagName(name, false); err != nil {
		return nil, err
	}

	if config.UsingDB() {
		var cerr error
		found, cerr = checkForDataBagSQL(datastore.Dbh, name)
		if cerr != nil {
			err = util.Errorf(cerr.Error())
			err.SetStatus(http.StatusInternalServerError)
			return nil, err
		}
	} else {
		ds := datastore.New()
		_, found = ds.Get("data_bag", name)
	}
	if found {
		err = util.Errorf("Data bag %s already exists", name)
		err.SetStatus(http.StatusConflict)
		return nil, err
	}

	dbiMap := make(map[string]*DataBagItem)
	dataBag := &DataBag{
		Name:         name,
		DataBagItems: dbiMap,
	}
	indexer.CreateNewCollection(name)
	return dataBag, nil
}
Пример #5
0
// UpdateFromJSON updates a user from a JSON object, carrying out a bunch of
// validations inside.
func (u *User) UpdateFromJSON(jsonUser map[string]interface{}) util.Gerror {
	userName, nerr := util.ValidateAsString(jsonUser["name"])
	if nerr != nil {
		return nerr
	}
	if u.Username != userName {
		err := util.Errorf("User name %s and %s from JSON do not match", u.Username, userName)
		return err
	}

	/* Validations. */
	/* Invalid top level elements */
	validElements := []string{"username", "name", "org_name", "public_key", "private_key", "admin", "password", "email", "salt"}
ValidElem:
	for k := range jsonUser {
		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

	// Check the password first. If it's bad, bail before touching anything
	// else.
	if passwd, ok := jsonUser["password"]; ok {
		passwd, verr = util.ValidateAsString(passwd)
		if verr != nil {
			return verr
		}
		if passwd != "" {
			verr = u.SetPasswd(passwd.(string))
			if verr != nil {
				return verr
			}
		}
	}

	if adminVal, ok := jsonUser["admin"]; ok {
		var ab bool
		if ab, verr = util.ValidateAsBool(adminVal); verr != nil {
			// NOTE: may need to tweak this error message depending
			// if this is a user or a client
			verr = util.Errorf("Field 'admin' invalid")
			return verr
		} else if u.Admin && !ab {
			if u.isLastAdmin() {
				verr = util.Errorf("Cannot remove admin status from the last admin")
				verr.SetStatus(http.StatusForbidden)
				return verr
			}
		}
		u.Admin = ab
	}

	return nil
}
Пример #6
0
func chkInMemUser(name string) util.Gerror {
	var err util.Gerror
	ds := datastore.New()
	if _, found := ds.Get("user", name); found {
		err = util.Errorf("a user named %s was found that would conflict with this client", name)
		err.SetStatus(http.StatusConflict)
	}
	return err
}
Пример #7
0
// New creates a new API user.
func New(name string) (*User, util.Gerror) {
	var found bool
	var err util.Gerror
	if config.UsingDB() {
		var uerr error
		found, uerr = checkForUserSQL(datastore.Dbh, name)
		if uerr != nil {
			err = util.Errorf(uerr.Error())
			err.SetStatus(http.StatusInternalServerError)
			return nil, err
		}
	} else {
		ds := datastore.New()
		_, found = ds.Get("user", name)
	}
	if found {
		err := util.Errorf("User '%s' already exists", name)
		err.SetStatus(http.StatusConflict)
		return nil, err
	}

	if err := validateUserName(name); err != nil {
		return nil, err
	}

	salt, saltErr := chefcrypto.GenerateSalt()
	if saltErr != nil {
		err := util.Errorf(saltErr.Error())
		return nil, err
	}
	user := &User{
		Username: name,
		Name:     name,
		Admin:    false,
		Email:    "",
		pubKey:   "",
		salt:     salt,
	}
	return user, nil
}
Пример #8
0
// Get an environment.
func Get(envName string) (*ChefEnvironment, util.Gerror) {
	if envName == "_default" {
		return defaultEnvironment(), nil
	}
	var env *ChefEnvironment
	var found bool
	if config.UsingDB() {
		var err error
		env, err = getEnvironmentSQL(envName)
		if err != nil {
			var gerr util.Gerror
			if err != sql.ErrNoRows {
				gerr = util.CastErr(err)
				gerr.SetStatus(http.StatusInternalServerError)
				return nil, gerr
			}
			found = false
		} else {
			found = true
		}
	} else {
		ds := datastore.New()
		var e interface{}
		e, found = ds.Get("env", envName)
		if e != nil {
			env = e.(*ChefEnvironment)
		}
	}
	if !found {
		err := util.Errorf("Cannot load environment %s", envName)
		err.SetStatus(http.StatusNotFound)
		return nil, err
	}

	return env, nil
}
Пример #9
0
// New creates a new client.
func New(clientname string) (*Client, util.Gerror) {
	var found bool
	var err util.Gerror
	if config.UsingDB() {
		var cerr error
		found, cerr = checkForClientSQL(datastore.Dbh, clientname)
		if cerr != nil {
			err = util.Errorf(cerr.Error())
			err.SetStatus(http.StatusInternalServerError)
			return nil, err
		}
	} else {
		ds := datastore.New()
		_, found = ds.Get("client", clientname)
	}
	if found {
		err = util.Errorf("Client already exists")
		err.SetStatus(http.StatusConflict)
		return nil, err
	}
	if err := validateClientName(clientname); err != nil {
		return nil, err
	}
	client := &Client{
		Name:        clientname,
		NodeName:    clientname,
		ChefType:    "client",
		JSONClass:   "Chef::ApiClient",
		Validator:   false,
		Orgname:     "",
		pubKey:      "",
		Admin:       false,
		Certificate: "",
	}
	return client, nil
}
Пример #10
0
// UpdateFromJSON updates a client/user from a json object. Does a bunch of
// validations inside rather than in the handler.
func (c *Client) UpdateFromJSON(jsonActor map[string]interface{}) util.Gerror {
	actorName, nerr := util.ValidateAsString(jsonActor["name"])
	if nerr != nil {
		return nerr
	}
	if c.Name != actorName {
		err := util.Errorf("Client name %s and %s from JSON do not match", c.Name, actorName)
		return err
	}

	/* Validations. */
	/* Invalid top level elements */
	validElements := []string{"name", "json_class", "chef_type", "validator", "org_name", "orgname", "public_key", "private_key", "admin", "certificate", "password", "node_name", "clientname"}
ValidElem:
	for k := range jsonActor {
		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

	jsonActor["json_class"], verr = util.ValidateAsFieldString(jsonActor["json_class"])
	if verr != nil {
		if verr.Error() == "Field 'name' nil" {
			jsonActor["json_class"] = c.JSONClass
		} else {
			return verr
		}
	} else {
		if jsonActor["json_class"].(string) != "Chef::ApiClient" {
			verr = util.Errorf("Field 'json_class' invalid")
			return verr
		}
	}

	jsonActor["chef_type"], verr = util.ValidateAsFieldString(jsonActor["chef_type"])
	if verr != nil {
		if verr.Error() == "Field 'name' nil" {
			jsonActor["chef_type"] = c.ChefType
		} else {
			return verr
		}
	} else {
		if jsonActor["chef_type"].(string) != "client" {
			verr = util.Errorf("Field 'chef_type' invalid")
			return verr
		}
	}

	var ab, vb bool
	if adminVal, ok := jsonActor["admin"]; ok {
		if ab, verr = util.ValidateAsBool(adminVal); verr != nil {
			// NOTE: may need to tweak this error message depending
			// if this is a user or a client
			verr = util.Errorf("Field 'admin' invalid")
			return verr
		} else if c.Admin && !ab {
			if c.isLastAdmin() {
				verr = util.Errorf("Cannot remove admin status from the last admin")
				verr.SetStatus(http.StatusForbidden)
				return verr
			}
		}
	}
	if validatorVal, ok := jsonActor["validator"]; ok {
		if vb, verr = util.ValidateAsBool(validatorVal); verr != nil {
			return verr
		}
	}
	if ab && vb {
		verr = util.Errorf("Client can be either an admin or a validator, but not both.")
		verr.SetStatus(http.StatusBadRequest)
		return verr
	}
	c.Admin = ab
	c.Validator = vb

	c.ChefType = jsonActor["chef_type"].(string)
	c.JSONClass = jsonActor["json_class"].(string)

	return nil
}