mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-25 21:09:05 +01:00
Add /search endpoint which redirects to user/job
This commit is contained in:
parent
0ca7dbb4f1
commit
27fd3c4e5a
@ -266,6 +266,11 @@ func (api *RestApi) stopJob(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
job, err = api.JobRepository.FindById(id)
|
||||
} else {
|
||||
if req.JobId == nil || req.Cluster == nil || req.StartTime == nil {
|
||||
http.Error(rw, "'jobId', 'cluster' and 'startTime' are required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
job, err = api.JobRepository.Find(*req.JobId, *req.Cluster, *req.StartTime)
|
||||
}
|
||||
|
||||
|
10
init-db.go
10
init-db.go
@ -65,6 +65,12 @@ const JOBS_DB_SCHEMA string = `
|
||||
FOREIGN KEY (tag_id) REFERENCES tag (id) ON DELETE CASCADE);
|
||||
`
|
||||
|
||||
const JOBS_DB_INDEXES string = `
|
||||
CREATE INDEX job_by_user ON job (user);
|
||||
CREATE INDEX job_by_starttime ON job (start_time);
|
||||
CREATE INDEX job_by_job_id ON job (job_id);
|
||||
`
|
||||
|
||||
// Delete the tables "job", "tag" and "jobtag" from the database and
|
||||
// repopulate them using the jobs found in `archive`.
|
||||
func initDB(db *sqlx.DB, archive string) error {
|
||||
@ -178,9 +184,7 @@ func initDB(db *sqlx.DB, archive string) error {
|
||||
|
||||
// Create indexes after inserts so that they do not
|
||||
// need to be continually updated.
|
||||
if _, err := db.Exec(`
|
||||
CREATE INDEX job_by_user ON job (user);
|
||||
CREATE INDEX job_by_starttime ON job (start_time);`); err != nil {
|
||||
if _, err := db.Exec(JOBS_DB_INDEXES); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,12 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/ClusterCockpit/cc-backend/auth"
|
||||
"github.com/ClusterCockpit/cc-backend/log"
|
||||
"github.com/ClusterCockpit/cc-backend/schema"
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
@ -141,3 +147,38 @@ func (r *JobRepository) TagId(tagType string, tagName string) (tagId int64, exis
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var ErrNotFound = errors.New("no such job or user")
|
||||
|
||||
// FindJobOrUser returns a job database ID or a username if a job or user machtes the search term.
|
||||
// As 0 is a valid job id, check if username is "" instead in order to check what machted.
|
||||
// If nothing matches the search, `ErrNotFound` is returned.
|
||||
func (r *JobRepository) FindJobOrUser(ctx context.Context, searchterm string) (job int64, username string, err error) {
|
||||
user := auth.GetUser(ctx)
|
||||
if id, err := strconv.Atoi(searchterm); err == nil {
|
||||
qb := sq.Select("job.id").From("job").Where("job.job_id = ?", id)
|
||||
if user != nil && !user.HasRole(auth.RoleAdmin) {
|
||||
qb = qb.Where("job.user = ?", user.Username)
|
||||
}
|
||||
|
||||
err := qb.RunWith(r.DB).QueryRow().Scan(&job)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return 0, "", err
|
||||
} else if err == nil {
|
||||
return job, "", nil
|
||||
}
|
||||
}
|
||||
|
||||
if user == nil || user.HasRole(auth.RoleAdmin) {
|
||||
err := sq.Select("job.user").Distinct().From("job").
|
||||
Where("job.user = ?", searchterm).
|
||||
RunWith(r.DB).QueryRow().Scan(&username)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
return 0, "", err
|
||||
} else if err == nil {
|
||||
return 0, username, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, "", ErrNotFound
|
||||
}
|
||||
|
24
server.go
24
server.go
@ -10,6 +10,7 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
@ -375,6 +376,29 @@ func main() {
|
||||
})
|
||||
})
|
||||
|
||||
secured.HandleFunc("/search", func(rw http.ResponseWriter, r *http.Request) {
|
||||
if search := r.URL.Query().Get("searchId"); search != "" {
|
||||
job, username, err := api.JobRepository.FindJobOrUser(r.Context(), search)
|
||||
if err == repository.ErrNotFound {
|
||||
http.Redirect(rw, r, "/monitoring/jobs/?jobId="+url.QueryEscape(search), http.StatusTemporaryRedirect)
|
||||
return
|
||||
} else if err != nil {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if username != "" {
|
||||
http.Redirect(rw, r, "/monitoring/user/"+username, http.StatusTemporaryRedirect)
|
||||
return
|
||||
} else {
|
||||
http.Redirect(rw, r, fmt.Sprintf("/monitoring/job/%d", job), http.StatusTemporaryRedirect)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Error(rw, "'searchId' query parameter missing", http.StatusBadRequest)
|
||||
}
|
||||
})
|
||||
|
||||
setupRoutes(secured, routes)
|
||||
api.MountRoutes(secured)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user