feat(ui): create runner from web

This commit is contained in:
Denis Gukov 2024-09-28 19:05:26 +05:00
parent 611c0efbbe
commit 9d7afb339a
6 changed files with 53 additions and 22 deletions

View File

@ -80,7 +80,6 @@ func Route() *mux.Router {
publicAPIRouter := r.PathPrefix(webPath + "api").Subrouter() publicAPIRouter := r.PathPrefix(webPath + "api").Subrouter()
publicAPIRouter.Use(StoreMiddleware, JSONMiddleware) publicAPIRouter.Use(StoreMiddleware, JSONMiddleware)
publicAPIRouter.HandleFunc("/runners", runners.RegisterRunner).Methods("POST")
publicAPIRouter.HandleFunc("/auth/login", login).Methods("GET", "POST") publicAPIRouter.HandleFunc("/auth/login", login).Methods("GET", "POST")
publicAPIRouter.HandleFunc("/auth/logout", logout).Methods("POST") publicAPIRouter.HandleFunc("/auth/logout", logout).Methods("POST")
publicAPIRouter.HandleFunc("/auth/oidc/{provider}/login", oidcLogin).Methods("GET") publicAPIRouter.HandleFunc("/auth/oidc/{provider}/login", oidcLogin).Methods("GET")
@ -88,7 +87,11 @@ func Route() *mux.Router {
publicAPIRouter.HandleFunc("/auth/oidc/{provider}/redirect/{redirect_path:.*}", oidcRedirect).Methods("GET") publicAPIRouter.HandleFunc("/auth/oidc/{provider}/redirect/{redirect_path:.*}", oidcRedirect).Methods("GET")
runnersAPI := r.PathPrefix(webPath + "internal").Subrouter() runnersAPI := r.PathPrefix(webPath + "internal").Subrouter()
runnersAPI.Use(StoreMiddleware, JSONMiddleware, runners.RunnerMiddleware)
runnersAPI.Use(StoreMiddleware, JSONMiddleware)
runnersAPI.HandleFunc("/runners", runners.RegisterRunner).Methods("POST")
runnersAPI.Use(runners.RunnerMiddleware)
runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.GetRunner).Methods("GET", "HEAD") runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.GetRunner).Methods("GET", "HEAD")
runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.UpdateRunner).Methods("PUT") runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.UpdateRunner).Methods("PUT")
runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.UnregisterRunner).Methods("DELETE") runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.UnregisterRunner).Methods("DELETE")

View File

