mirror of
https://github.com/semaphoreui/semaphore.git
synced 2024-11-23 20:35:24 +01:00
feat(be): api/runners -> internal/runners
This commit is contained in:
parent
9817b345e6
commit
dc565f3508
@ -87,7 +87,7 @@ func Route() *mux.Router {
|
||||
publicAPIRouter.HandleFunc("/auth/oidc/{provider}/redirect", oidcRedirect).Methods("GET")
|
||||
publicAPIRouter.HandleFunc("/auth/oidc/{provider}/redirect/{redirect_path:.*}", oidcRedirect).Methods("GET")
|
||||
|
||||
runnersAPI := r.PathPrefix(webPath + "api").Subrouter()
|
||||
runnersAPI := r.PathPrefix(webPath + "internal").Subrouter()
|
||||
runnersAPI.Use(StoreMiddleware, JSONMiddleware, runners.RunnerMiddleware)
|
||||
runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.GetRunner).Methods("GET", "HEAD")
|
||||
runnersAPI.Path("/runners/{runner_id}").HandlerFunc(runners.UpdateRunner).Methods("PUT")
|
||||
@ -128,10 +128,10 @@ func Route() *mux.Router {
|
||||
adminAPI.Path("/options").HandlerFunc(getOptions).Methods("GET", "HEAD")
|
||||
adminAPI.Path("/options").HandlerFunc(setOption).Methods("POST")
|
||||
|
||||
adminAPI.Path("/global-runners").HandlerFunc(getGlobalRunners).Methods("GET", "HEAD")
|
||||
adminAPI.Path("/global-runners").HandlerFunc(addGlobalRunner).Methods("POST", "HEAD")
|
||||
adminAPI.Path("/runners").HandlerFunc(getGlobalRunners).Methods("GET", "HEAD")
|
||||
adminAPI.Path("/runners").HandlerFunc(addGlobalRunner).Methods("POST", "HEAD")
|
||||
|
||||
globalRunnersAPI := adminAPI.PathPrefix("/global-runners").Subrouter()
|
||||
globalRunnersAPI := adminAPI.PathPrefix("/runners").Subrouter()
|
||||
globalRunnersAPI.Use(globalRunnerMiddleware)
|
||||
globalRunnersAPI.Path("/{runner_id}").HandlerFunc(getGlobalRunner).Methods("GET", "HEAD")
|
||||
globalRunnersAPI.Path("/{runner_id}").HandlerFunc(updateGlobalRunner).Methods("PUT", "POST")
|
||||
|
@ -9,36 +9,32 @@ import (
|
||||
"github.com/gorilla/context"
|
||||
)
|
||||
|
||||
type minimalGlobalRunner struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Active bool `json:"active"`
|
||||
Webhook string `db:"webhook" json:"webhook"`
|
||||
MaxParallelTasks int `db:"max_parallel_tasks" json:"max_parallel_tasks"`
|
||||
}
|
||||
//type minimalGlobalRunner struct {
|
||||
// ID int `json:"id"`
|
||||
// Name string `json:"name"`
|
||||
// Active bool `json:"active"`
|
||||
// Webhook string `db:"webhook" json:"webhook"`
|
||||
// MaxParallelTasks int `db:"max_parallel_tasks" json:"max_parallel_tasks"`
|
||||
//}
|
||||
|
||||
func getGlobalRunners(w http.ResponseWriter, r *http.Request) {
|
||||
runners, err := helpers.Store(r).GetGlobalRunners()
|
||||
runners, err := helpers.Store(r).GetGlobalRunners(false)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var result = make([]minimalGlobalRunner, 0)
|
||||
var result = make([]db.Runner, 0)
|
||||
|
||||
for _, runner := range runners {
|
||||
result = append(result, minimalGlobalRunner{
|
||||
ID: runner.ID,
|
||||
Name: "",
|
||||
Active: false,
|
||||
})
|
||||
result = append(result, runner)
|
||||
}
|
||||
|
||||
helpers.WriteJSON(w, http.StatusOK, result)
|
||||
}
|
||||
|
||||
func addGlobalRunner(w http.ResponseWriter, r *http.Request) {
|
||||
var runner minimalGlobalRunner
|
||||
var runner db.Runner
|
||||
if !helpers.Bind(w, r, &runner) {
|
||||
return
|
||||
}
|
||||
@ -86,7 +82,7 @@ func globalRunnerMiddleware(next http.Handler) http.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
context.Set(r, "runner", runner)
|
||||
context.Set(r, "runner", &runner)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
@ -94,12 +90,7 @@ func globalRunnerMiddleware(next http.Handler) http.Handler {
|
||||
func getGlobalRunner(w http.ResponseWriter, r *http.Request) {
|
||||
runner := context.Get(r, "runner").(*db.Runner)
|
||||
|
||||
helpers.WriteJSON(w, http.StatusOK, minimalGlobalRunner{
|
||||
Name: "",
|
||||
Active: true,
|
||||
Webhook: runner.Webhook,
|
||||
MaxParallelTasks: runner.MaxParallelTasks,
|
||||
})
|
||||
helpers.WriteJSON(w, http.StatusOK, runner)
|
||||
}
|
||||
|
||||
func updateGlobalRunner(w http.ResponseWriter, r *http.Request) {
|
||||
@ -150,7 +141,7 @@ func setGlobalRunnerActive(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
runner.Active = body.Active
|
||||
|
||||
err := store.UpdateRunner(runner)
|
||||
err := store.UpdateRunner(*runner)
|
||||
|
||||
if err != nil {
|
||||
helpers.WriteErrorStatus(w, err.Error(), http.StatusBadRequest)
|
||||
@ -159,40 +150,3 @@ func setGlobalRunnerActive(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
//func updateUser(w http.ResponseWriter, r *http.Request) {
|
||||
// targetUser := context.Get(r, "_user").(db.User)
|
||||
// editor := context.Get(r, "user").(*db.User)
|
||||
//
|
||||
// var user db.UserWithPwd
|
||||
// if !helpers.Bind(w, r, &user) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if !editor.Admin && editor.ID != targetUser.ID {
|
||||
// log.Warn(editor.Username + " is not permitted to edit users")
|
||||
// w.WriteHeader(http.StatusUnauthorized)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if editor.ID == targetUser.ID && targetUser.Admin != user.Admin {
|
||||
// log.Warn("User can't edit his own role")
|
||||
// w.WriteHeader(http.StatusUnauthorized)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if targetUser.External && targetUser.Username != user.Username {
|
||||
// log.Warn("Username is not editable for external users")
|
||||
// w.WriteHeader(http.StatusBadRequest)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// user.ID = targetUser.ID
|
||||
// if err := helpers.Store(r).UpdateUser(user); err != nil {
|
||||
// log.Error(err.Error())
|
||||
// w.WriteHeader(http.StatusBadRequest)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// w.WriteHeader(http.StatusNoContent)
|
||||
//}
|
||||
|
@ -14,7 +14,7 @@ import (
|
||||
func RunnerMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
token := r.Header.Get("X-API-Token")
|
||||
token := r.Header.Get("X-Runner-Token")
|
||||
|
||||
if token == "" {
|
||||
helpers.WriteJSON(w, http.StatusUnauthorized, map[string]string{
|
||||
|
@ -8,6 +8,6 @@
|
||||
|
||||
"runner": {
|
||||
"config_file": "/tmp/semaphore-runner.json",
|
||||
"api_url": "http://localhost:3000/api"
|
||||
"api_url": "http://localhost:3000/internal"
|
||||
}
|
||||
}
|
@ -257,7 +257,7 @@ type Store interface {
|
||||
GetRunners(projectID int) ([]Runner, error)
|
||||
DeleteRunner(projectID int, runnerID int) error
|
||||
GetGlobalRunner(runnerID int) (Runner, error)
|
||||
GetGlobalRunners() ([]Runner, error)
|
||||
GetGlobalRunners(activeOnly bool) ([]Runner, error)
|
||||
DeleteGlobalRunner(runnerID int) error
|
||||
UpdateRunner(runner Runner) error
|
||||
CreateRunner(runner Runner) (Runner, error)
|
||||
|
@ -23,8 +23,14 @@ func (d *BoltDb) GetGlobalRunner(runnerID int) (runner db.Runner, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (d *BoltDb) GetGlobalRunners() (runners []db.Runner, err error) {
|
||||
err = d.getObjects(0, db.GlobalRunnerProps, db.RetrieveQueryParams{}, nil, &runners)
|
||||
func (d *BoltDb) GetGlobalRunners(activeOnly bool) (runners []db.Runner, err error) {
|
||||
err = d.getObjects(0, db.GlobalRunnerProps, db.RetrieveQueryParams{}, func(i interface{}) bool {
|
||||
runner := i.(*db.Runner)
|
||||
if activeOnly {
|
||||
return runner.Active
|
||||
}
|
||||
return true
|
||||
}, &runners)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package sql
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/ansible-semaphore/semaphore/db"
|
||||
"github.com/gorilla/securecookie"
|
||||
)
|
||||
@ -23,8 +24,14 @@ func (d *SqlDb) GetGlobalRunner(runnerID int) (runner db.Runner, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (d *SqlDb) GetGlobalRunners() (runners []db.Runner, err error) {
|
||||
err = d.getObjects(0, db.GlobalRunnerProps, db.RetrieveQueryParams{}, nil, &runners)
|
||||
func (d *SqlDb) GetGlobalRunners(activeOnly bool) (runners []db.Runner, err error) {
|
||||
err = d.getObjects(0, db.GlobalRunnerProps, db.RetrieveQueryParams{}, func(builder squirrel.SelectBuilder) squirrel.SelectBuilder {
|
||||
if activeOnly {
|
||||
builder = builder.Where("active=?", activeOnly)
|
||||
}
|
||||
|
||||
return builder
|
||||
}, &runners)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ services:
|
||||
image: docker.io/semaphoreui/runner:${SEMAPHORE_VERSION:-latest}
|
||||
restart: always
|
||||
environment:
|
||||
SEMAPHORE_RUNNER_API_URL: ${SEMAPHORE_RUNNER_API_URL:-http://server:3000/api}
|
||||
SEMAPHORE_RUNNER_API_URL: ${SEMAPHORE_RUNNER_API_URL:-http://server:3000/internal}
|
||||
SEMAPHORE_RUNNER_REGISTRATION_TOKEN: ${SEMAPHORE_RUNNER_REGISTRATION_TOKEN:-H1wDyorbg6gTSwJlVwle2Fne}
|
||||
|
||||
server:
|
||||
|
@ -220,7 +220,7 @@ func (p *JobPool) sendProgress() {
|
||||
return
|
||||
}
|
||||
|
||||
req.Header.Set("X-API-Token", p.config.Token)
|
||||
req.Header.Set("X-Runner-Token", p.config.Token)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
@ -315,7 +315,7 @@ func (p *JobPool) checkNewJobs() {
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
|
||||
req.Header.Set("X-API-Token", p.config.Token)
|
||||
req.Header.Set("X-Runner-Token", p.config.Token)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("Error creating request:", err)
|
||||
|
@ -79,7 +79,7 @@ func (t *RemoteJob) Run(username string, incomingVersion *string) (err error) {
|
||||
|
||||
var runners []db.Runner
|
||||
db.StoreSession(t.taskPool.store, "run remote job", func() {
|
||||
runners, err = t.taskPool.store.GetGlobalRunners()
|
||||
runners, err = t.taskPool.store.GetGlobalRunners(true)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
@ -26,7 +26,7 @@
|
||||
@yes="deleteItem(itemId)"
|
||||
/>
|
||||
|
||||
<v-toolbar flat >
|
||||
<v-toolbar flat>
|
||||
<v-btn
|
||||
icon
|
||||
class="mr-4"
|
||||
@ -39,7 +39,8 @@
|
||||
<v-btn
|
||||
color="primary"
|
||||
@click="editItem('new')"
|
||||
>{{ $t('newRunner') }}</v-btn>
|
||||
>{{ $t('newRunner') }}
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
|
||||
<v-data-table
|
||||
@ -48,20 +49,17 @@
|
||||
class="mt-4"
|
||||
:footer-props="{ itemsPerPageOptions: [20] }"
|
||||
>
|
||||
<template v-slot:item.external="{ item }">
|
||||
<v-icon v-if="item.external">mdi-checkbox-marked</v-icon>
|
||||
<v-icon v-else>mdi-checkbox-blank-outline</v-icon>
|
||||
<template v-slot:item.active="{ item }">
|
||||
<v-switch
|
||||
v-model="item.active"
|
||||
inset
|
||||
@change="setActive(item.id, item.active)"
|
||||
></v-switch>
|
||||
</template>
|
||||
|
||||
<template v-slot:item.alert="{ item }">
|
||||
<v-icon v-if="item.alert">mdi-checkbox-marked</v-icon>
|
||||
<v-icon v-else>mdi-checkbox-blank-outline</v-icon>
|
||||
</template>
|
||||
<template v-slot:item.name="{ item }">{{ item.name || '—' }}</template>
|
||||
|
||||
<template v-slot:item.admin="{ item }">
|
||||
<v-icon v-if="item.admin">mdi-checkbox-marked</v-icon>
|
||||
<v-icon v-else>mdi-checkbox-blank-outline</v-icon>
|
||||
</template>
|
||||
<template v-slot:item.webhook="{ item }">{{ item.webhook || '—' }}</template>
|
||||
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<div style="white-space: nowrap">
|
||||
@ -92,6 +90,7 @@ import YesNoDialog from '@/components/YesNoDialog.vue';
|
||||
import ItemListPageBase from '@/components/ItemListPageBase';
|
||||
import EditDialog from '@/components/EditDialog.vue';
|
||||
import RunnerForm from '@/components/RunnerForm.vue';
|
||||
import axios from 'axios';
|
||||
|
||||
export default {
|
||||
mixins: [ItemListPageBase],
|
||||
@ -103,16 +102,38 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
async setActive(runnerId, active) {
|
||||
await axios({
|
||||
method: 'post',
|
||||
url: `/api/runners/${runnerId}/active`,
|
||||
responseType: 'json',
|
||||
data: {
|
||||
active,
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
getHeaders() {
|
||||
return [{
|
||||
text: this.$i18n.t('name'),
|
||||
value: 'name',
|
||||
width: '50%',
|
||||
},
|
||||
{
|
||||
text: this.$i18n.t('active'),
|
||||
value: 'active',
|
||||
}];
|
||||
return [
|
||||
{
|
||||
value: 'active',
|
||||
}, {
|
||||
text: this.$i18n.t('name'),
|
||||
value: 'name',
|
||||
width: '50%',
|
||||
},
|
||||
{
|
||||
text: this.$i18n.t('webhook'),
|
||||
value: 'webhook',
|
||||
},
|
||||
{
|
||||
text: this.$i18n.t('max_parallel_tasks'),
|
||||
value: 'max_parallel_tasks',
|
||||
}, {
|
||||
text: this.$i18n.t('actions'),
|
||||
value: 'actions',
|
||||
sortable: false,
|
||||
}];
|
||||
},
|
||||
|
||||
async returnToProjects() {
|
||||
|
Loading…
Reference in New Issue
Block a user