From f250a2180c8642e4620955244ed6cbd76b0718b1 Mon Sep 17 00:00:00 2001 From: simon987 Date: Thu, 24 Jan 2019 20:39:17 -0500 Subject: [PATCH] Added public project attribute & worker access api endpoints --- api/main.go | 3 + api/project.go | 2 + api/task.go | 36 +++++-- api/worker.go | 50 +++++++++ schema.sql | 44 +++++--- storage/project.go | 18 ++-- storage/task.go | 35 +++--- storage/worker.go | 43 ++++++++ test/api_project_test.go | 4 + test/api_task_test.go | 86 +++++++++++++++ test/api_worker_test.go | 102 ++++++++++++++++++ test/schema.sql | 45 +++++--- web/angular/src/app/app.module.ts | 9 ++ .../create-project.component.html | 21 ++-- .../create-project.component.ts | 3 +- web/angular/src/app/models/project.ts | 1 + 16 files changed, 432 insertions(+), 70 deletions(-) mode change 100644 => 100755 test/schema.sql diff --git a/api/main.go b/api/main.go index 9208623..4b6f6fe 100644 --- a/api/main.go +++ b/api/main.go @@ -50,6 +50,9 @@ func New() *WebAPI { api.router.POST("/worker/create", LogRequestMiddleware(api.WorkerCreate)) api.router.GET("/worker/get/:id", LogRequestMiddleware(api.WorkerGet)) + api.router.POST("/access/grant", LogRequestMiddleware(api.WorkerGrantAccess)) + api.router.POST("/access/remove", LogRequestMiddleware(api.WorkerRemoveAccess)) + api.router.POST("/project/create", LogRequestMiddleware(api.ProjectCreate)) api.router.GET("/project/get/:id", LogRequestMiddleware(api.ProjectGet)) api.router.GET("/project/stats/:id", LogRequestMiddleware(api.ProjectGetStats)) diff --git a/api/project.go b/api/project.go index be05161..67b2426 100644 --- a/api/project.go +++ b/api/project.go @@ -13,6 +13,7 @@ type CreateProjectRequest struct { Version string `json:"version"` Priority int64 `json:"priority"` Motd string `json:"motd"` + Public bool `json:"public"` } type CreateProjectResponse struct { @@ -51,6 +52,7 @@ func (api *WebAPI) ProjectCreate(r *Request) { GitRepo: createReq.GitRepo, Priority: createReq.Priority, Motd: createReq.Motd, + Public: createReq.Public, } if isValidProject(project) { diff --git a/api/task.go b/api/task.go index 0a54ba6..da13892 100644 --- a/api/task.go +++ b/api/task.go @@ -9,10 +9,11 @@ import ( ) type CreateTaskRequest struct { - Project int64 `json:"project"` - MaxRetries int64 `json:"max_retries"` - Recipe string `json:"recipe"` - Priority int64 `json:"priority"` + Project int64 `json:"project"` + MaxRetries int64 `json:"max_retries"` + Recipe string `json:"recipe"` + Priority int64 `json:"priority"` + MaxAssignTime int64 `json:"max_assign_time"` } type ReleaseTaskRequest struct { @@ -43,9 +44,11 @@ func (api *WebAPI) TaskCreate(r *Request) { if r.GetJson(&createReq) { task := &storage.Task{ - MaxRetries: createReq.MaxRetries, - Recipe: createReq.Recipe, - Priority: createReq.Priority, + MaxRetries: createReq.MaxRetries, + Recipe: createReq.Recipe, + Priority: createReq.Priority, + AssignTime: 0, + MaxAssignTime: createReq.MaxAssignTime, } if isTaskValid(task) { @@ -99,10 +102,21 @@ func (api *WebAPI) TaskGetFromProject(r *Request) { handleErr(err, r) task := api.Database.GetTaskFromProject(worker, int64(project)) - r.OkJson(GetTaskResponse{ - Ok: true, - Task: task, - }) + if task == nil { + + r.OkJson(GetTaskResponse{ + Ok: false, + Message: "No task available", + }) + + } else { + + r.OkJson(GetTaskResponse{ + Ok: true, + Task: task, + }) + } + } func (api *WebAPI) TaskGet(r *Request) { diff --git a/api/worker.go b/api/worker.go index 441ca18..23c2671 100644 --- a/api/worker.go +++ b/api/worker.go @@ -22,6 +22,16 @@ type GetWorkerResponse struct { Worker *storage.Worker `json:"worker,omitempty"` } +type WorkerAccessRequest struct { + WorkerId *uuid.UUID `json:"worker_id"` + ProjectId int64 `json:"project_id"` +} + +type WorkerAccessResponse struct { + Ok bool `json:"ok"` + Message string `json:"message"` +} + func (api *WebAPI) WorkerCreate(r *Request) { workerReq := &CreateWorkerRequest{} @@ -86,6 +96,46 @@ func (api *WebAPI) WorkerGet(r *Request) { } } +func (api *WebAPI) WorkerGrantAccess(r *Request) { + + req := &WorkerAccessRequest{} + if r.GetJson(req) { + + ok := api.Database.GrantAccess(req.WorkerId, req.ProjectId) + + if ok { + r.OkJson(WorkerAccessResponse{ + Ok: true, + }) + } else { + r.OkJson(WorkerAccessResponse{ + Ok: false, + Message: "Worker already has access to this project", + }) + } + } +} + +func (api *WebAPI) WorkerRemoveAccess(r *Request) { + + req := &WorkerAccessRequest{} + if r.GetJson(req) { + + ok := api.Database.RemoveAccess(req.WorkerId, req.ProjectId) + + if ok { + r.OkJson(WorkerAccessResponse{ + Ok: true, + }) + } else { + r.OkJson(WorkerAccessResponse{ + Ok: false, + Message: "Worker did not have access to this project", + }) + } + } +} + func (api *WebAPI) workerCreate(request *CreateWorkerRequest, identity *storage.Identity) (uuid.UUID, error) { worker := storage.Worker{ diff --git a/schema.sql b/schema.sql index eb59f14..97c8f17 100755 --- a/schema.sql +++ b/schema.sql @@ -1,18 +1,20 @@ -DROP TABLE IF EXISTS workeridentity, Worker, Project, Task, log_entry; +DROP TABLE IF EXISTS worker_identity, worker, project, task, log_entry, + worker_has_access_to_project; DROP TYPE IF EXISTS status; -DROP TYPE IF EXISTS loglevel; +DROP TYPE IF EXISTS log_level; CREATE TYPE status as ENUM ( 'new', 'failed', - 'closed' + 'closed', + 'timeout' ); -CREATE TYPE loglevel as ENUM ( +CREATE TYPE log_level as ENUM ( 'fatal', 'panic', 'error', 'warning', 'info', 'debug', 'trace' ); -CREATE TABLE workerIdentity +CREATE TABLE worker_identity ( id SERIAL PRIMARY KEY, remote_addr TEXT, @@ -24,6 +26,7 @@ CREATE TABLE workerIdentity CREATE TABLE worker ( id TEXT PRIMARY KEY, + alias TEXT DEFAULT NULL, created INTEGER, identity INTEGER REFERENCES workerIdentity (id) ); @@ -35,24 +38,35 @@ CREATE TABLE project name TEXT UNIQUE, clone_url TEXT, git_repo TEXT UNIQUE, - version TEXT + version TEXT, + motd TEXT, + public boolean +); + +CREATE TABLE worker_has_access_to_project +( + worker TEXT REFERENCES worker (id), + project INTEGER REFERENCES project (id), + primary key (worker, project) ); CREATE TABLE task ( - id SERIAL PRIMARY KEY, - priority INTEGER DEFAULT 0, - project INTEGER REFERENCES project (id), - assignee TEXT REFERENCES worker (id), - retries INTEGER DEFAULT 0, - max_retries INTEGER, - status Status DEFAULT 'new', - recipe TEXT + id SERIAL PRIMARY KEY, + priority INTEGER DEFAULT 0, + project INTEGER REFERENCES project (id), + assignee TEXT REFERENCES worker (id), + retries INTEGER DEFAULT 0, + max_retries INTEGER, + status Status DEFAULT 'new', + recipe TEXT, + max_assign_time INTEGER DEFAULT 0, + assign_time INTEGER DEFAULT 0 ); CREATE TABLE log_entry ( - level loglevel, + level log_level, message TEXT, message_data TEXT, timestamp INT diff --git a/storage/project.go b/storage/project.go index 2e6a0e7..a85ee2c 100644 --- a/storage/project.go +++ b/storage/project.go @@ -15,6 +15,7 @@ type Project struct { GitRepo string `json:"git_repo"` Version string `json:"version"` Motd string `json:"motd"` + Public bool `json:"public"` } type AssignedTasks struct { @@ -39,9 +40,9 @@ func (database *Database) SaveProject(project *Project) (int64, error) { func saveProject(project *Project, db *sql.DB) (int64, error) { - row := db.QueryRow(`INSERT INTO project (name, git_repo, clone_url, version, priority, motd) - VALUES ($1,$2,$3,$4,$5,$6) RETURNING id`, - project.Name, project.GitRepo, project.CloneUrl, project.Version, project.Priority, project.Motd) + row := db.QueryRow(`INSERT INTO project (name, git_repo, clone_url, version, priority, motd, public) + VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING id`, + project.Name, project.GitRepo, project.CloneUrl, project.Version, project.Priority, project.Motd, project.Public) var id int64 err := row.Scan(&id) @@ -93,8 +94,8 @@ func getProject(id int64, db *sql.DB) *Project { func scanProject(row *sql.Row) (*Project, error) { project := &Project{} - err := row.Scan(&project.Id, &project.Priority, &project.Motd, &project.Name, &project.CloneUrl, - &project.GitRepo, &project.Version) + err := row.Scan(&project.Id, &project.Priority, &project.Name, &project.CloneUrl, + &project.GitRepo, &project.Version, &project.Motd, &project.Public) return project, err } @@ -120,8 +121,8 @@ func (database *Database) UpdateProject(project *Project) { db := database.getDB() res, err := db.Exec(`UPDATE project - SET (priority, name, clone_url, git_repo, version, motd) = ($1,$2,$3,$4,$5,$6) WHERE id=$7`, - project.Priority, project.Name, project.CloneUrl, project.GitRepo, project.Version, project.Motd, project.Id) + SET (priority, name, clone_url, git_repo, version, motd, public) = ($1,$2,$3,$4,$5,$6,$7) WHERE id=$8`, + project.Priority, project.Name, project.CloneUrl, project.GitRepo, project.Version, project.Motd, project.Public, project.Id) handleErr(err) rowsAffected, _ := res.RowsAffected() @@ -156,6 +157,7 @@ func (database *Database) GetProjectStats(id int64) *ProjectStats { return nil } + //todo: only expose worker alias rows, err := db.Query(`SELECT assignee, COUNT(*) FROM TASK LEFT JOIN worker ON TASK.assignee = worker.id WHERE project=$1 GROUP BY assignee`, id) @@ -189,7 +191,7 @@ func (database Database) GetAllProjectsStats() *[]ProjectStats { stats := ProjectStats{} p := &Project{} err := rows.Scan(&stats.NewTaskCount, &stats.FailedTaskCount, &stats.ClosedTaskCount, - &p.Id, &p.Priority, &p.Motd, &p.Name, &p.CloneUrl, &p.GitRepo, &p.Version) + &p.Id, &p.Priority, &p.Motd, &p.Name, &p.CloneUrl, &p.GitRepo, &p.Version, &p.Public) handleErr(err) stats.Project = p diff --git a/storage/task.go b/storage/task.go index 4605ae2..d677925 100644 --- a/storage/task.go +++ b/storage/task.go @@ -7,14 +7,16 @@ import ( ) type Task struct { - Id int64 `json:"id"` - Priority int64 `json:"priority"` - Project *Project `json:"project"` - Assignee uuid.UUID `json:"assignee"` - Retries int64 `json:"retries"` - MaxRetries int64 `json:"max_retries"` - Status string `json:"status"` - Recipe string `json:"recipe"` + Id int64 `json:"id"` + Priority int64 `json:"priority"` + Project *Project `json:"project"` + Assignee uuid.UUID `json:"assignee"` + Retries int64 `json:"retries"` + MaxRetries int64 `json:"max_retries"` + Status string `json:"status"` + Recipe string `json:"recipe"` + MaxAssignTime int64 `json:"max_assign_time"` + AssignTime int64 `json:"assign_time"` } func (database *Database) SaveTask(task *Task, project int64) error { @@ -22,9 +24,9 @@ func (database *Database) SaveTask(task *Task, project int64) error { db := database.getDB() res, err := db.Exec(` - INSERT INTO task (project, max_retries, recipe, priority) - VALUES ($1,$2,$3,$4)`, - project, task.MaxRetries, task.Recipe, task.Priority) + INSERT INTO task (project, max_retries, recipe, priority, max_assign_time) + VALUES ($1,$2,$3,$4,$5)`, + project, task.MaxRetries, task.Recipe, task.Priority, task.MaxAssignTime) if err != nil { logrus.WithError(err).WithFields(logrus.Fields{ "task": task, @@ -56,6 +58,9 @@ func (database *Database) GetTask(worker *Worker) *Task { FROM task INNER JOIN project p on task.project = p.id WHERE assignee IS NULL + AND (p.public OR EXISTS ( + SELECT 1 FROM worker_has_access_to_project a WHERE a.worker=$1 AND a.project=p.id + )) ORDER BY p.priority DESC, task.priority DESC LIMIT 1 ) @@ -134,6 +139,9 @@ func (database *Database) GetTaskFromProject(worker *Worker, projectId int64) *T FROM task INNER JOIN project p on task.project = p.id WHERE assignee IS NULL AND p.id=$2 + AND (p.public OR EXISTS ( + SELECT 1 FROM worker_has_access_to_project a WHERE a.worker=$1 AND a.project=$2 + )) ORDER BY task.priority DESC LIMIT 1 ) @@ -165,8 +173,9 @@ func scanTask(row *sql.Row) *Task { task.Project = project err := row.Scan(&task.Id, &task.Priority, &project.Id, &task.Assignee, - &task.Retries, &task.MaxRetries, &task.Status, &task.Recipe, &project.Id, - &project.Priority, &project.Motd, &project.Name, &project.CloneUrl, &project.GitRepo, &project.Version) + &task.Retries, &task.MaxRetries, &task.Status, &task.Recipe, &task.MaxAssignTime, + &task.AssignTime, &project.Id, &project.Priority, &project.Name, + &project.CloneUrl, &project.GitRepo, &project.Version, &project.Motd, &project.Public) handleErr(err) return task diff --git a/storage/worker.go b/storage/worker.go index f673d2c..7033734 100644 --- a/storage/worker.go +++ b/storage/worker.go @@ -101,3 +101,46 @@ func getOrCreateIdentity(identity *Identity, db *sql.DB) int64 { return rowId } + +func (database *Database) GrantAccess(workerId *uuid.UUID, projectId int64) bool { + + db := database.getDB() + res, err := db.Exec(`INSERT INTO worker_has_access_to_project (worker, project) VALUES ($1,$2) + ON CONFLICT DO NOTHING`, + workerId, projectId) + if err != nil { + logrus.WithFields(logrus.Fields{ + "workerId": workerId, + "projectId": projectId, + }).WithError(err).Warn("Database.GrantAccess INSERT worker_hase_access_to_project") + return false + } + + rowsAffected, _ := res.RowsAffected() + + logrus.WithFields(logrus.Fields{ + "rowsAffected": rowsAffected, + "workerId": workerId, + "projectId": projectId, + }).Trace("Database.GrantAccess INSERT worker_has_access_to_project") + + return rowsAffected == 1 +} + +func (database Database) RemoveAccess(workerId *uuid.UUID, projectId int64) bool { + + db := database.getDB() + res, err := db.Exec(`DELETE FROM worker_has_access_to_project WHERE worker=$1 AND project=$2`, + workerId, projectId) + handleErr(err) + + rowsAffected, _ := res.RowsAffected() + + logrus.WithFields(logrus.Fields{ + "rowsAffected": rowsAffected, + "workerId": workerId, + "projectId": projectId, + }).Trace("Database.RemoveAccess DELETE worker_has_access_to_project") + + return rowsAffected == 1 +} diff --git a/test/api_project_test.go b/test/api_project_test.go index 6da6cb6..a72f6b6 100644 --- a/test/api_project_test.go +++ b/test/api_project_test.go @@ -19,6 +19,7 @@ func TestCreateGetProject(t *testing.T) { Version: "Test Version", Priority: 123, Motd: "motd", + Public: true, }) id := resp.Id @@ -56,6 +57,9 @@ func TestCreateGetProject(t *testing.T) { if getResp.Project.Motd != "motd" { t.Error() } + if getResp.Project.Public != true { + t.Error() + } } func TestCreateProjectInvalid(t *testing.T) { diff --git a/test/api_task_test.go b/test/api_task_test.go index 1b5bbc2..c5e22ba 100644 --- a/test/api_task_test.go +++ b/test/api_task_test.go @@ -129,6 +129,7 @@ func TestCreateGetTask(t *testing.T) { CloneUrl: "http://github.com/test/test", GitRepo: "myrepo", Priority: 999, + Public: true, }) createTask(api.CreateTaskRequest{ @@ -170,6 +171,9 @@ func TestCreateGetTask(t *testing.T) { if taskResp.Task.Project.CloneUrl != "http://github.com/test/test" { t.Error() } + if taskResp.Task.Project.Public != true { + t.Error() + } } func createTasks(prefix string) (int64, int64) { @@ -180,6 +184,7 @@ func createTasks(prefix string) (int64, int64) { CloneUrl: "http://github.com/test/test", GitRepo: prefix + "low1", Priority: 1, + Public: true, }) highP := createProject(api.CreateProjectRequest{ Name: prefix + "high", @@ -187,6 +192,7 @@ func createTasks(prefix string) (int64, int64) { CloneUrl: "http://github.com/test/test", GitRepo: prefix + "high1", Priority: 999, + Public: true, }) createTask(api.CreateTaskRequest{ Project: lowP.Id, @@ -266,6 +272,86 @@ func TestTaskPriority(t *testing.T) { } } +func TestTaskNoAccess(t *testing.T) { + + wid := genWid() + + pid := createProject(api.CreateProjectRequest{ + Name: "This is a private proj", + Motd: "private", + Version: "private", + Priority: 1, + CloneUrl: "fjkslejf cesl", + GitRepo: "fffffffff", + Public: false, + }).Id + + createResp := createTask(api.CreateTaskRequest{ + Project: pid, + Priority: 1, + MaxAssignTime: 10, + MaxRetries: 2, + Recipe: "---", + }) + + if createResp.Ok != true { + t.Error() + } + + grantAccess(wid, pid) + removeAccess(wid, pid) + + tResp := getTaskFromProject(pid, wid) + + if tResp.Ok != false { + t.Error() + } + if len(tResp.Message) <= 0 { + t.Error() + } + if tResp.Task != nil { + t.Error() + } +} + +func TestTaskHasAccess(t *testing.T) { + + wid := genWid() + + pid := createProject(api.CreateProjectRequest{ + Name: "This is a private proj1", + Motd: "private1", + Version: "private1", + Priority: 1, + CloneUrl: "josaeiuf cesl", + GitRepo: "wewwwwwwwwwwwwwwwwwwwwww", + Public: false, + }).Id + + createResp := createTask(api.CreateTaskRequest{ + Project: pid, + Priority: 1, + MaxAssignTime: 10, + MaxRetries: 2, + Recipe: "---", + }) + + if createResp.Ok != true { + t.Error() + } + + grantAccess(wid, pid) + + tResp := getTaskFromProject(pid, wid) + + if tResp.Ok != true { + t.Error() + } + if tResp.Task == nil { + t.Error() + } +} + func TestNoMoreTasks(t *testing.T) { wid := genWid() diff --git a/test/api_worker_test.go b/test/api_worker_test.go index b6327ef..57fa67c 100644 --- a/test/api_worker_test.go +++ b/test/api_worker_test.go @@ -66,6 +66,78 @@ func TestGetWorkerInvalid(t *testing.T) { } } +func TestGrantAccessFailedProjectConstraint(t *testing.T) { + + wid := genWid() + + resp := grantAccess(wid, 38274593) + + if resp.Ok != false { + t.Error() + } + if len(resp.Message) <= 0 { + t.Error() + } +} + +func TestRemoveAccessFailedProjectConstraint(t *testing.T) { + + wid := genWid() + + resp := removeAccess(wid, 38274593) + + if resp.Ok != false { + t.Error() + } + if len(resp.Message) <= 0 { + t.Error() + } +} + +func TestRemoveAccessFailedWorkerConstraint(t *testing.T) { + + pid := createProject(api.CreateProjectRequest{ + Priority: 1, + GitRepo: "dfffffffffff", + CloneUrl: "fffffffffff23r", + Version: "f83w9rw", + Motd: "ddddddddd", + Name: "removeaccessfailedworkerconstraint", + Public: true, + }).Id + + resp := removeAccess(&uuid.Nil, pid) + + if resp.Ok != false { + t.Error() + } + if len(resp.Message) <= 0 { + t.Error() + } +} + +func TestGrantAccessFailedWorkerConstraint(t *testing.T) { + + pid := createProject(api.CreateProjectRequest{ + Priority: 1, + GitRepo: "dfffffffffff1", + CloneUrl: "fffffffffff23r1", + Version: "f83w9rw1", + Motd: "ddddddddd1", + Name: "grantaccessfailedworkerconstraint", + Public: true, + }).Id + + resp := removeAccess(&uuid.Nil, pid) + + if resp.Ok != false { + t.Error() + } + if len(resp.Message) <= 0 { + t.Error() + } +} + func createWorker(req api.CreateWorkerRequest) (*api.CreateWorkerResponse, *http.Response) { r := Post("/worker/create", req) @@ -94,3 +166,33 @@ func genWid() *uuid.UUID { resp, _ := createWorker(api.CreateWorkerRequest{}) return &resp.WorkerId } + +func grantAccess(wid *uuid.UUID, project int64) *api.WorkerAccessResponse { + + r := Post("/access/grant", api.WorkerAccessRequest{ + WorkerId: wid, + ProjectId: project, + }) + + var resp *api.WorkerAccessResponse + data, _ := ioutil.ReadAll(r.Body) + err := json.Unmarshal(data, &resp) + handleErr(err) + + return resp +} + +func removeAccess(wid *uuid.UUID, project int64) *api.WorkerAccessResponse { + + r := Post("/access/remove", api.WorkerAccessRequest{ + WorkerId: wid, + ProjectId: project, + }) + + var resp *api.WorkerAccessResponse + data, _ := ioutil.ReadAll(r.Body) + err := json.Unmarshal(data, &resp) + handleErr(err) + + return resp +} diff --git a/test/schema.sql b/test/schema.sql old mode 100644 new mode 100755 index ca9df60..97c8f17 --- a/test/schema.sql +++ b/test/schema.sql @@ -1,18 +1,20 @@ -DROP TABLE IF EXISTS workeridentity, Worker, Project, Task, log_entry; +DROP TABLE IF EXISTS worker_identity, worker, project, task, log_entry, + worker_has_access_to_project; DROP TYPE IF EXISTS status; -DROP TYPE IF EXISTS loglevel; +DROP TYPE IF EXISTS log_level; CREATE TYPE status as ENUM ( 'new', 'failed', - 'closed' + 'closed', + 'timeout' ); -CREATE TYPE loglevel as ENUM ( +CREATE TYPE log_level as ENUM ( 'fatal', 'panic', 'error', 'warning', 'info', 'debug', 'trace' ); -CREATE TABLE workerIdentity +CREATE TABLE worker_identity ( id SERIAL PRIMARY KEY, remote_addr TEXT, @@ -24,6 +26,7 @@ CREATE TABLE workerIdentity CREATE TABLE worker ( id TEXT PRIMARY KEY, + alias TEXT DEFAULT NULL, created INTEGER, identity INTEGER REFERENCES workerIdentity (id) ); @@ -32,28 +35,38 @@ CREATE TABLE project ( id SERIAL PRIMARY KEY, priority INTEGER DEFAULT 0, - motd TEXT DEFAULT '', name TEXT UNIQUE, clone_url TEXT, git_repo TEXT UNIQUE, - version TEXT + version TEXT, + motd TEXT, + public boolean +); + +CREATE TABLE worker_has_access_to_project +( + worker TEXT REFERENCES worker (id), + project INTEGER REFERENCES project (id), + primary key (worker, project) ); CREATE TABLE task ( - id SERIAL PRIMARY KEY, - priority INTEGER DEFAULT 0, - project INTEGER REFERENCES project (id), - assignee TEXT REFERENCES worker (id), - retries INTEGER DEFAULT 0, - max_retries INTEGER, - status Status DEFAULT 'new', - recipe TEXT + id SERIAL PRIMARY KEY, + priority INTEGER DEFAULT 0, + project INTEGER REFERENCES project (id), + assignee TEXT REFERENCES worker (id), + retries INTEGER DEFAULT 0, + max_retries INTEGER, + status Status DEFAULT 'new', + recipe TEXT, + max_assign_time INTEGER DEFAULT 0, + assign_time INTEGER DEFAULT 0 ); CREATE TABLE log_entry ( - level loglevel, + level log_level, message TEXT, message_data TEXT, timestamp INT diff --git a/web/angular/src/app/app.module.ts b/web/angular/src/app/app.module.ts index f7c7cde..64fdfd1 100755 --- a/web/angular/src/app/app.module.ts +++ b/web/angular/src/app/app.module.ts @@ -10,12 +10,16 @@ import { MatAutocompleteModule, MatButtonModule, MatCardModule, + MatCheckboxModule, + MatDividerModule, MatExpansionModule, MatFormFieldModule, MatIconModule, MatInputModule, MatMenuModule, MatPaginatorModule, + MatSliderModule, + MatSlideToggleModule, MatSortModule, MatTableModule, MatToolbarModule, @@ -58,6 +62,11 @@ import {UpdateProjectComponent} from './update-project/update-project.component' MatTreeModule, BrowserAnimationsModule, HttpClientModule, + MatSliderModule, + MatSlideToggleModule, + MatCheckboxModule, + MatDividerModule + ], exports: [], providers: [ diff --git a/web/angular/src/app/create-project/create-project.component.html b/web/angular/src/app/create-project/create-project.component.html index fa7a0af..35323f9 100644 --- a/web/angular/src/app/create-project/create-project.component.html +++ b/web/angular/src/app/create-project/create-project.component.html @@ -4,21 +4,30 @@
- - + + Project name + - + + + Git clone URL - + + Repository name - Changes on the master branch will be tracked if webhooks are - enabled + + Changes on the master branch will be tracked if webhooks are enabled + + Public project + + +
diff --git a/web/angular/src/app/create-project/create-project.component.ts b/web/angular/src/app/create-project/create-project.component.ts index da720d3..8a289e2 100644 --- a/web/angular/src/app/create-project/create-project.component.ts +++ b/web/angular/src/app/create-project/create-project.component.ts @@ -11,7 +11,8 @@ export class CreateProjectComponent implements OnInit { private project = new Project(); constructor() { - this.project.name = "test" + this.project.name = "test"; + this.project.public = true; } ngOnInit() { diff --git a/web/angular/src/app/models/project.ts b/web/angular/src/app/models/project.ts index 4e2ad4f..eb49c56 100644 --- a/web/angular/src/app/models/project.ts +++ b/web/angular/src/app/models/project.ts @@ -6,4 +6,5 @@ export class Project { public clone_url: string; public git_repo: string; public version: string; + public public: boolean; }