@ -33,23 +33,19 @@ func getGlobalRunners(w http.ResponseWriter, r *http.Request) {
helpers.WriteJSON(w, http.StatusOK, result) helpers.WriteJSON(w, http.StatusOK, result)
} }
type runnerWithToken struct {
db.Runner
Token string `json:"token"`
}
func addGlobalRunner(w http.ResponseWriter, r *http.Request) { func addGlobalRunner(w http.ResponseWriter, r *http.Request) {
var runner db.Runner var runner db.Runner
if !helpers.Bind(w, r, &runner) { if !helpers.Bind(w, r, &runner) {
return return
} }
editor := context.Get(r, "user").(*db.User) runner.ProjectID = nil
if !editor.Admin { newRunner, err := helpers.Store(r).CreateRunner(runner)
log.Warn(editor.Username + " is not permitted to create users")
w.WriteHeader(http.StatusUnauthorized)
return
}
newRunner, err := helpers.Store(r).CreateRunner(db.Runner{
Webhook: runner.Webhook,
MaxParallelTasks: runner.MaxParallelTasks,
})
if err != nil { if err != nil {
log.Warn("Runner is not created: " + err.Error()) log.Warn("Runner is not created: " + err.Error())
@ -57,7 +53,10 @@ func addGlobalRunner(w http.ResponseWriter, r *http.Request) {
return return
} }
helpers.WriteJSON(w, http.StatusCreated, newRunner) helpers.WriteJSON(w, http.StatusCreated, runnerWithToken{
Runner: newRunner,
Token: newRunner.Token,
})
} }
func globalRunnerMiddleware(next http.Handler) http.Handler { func globalRunnerMiddleware(next http.Handler) http.Handler {
@ -94,13 +93,19 @@ func getGlobalRunner(w http.ResponseWriter, r *http.Request) {
} }
func updateGlobalRunner(w http.ResponseWriter, r *http.Request) { func updateGlobalRunner(w http.ResponseWriter, r *http.Request) {
runner := context.Get(r, "runner").(*db.Runner) oldRunner := context.Get(r, "runner").(*db.Runner)
var runner db.Runner
if !helpers.Bind(w, r, &runner) {
return
}
store := helpers.Store(r) store := helpers.Store(r)
runner.ID = oldRunner.ID
runner.ProjectID = nil runner.ProjectID = nil
err := store.UpdateRunner(*runner) err := store.UpdateRunner(runner)
if err != nil { if err != nil {
helpers.WriteErrorStatus(w, err.Error(), http.StatusBadRequest) helpers.WriteErrorStatus(w, err.Error(), http.StatusBadRequest)

View File

@ -8,7 +8,7 @@ type RunnerState string
//) //)
type Runner struct { type Runner struct {
ID int `db:"id" json:"-"` ID int `db:"id" json:"id"`
Token string `db:"token" json:"-"` Token string `db:"token" json:"-"`
ProjectID *int `db:"project_id" json:"project_id"` ProjectID *int `db:"project_id" json:"project_id"`
//State RunnerState `db:"state" json:"state"` //State RunnerState `db:"state" json:"state"`

View File

@ -42,7 +42,9 @@ func (d *SqlDb) DeleteGlobalRunner(runnerID int) (err error) {
func (d *SqlDb) UpdateRunner(runner db.Runner) (err error) { func (d *SqlDb) UpdateRunner(runner db.Runner) (err error) {
_, err = d.exec( _, err = d.exec(
"update runner set webhook=?, max_parallel_tasks=? where id=?", "update runner set name=?, active=?, webhook=?, max_parallel_tasks=? where id=?",
runner.Name,
runner.Active,
runner.Webhook, runner.Webhook,
runner.MaxParallelTasks, runner.MaxParallelTasks,
runner.ID) runner.ID)
@ -55,11 +57,13 @@ func (d *SqlDb) CreateRunner(runner db.Runner) (newRunner db.Runner, err error)
insertID, err := d.insert( insertID, err := d.insert(
"id", "id",
"insert into runner (project_id, token, webhook, max_parallel_tasks) values (?, ?, ?, ?)", "insert into runner (project_id, token, webhook, max_parallel_tasks, name, active) values (?, ?, ?, ?, ?, ?)",
runner.ProjectID, runner.ProjectID,
token, token,
runner.Webhook, runner.Webhook,
runner.MaxParallelTasks) runner.MaxParallelTasks,
runner.Name,
runner.Active)
if err != nil { if err != nil {
return return

View File

@ -19,9 +19,24 @@
:disabled="formSaving" :disabled="formSaving"
></v-text-field> ></v-text-field>
<v-text-field
v-model="item.webhook"
:label="$t('webhook')"
required
:disabled="formSaving"
></v-text-field>
<v-text-field
type="number"
v-model.number="item.max_parallel_tasks"
:label="$t('maxNumberOfParallelTasksOptional')"
required
:disabled="formSaving"
></v-text-field>
<v-checkbox <v-checkbox
v-model="item.active" v-model="item.active"
:label="$t('adminUser')" :label="$t('active')"
v-if="isAdmin" v-if="isAdmin"
></v-checkbox> ></v-checkbox>
</v-form> </v-form>

View File

@ -61,6 +61,10 @@
<template v-slot:item.webhook="{ item }">{{ item.webhook || '&mdash;' }}</template> <template v-slot:item.webhook="{ item }">{{ item.webhook || '&mdash;' }}</template>
<template v-slot:item.max_parallel_tasks="{ item }">
{{ item.max_parallel_tasks || '∞' }}
</template>
<template v-slot:item.actions="{ item }"> <template v-slot:item.actions="{ item }">
<div style="white-space: nowrap"> <div style="white-space: nowrap">
<v-btn <v-btn
@ -127,7 +131,7 @@ export default {
value: 'webhook', value: 'webhook',
}, },
{ {
text: this.$i18n.t('max_parallel_tasks'), text: this.$i18n.t('maxNumberOfParallelTasksOptional'),
value: 'max_parallel_tasks', value: 'max_parallel_tasks',
}, { }, {
text: this.$i18n.t('actions'), text: this.$i18n.t('actions'),