Exemple #1
0
func (api *Api) GetAllEnvCaps(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	qs := r.URL.Query() // Query string - map[string][]string

	envcaps := []EnvCap{}

	if len(qs["code"]) > 0 {
		srch := qs["code"][0]
		mutex.Lock()
		api.db.Order("code").Find(&envcaps, "code = ?", srch)
		mutex.Unlock()
	} else {
		mutex.Lock()
		err := api.db.Order("Code").Find(&envcaps)
		mutex.Unlock()
		if err.Error != nil {
			if !err.RecordNotFound() {
				rest.Error(w, err.Error.Error(), 500)
				return
			}
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(envcaps))
	for i := range envcaps {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = envcaps[i].Id
		u[i]["Code"] = envcaps[i].Code
		u[i]["Desc"] = envcaps[i].Desc
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #2
0
func (api *Api) Logout(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	session := Session{}
	var errl error = nil
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 400)
		return
	}

	mutex.Lock()
	if err := api.db.Delete(&session).Error; err != nil {
		rest.Error(w, err.Error(), 400)
		mutex.Unlock()
		return
	}
	mutex.Unlock()

	logit("User '" + login + "' logged out")
	api.LogActivity(session.Id, "User '"+login+"' logged out")
	w.WriteJson("Success")
}
Exemple #3
0
func (api *Api) AddPerm(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	permData := Perm{}

	if err := r.DecodeJsonPayload(&permData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if permData.UserId == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}
	perm := Perm{}
	mutex.Lock()
	if !api.db.Find(&perm, "env_id = ? and user_id = ?", permData.EnvId,
		permData.UserId).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Add perm

	mutex.Lock()
	if err := api.db.Save(&permData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	text := fmt.Sprintf("Added new environment permission. PermID = '%d'.",
		permData.Id)

	api.LogActivity(session.Id, text)
	w.WriteJson(permData)
}
Exemple #4
0
func (api *Api) AddEnvCap(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	EnvCapData := EnvCap{}

	if err := r.DecodeJsonPayload(&EnvCapData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if len(EnvCapData.Code) == 0 || len(EnvCapData.Desc) == 0 {
		rest.Error(w, "A required field is empty.", 400)
		return
	}
	EnvCap := EnvCap{}
	mutex.Lock()
	if !api.db.Find(&EnvCap, "code = ?", EnvCapData.Code).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Add EnvCap

	mutex.Lock()
	if err := api.db.Save(&EnvCapData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	text := fmt.Sprintf("Added new EnvCap, '%s'.",
		EnvCapData.Code)

	api.LogActivity(session.Id, text)
	w.WriteJson(EnvCapData)
}
Exemple #5
0
func (api *Api) AddRepo(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	repoData := Repo{}

	if err := r.DecodeJsonPayload(&repoData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if len(repoData.Url) == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}
	repo := Repo{}
	mutex.Lock()
	if !api.db.Find(&repo, "Url = ?", repoData.Url).
		RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Add repo

	mutex.Lock()
	if err := api.db.Save(&repoData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id, "Added new repo '"+repoData.Url+"'.")
	w.WriteJson(repoData)
}
Exemple #6
0
func (api *Api) AddOutputLine(w rest.ResponseWriter, r *rest.Request) {

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is not allowed
	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	// Check credentials
	//session := Session{}
	var errl error
	if _, errl = api.CheckLoginNoExpiry(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	//defer api.TouchSession( guid )

	outputLineData := OutputLine{}

	if err := r.DecodeJsonPayload(&outputLineData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if outputLineData.JobId == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}

	// Add OutputLine

	mutex.Lock()
	if err := api.db.Save(&outputLineData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	//text := ""
	//fmt.Sprintf( text,"%d",outputLineData.JobId )
	//api.LogActivity( session.Id, "Started outputLine logging for job '"+
	//    text+"'." )

	w.WriteJson("Success")
}
Exemple #7
0
func (api *Api) DeleteEnv(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Delete

	id := 0
	if id, errl = strconv.Atoi(r.PathParam("id")); errl != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	env := Env{}
	mutex.Lock()
	if api.db.First(&env, id).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	mutex.Lock()
	if err := api.db.Delete(&env).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	dc := Dc{}
	mutex.Lock()
	api.db.First(&dc, env.DcId)
	mutex.Unlock()

	text := fmt.Sprintf("Deleted environment '%s->%s'.",
		dc.SysName, env.SysName)

	api.LogActivity(session.Id, text)

	w.WriteJson("Success")
}
Exemple #8
0
func (api *Api) DeletePlugin(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Delete

	id := 0
	if id, errl = strconv.Atoi(r.PathParam("id")); errl != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	plugin := Plugin{}
	mutex.Lock()
	if api.db.First(&plugin, id).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	mutex.Lock()
	if err := api.db.Delete(&plugin).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	if err := api.db.Where("plugin_id = ?", plugin.Id).
		Delete(File{}).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id,
		"Deleted plugin '"+plugin.Name+"'.")

	w.WriteJson("Success")
}
Exemple #9
0
func (api *Api) DeleteJob(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Delete

	id := 0
	if id, errl = strconv.Atoi(r.PathParam("id")); errl != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	job := Job{}
	mutex.Lock()
	if api.db.First(&job, id).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	mutex.Lock()
	if err := api.db.Delete(&job).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id, fmt.Sprintf("Deleted job %d.", job.Id))

	w.WriteJson(&job)
}
Exemple #10
0
func (api *Api) DeleteOutputLine(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is not allowed

	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Delete

	id := 0
	if id, errl = strconv.Atoi(r.PathParam("id")); errl != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	outputline := OutputLine{}
	mutex.Lock()
	if err := api.db.Where("job_id = ?", id).Delete(&outputline).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id,
		fmt.Sprintf("Deleted outputlines for job %d.", id))

	w.WriteJson("Success")
}
Exemple #11
0
// AddUser processes "POST /users" queries.
//
func (api *Api) AddUser(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	userData := User{}

	if err := r.DecodeJsonPayload(&userData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if len(userData.Login) == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}
	user := User{}
	mutex.Lock()
	if !api.db.Find(&user, "login = ?", userData.Login).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Add user

	if len(userData.Passhash) == 0 {
		rest.Error(w, "Empty password not allowed.", 400)
		return
	}

	c := &Crypt{}
	c.Pass = []byte(userData.Passhash)
	c.Crypt()
	userData.Passhash = string(c.Hash)

	mutex.Lock()
	if err := api.db.Save(&userData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id, "Added new user '"+userData.Login+"'.")
	w.WriteJson(userData)
}
Exemple #12
0
func (api *Api) GetAllScripts(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Anyone can read the list of scripts

	/*
	   if login != "admin" {
	       rest.Error(w, "Not allowed", 400)
	       return
	   }*/

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	scripts := []Script{}
	qs := r.URL.Query() // Query string - map[string][]string
	if len(qs["id"]) > 0 {
		srch := qs["id"][0]
		mutex.Lock()
		api.db.Order("id").Find(&scripts, "id = ?", srch)
		mutex.Unlock()
		/*
		   if api.db.Order("id").
		      Find(&scripts, "id = ?", srch).RecordNotFound() {
		       rest.Error(w, "No results.", 400)
		       return
		   }
		*/
	} else if len(qs["name"]) > 0 {
		srch := qs["name"][0]
		mutex.Lock()
		api.db.Order("name").Find(&scripts, "name = ?", srch)
		mutex.Unlock()
		/*
		   if api.db.Order("name").
		      Find(&scripts, "name = ?", srch).RecordNotFound() {
		       rest.Error(w, "No results.", 400)
		       return
		   }
		*/
	} else {
		// No results is not an error
		mutex.Lock()
		err := api.db.Order("id").Find(&scripts)
		mutex.Unlock()
		if err.Error != nil {
			if !err.RecordNotFound() {
				rest.Error(w, err.Error.Error(), 500)
				return
			}
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(scripts))
	for i := range scripts {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = scripts[i].Id
		u[i]["Name"] = scripts[i].Name
		u[i]["Desc"] = scripts[i].Desc
		// 'Source' doesn't go through Unmarshall so
		// is output as base64, good. Use nosource to
		// exclude this field.
		if len(qs["nosource"]) == 0 {
			u[i]["Source"] = scripts[i].Source
		}
		u[i]["Type"] = scripts[i].Type
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #13
0
func (api *Api) UpdateScript(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Ensure user exists

	id := r.PathParam("id")

	// Check that the id string is a number
	if _, err := strconv.Atoi(id); err != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	// Load data from db, then ...
	script := Script{}
	mutex.Lock()
	if api.db.Find(&script, id).RecordNotFound() {
		mutex.Unlock()
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	// ... overwrite any sent fields
	if err := r.DecodeJsonPayload(&script); err != nil {
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Invalid data format received.", 400)
		return
	}

	script_srch := Script{}
	mutex.Lock()
	if !api.db.Find(&script_srch, "name = ? and id != ?",
		script.Name, script.Id).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Work out type:
	//   Write to disk then use unix 'file -b' (brief)

	if len(script.Source) > 0 {
		if err := ioutil.WriteFile(os.TempDir()+"/obdi_scriptcheck",
			script.Source, 0644); err != nil {
			script.Type = "Write file failed. Type of script unknown. (" +
				err.Error() + ")"
		} else {
			runCmd := exec.Command("file", "-b",
				os.TempDir()+"/obdi_scriptcheck")
			output, err := runCmd.Output()
			if err != nil {
				script.Type = "Unix 'file' failed. Type of script unknown." +
					" (" + err.Error() + ")"
			} else {
				script.Type = string(output)
			}
		}
	}

	// Force the use of the path id over an id in the payload
	Id, _ := strconv.Atoi(id)
	script.Id = int64(Id)

	mutex.Lock()
	if err := api.db.Save(&script).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id,
		"Updated data centre details for '"+script.Name+"'.")

	w.WriteJson(script)
}
Exemple #14
0
func (api *Api) AddScript(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	scriptData := Script{}

	if err := r.DecodeJsonPayload(&scriptData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if len(scriptData.Source) == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}
	script := Script{}
	mutex.Lock()
	if !api.db.Find(&script, "name = ?", scriptData.Name).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Work out type:
	//   Write to disk then use unix 'file -b' (brief)

	if err := ioutil.WriteFile(os.TempDir()+"/obdi_scriptcheck",
		scriptData.Source, 0644); err != nil {
		scriptData.Type = "Unknown type of script"
	} else {
		runCmd := exec.Command("file", "-b", os.TempDir()+"/obdi_scriptcheck")
		output, err := runCmd.Output()
		if err != nil {
			scriptData.Type = "Unknown type of script"
		} else {
			scriptData.Type = string(output)
		}
	}

	// Add script

	mutex.Lock()
	if err := api.db.Save(&scriptData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	// Try to start the script

	text := fmt.Sprintf("Added new script, %s.", scriptData.Name)
	api.LogActivity(session.Id, text)

	scriptData.Source = []byte{}
	w.WriteJson(scriptData)
}
Exemple #15
0
func (api *Api) KillJob(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Delete

	id := 0
	if id, errl = strconv.Atoi(r.PathParam("id")); errl != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	job := Job{}
	mutex.Lock()
	if api.db.First(&job, id).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	env := Env{}
	mutex.Lock()
	api.db.Model(&job).Related(&env)
	mutex.Unlock()

	if env.WorkerUrl == "" || env.WorkerKey == "" {
		txt := "WorkerUrl or WorkerKey not set for the target environment"
		rest.Error(w, txt, 400)
		return
	}

	type Jobkill struct {
		JobID int64
		Key   string
	}
	data := Jobkill{
		JobID: job.Id,
		Key:   env.WorkerKey,
	}
	// Encode
	jsondata, err := json.Marshal(data)
	if err != nil {
		txt := fmt.Sprintf(
			"Error sending kill command to worker, JSON Encode:",
			err.Error())
		rest.Error(w, txt, 400)
		return
	}
	// POST to worker
	resp, err := DELETE(jsondata, env.WorkerUrl, "jobs")
	if err != nil {
		txt := "Could not send kill command to worker. ('" + err.Error() + "')"
		rest.Error(w, txt, 400)
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		var body []byte
		if b, err := ioutil.ReadAll(resp.Body); err != nil {
			txt := fmt.Sprintf("Error reading Body ('%s').", err.Error())
			rest.Error(w, txt, 400)
			return
		} else {
			body = b
		}
		type myErr struct {
			Error string
		}
		errstr := myErr{}
		if err := json.Unmarshal(body, &errstr); err != nil {
			txt := fmt.Sprintf("Error decoding JSON ('%s')"+
				". Check the Worker URL.", err.Error())
			rest.Error(w, txt, 400)
			return
		}

		txt := "Sending Kill failed. Worker said: '" +
			errstr.Error + "'"
		rest.Error(w, txt, 400)
		return
	}

	api.LogActivity(session.Id, fmt.Sprintf("Killed job %d.", job.Id))

	w.WriteJson(&job)
}
Exemple #16
0
func (api *Api) GetAllFiles(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Anyone can view files

	/*
	   if login != "admin" {
	       rest.Error(w, "Not allowed", 400)
	       return
	   }
	*/

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	files := []File{}
	qs := r.URL.Query() // Query string - map[string][]string
	if len(qs["name"]) > 0 && len(qs["plugin_id"]) > 0 {
		srch1 := qs["name"][0]
		srch2 := qs["plugin_id"][0]
		mutex.Lock()
		api.db.Order("name").Find(&files, "name = ? and plugin_id = ?",
			srch1, srch2)
		mutex.Unlock()
		/*
		   if api.db.Order("name").
		      Find(&files, "name = ?", srch).RecordNotFound() {
		       rest.Error(w, "No results.", 400)
		       return
		   }
		*/
	} else if len(qs["name"]) > 0 {
		srch := qs["name"][0]
		mutex.Lock()
		api.db.Order("name").Find(&files, "name = ?", srch)
		mutex.Unlock()
		/*
		   if api.db.Order("name").
		      Find(&files, "name = ?", srch).RecordNotFound() {
		       rest.Error(w, "No results.", 400)
		       return
		   }
		*/
	} else {
		// No results is not an error
		mutex.Lock()
		err := api.db.Order("name").Find(&files)
		mutex.Unlock()
		if err.Error != nil {
			if !err.RecordNotFound() {
				rest.Error(w, err.Error.Error(), 500)
				return
			}
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(files))
	for i := range files {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = files[i].Id
		u[i]["Name"] = files[i].Name
		u[i]["Desc"] = files[i].Desc
		u[i]["Url"] = files[i].Url
		u[i]["Type"] = files[i].Type
		u[i]["PluginId"] = files[i].PluginId

		plugin := Plugin{}
		mutex.Lock()
		api.db.Model(&files[i]).Related(&plugin)
		mutex.Unlock()

		u[i]["PluginName"] = plugin.Name
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #17
0
func (api *Api) UpdateEnvCap(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Ensure user exists

	id := r.PathParam("id")

	// Check that the id string is a number
	if _, err := strconv.Atoi(id); err != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	// Load data from db, then ...
	EnvCap := EnvCap{}
	mutex.Lock()
	if api.db.Find(&EnvCap, id).RecordNotFound() {
		mutex.Unlock()
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	// ... overwrite any sent fields
	if err := r.DecodeJsonPayload(&EnvCap); err != nil {
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Invalid data format received.", 400)
		return
	}

	// Force the use of the path id over an id in the payload
	Id, _ := strconv.Atoi(id)
	EnvCap.Id = int64(Id)

	mutex.Lock()
	if err := api.db.Save(&EnvCap).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	text := fmt.Sprintf("Updated EnvCap, '%s'.",
		EnvCap.Code)

	api.LogActivity(session.Id, text)

	w.WriteJson("Success")
}
Exemple #18
0
func (api *Api) GetAllPlugins(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Anyone can view plugins

	/*
	   if login != "admin" {
	       rest.Error(w, "Not allowed", 400)
	       return
	   }
	*/

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	plugins := []Plugin{}
	qs := r.URL.Query() // Query string - map[string][]string
	if len(qs["name"]) > 0 {
		srch := qs["name"][0]
		mutex.Lock()
		api.db.Order("name").Find(&plugins, "name = ?", srch)
		mutex.Unlock()
		/*
		   if api.db.Order("name").
		      Find(&plugins, "name = ?", srch).RecordNotFound() {
		       rest.Error(w, "No results.", 400)
		       return
		   }
		*/
	} else {
		// No results is not an error
		mutex.Lock()
		err := api.db.Order("name").Find(&plugins)
		mutex.Unlock()
		if err.Error != nil {
			if !err.RecordNotFound() {
				rest.Error(w, err.Error.Error(), 500)
				return
			}
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(plugins))
	for i := range plugins {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = plugins[i].Id
		u[i]["Name"] = plugins[i].Name
		u[i]["Desc"] = plugins[i].Desc
		u[i]["Parent"] = plugins[i].Parent
		u[i]["HasView"] = plugins[i].HasView
		u[i]["CreatedAt"] = plugins[i].CreatedAt
		// UpdatedAt  doesn't get updated 'cos we use Save
		// //u[i]["UpdatedAt"] = plugins[i].CreatedAt
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #19
0
func (api *Api) UpdateJob(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is not allowed

	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Ensure user exists

	id := r.PathParam("id")

	// Check that the id string is a number
	if _, err := strconv.Atoi(id); err != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	// Load data from db, then ...
	job := Job{}
	mutex.Lock()
	if api.db.Find(&job, id).RecordNotFound() {
		mutex.Unlock()
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Job ID not found.", 400)
		return
	}
	mutex.Unlock()

	// ... overwrite any sent fields
	if err := r.DecodeJsonPayload(&job); err != nil {
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Invalid data format received.", 400)
		return
	}

	// Force the use of the path id over an id in the payload
	Id, _ := strconv.Atoi(id)
	job.Id = int64(Id)

	mutex.Lock()
	if err := api.db.Save(&job).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id,
		fmt.Sprintf("Updated job details for jobId %d.", job.Id))

	w.WriteJson(job)
}
Exemple #20
0
func (api *Api) UpdatePlugin(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Ensure user exists

	id := r.PathParam("id")

	// Check that the id string is a number
	if _, err := strconv.Atoi(id); err != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	// Load data from db, then ...
	plugin := Plugin{}
	mutex.Lock()
	if api.db.Find(&plugin, id).RecordNotFound() {
		mutex.Unlock()
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	// ... overwrite any sent fields
	if err := r.DecodeJsonPayload(&plugin); err != nil {
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Invalid data format received.", 400)
		return
	}

	// Force the use of the path id over an id in the payload
	Id, _ := strconv.Atoi(id)
	plugin.Id = int64(Id)

	// Make sure parent exists
	pluginSrch := Plugin{}
	mutex.Lock()
	if len(plugin.Parent) > 0 && api.db.Find(&pluginSrch, "name = ?",
		plugin.Parent).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Parent not found.", 400)
		return
	}
	mutex.Unlock()
	if pluginSrch.Id == plugin.Id {
		rest.Error(w, "Cannot be a parent of itself.", 400)
		return
	}

	mutex.Lock()
	if err := api.db.Save(&plugin).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id,
		"Updated plugin details for '"+plugin.Name+"'.")

	w.WriteJson("Success")
}
Exemple #21
0
func (api *Api) AddPlugin(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	pluginData := Plugin{}

	if err := r.DecodeJsonPayload(&pluginData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if len(pluginData.Name) == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}
	plugin := Plugin{}
	mutex.Lock()
	if !api.db.Find(&plugin, "name = ?", pluginData.Name).
		RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Make sure parent exists
	mutex.Lock()
	if len(pluginData.Parent) > 0 && api.db.Find(&plugin, "name = ?",
		pluginData.Parent).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Parent not found.", 400)
		return
	}
	mutex.Unlock()

	// Add plugin

	mutex.Lock()
	if err := api.db.Save(&pluginData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id, "Added new plugin '"+pluginData.Name+"'.")
	w.WriteJson(pluginData)
}
Exemple #22
0
func (api *Api) AddDcCapMap(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	dcCapMapData := DcCapMap{}

	if err := r.DecodeJsonPayload(&dcCapMapData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if dcCapMapData.DcId == 0 || dcCapMapData.DcCapId == 0 {
		rest.Error(w, "A required field is empty.", 400)
		return
	}
	dcCapMap := DcCapMap{}
	mutex.Lock()
	if !api.db.Find(&dcCapMap, "dc_id = ? and dc_cap_id = ?",
		dcCapMapData.DcId, dcCapMapData.DcCapId).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Check that DcId and DcCapId exist
	dc := Dc{}
	mutex.Lock()
	if api.db.Find(&dc, dcCapMapData.DcId).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Invalid data centre id.", 400)
		return
	}
	mutex.Unlock()
	dcCap := DcCap{}
	mutex.Lock()
	if api.db.Find(&dcCap, dcCapMapData.DcCapId).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Invalid data centre capability id.", 400)
		return
	}
	mutex.Unlock()

	// Add DcCapMap

	mutex.Lock()
	if err := api.db.Save(&dcCapMapData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	text := fmt.Sprintf("Added new DcCapMap, '%d'.",
		dcCapMapData.Id)

	api.LogActivity(session.Id, text)
	w.WriteJson(dcCapMapData)
}
Exemple #23
0
func (api *Api) GetAllEnvs(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Anyone can view envs

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	envs := []Env{}
	qs := r.URL.Query() // Query string - map[string][]string
	if login == "admin" {
		if len(qs["sys_name"]) > 0 {
			srch := qs["sys_name"][0]
			if len(qs["dc_id"]) > 0 {
				dcid := qs["dc_id"][0]
				mutex.Lock()
				api.db.Order("sys_name").Find(&envs,
					"sys_name = ? and dc_id = ?", srch, dcid)
				mutex.Unlock()
			} else {
				mutex.Lock()
				api.db.Order("sys_name").Find(&envs, "sys_name = ?", srch)
				mutex.Unlock()
			}
			/*
			   if api.db.Order("sys_name").
			      Find(&envs, "sys_name = ?", srch).RecordNotFound() {
			       rest.Error(w, "No results.", 400)
			       return
			   }
			*/
		} else {
			mutex.Lock()
			err := api.db.Order("dc_id,sys_name").Find(&envs)
			mutex.Unlock()
			if err.Error != nil {
				if !err.RecordNotFound() {
					rest.Error(w, err.Error.Error(), 500)
					return
				}
			}
		}
	} else { //Not admin

		// Only return readable/writeable envs for the current user

		additional_where := ""

		if len(qs["env_id"]) > 0 {
			additional_where = "AND envs.id = " + qs["env_id"][0]
		}

		if len(qs["writeable"]) > 0 { // only writeable envs
			mutex.Lock()
			api.db.Where("envs.id in (SELECT perms.env_id from perms "+
				"LEFT JOIN users on users.id=perms.user_id "+
				"WHERE users.login=? and perms.writeable=1) "+
				additional_where,
				login).Find(&envs)
			mutex.Unlock()
		} else { // readable or writeable envs
			mutex.Lock()
			api.db.Where("envs.id in (SELECT perms.env_id from perms "+
				"LEFT JOIN users on users.id=perms.user_id "+
				"WHERE users.login=? and perms.enabled=1) "+
				additional_where,
				login).Find(&envs)
			mutex.Unlock()
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(envs))
	for i := range envs {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = envs[i].Id
		u[i]["DispName"] = envs[i].DispName
		u[i]["SysName"] = envs[i].SysName
		//u[i]["WorkerIp"] = envs[i].WorkerIp
		//u[i]["WorkerPort"] = envs[i].WorkerPort
		u[i]["WorkerUrl"] = envs[i].WorkerUrl
		if login == "admin" {
			u[i]["WorkerKey"] = envs[i].WorkerKey
		}
		u[i]["CreatedAt"] = envs[i].CreatedAt

		dc := Dc{}
		mutex.Lock()
		api.db.Model(&envs[i]).Related(&dc)
		mutex.Unlock()

		u[i]["DcSysName"] = dc.SysName
		u[i]["DcDispName"] = dc.DispName
		u[i]["DcId"] = dc.Id
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #24
0
// UpdateUser processes "PUT /users" queries.
//
func (api *Api) UpdateUser(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Ensure user exists

	id := r.PathParam("id")

	// Check that the id string is a number
	if _, err := strconv.Atoi(id); err != nil {
		rest.Error(w, "Invalid id.", 400)
		return
	}

	// Load data from db, then ...
	user := User{}
	mutex.Lock()
	if api.db.Find(&user, id).RecordNotFound() {
		mutex.Unlock()
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Record not found.", 400)
		return
	}
	mutex.Unlock()

	// FIXME: DecodeJsonPayload(&somethingelse) then
	// merge with 'user' manually. This will remove
	// the 'password can't begin with $' limitation.

	// ... overwrite any sent fields
	if err := r.DecodeJsonPayload(&user); err != nil {
		//rest.Error(w, err.Error(), 400)
		rest.Error(w, "Invalid data format received.", 400)
		return
	}

	// Add user

	if !strings.HasPrefix(user.Passhash, "$") {
		c := &Crypt{}
		c.Pass = []byte(user.Passhash)
		c.Crypt()
		user.Passhash = string(c.Hash)
	}

	// Force the use of the path id over an id in the payload
	Id, _ := strconv.Atoi(id)
	user.Id = int64(Id)

	mutex.Lock()
	if err := api.db.Save(&user).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	api.LogActivity(session.Id,
		"Updated user details for '"+user.Login+"'.")

	w.WriteJson(user)
}
Exemple #25
0
// GetAllUsers processes "GET /users" queries.
//
func (api *Api) GetAllUsers(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	users := []User{}
	qs := r.URL.Query() // map[string][]string
	if len(qs["login"]) > 0 {
		srch := qs["login"][0]
		mutex.Lock()
		if api.db.Order("login").
			Find(&users, "login = ?", srch).RecordNotFound() {
			mutex.Unlock()
			rest.Error(w, "No results.", 400)
			return
		}
		mutex.Unlock()
	} else {
		mutex.Lock()
		if api.db.Order("login").Find(&users).RecordNotFound() {
			mutex.Unlock()
			rest.Error(w, "Empty Table.", 400)
			return
		}
		mutex.Unlock()
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(users))
	for i := range users {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = users[i].Id
		u[i]["Login"] = users[i].Login
		u[i]["Forename"] = users[i].Forename
		u[i]["Surname"] = users[i].Surname
		u[i]["Enabled"] = users[i].Enabled
		u[i]["CreatedAt"] = users[i].CreatedAt
		u[i]["Email"] = users[i].Email
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #26
0
func (api *Api) GetAllOutputLines(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is not allowed
	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	outputlines := []OutputLine{}
	qs := r.URL.Query() // Query string - map[string][]string
	if len(qs["job_id"]) > 0 {
		srch := qs["job_id"][0]
		if len(qs["top"]) > 0 {
			mutex.Lock()
			api.db.Order("serial").Limit(qs["top"][0]).Find(&outputlines,
				"job_id = ?", srch)
			mutex.Unlock()
		} else if len(qs["bottom"]) > 0 {
			mutex.Lock()
			// TODO last X lines but *in* order
			api.db.Order("serial desc").Limit(qs["bottom"][0]).
				Find(&outputlines, "job_id = ?", srch)
			mutex.Unlock()
		} else {
			mutex.Lock()
			api.db.Order("serial").Find(&outputlines, "job_id = ?", srch)
			mutex.Unlock()
		}
	} else {
		mutex.Lock()
		err := api.db.Order("serial").Find(&outputlines)
		mutex.Unlock()
		if err.Error != nil {
			if !err.RecordNotFound() {
				rest.Error(w, err.Error.Error(), 500)
				return
			}
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(outputlines))
	for i := range outputlines {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = outputlines[i].Id
		u[i]["Serial"] = outputlines[i].Serial
		u[i]["JobId"] = outputlines[i].JobId
		u[i]["Text"] = outputlines[i].Text
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #27
0
func (api *Api) GetAllJobs(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is NOT allowed

	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	//session := Session{}
	var errl error = nil
	//if session,errl = api.CheckLogin( login, guid ); errl != nil {
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	jobs := []Job{}
	qs := r.URL.Query() // Query string - map[string][]string
	if len(qs["job_id"]) > 0 {
		srch := qs["job_id"][0]
		mutex.Lock()
		api.db.Order("id desc").Find(&jobs, "id = ?", srch)
		mutex.Unlock()
		/*
		   if api.db.Order("id").
		      Find(&jobs, "id = ?", srch).RecordNotFound() {
		       rest.Error(w, "No results.", 400)
		       return
		   }
		*/
	} else {
		// No results is not an error
		mutex.Lock()
		err := api.db.Order("id desc").Limit(200).Find(&jobs)
		mutex.Unlock()
		if err.Error != nil {
			if !err.RecordNotFound() {
				rest.Error(w, err.Error.Error(), 500)
				return
			}
		}
	}

	// Create a slice of maps from users struct
	// to selectively copy database fields for display

	u := make([]map[string]interface{}, len(jobs))
	for i := range jobs {
		u[i] = make(map[string]interface{})
		u[i]["Id"] = jobs[i].Id
		u[i]["ScriptId"] = jobs[i].ScriptId
		u[i]["UserLogin"] = jobs[i].UserLogin
		u[i]["Args"] = jobs[i].Args
		u[i]["EnvVars"] = jobs[i].EnvVars
		u[i]["Status"] = jobs[i].Status
		u[i]["StatusReason"] = jobs[i].StatusReason
		u[i]["StatusPercent"] = jobs[i].StatusPercent
		u[i]["CreatedAt"] = jobs[i].CreatedAt
		u[i]["UpdatedAt"] = jobs[i].UpdatedAt
		u[i]["Type"] = jobs[i].Type
		//u[i]["WorkerIp"] = jobs[i].WorkerIp
		//u[i]["WorkerPort"] = jobs[i].WorkerPort
		u[i]["EnvId"] = jobs[i].EnvId

		env := Env{}
		mutex.Lock()
		api.db.Model(&jobs[i]).Related(&env)
		mutex.Unlock()

		u[i]["EnvSysName"] = env.SysName
		u[i]["EnvDispName"] = env.DispName
		u[i]["WorkerUrl"] = env.WorkerUrl

		dc := Dc{}
		mutex.Lock()
		api.db.Model(&env).Related(&dc)
		mutex.Unlock()

		u[i]["DcId"] = dc.Id
		u[i]["DcSysName"] = dc.SysName
		u[i]["DcDispName"] = dc.DispName

		script := Script{}
		mutex.Lock()
		api.db.Model(&jobs[i]).Related(&script)
		mutex.Unlock()

		u[i]["ScriptName"] = script.Name
		u[i]["ScriptDesc"] = script.Desc
		u[i]["ScriptType"] = script.Type
	}

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
	w.WriteJson(&u)
}
Exemple #28
0
func (api *Api) AddJob(w rest.ResponseWriter, r *rest.Request) {

	// This function will return successfully in all cases, after
	// the sanity checks. Errors are saved in to the job here, or by
	// the worker.

	//
	// TODO: Delete jobs (and output_lines) over N days old here
	//

	logit(fmt.Sprintf("Connection from %s", r.RemoteAddr))

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is not allowed

	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	jobData := Job{}

	if err := r.DecodeJsonPayload(&jobData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if jobData.ScriptId == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}

	jobData.UserLogin = login

	// Sanity checks

	if jobData.ScriptId == 0 {
		txt := "Script ID must be specified"
		rest.Error(w, txt, 400)
		return
	}

	if jobData.EnvId == 0 {
		txt := "Environment ID must be specified"
		rest.Error(w, txt, 400)
		return
	}

	// Add job to DB

	saveJob := func() {
		mutex.Lock()
		if err := api.db.Save(&jobData).Error; err != nil {
			mutex.Unlock()
			rest.Error(w, err.Error(), 400)
			return
		}
		mutex.Unlock()
	}

	saveJob()

	// Get the associated environment data

	env := Env{}
	mutex.Lock()
	api.db.Model(&jobData).Related(&env)
	mutex.Unlock()

	// We need WorkerUrl and WorkerKey

	if env.WorkerUrl == "" || env.WorkerKey == "" {
		txt := "WorkerUrl or WorkerKey not set for this environment"
		jobData.Status = STATUS_ERROR
		jobData.StatusReason = txt
		saveJob()
		w.WriteJson(jobData)
		return
	}

	// Send the job to the worker

	script := Script{}

	saveJob()

	mutex.Lock()
	if err := api.db.Find(&script, jobData.ScriptId); err.Error != nil {
		mutex.Unlock()
		txt := fmt.Sprintf("Script ID %d not found ('%s')", jobData.ScriptId,
			err.Error.Error())
		jobData.Status = STATUS_ERROR
		jobData.StatusReason = txt
		saveJob()
		w.WriteJson(jobData)
		//rest.Error(w, txt, 400)
		return
	}
	mutex.Unlock()

	// Jobsend definition
	type Jobsend struct {
		ScriptSource []byte
		ScriptName   string
		Args         string
		EnvVars      string
		//NotifURL        string
		JobID int64
		Key   string
		Type  int64 // 1 - user job, 2 - system job
	}

	// Jobsend data
	data := Jobsend{
		ScriptSource: script.Source,
		ScriptName:   script.Name,
		JobID:        jobData.Id,
		Key:          env.WorkerKey,
		Args:         jobData.Args,
		EnvVars:      jobData.EnvVars,
		Type:         jobData.Type,
	}

	// Encode
	jsondata, err := json.Marshal(data)
	if err != nil {
		txt := fmt.Sprintf("Error sending job to worker, JSON Encode:",
			err.Error())
		jobData.Status = STATUS_ERROR
		jobData.StatusReason = txt
		saveJob()
		w.WriteJson(jobData)
		//rest.Error(w, txt, 400)
		return
	}
	// POST to worker
	resp, err := POST(jsondata, env.WorkerUrl, "jobs")
	//fmt.Printf("%+v", jsondata)
	if err != nil {
		txt := "Could not send job to worker. ('" + err.Error() + "')"
		jobData.Status = STATUS_ERROR
		jobData.StatusReason = txt
		saveJob()
		w.WriteJson(jobData)
		//rest.Error(w, txt, 400)
		return
	}
	defer resp.Body.Close()

	text := fmt.Sprintf("Added new job, %d.", jobData.Id)
	api.LogActivity(session.Id, text)
	w.WriteJson(jobData)
}
Exemple #29
0
func (api *Api) GenericPutEndpoint(w rest.ResponseWriter, r *rest.Request) {

	// Reserve the tcp plugin port now
	iport := api.Port()
	port := strconv.FormatInt(iport, 10)
	defer api.DecrementPort(iport)

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Admin is not allowed
	if login == "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	var errl error = nil
	if _, errl = api.CheckLogin(login, guid); errl != nil {
		logit(errl.Error())
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// If the plugin isn't available try to compile it

	endpoint := r.PathParam("endpoint")
	subitem := r.PathParam("subitem")
	pluginFile := path.Join(config.GoPluginDir, endpoint, subitem)
	if err := api.CompilePlugin(w, pluginFile, endpoint, subitem); err != nil {
		return
	}

	// Run the Go plugin

	var reply []byte
	var err error

	if reply, err = api.RunPluginUsingRPC(w, r, pluginFile, port, "PUT"); err != nil {
		return // Just return full error was written in RunPluginUsingRPC
	}

	// Decode arbitrary JSON. Pull out the mandatory PluginReturn
	// and PluginError fields - all plugins send at least these.

	var generic interface{}
	json.Unmarshal(reply, &generic)
	genericReply := generic.(map[string]interface{})

	var pluginReturn int64
	var pluginError string
	for k, v := range genericReply {
		if k == "PluginReturn" {
			pluginReturn = int64(v.(float64))
		}
		if k == "PluginError" {
			pluginError = v.(string)
		}
	}

	// Return, 0 - success, 1 - error
	if pluginReturn == 1 {
		txt := fmt.Sprintf("Plugin returned error. %s", pluginError)
		rest.Error(w, txt, 400)
		logit(txt)
		return
	}

	// Response is already json encoded so send it raw
	w.(http.ResponseWriter).Write(reply)

	// Too much noise
	//api.LogActivity( session.Id, "Sent list of users" )
}
Exemple #30
0
func (api *Api) AddEnv(w rest.ResponseWriter, r *rest.Request) {

	// Check credentials

	login := r.PathParam("login")
	guid := r.PathParam("GUID")

	// Only admin is allowed

	if login != "admin" {
		rest.Error(w, "Not allowed", 400)
		return
	}

	session := Session{}
	var errl error
	if session, errl = api.CheckLogin(login, guid); errl != nil {
		rest.Error(w, errl.Error(), 401)
		return
	}

	defer api.TouchSession(guid)

	// Can't add if it exists already

	envData := Env{}

	if err := r.DecodeJsonPayload(&envData); err != nil {
		rest.Error(w, "Invalid data format received.", 400)
		return
	} else if len(envData.SysName) == 0 {
		rest.Error(w, "Incorrect data format received.", 400)
		return
	}
	env := Env{}
	mutex.Lock()
	if !api.db.Find(&env, "sys_name = ? and dc_id = ?",
		envData.SysName, envData.DcId).RecordNotFound() {
		mutex.Unlock()
		rest.Error(w, "Record exists.", 400)
		return
	}
	mutex.Unlock()

	// Add env

	mutex.Lock()
	if err := api.db.Save(&envData).Error; err != nil {
		mutex.Unlock()
		rest.Error(w, err.Error(), 400)
		return
	}
	mutex.Unlock()

	dc := Dc{}
	mutex.Lock()
	api.db.First(&dc, envData.DcId)
	mutex.Unlock()

	text := fmt.Sprintf("Added new environment '%s->%s'.",
		dc.SysName, envData.SysName)

	api.LogActivity(session.Id, text)
	w.WriteJson(envData)
}