Datacenter Update to Ws
This commit is contained in:
@@ -3,6 +3,7 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
oclib "cloud.o-forge.io/core/oc-lib"
|
oclib "cloud.o-forge.io/core/oc-lib"
|
||||||
beego "github.com/beego/beego/v2/server/web"
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
@@ -28,11 +29,15 @@ func isAdmin(groups []string) bool {
|
|||||||
|
|
||||||
// @Title GetAll
|
// @Title GetAll
|
||||||
// @Description Retourne toutes les images autorisées à persister sur ce peer
|
// @Description Retourne toutes les images autorisées à persister sur ce peer
|
||||||
|
// @Param offset query string false
|
||||||
|
// @Param limit query string false
|
||||||
// @Success 200 {object} []allowed_image.AllowedImage
|
// @Success 200 {object} []allowed_image.AllowedImage
|
||||||
// @router / [get]
|
// @router / [get]
|
||||||
func (o *AllowedImageController) GetAll() {
|
func (o *AllowedImageController) GetAll() {
|
||||||
|
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
|
||||||
|
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
|
||||||
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||||
res := oclib.NewRequest(oclib.LibDataEnum(oclib.ALLOWED_IMAGE), user, peerID, groups, nil).LoadAll(false)
|
res := oclib.NewRequest(oclib.LibDataEnum(oclib.ALLOWED_IMAGE), user, peerID, groups, nil).LoadAll(false, int64(offset), int64(limit))
|
||||||
o.Data["json"] = res
|
o.Data["json"] = res
|
||||||
o.ServeJSON()
|
o.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"oc-datacenter/infrastructure/monitor"
|
"oc-datacenter/infrastructure/monitor"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
oclib "cloud.o-forge.io/core/oc-lib"
|
oclib "cloud.o-forge.io/core/oc-lib"
|
||||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||||
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
beego "github.com/beego/beego/v2/server/web"
|
beego "github.com/beego/beego/v2/server/web"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
@@ -16,74 +19,143 @@ type DatacenterController struct {
|
|||||||
beego.Controller
|
beego.Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resourceTypeEnum(t string, special bool) []oclib.LibDataEnum {
|
||||||
|
e := []oclib.LibDataEnum{}
|
||||||
|
if special && t == "resource" {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
if t == "storage" || t == "live" {
|
||||||
|
e = append(e, oclib.LibDataEnum(oclib.LIVE_STORAGE))
|
||||||
|
}
|
||||||
|
if t == "datacenter" || t == "live" {
|
||||||
|
e = append(e, oclib.LibDataEnum(oclib.LIVE_DATACENTER))
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *DatacenterController) collection(special bool) []oclib.LibDataEnum {
|
||||||
|
// Extrait le type depuis le segment d'URL après "resource"
|
||||||
|
// URL forme: /oc/resource/{type}/...
|
||||||
|
typ := o.Ctx.Input.Param(":type")
|
||||||
|
return resourceTypeEnum(typ, special)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Title Search
|
||||||
|
// @Description search datacenter
|
||||||
|
// @Param type path string true "the type you want to get"
|
||||||
|
// @Param search path string true "the word search you want to get"
|
||||||
|
// @Param is_draft query string false "draft wished"
|
||||||
|
// @Param offset query string false
|
||||||
|
// @Param limit query string false
|
||||||
|
// @Success 200 {workspace} models.workspace
|
||||||
|
// @router /:type/search/:search [get]
|
||||||
|
func (o *DatacenterController) Search() {
|
||||||
|
/*
|
||||||
|
* This is a sample of how to use the search function
|
||||||
|
* The search function is used to search for data in the database
|
||||||
|
* The search function takes in a filter and a data type
|
||||||
|
* The filter is a struct that contains the search parameters
|
||||||
|
* The data type is an enum that specifies the type of data to search for
|
||||||
|
* The search function returns a list of data that matches the filter
|
||||||
|
* The data is then returned as a json object
|
||||||
|
*/
|
||||||
|
// store and return Id or post with UUID
|
||||||
|
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||||
|
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
|
||||||
|
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
|
||||||
|
search := o.Ctx.Input.Param(":search")
|
||||||
|
if search == "*" {
|
||||||
|
search = ""
|
||||||
|
}
|
||||||
|
isDraft := o.Ctx.Input.Query("is_draft")
|
||||||
|
m := map[string][]utils.ShallowDBObject{}
|
||||||
|
for _, col := range o.collection(false) {
|
||||||
|
if m[col.String()] == nil {
|
||||||
|
m[col.String()] = []utils.ShallowDBObject{}
|
||||||
|
}
|
||||||
|
s := oclib.NewRequest(col, user, peerID, groups, nil).Search(&dbs.Filters{
|
||||||
|
Or: map[string][]dbs.Filter{
|
||||||
|
// "abstractlive.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: peerID}},
|
||||||
|
"abstractlive.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
|
||||||
|
},
|
||||||
|
}, "", isDraft == "true", int64(offset), int64(limit))
|
||||||
|
fmt.Println(s)
|
||||||
|
m[col.String()] = append(m[col.String()], s.Data...)
|
||||||
|
}
|
||||||
|
o.Data["json"] = map[string]interface{}{
|
||||||
|
"data": m,
|
||||||
|
"code": 200,
|
||||||
|
"err": nil,
|
||||||
|
}
|
||||||
|
o.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
// @Title GetAll
|
// @Title GetAll
|
||||||
// @Description find booking by id
|
// @Description find booking by id
|
||||||
|
// @Param type path string true "the word type you want to get"
|
||||||
// @Param is_draft query string false "draft wished"
|
// @Param is_draft query string false "draft wished"
|
||||||
|
// @Param offset query string false
|
||||||
|
// @Param limit query string false
|
||||||
// @Success 200 {booking} models.booking
|
// @Success 200 {booking} models.booking
|
||||||
// @router / [get]
|
// @router / [get]
|
||||||
func (o *DatacenterController) GetAll() {
|
func (o *DatacenterController) GetAll() {
|
||||||
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||||
isDraft := o.Ctx.Input.Query("is_draft")
|
isDraft := o.Ctx.Input.Query("is_draft")
|
||||||
storages := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), user, peerID, groups, nil).Search(&dbs.Filters{
|
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
|
||||||
Or: map[string][]dbs.Filter{
|
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
|
||||||
"abstractinstanciatedresource.abstractresource.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: peerID}},
|
m := map[string][]utils.ShallowDBObject{}
|
||||||
},
|
for _, col := range o.collection(false) {
|
||||||
}, "", isDraft == "true")
|
if m[col.String()] == nil {
|
||||||
computes := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_DATACENTER), user, peerID, groups, nil).Search(&dbs.Filters{
|
m[col.String()] = []utils.ShallowDBObject{}
|
||||||
Or: map[string][]dbs.Filter{
|
}
|
||||||
"abstractinstanciatedresource.abstractresource.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: peerID}},
|
s := oclib.NewRequest(oclib.LibDataEnum(col), user, peerID, groups, nil).LoadAll(isDraft == "true", int64(offset), int64(limit))
|
||||||
},
|
fmt.Println(s)
|
||||||
}, "", isDraft == "true")
|
m[col.String()] = append(m[col.String()], s.Data...)
|
||||||
storages.Data = append(storages.Data, computes.Data...)
|
}
|
||||||
if storages.Err != "" {
|
fmt.Println(m)
|
||||||
storages.Err += " - " + computes.Err
|
o.Data["json"] = map[string]interface{}{
|
||||||
|
"data": m,
|
||||||
|
"code": 200,
|
||||||
|
"err": nil,
|
||||||
}
|
}
|
||||||
o.Data["json"] = storages
|
|
||||||
o.ServeJSON()
|
o.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Title Get
|
// @Title Get
|
||||||
// @Description find booking by id
|
// @Description find booking by id
|
||||||
// @Param id path string true "the id you want to get"
|
// @Param id path string true "the id you want to get"
|
||||||
|
// @Param type path string true "the word type you want to get"
|
||||||
// @Param is_draft query string false "draft wished"
|
// @Param is_draft query string false "draft wished"
|
||||||
// @Success 200 {booking} models.booking
|
// @Success 200 {booking} models.booking
|
||||||
// @router /:id [get]
|
// @router /:type/:id [get]
|
||||||
func (o *DatacenterController) Get() {
|
func (o *DatacenterController) Get() {
|
||||||
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||||
isDraft := o.Ctx.Input.Query("is_draft")
|
|
||||||
id := o.Ctx.Input.Param(":id")
|
id := o.Ctx.Input.Param(":id")
|
||||||
storages := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), user, peerID, groups, nil).Search(&dbs.Filters{
|
for _, col := range o.collection(false) {
|
||||||
Or: map[string][]dbs.Filter{
|
data := oclib.NewRequest(col, user, peerID, groups, nil).LoadOne(id)
|
||||||
"abstractinstanciatedresource.abstractresource.abstractobject.id": {{Operator: dbs.EQUAL.String(), Value: id}},
|
o.Data["json"] = data
|
||||||
"abstractinstanciatedresource.abstractresource.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: peerID}},
|
if data.Data != nil {
|
||||||
},
|
break
|
||||||
}, "", isDraft == "true")
|
|
||||||
if len(storages.Data) == 0 {
|
|
||||||
computes := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_DATACENTER), user, peerID, groups, nil).Search(&dbs.Filters{
|
|
||||||
Or: map[string][]dbs.Filter{
|
|
||||||
"abstractinstanciatedresource.abstractresource.abstractobject.id": {{Operator: dbs.EQUAL.String(), Value: id}},
|
|
||||||
"abstractinstanciatedresource.abstractresource.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: peerID}},
|
|
||||||
},
|
|
||||||
}, "", isDraft == "true")
|
|
||||||
if len(computes.Data) == 0 {
|
|
||||||
o.Data["json"] = map[string]interface{}{
|
|
||||||
"data": nil,
|
|
||||||
"code": computes.Code,
|
|
||||||
"err": computes.Err,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
o.Data["json"] = map[string]interface{}{
|
|
||||||
"data": computes.Data[0],
|
|
||||||
"code": computes.Code,
|
|
||||||
"err": computes.Err,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
o.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
// @Title Delete
|
||||||
o.Data["json"] = map[string]interface{}{
|
// @Description find booking by id
|
||||||
"data": storages.Data[0],
|
// @Param id path string true "the id you want to get"
|
||||||
"code": storages.Code,
|
// @Param type path string true "the word type you want to get"
|
||||||
"err": storages.Err,
|
// @Param is_draft query string false "draft wished"
|
||||||
|
// @Success 200 {booking} models.booking
|
||||||
|
// @router /:type/:id [delete]
|
||||||
|
func (o *DatacenterController) Delete() {
|
||||||
|
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||||
|
id := o.Ctx.Input.Param(":id")
|
||||||
|
for _, col := range o.collection(false) {
|
||||||
|
data := oclib.NewRequest(col, user, peerID, groups, nil).DeleteOne(id)
|
||||||
|
o.Data["json"] = data
|
||||||
|
if data.Data != nil {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o.ServeJSON()
|
o.ServeJSON()
|
||||||
@@ -97,7 +169,7 @@ var upgrader = websocket.Upgrader{
|
|||||||
// @Description find booking by id
|
// @Description find booking by id
|
||||||
// @Param id path string true "the id you want to get"
|
// @Param id path string true "the id you want to get"
|
||||||
// @Success 200 {booking} models.booking
|
// @Success 200 {booking} models.booking
|
||||||
// @router /:id [get]
|
// @router /logs/:id [get]
|
||||||
func (o *DatacenterController) Log() {
|
func (o *DatacenterController) Log() {
|
||||||
// user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
// user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
|
||||||
id := o.Ctx.Input.Param(":id")
|
id := o.Ctx.Input.Param(":id")
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -15,7 +15,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.o-forge.io/core/oc-lib v0.0.0-20260325092016-4580200e8057 // indirect
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260408134044-284533ad1d7b // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/biter777/countries v1.7.5 // indirect
|
github.com/biter777/countries v1.7.5 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -14,6 +14,10 @@ cloud.o-forge.io/core/oc-lib v0.0.0-20260324114937-6d0c78946e8b h1:y0rppyzGIQTIy
|
|||||||
cloud.o-forge.io/core/oc-lib v0.0.0-20260324114937-6d0c78946e8b/go.mod h1:+ENuvBfZdESSvecoqGY/wSvRlT3vinEolxKgwbOhUpA=
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260324114937-6d0c78946e8b/go.mod h1:+ENuvBfZdESSvecoqGY/wSvRlT3vinEolxKgwbOhUpA=
|
||||||
cloud.o-forge.io/core/oc-lib v0.0.0-20260325092016-4580200e8057 h1:pR+lZzcCWZ0kke2r2xXa7OpdbLpPW3gZSWZ8gGHh274=
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260325092016-4580200e8057 h1:pR+lZzcCWZ0kke2r2xXa7OpdbLpPW3gZSWZ8gGHh274=
|
||||||
cloud.o-forge.io/core/oc-lib v0.0.0-20260325092016-4580200e8057/go.mod h1:+ENuvBfZdESSvecoqGY/wSvRlT3vinEolxKgwbOhUpA=
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260325092016-4580200e8057/go.mod h1:+ENuvBfZdESSvecoqGY/wSvRlT3vinEolxKgwbOhUpA=
|
||||||
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260407090927-6fe91eda875d h1:54Vl14gurwAkmZEaWZKUM5eDZfB7MF/fzWjibWLQljE=
|
||||||
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260407090927-6fe91eda875d/go.mod h1:+ENuvBfZdESSvecoqGY/wSvRlT3vinEolxKgwbOhUpA=
|
||||||
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260408134044-284533ad1d7b h1:mOU+tc87/KEQgFmw1RcQ9E9Rbz8Q2jLOh5Cpu6po9Ww=
|
||||||
|
cloud.o-forge.io/core/oc-lib v0.0.0-20260408134044-284533ad1d7b/go.mod h1:+ENuvBfZdESSvecoqGY/wSvRlT3vinEolxKgwbOhUpA=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ func provisionPVCsForTarget(ctx context.Context, targetNS string, sourceExecutio
|
|||||||
"executions_id": {{Operator: dbs.EQUAL.String(), Value: sourceExecutionsID}},
|
"executions_id": {{Operator: dbs.EQUAL.String(), Value: sourceExecutionsID}},
|
||||||
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 1000)
|
||||||
|
|
||||||
if res.Err != "" || len(res.Data) == 0 {
|
if res.Err != "" || len(res.Data) == 0 {
|
||||||
return
|
return
|
||||||
@@ -424,7 +424,7 @@ func (s *AdmiraltySetter) TeardownIfRemote(exec *workflow_execution.WorkflowExec
|
|||||||
"executions_id": {{Operator: dbs.EQUAL.String(), Value: exec.ExecutionsID}},
|
"executions_id": {{Operator: dbs.EQUAL.String(), Value: exec.ExecutionsID}},
|
||||||
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.COMPUTE_RESOURCE.EnumIndex()}},
|
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.COMPUTE_RESOURCE.EnumIndex()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 1000)
|
||||||
|
|
||||||
if res.Err != "" || len(res.Data) == 0 {
|
if res.Err != "" || len(res.Data) == 0 {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ func BootstrapAllowedImages() {
|
|||||||
And: map[string][]dbs.Filter{
|
And: map[string][]dbs.Filter{
|
||||||
"image": {{Operator: dbs.EQUAL.String(), Value: img.Image}},
|
"image": {{Operator: dbs.EQUAL.String(), Value: img.Image}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 1)
|
||||||
if existing.Err != "" || len(existing.Data) > 0 {
|
if existing.Err != "" || len(existing.Data) > 0 {
|
||||||
continue // déjà présente ou erreur de recherche : on passe
|
continue // déjà présente ou erreur de recherche : on passe
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,112 +0,0 @@
|
|||||||
package infrastructure
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
oclib "cloud.o-forge.io/core/oc-lib"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
|
||||||
bookingmodel "cloud.o-forge.io/core/oc-lib/models/booking"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
||||||
)
|
|
||||||
|
|
||||||
// processedBookings tracks booking IDs already handled this process lifetime.
|
|
||||||
var processedBookings sync.Map
|
|
||||||
|
|
||||||
// closingStates is the set of terminal booking states.
|
|
||||||
var ClosingStates = map[enum.BookingStatus]bool{
|
|
||||||
enum.FAILURE: true,
|
|
||||||
enum.SUCCESS: true,
|
|
||||||
enum.FORGOTTEN: true,
|
|
||||||
enum.CANCELLED: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
// WatchBookings is a safety-net fallback for when oc-monitord fails to launch.
|
|
||||||
// It detects bookings that are past expected_start_date by at least 1 minute and
|
|
||||||
// are still in a non-terminal state. Instead of writing to the database directly,
|
|
||||||
// it emits WORKFLOW_STEP_DONE_EVENT with State=FAILURE on NATS so that oc-scheduler
|
|
||||||
// handles the state transition — keeping a single source of truth for booking state.
|
|
||||||
//
|
|
||||||
// Must be launched in a goroutine from main.
|
|
||||||
func WatchBookings() {
|
|
||||||
logger := oclib.GetLogger()
|
|
||||||
logger.Info().Msg("BookingWatchdog: started")
|
|
||||||
ticker := time.NewTicker(time.Minute)
|
|
||||||
defer ticker.Stop()
|
|
||||||
for range ticker.C {
|
|
||||||
if err := scanStaleBookings(); err != nil {
|
|
||||||
logger.Error().Msg("BookingWatchdog: " + err.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// scanStaleBookings queries all bookings whose ExpectedStartDate passed more than
|
|
||||||
// 1 minute ago. Non-terminal ones get a WORKFLOW_STEP_DONE_EVENT FAILURE emitted
|
|
||||||
// on NATS so oc-scheduler closes them.
|
|
||||||
func scanStaleBookings() error {
|
|
||||||
myself, err := oclib.GetMySelf()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not resolve local peer: %w", err)
|
|
||||||
}
|
|
||||||
peerID := myself.GetID()
|
|
||||||
|
|
||||||
deadline := time.Now().UTC().Add(-time.Minute)
|
|
||||||
res := oclib.NewRequest(oclib.LibDataEnum(oclib.BOOKING), "", peerID, []string{}, nil).
|
|
||||||
Search(&dbs.Filters{
|
|
||||||
And: map[string][]dbs.Filter{
|
|
||||||
"expected_start_date": {{
|
|
||||||
Operator: dbs.LTE.String(),
|
|
||||||
Value: primitive.NewDateTimeFromTime(deadline),
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}, "", false)
|
|
||||||
|
|
||||||
if res.Err != "" {
|
|
||||||
return fmt.Errorf("stale booking search failed: %s", res.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, dbo := range res.Data {
|
|
||||||
b, ok := dbo.(*bookingmodel.Booking)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
go emitWatchdogFailure(b)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// emitWatchdogFailure publishes a WORKFLOW_STEP_DONE_EVENT FAILURE for a stale
|
|
||||||
// booking. oc-scheduler is the single authority for booking state transitions.
|
|
||||||
func emitWatchdogFailure(b *bookingmodel.Booking) {
|
|
||||||
logger := oclib.GetLogger()
|
|
||||||
|
|
||||||
if _, done := processedBookings.Load(b.GetID()); done {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ClosingStates[b.State] {
|
|
||||||
processedBookings.Store(b.GetID(), struct{}{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now().UTC()
|
|
||||||
payload, err := json.Marshal(tools.WorkflowLifecycleEvent{
|
|
||||||
BookingID: b.GetID(),
|
|
||||||
State: enum.FAILURE.EnumIndex(),
|
|
||||||
RealEnd: &now,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tools.NewNATSCaller().SetNATSPub(tools.WORKFLOW_STEP_DONE_EVENT, tools.NATSResponse{
|
|
||||||
FromApp: "oc-datacenter",
|
|
||||||
Method: int(tools.WORKFLOW_STEP_DONE_EVENT),
|
|
||||||
Payload: payload,
|
|
||||||
})
|
|
||||||
|
|
||||||
logger.Info().Msgf("BookingWatchdog: booking %s stale → emitting FAILURE", b.GetID())
|
|
||||||
processedBookings.Store(b.GetID(), struct{}{})
|
|
||||||
}
|
|
||||||
@@ -152,7 +152,7 @@ func (s *KubernetesService) filterNonAllowed(images []string) []string {
|
|||||||
And: map[string][]dbs.Filter{
|
And: map[string][]dbs.Filter{
|
||||||
"image": {{Operator: dbs.EQUAL.String(), Value: name}},
|
"image": {{Operator: dbs.EQUAL.String(), Value: name}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 1000)
|
||||||
|
|
||||||
if len(res.Data) == 0 {
|
if len(res.Data) == 0 {
|
||||||
toRemove = append(toRemove, img)
|
toRemove = append(toRemove, img)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func Call(book *booking.Booking,
|
|||||||
"source": {{Operator: dbs.EQUAL.String(), Value: instance.Source}},
|
"source": {{Operator: dbs.EQUAL.String(), Value: instance.Source}},
|
||||||
"abstractlive.resources_id": {{Operator: dbs.EQUAL.String(), Value: computeRes.GetID()}},
|
"abstractlive.resources_id": {{Operator: dbs.EQUAL.String(), Value: computeRes.GetID()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 1000)
|
||||||
if res.Err != "" {
|
if res.Err != "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"oc-datacenter/infrastructure"
|
||||||
"oc-datacenter/infrastructure/admiralty"
|
"oc-datacenter/infrastructure/admiralty"
|
||||||
"oc-datacenter/infrastructure/kubernetes"
|
"oc-datacenter/infrastructure/kubernetes"
|
||||||
"oc-datacenter/infrastructure/kubernetes/models"
|
"oc-datacenter/infrastructure/kubernetes/models"
|
||||||
@@ -237,7 +238,7 @@ func ListenNATS() {
|
|||||||
if err := json.Unmarshal(resp.Payload, &evt); err != nil || evt.ExecutionsID == "" {
|
if err := json.Unmarshal(resp.Payload, &evt); err != nil || evt.ExecutionsID == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go kubernetes.NewKubernetesService(evt.ExecutionsID).TeardownForExecution(evt.ExecutionID)
|
go infrastructure.TeardownForExecution(evt.ExecutionID, evt.ExecutionsID)
|
||||||
},
|
},
|
||||||
|
|
||||||
// ─── REMOVE_RESOURCE ────────────────────────────────────────────────────────
|
// ─── REMOVE_RESOURCE ────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ func (m *MinioSetter) TeardownAsSource(ctx context.Context, event MinioDeleteEve
|
|||||||
// loadMinioURL searches through all live storages accessible by peerID to find
|
// loadMinioURL searches through all live storages accessible by peerID to find
|
||||||
// the one that references MinioID, and returns its endpoint URL.
|
// the one that references MinioID, and returns its endpoint URL.
|
||||||
func (m *MinioSetter) loadMinioURL(peerID string) (string, error) {
|
func (m *MinioSetter) loadMinioURL(peerID string) (string, error) {
|
||||||
res := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), "", peerID, []string{}, nil).LoadAll(false)
|
res := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), "", peerID, []string{}, nil).LoadAll(false, 0, 10000)
|
||||||
if res.Err != "" {
|
if res.Err != "" {
|
||||||
return "", fmt.Errorf("loadMinioURL: failed to load live storages: %s", res.Err)
|
return "", fmt.Errorf("loadMinioURL: failed to load live storages: %s", res.Err)
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ func (m *MinioSetter) TeardownForExecution(ctx context.Context, localPeerID stri
|
|||||||
"executions_id": {{Operator: dbs.EQUAL.String(), Value: m.ExecutionsID}},
|
"executions_id": {{Operator: dbs.EQUAL.String(), Value: m.ExecutionsID}},
|
||||||
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 10000)
|
||||||
|
|
||||||
if res.Err != "" || len(res.Data) == 0 {
|
if res.Err != "" || len(res.Data) == 0 {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ func (p *PVCSetter) TeardownAsSource(ctx context.Context, event PVCDeleteEvent)
|
|||||||
|
|
||||||
// ResolveStorageName returns the live storage name for a given storageID, or "" if not found.
|
// ResolveStorageName returns the live storage name for a given storageID, or "" if not found.
|
||||||
func ResolveStorageName(storageID, peerID string) string {
|
func ResolveStorageName(storageID, peerID string) string {
|
||||||
res := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), "", peerID, []string{}, nil).LoadAll(false)
|
res := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), "", peerID, []string{}, nil).LoadAll(false, 0, 10000)
|
||||||
if res.Err != "" {
|
if res.Err != "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ func ResolveStorageName(storageID, peerID string) string {
|
|||||||
|
|
||||||
// loadStorageSize looks up the SizeGB for this storage in live storages.
|
// loadStorageSize looks up the SizeGB for this storage in live storages.
|
||||||
func (p *PVCSetter) loadStorageSize(peerID string) (string, error) {
|
func (p *PVCSetter) loadStorageSize(peerID string) (string, error) {
|
||||||
res := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), "", peerID, []string{}, nil).LoadAll(false)
|
res := oclib.NewRequest(oclib.LibDataEnum(oclib.LIVE_STORAGE), "", peerID, []string{}, nil).LoadAll(false, 0, 10000)
|
||||||
if res.Err != "" {
|
if res.Err != "" {
|
||||||
return "", fmt.Errorf("loadStorageSize: %s", res.Err)
|
return "", fmt.Errorf("loadStorageSize: %s", res.Err)
|
||||||
}
|
}
|
||||||
@@ -199,7 +199,7 @@ func (p *PVCSetter) TeardownForExecution(ctx context.Context, localPeerID string
|
|||||||
"executions_id": {{Operator: dbs.EQUAL.String(), Value: p.ExecutionsID}},
|
"executions_id": {{Operator: dbs.EQUAL.String(), Value: p.ExecutionsID}},
|
||||||
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 10000)
|
||||||
|
|
||||||
if res.Err != "" || len(res.Data) == 0 {
|
if res.Err != "" || len(res.Data) == 0 {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,27 +1,126 @@
|
|||||||
package kubernetes
|
package infrastructure
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"oc-datacenter/conf"
|
||||||
|
"oc-datacenter/infrastructure/admiralty"
|
||||||
|
"oc-datacenter/infrastructure/kubernetes"
|
||||||
|
"oc-datacenter/infrastructure/storage"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"oc-datacenter/conf"
|
|
||||||
"oc-datacenter/infrastructure"
|
|
||||||
"oc-datacenter/infrastructure/admiralty"
|
|
||||||
"oc-datacenter/infrastructure/storage"
|
|
||||||
|
|
||||||
oclib "cloud.o-forge.io/core/oc-lib"
|
oclib "cloud.o-forge.io/core/oc-lib"
|
||||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||||
bookingmodel "cloud.o-forge.io/core/oc-lib/models/booking"
|
bookingmodel "cloud.o-forge.io/core/oc-lib/models/booking"
|
||||||
|
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
|
"cloud.o-forge.io/core/oc-lib/models/workflow_execution"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// uuidNsPattern matches Kubernetes namespace names that are execution UUIDs.
|
// processedBookings tracks booking IDs already handled this process lifetime.
|
||||||
|
var processedBookings sync.Map
|
||||||
|
|
||||||
|
// closingStates is the set of terminal booking states.
|
||||||
|
var ClosingStates = map[enum.BookingStatus]bool{
|
||||||
|
enum.FAILURE: true,
|
||||||
|
enum.SUCCESS: true,
|
||||||
|
enum.FORGOTTEN: true,
|
||||||
|
enum.CANCELLED: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// WatchBookings is a safety-net fallback for when oc-monitord fails to launch.
|
||||||
|
// It detects bookings that are past expected_start_date by at least 1 minute and
|
||||||
|
// are still in a non-terminal state. Instead of writing to the database directly,
|
||||||
|
// it emits WORKFLOW_STEP_DONE_EVENT with State=FAILURE on NATS so that oc-scheduler
|
||||||
|
// handles the state transition — keeping a single source of truth for booking state.
|
||||||
|
//
|
||||||
|
// Must be launched in a goroutine from main.
|
||||||
|
func WatchBookings() {
|
||||||
|
logger := oclib.GetLogger()
|
||||||
|
logger.Info().Msg("BookingWatchdog: started")
|
||||||
|
ticker := time.NewTicker(time.Minute)
|
||||||
|
defer ticker.Stop()
|
||||||
|
for range ticker.C {
|
||||||
|
if err := scanStaleBookings(); err != nil {
|
||||||
|
logger.Error().Msg("BookingWatchdog: " + err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scanStaleBookings queries all bookings whose ExpectedStartDate passed more than
|
||||||
|
// 1 minute ago. Non-terminal ones get a WORKFLOW_STEP_DONE_EVENT FAILURE emitted
|
||||||
|
// on NATS so oc-scheduler closes them.
|
||||||
|
func scanStaleBookings() error {
|
||||||
|
myself, err := oclib.GetMySelf()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not resolve local peer: %w", err)
|
||||||
|
}
|
||||||
|
peerID := myself.GetID()
|
||||||
|
|
||||||
|
deadline := time.Now().UTC().Add(-time.Minute)
|
||||||
|
res := oclib.NewRequest(oclib.LibDataEnum(oclib.BOOKING), "", peerID, []string{}, nil).
|
||||||
|
Search(&dbs.Filters{
|
||||||
|
And: map[string][]dbs.Filter{
|
||||||
|
"expected_start_date": {{
|
||||||
|
Operator: dbs.LTE.String(),
|
||||||
|
Value: primitive.NewDateTimeFromTime(deadline),
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}, "", false, 0, 10000)
|
||||||
|
|
||||||
|
if res.Err != "" {
|
||||||
|
return fmt.Errorf("stale booking search failed: %s", res.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, dbo := range res.Data {
|
||||||
|
b, ok := dbo.(*bookingmodel.Booking)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go emitWatchdogFailure(b)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// emitWatchdogFailure publishes a WORKFLOW_STEP_DONE_EVENT FAILURE for a stale
|
||||||
|
// booking. oc-scheduler is the single authority for booking state transitions.
|
||||||
|
func emitWatchdogFailure(b *bookingmodel.Booking) {
|
||||||
|
logger := oclib.GetLogger()
|
||||||
|
|
||||||
|
if _, done := processedBookings.Load(b.GetID()); done {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ClosingStates[b.State] {
|
||||||
|
processedBookings.Store(b.GetID(), struct{}{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
payload, err := json.Marshal(tools.WorkflowLifecycleEvent{
|
||||||
|
BookingID: b.GetID(),
|
||||||
|
State: enum.FAILURE.EnumIndex(),
|
||||||
|
RealEnd: &now,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tools.NewNATSCaller().SetNATSPub(tools.WORKFLOW_STEP_DONE_EVENT, tools.NATSResponse{
|
||||||
|
FromApp: "oc-datacenter",
|
||||||
|
Method: int(tools.WORKFLOW_STEP_DONE_EVENT),
|
||||||
|
Payload: payload,
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.Info().Msgf("BookingWatchdog: booking %s stale → emitting FAILURE", b.GetID())
|
||||||
|
processedBookings.Store(b.GetID(), struct{}{})
|
||||||
|
}
|
||||||
|
|
||||||
var uuidNsPattern = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
|
var uuidNsPattern = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)
|
||||||
|
|
||||||
// WatchInfra is a safety-net watchdog that periodically scans Kubernetes for
|
// WatchInfra is a safety-net watchdog that periodically scans Kubernetes for
|
||||||
@@ -30,22 +129,22 @@ var uuidNsPattern = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-
|
|||||||
// missed due to oc-monitord or oc-datacenter crash/restart).
|
// missed due to oc-monitord or oc-datacenter crash/restart).
|
||||||
//
|
//
|
||||||
// Must be launched in a goroutine from main.
|
// Must be launched in a goroutine from main.
|
||||||
func (s *KubernetesService) Watch() {
|
func Watch() {
|
||||||
logger := oclib.GetLogger()
|
logger := oclib.GetLogger()
|
||||||
logger.Info().Msg("InfraWatchdog: started")
|
logger.Info().Msg("InfraWatchdog: started")
|
||||||
ticker := time.NewTicker(5 * time.Minute)
|
ticker := time.NewTicker(5 * time.Minute)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
if err := s.scanOrphaned(); err != nil {
|
if err := scanOrphaned(); err != nil {
|
||||||
logger.Error().Msg("InfraWatchdog: " + err.Error())
|
logger.Error().Msg("InfraWatchdog: " + err.Error())
|
||||||
}
|
}
|
||||||
if err := s.scanOrphanedMinio(); err != nil {
|
if err := scanOrphanedMinio(); err != nil {
|
||||||
logger.Error().Msg("InfraWatchdog(minio): " + err.Error())
|
logger.Error().Msg("InfraWatchdog(minio): " + err.Error())
|
||||||
}
|
}
|
||||||
if err := s.scanOrphanedAdmiraltyNodes(); err != nil {
|
if err := scanOrphanedAdmiraltyNodes(); err != nil {
|
||||||
logger.Error().Msg("InfraWatchdog(admiralty-nodes): " + err.Error())
|
logger.Error().Msg("InfraWatchdog(admiralty-nodes): " + err.Error())
|
||||||
}
|
}
|
||||||
if err := s.scanOrphanedPVC(); err != nil {
|
if err := scanOrphanedPVC(); err != nil {
|
||||||
logger.Error().Msg("InfraWatchdog(pvc): " + err.Error())
|
logger.Error().Msg("InfraWatchdog(pvc): " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +153,7 @@ func (s *KubernetesService) Watch() {
|
|||||||
// scanOrphanedInfra lists all UUID-named Kubernetes namespaces, looks up their
|
// scanOrphanedInfra lists all UUID-named Kubernetes namespaces, looks up their
|
||||||
// WorkflowExecution in the DB, and triggers teardown for any that are in a
|
// WorkflowExecution in the DB, and triggers teardown for any that are in a
|
||||||
// terminal state. Namespaces already in Terminating phase are skipped.
|
// terminal state. Namespaces already in Terminating phase are skipped.
|
||||||
func (s *KubernetesService) scanOrphaned() error {
|
func scanOrphaned() error {
|
||||||
logger := oclib.GetLogger()
|
logger := oclib.GetLogger()
|
||||||
|
|
||||||
serv, err := tools.NewKubernetesService(
|
serv, err := tools.NewKubernetesService(
|
||||||
@@ -98,7 +197,7 @@ func (s *KubernetesService) scanOrphaned() error {
|
|||||||
|
|
||||||
logger.Info().Msgf("InfraWatchdog: orphaned infra detected for execution %s (state=%v) → teardown",
|
logger.Info().Msgf("InfraWatchdog: orphaned infra detected for execution %s (state=%v) → teardown",
|
||||||
executionsID, exec.State)
|
executionsID, exec.State)
|
||||||
go s.TeardownForExecution(exec.GetID())
|
go TeardownForExecution(exec.GetID(), exec.ExecutionsID)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -107,7 +206,7 @@ func (s *KubernetesService) scanOrphaned() error {
|
|||||||
// terminal state and triggers Minio teardown for each unique executionsID found.
|
// terminal state and triggers Minio teardown for each unique executionsID found.
|
||||||
// This covers the case where the Kubernetes namespace is already gone (manual
|
// This covers the case where the Kubernetes namespace is already gone (manual
|
||||||
// deletion, prior partial teardown) but Minio SA and bucket were never revoked.
|
// deletion, prior partial teardown) but Minio SA and bucket were never revoked.
|
||||||
func (s *KubernetesService) scanOrphanedMinio() error {
|
func scanOrphanedMinio() error {
|
||||||
logger := oclib.GetLogger()
|
logger := oclib.GetLogger()
|
||||||
|
|
||||||
myself, err := oclib.GetMySelf()
|
myself, err := oclib.GetMySelf()
|
||||||
@@ -121,7 +220,7 @@ func (s *KubernetesService) scanOrphanedMinio() error {
|
|||||||
And: map[string][]dbs.Filter{
|
And: map[string][]dbs.Filter{
|
||||||
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 10000)
|
||||||
|
|
||||||
if res.Err != "" {
|
if res.Err != "" {
|
||||||
return fmt.Errorf("failed to search LIVE_STORAGE bookings: %s", res.Err)
|
return fmt.Errorf("failed to search LIVE_STORAGE bookings: %s", res.Err)
|
||||||
@@ -175,7 +274,7 @@ func (s *KubernetesService) scanOrphanedMinio() error {
|
|||||||
// This covers the gap where the namespace is already gone (or Terminating) but
|
// This covers the gap where the namespace is already gone (or Terminating) but
|
||||||
// the virtual node was never cleaned up by the Admiralty controller — which can
|
// the virtual node was never cleaned up by the Admiralty controller — which can
|
||||||
// happen when the node goes NotReady before the AdmiraltyTarget CRD is deleted.
|
// happen when the node goes NotReady before the AdmiraltyTarget CRD is deleted.
|
||||||
func (s *KubernetesService) scanOrphanedAdmiraltyNodes() error {
|
func scanOrphanedAdmiraltyNodes() error {
|
||||||
logger := oclib.GetLogger()
|
logger := oclib.GetLogger()
|
||||||
|
|
||||||
serv, err := tools.NewKubernetesService(
|
serv, err := tools.NewKubernetesService(
|
||||||
@@ -251,7 +350,7 @@ func (s *KubernetesService) scanOrphanedAdmiraltyNodes() error {
|
|||||||
//
|
//
|
||||||
// A LIVE_STORAGE booking is treated as a local PVC only when ResolveStorageName
|
// A LIVE_STORAGE booking is treated as a local PVC only when ResolveStorageName
|
||||||
// returns a non-empty name — the same guard used by teardownPVCForExecution.
|
// returns a non-empty name — the same guard used by teardownPVCForExecution.
|
||||||
func (s *KubernetesService) scanOrphanedPVC() error {
|
func scanOrphanedPVC() error {
|
||||||
logger := oclib.GetLogger()
|
logger := oclib.GetLogger()
|
||||||
|
|
||||||
myself, err := oclib.GetMySelf()
|
myself, err := oclib.GetMySelf()
|
||||||
@@ -265,7 +364,7 @@ func (s *KubernetesService) scanOrphanedPVC() error {
|
|||||||
And: map[string][]dbs.Filter{
|
And: map[string][]dbs.Filter{
|
||||||
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
"resource_type": {{Operator: dbs.EQUAL.String(), Value: tools.LIVE_STORAGE.EnumIndex()}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 10000)
|
||||||
|
|
||||||
if res.Err != "" {
|
if res.Err != "" {
|
||||||
return fmt.Errorf("failed to search LIVE_STORAGE bookings: %s", res.Err)
|
return fmt.Errorf("failed to search LIVE_STORAGE bookings: %s", res.Err)
|
||||||
@@ -314,7 +413,7 @@ func findTerminalExecution(executionsID string, peerID string) *workflow_executi
|
|||||||
And: map[string][]dbs.Filter{
|
And: map[string][]dbs.Filter{
|
||||||
"executions_id": {{Operator: dbs.EQUAL.String(), Value: executionsID}},
|
"executions_id": {{Operator: dbs.EQUAL.String(), Value: executionsID}},
|
||||||
},
|
},
|
||||||
}, "", false)
|
}, "", false, 0, 10000)
|
||||||
|
|
||||||
if res.Err != "" || len(res.Data) == 0 {
|
if res.Err != "" || len(res.Data) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@@ -325,7 +424,7 @@ func findTerminalExecution(executionsID string, peerID string) *workflow_executi
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !infrastructure.ClosingStates[exec.State] {
|
if !ClosingStates[exec.State] {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return exec
|
return exec
|
||||||
@@ -334,7 +433,7 @@ func findTerminalExecution(executionsID string, peerID string) *workflow_executi
|
|||||||
// teardownInfraForExecution handles infrastructure cleanup when a workflow terminates.
|
// teardownInfraForExecution handles infrastructure cleanup when a workflow terminates.
|
||||||
// oc-datacenter is responsible only for infra here — booking/execution state
|
// oc-datacenter is responsible only for infra here — booking/execution state
|
||||||
// is managed by oc-scheduler.
|
// is managed by oc-scheduler.
|
||||||
func (s *KubernetesService) TeardownForExecution(executionID string) {
|
func TeardownForExecution(executionID string, executionsID string) {
|
||||||
logger := oclib.GetLogger()
|
logger := oclib.GetLogger()
|
||||||
|
|
||||||
myself, err := oclib.GetMySelf()
|
myself, err := oclib.GetMySelf()
|
||||||
@@ -352,8 +451,8 @@ func (s *KubernetesService) TeardownForExecution(executionID string) {
|
|||||||
exec := res.(*workflow_execution.WorkflowExecution)
|
exec := res.(*workflow_execution.WorkflowExecution)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
admiralty.NewAdmiraltySetter(s.ExecutionsID).TeardownIfRemote(exec, selfPeerID)
|
admiralty.NewAdmiraltySetter(executionsID).TeardownIfRemote(exec, selfPeerID)
|
||||||
storage.NewMinioSetter(s.ExecutionsID, "").TeardownForExecution(ctx, selfPeerID)
|
storage.NewMinioSetter(executionsID, "").TeardownForExecution(ctx, selfPeerID)
|
||||||
storage.NewPVCSetter(s.ExecutionsID, "").TeardownForExecution(ctx, selfPeerID)
|
storage.NewPVCSetter(executionsID, "").TeardownForExecution(ctx, selfPeerID)
|
||||||
s.CleanupImages(ctx)
|
kubernetes.NewKubernetesService(executionsID).CleanupImages(ctx)
|
||||||
}
|
}
|
||||||
5
main.go
5
main.go
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"oc-datacenter/conf"
|
"oc-datacenter/conf"
|
||||||
"oc-datacenter/infrastructure"
|
"oc-datacenter/infrastructure"
|
||||||
|
"oc-datacenter/infrastructure/nats"
|
||||||
_ "oc-datacenter/routers"
|
_ "oc-datacenter/routers"
|
||||||
|
|
||||||
oclib "cloud.o-forge.io/core/oc-lib"
|
oclib "cloud.o-forge.io/core/oc-lib"
|
||||||
@@ -30,9 +31,9 @@ func main() {
|
|||||||
|
|
||||||
infrastructure.BootstrapAllowedImages()
|
infrastructure.BootstrapAllowedImages()
|
||||||
|
|
||||||
go infrastructure.ListenNATS()
|
go nats.ListenNATS()
|
||||||
go infrastructure.WatchBookings()
|
go infrastructure.WatchBookings()
|
||||||
go infrastructure.WatchInfra()
|
go infrastructure.Watch()
|
||||||
|
|
||||||
beego.Run()
|
beego.Run()
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
oc-datacenter
BIN
oc-datacenter
Binary file not shown.
@@ -7,43 +7,7 @@ import (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"],
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "GetKubeSecret",
|
|
||||||
Router: `/secret/:execution/:peer`,
|
|
||||||
AllowHTTPMethods: []string{"get"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "GetAllTargets",
|
|
||||||
Router: `/targets`,
|
|
||||||
AllowHTTPMethods: []string{"get"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "GetOneTarget",
|
|
||||||
Router: `/targets/:execution`,
|
|
||||||
AllowHTTPMethods: []string{"get"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AdmiraltyController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "DeleteAdmiraltySession",
|
|
||||||
Router: `/targets/:execution`,
|
|
||||||
AllowHTTPMethods: []string{"delete"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "GetAll",
|
Method: "GetAll",
|
||||||
Router: `/`,
|
Router: `/`,
|
||||||
@@ -52,7 +16,7 @@ func init() {
|
|||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "Post",
|
Method: "Post",
|
||||||
Router: `/`,
|
Router: `/`,
|
||||||
@@ -61,7 +25,7 @@ func init() {
|
|||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "Get",
|
Method: "Get",
|
||||||
Router: `/:id`,
|
Router: `/:id`,
|
||||||
@@ -70,65 +34,11 @@ func init() {
|
|||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:AllowedImageController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "Log",
|
Method: "Delete",
|
||||||
Router: `/:id`,
|
Router: `/:id`,
|
||||||
AllowHTTPMethods: []string{"get"},
|
AllowHTTPMethods: []string{"delete"},
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "Put",
|
|
||||||
Router: `/:id`,
|
|
||||||
AllowHTTPMethods: []string{"put"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "Check",
|
|
||||||
Router: `/check/:id/:start_date/:end_date`,
|
|
||||||
AllowHTTPMethods: []string{"get"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "ExtendForExecution",
|
|
||||||
Router: `/extend/:resource_id/from_execution/:execution_id/to/:duration`,
|
|
||||||
AllowHTTPMethods: []string{"post"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "ExtendForNamespace",
|
|
||||||
Router: `/extend/:resource_id/from_namespace/:namespace/to/:duration`,
|
|
||||||
AllowHTTPMethods: []string{"post"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "Search",
|
|
||||||
Router: `/search/:start_date/:end_date`,
|
|
||||||
AllowHTTPMethods: []string{"get"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:BookingController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "ExecutionSearch",
|
|
||||||
Router: `/search/execution/:id`,
|
|
||||||
AllowHTTPMethods: []string{"get"},
|
|
||||||
MethodParams: param.Make(),
|
MethodParams: param.Make(),
|
||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
@@ -145,17 +55,35 @@ func init() {
|
|||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "Get",
|
Method: "Get",
|
||||||
Router: `/:id`,
|
Router: `/:type/:id`,
|
||||||
AllowHTTPMethods: []string{"get"},
|
AllowHTTPMethods: []string{"get"},
|
||||||
MethodParams: param.Make(),
|
MethodParams: param.Make(),
|
||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:MinioController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:MinioController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "CreateServiceAccount",
|
Method: "Delete",
|
||||||
Router: `/serviceaccount/:minioId/:executions`,
|
Router: `/:type/:id`,
|
||||||
AllowHTTPMethods: []string{"post"},
|
AllowHTTPMethods: []string{"delete"},
|
||||||
|
MethodParams: param.Make(),
|
||||||
|
Filters: nil,
|
||||||
|
Params: nil})
|
||||||
|
|
||||||
|
beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"],
|
||||||
|
beego.ControllerComments{
|
||||||
|
Method: "Search",
|
||||||
|
Router: `/:type/search/:search`,
|
||||||
|
AllowHTTPMethods: []string{"get"},
|
||||||
|
MethodParams: param.Make(),
|
||||||
|
Filters: nil,
|
||||||
|
Params: nil})
|
||||||
|
|
||||||
|
beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:DatacenterController"],
|
||||||
|
beego.ControllerComments{
|
||||||
|
Method: "Log",
|
||||||
|
Router: `/logs/:id`,
|
||||||
|
AllowHTTPMethods: []string{"get"},
|
||||||
MethodParams: param.Make(),
|
MethodParams: param.Make(),
|
||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
@@ -169,15 +97,6 @@ func init() {
|
|||||||
Filters: nil,
|
Filters: nil,
|
||||||
Params: nil})
|
Params: nil})
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:VectorController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:VectorController"],
|
|
||||||
beego.ControllerComments{
|
|
||||||
Method: "Receive",
|
|
||||||
Router: `/`,
|
|
||||||
AllowHTTPMethods: []string{"post"},
|
|
||||||
MethodParams: param.Make(),
|
|
||||||
Filters: nil,
|
|
||||||
Params: nil})
|
|
||||||
|
|
||||||
beego.GlobalControllerRouter["oc-datacenter/controllers:VersionController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:VersionController"],
|
beego.GlobalControllerRouter["oc-datacenter/controllers:VersionController"] = append(beego.GlobalControllerRouter["oc-datacenter/controllers:VersionController"],
|
||||||
beego.ControllerComments{
|
beego.ControllerComments{
|
||||||
Method: "GetAll",
|
Method: "GetAll",
|
||||||
|
|||||||
@@ -14,11 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
ns := beego.NewNamespace("/oc/",
|
ns := beego.NewNamespace("/oc",
|
||||||
beego.NSInclude(
|
beego.NSInclude(
|
||||||
&controllers.DatacenterController{},
|
&controllers.DatacenterController{},
|
||||||
),
|
),
|
||||||
|
|
||||||
beego.NSNamespace("/session",
|
beego.NSNamespace("/session",
|
||||||
beego.NSInclude(
|
beego.NSInclude(
|
||||||
&controllers.SessionController{},
|
&controllers.SessionController{},
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
// Begin Swagger UI call region
|
// Begin Swagger UI call region
|
||||||
const ui = SwaggerUIBundle({
|
const ui = SwaggerUIBundle({
|
||||||
url: "https://petstore.swagger.io/v2/swagger.json",
|
url: "swagger.json",
|
||||||
dom_id: '#swagger-ui',
|
dom_id: '#swagger-ui',
|
||||||
deepLinking: true,
|
deepLinking: true,
|
||||||
presets: [
|
presets: [
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"url": "https://www.gnu.org/licenses/agpl-3.0.html"
|
"url": "https://www.gnu.org/licenses/agpl-3.0.html"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"basePath": "/oc/",
|
"basePath": "/oc",
|
||||||
"paths": {
|
"paths": {
|
||||||
"/": {
|
"/": {
|
||||||
"get": {
|
"get": {
|
||||||
@@ -23,11 +23,30 @@
|
|||||||
"description": "find booking by id\n\u003cbr\u003e",
|
"description": "find booking by id\n\u003cbr\u003e",
|
||||||
"operationId": "DatacenterController.GetAll",
|
"operationId": "DatacenterController.GetAll",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "type",
|
||||||
|
"description": "the word type you want to get",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"name": "is_draft",
|
"name": "is_draft",
|
||||||
"description": "draft wished",
|
"description": "draft wished",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "offset",
|
||||||
|
"description": "false",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "limit",
|
||||||
|
"description": "false",
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -37,222 +56,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admiralty/kubeconfig/{execution}": {
|
"/allowed-image/": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"admiralty"
|
"allowed-image"
|
||||||
],
|
],
|
||||||
"parameters": [
|
"description": "Retourne toutes les images autorisées à persister sur ce peer\n\u003cbr\u003e",
|
||||||
{
|
"operationId": "AllowedImageController.GetAll",
|
||||||
"in": "path",
|
|
||||||
"name": "execution",
|
|
||||||
"description": "execution id of the workflow",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admiralty/node/{execution}": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "execution",
|
|
||||||
"description": "execution id of the workflow",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admiralty/secret/{execution}": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "execution",
|
|
||||||
"description": "execution id of the workflow",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"post": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "execution",
|
|
||||||
"description": "execution id of the workflow",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "body",
|
|
||||||
"name": "kubeconfig",
|
|
||||||
"description": "Kubeconfig to use when creating secret",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/controllers.RemoteKubeconfig"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"201": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admiralty/source/{execution}": {
|
|
||||||
"post": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"description": "Create an Admiralty Source on remote cluster\n\u003cbr\u003e",
|
|
||||||
"operationId": "AdmiraltyController.CreateSource",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "execution",
|
|
||||||
"description": "execution id of the workflow",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"201": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admiralty/target/{execution}": {
|
|
||||||
"post": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"description": "Create an Admiralty Target in the namespace associated to the executionID\n\u003cbr\u003e",
|
|
||||||
"operationId": "AdmiraltyController.CreateAdmiraltyTarget",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "execution",
|
|
||||||
"description": "execution id of the workflow",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"201": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admiralty/targets": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"description": "find all Admiralty Target\n\u003cbr\u003e",
|
|
||||||
"operationId": "AdmiraltyController.GetAllTargets",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admiralty/targets/{execution}": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"admiralty"
|
|
||||||
],
|
|
||||||
"description": "find one Admiralty Target\n\u003cbr\u003e",
|
|
||||||
"operationId": "AdmiraltyController.GetOneTarget",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "id",
|
|
||||||
"description": "the name of the target to get",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/booking/": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"booking"
|
|
||||||
],
|
|
||||||
"description": "find booking by id\n\u003cbr\u003e",
|
|
||||||
"operationId": "BookingController.GetAll",
|
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"name": "is_draft",
|
"name": "offset",
|
||||||
"description": "draft wished",
|
"description": "false",
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "{booking} models.booking"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"post": {
|
|
||||||
"tags": [
|
|
||||||
"booking"
|
|
||||||
],
|
|
||||||
"description": "create booking\n\u003cbr\u003e",
|
|
||||||
"operationId": "BookingController.Post.",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "body",
|
|
||||||
"name": "booking",
|
|
||||||
"description": "the booking you want to post",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"name": "is_draft",
|
"name": "limit",
|
||||||
"description": "draft wished",
|
"description": "false",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -260,44 +81,54 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/models.object"
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/allowed_image.AllowedImage"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/booking/check/{id}/{start_date}/{end_date}": {
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"allowed-image"
|
||||||
|
],
|
||||||
|
"description": "Ajoute une image à la liste des images autorisées (peer admin uniquement)\n\u003cbr\u003e",
|
||||||
|
"operationId": "AllowedImageController.Post",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "body",
|
||||||
|
"name": "body",
|
||||||
|
"description": "Image à autoriser",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/allowed_image.AllowedImage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/allowed_image.AllowedImage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/allowed-image/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"booking"
|
"allowed-image"
|
||||||
],
|
],
|
||||||
"description": "check booking\n\u003cbr\u003e",
|
"description": "Retourne une image autorisée par son ID\n\u003cbr\u003e",
|
||||||
"operationId": "BookingController.Check",
|
"operationId": "AllowedImageController.Get",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"description": "id of the datacenter",
|
"description": "ID de l'image autorisée",
|
||||||
"type": "string"
|
"required": true,
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "start_date",
|
|
||||||
"description": "2006-01-02T15:04:05",
|
|
||||||
"type": "string",
|
|
||||||
"default": "the booking start date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "end_date",
|
|
||||||
"description": "2006-01-02T15:04:05",
|
|
||||||
"type": "string",
|
|
||||||
"default": "the booking end date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "query",
|
|
||||||
"name": "is_draft",
|
|
||||||
"description": "draft wished",
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -305,84 +136,43 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "",
|
"description": "",
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/models.object"
|
"$ref": "#/definitions/allowed_image.AllowedImage"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/booking/search/execution/{id}": {
|
"delete": {
|
||||||
"get": {
|
|
||||||
"tags": [
|
"tags": [
|
||||||
"booking"
|
"allowed-image"
|
||||||
],
|
],
|
||||||
"description": "search bookings by execution\n\u003cbr\u003e",
|
"description": "Supprime une image de la liste des images autorisées (peer admin uniquement, entrées bootstrap non supprimables)\n\u003cbr\u003e",
|
||||||
"operationId": "BookingController.Search",
|
"operationId": "AllowedImageController.Delete",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"name": "id",
|
"name": "id",
|
||||||
"description": "id execution",
|
"description": "ID de l'image autorisée",
|
||||||
"required": true,
|
"required": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "query",
|
|
||||||
"name": "is_draft",
|
|
||||||
"description": "draft wished",
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "{workspace} models.workspace"
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/allowed_image.AllowedImage"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/booking/search/{start_date}/{end_date}": {
|
"/logs/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"booking"
|
"oc-datacenter/controllersDatacenterController"
|
||||||
],
|
|
||||||
"description": "search bookings\n\u003cbr\u003e",
|
|
||||||
"operationId": "BookingController.Search",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "start_date",
|
|
||||||
"description": "the word search you want to get",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "end_date",
|
|
||||||
"description": "the word search you want to get",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "query",
|
|
||||||
"name": "is_draft",
|
|
||||||
"description": "draft wished",
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "{workspace} models.workspace"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/booking/{id}": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"booking"
|
|
||||||
],
|
],
|
||||||
"description": "find booking by id\n\u003cbr\u003e",
|
"description": "find booking by id\n\u003cbr\u003e",
|
||||||
"operationId": "BookingController.Get",
|
"operationId": "DatacenterController.Log",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"in": "path",
|
"in": "path",
|
||||||
@@ -397,36 +187,6 @@
|
|||||||
"description": "{booking} models.booking"
|
"description": "{booking} models.booking"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"put": {
|
|
||||||
"tags": [
|
|
||||||
"booking"
|
|
||||||
],
|
|
||||||
"description": "create computes\n\u003cbr\u003e",
|
|
||||||
"operationId": "BookingController.Update",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"in": "path",
|
|
||||||
"name": "id",
|
|
||||||
"description": "the compute id you want to get",
|
|
||||||
"required": true,
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in": "body",
|
|
||||||
"name": "body",
|
|
||||||
"description": "The compute content",
|
|
||||||
"required": true,
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/models.compute"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "{compute} models.compute"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/session/token/{id}/{duration}": {
|
"/session/token/{id}/{duration}": {
|
||||||
@@ -485,7 +245,55 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/{id}": {
|
"/{type}/search/{search}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"oc-datacenter/controllersDatacenterController"
|
||||||
|
],
|
||||||
|
"description": "search datacenter\n\u003cbr\u003e",
|
||||||
|
"operationId": "DatacenterController.Search",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "type",
|
||||||
|
"description": "the type you want to get",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "search",
|
||||||
|
"description": "the word search you want to get",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "is_draft",
|
||||||
|
"description": "draft wished",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "offset",
|
||||||
|
"description": "false",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "limit",
|
||||||
|
"description": "false",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{workspace} models.workspace"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/{type}/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"oc-datacenter/controllersDatacenterController"
|
"oc-datacenter/controllersDatacenterController"
|
||||||
@@ -500,6 +308,47 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "type",
|
||||||
|
"description": "the word type you want to get",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "is_draft",
|
||||||
|
"description": "draft wished",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "{booking} models.booking"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"tags": [
|
||||||
|
"oc-datacenter/controllersDatacenterController"
|
||||||
|
],
|
||||||
|
"description": "find booking by id\n\u003cbr\u003e",
|
||||||
|
"operationId": "DatacenterController.Delete",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "id",
|
||||||
|
"description": "the id you want to get",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "type",
|
||||||
|
"description": "the word type you want to get",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"in": "query",
|
"in": "query",
|
||||||
"name": "is_draft",
|
"name": "is_draft",
|
||||||
@@ -516,21 +365,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"controllers.RemoteKubeconfig": {
|
"allowed_image.AllowedImage": {
|
||||||
"title": "RemoteKubeconfig",
|
"title": "AllowedImage",
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"Data": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"models.compute": {
|
|
||||||
"title": "compute",
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
"models.object": {
|
|
||||||
"title": "object",
|
|
||||||
"type": "object"
|
"type": "object"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -539,17 +375,13 @@
|
|||||||
"name": "oc-datacenter/controllersDatacenterController",
|
"name": "oc-datacenter/controllersDatacenterController",
|
||||||
"description": "Operations about workspace\n"
|
"description": "Operations about workspace\n"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "booking",
|
|
||||||
"description": "Operations about workspace\n"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "version",
|
"name": "version",
|
||||||
"description": "VersionController operations for Version\n"
|
"description": "VersionController operations for Version\n"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "admiralty",
|
"name": "allowed-image",
|
||||||
"description": "Operations about the admiralty objects of the datacenter\n"
|
"description": "AllowedImageController gère la liste locale des images autorisées à persister\nsur ce peer après l'exécution d'un workflow.\n\nGET /allowed-image/ → tous les utilisateurs authentifiés\nGET /allowed-image/:id → tous les utilisateurs authentifiés\nPOST /allowed-image/ → peer admin uniquement\nDELETE /allowed-image/:id → peer admin uniquement (bloqué si IsDefault)\n"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ info:
|
|||||||
license:
|
license:
|
||||||
name: AGPL
|
name: AGPL
|
||||||
url: https://www.gnu.org/licenses/agpl-3.0.html
|
url: https://www.gnu.org/licenses/agpl-3.0.html
|
||||||
basePath: /oc/
|
basePath: /oc
|
||||||
paths:
|
paths:
|
||||||
/:
|
/:
|
||||||
get:
|
get:
|
||||||
@@ -21,14 +21,27 @@ paths:
|
|||||||
<br>
|
<br>
|
||||||
operationId: DatacenterController.GetAll
|
operationId: DatacenterController.GetAll
|
||||||
parameters:
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: type
|
||||||
|
description: the word type you want to get
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
- in: query
|
- in: query
|
||||||
name: is_draft
|
name: is_draft
|
||||||
description: draft wished
|
description: draft wished
|
||||||
type: string
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: offset
|
||||||
|
description: "false"
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: limit
|
||||||
|
description: "false"
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: '{booking} models.booking'
|
description: '{booking} models.booking'
|
||||||
/{id}:
|
/{type}/{id}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- oc-datacenter/controllersDatacenterController
|
- oc-datacenter/controllersDatacenterController
|
||||||
@@ -42,6 +55,11 @@ paths:
|
|||||||
description: the id you want to get
|
description: the id you want to get
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
- in: path
|
||||||
|
name: type
|
||||||
|
description: the word type you want to get
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
- in: query
|
- in: query
|
||||||
name: is_draft
|
name: is_draft
|
||||||
description: draft wished
|
description: draft wished
|
||||||
@@ -49,134 +67,24 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: '{booking} models.booking'
|
description: '{booking} models.booking'
|
||||||
/admiralty/kubeconfig/{execution}:
|
delete:
|
||||||
get:
|
|
||||||
tags:
|
tags:
|
||||||
- admiralty
|
- oc-datacenter/controllersDatacenterController
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: execution
|
|
||||||
description: execution id of the workflow
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
/admiralty/node/{execution}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: execution
|
|
||||||
description: execution id of the workflow
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
/admiralty/secret/{execution}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: execution
|
|
||||||
description: execution id of the workflow
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: execution
|
|
||||||
description: execution id of the workflow
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- in: body
|
|
||||||
name: kubeconfig
|
|
||||||
description: Kubeconfig to use when creating secret
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/controllers.RemoteKubeconfig'
|
|
||||||
responses:
|
|
||||||
"201":
|
|
||||||
description: ""
|
|
||||||
/admiralty/source/{execution}:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
description: |-
|
description: |-
|
||||||
Create an Admiralty Source on remote cluster
|
find booking by id
|
||||||
<br>
|
<br>
|
||||||
operationId: AdmiraltyController.CreateSource
|
operationId: DatacenterController.Delete
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: execution
|
|
||||||
description: execution id of the workflow
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"201":
|
|
||||||
description: ""
|
|
||||||
/admiralty/target/{execution}:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
description: |-
|
|
||||||
Create an Admiralty Target in the namespace associated to the executionID
|
|
||||||
<br>
|
|
||||||
operationId: AdmiraltyController.CreateAdmiraltyTarget
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: execution
|
|
||||||
description: execution id of the workflow
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"201":
|
|
||||||
description: ""
|
|
||||||
/admiralty/targets:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
description: |-
|
|
||||||
find all Admiralty Target
|
|
||||||
<br>
|
|
||||||
operationId: AdmiraltyController.GetAllTargets
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
/admiralty/targets/{execution}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- admiralty
|
|
||||||
description: |-
|
|
||||||
find one Admiralty Target
|
|
||||||
<br>
|
|
||||||
operationId: AdmiraltyController.GetOneTarget
|
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
name: id
|
name: id
|
||||||
description: the name of the target to get
|
description: the id you want to get
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- in: path
|
||||||
|
name: type
|
||||||
|
description: the word type you want to get
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
/booking/:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- booking
|
|
||||||
description: |-
|
|
||||||
find booking by id
|
|
||||||
<br>
|
|
||||||
operationId: BookingController.GetAll
|
|
||||||
parameters:
|
|
||||||
- in: query
|
- in: query
|
||||||
name: is_draft
|
name: is_draft
|
||||||
description: draft wished
|
description: draft wished
|
||||||
@@ -184,38 +92,128 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: '{booking} models.booking'
|
description: '{booking} models.booking'
|
||||||
post:
|
/{type}/search/{search}:
|
||||||
|
get:
|
||||||
tags:
|
tags:
|
||||||
- booking
|
- oc-datacenter/controllersDatacenterController
|
||||||
description: |-
|
description: |-
|
||||||
create booking
|
search datacenter
|
||||||
<br>
|
<br>
|
||||||
operationId: BookingController.Post.
|
operationId: DatacenterController.Search
|
||||||
parameters:
|
parameters:
|
||||||
- in: body
|
- in: path
|
||||||
name: booking
|
name: type
|
||||||
description: the booking you want to post
|
description: the type you want to get
|
||||||
required: true
|
required: true
|
||||||
schema:
|
|
||||||
type: string
|
type: string
|
||||||
|
- in: path
|
||||||
|
name: search
|
||||||
|
description: the word search you want to get
|
||||||
|
required: true
|
||||||
type: string
|
type: string
|
||||||
- in: query
|
- in: query
|
||||||
name: is_draft
|
name: is_draft
|
||||||
description: draft wished
|
description: draft wished
|
||||||
type: string
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: offset
|
||||||
|
description: "false"
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: limit
|
||||||
|
description: "false"
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: '{workspace} models.workspace'
|
||||||
|
/allowed-image/:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- allowed-image
|
||||||
|
description: |-
|
||||||
|
Retourne toutes les images autorisées à persister sur ce peer
|
||||||
|
<br>
|
||||||
|
operationId: AllowedImageController.GetAll
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: offset
|
||||||
|
description: "false"
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: limit
|
||||||
|
description: "false"
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: ""
|
description: ""
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/models.object'
|
type: array
|
||||||
/booking/{id}:
|
items:
|
||||||
|
$ref: '#/definitions/allowed_image.AllowedImage'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- allowed-image
|
||||||
|
description: |-
|
||||||
|
Ajoute une image à la liste des images autorisées (peer admin uniquement)
|
||||||
|
<br>
|
||||||
|
operationId: AllowedImageController.Post
|
||||||
|
parameters:
|
||||||
|
- in: body
|
||||||
|
name: body
|
||||||
|
description: Image à autoriser
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/allowed_image.AllowedImage'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/allowed_image.AllowedImage'
|
||||||
|
/allowed-image/{id}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- booking
|
- allowed-image
|
||||||
|
description: |-
|
||||||
|
Retourne une image autorisée par son ID
|
||||||
|
<br>
|
||||||
|
operationId: AllowedImageController.Get
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: id
|
||||||
|
description: ID de l'image autorisée
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/allowed_image.AllowedImage'
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- allowed-image
|
||||||
|
description: |-
|
||||||
|
Supprime une image de la liste des images autorisées (peer admin uniquement, entrées bootstrap non supprimables)
|
||||||
|
<br>
|
||||||
|
operationId: AllowedImageController.Delete
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: id
|
||||||
|
description: ID de l'image autorisée
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/allowed_image.AllowedImage'
|
||||||
|
/logs/{id}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- oc-datacenter/controllersDatacenterController
|
||||||
description: |-
|
description: |-
|
||||||
find booking by id
|
find booking by id
|
||||||
<br>
|
<br>
|
||||||
operationId: BookingController.Get
|
operationId: DatacenterController.Log
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: path
|
||||||
name: id
|
name: id
|
||||||
@@ -225,107 +223,6 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: '{booking} models.booking'
|
description: '{booking} models.booking'
|
||||||
put:
|
|
||||||
tags:
|
|
||||||
- booking
|
|
||||||
description: |-
|
|
||||||
create computes
|
|
||||||
<br>
|
|
||||||
operationId: BookingController.Update
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: id
|
|
||||||
description: the compute id you want to get
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: The compute content
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/models.compute'
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: '{compute} models.compute'
|
|
||||||
/booking/check/{id}/{start_date}/{end_date}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- booking
|
|
||||||
description: |-
|
|
||||||
check booking
|
|
||||||
<br>
|
|
||||||
operationId: BookingController.Check
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: id
|
|
||||||
description: id of the datacenter
|
|
||||||
type: string
|
|
||||||
- in: path
|
|
||||||
name: start_date
|
|
||||||
description: 2006-01-02T15:04:05
|
|
||||||
type: string
|
|
||||||
default: the booking start date
|
|
||||||
- in: path
|
|
||||||
name: end_date
|
|
||||||
description: 2006-01-02T15:04:05
|
|
||||||
type: string
|
|
||||||
default: the booking end date
|
|
||||||
- in: query
|
|
||||||
name: is_draft
|
|
||||||
description: draft wished
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: ""
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/models.object'
|
|
||||||
/booking/search/{start_date}/{end_date}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- booking
|
|
||||||
description: |-
|
|
||||||
search bookings
|
|
||||||
<br>
|
|
||||||
operationId: BookingController.Search
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: start_date
|
|
||||||
description: the word search you want to get
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- in: path
|
|
||||||
name: end_date
|
|
||||||
description: the word search you want to get
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- in: query
|
|
||||||
name: is_draft
|
|
||||||
description: draft wished
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: '{workspace} models.workspace'
|
|
||||||
/booking/search/execution/{id}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- booking
|
|
||||||
description: |-
|
|
||||||
search bookings by execution
|
|
||||||
<br>
|
|
||||||
operationId: BookingController.Search
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: id
|
|
||||||
description: id execution
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
- in: query
|
|
||||||
name: is_draft
|
|
||||||
description: draft wished
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: '{workspace} models.workspace'
|
|
||||||
/session/token/{id}/{duration}:
|
/session/token/{id}/{duration}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -369,28 +266,22 @@ paths:
|
|||||||
"200":
|
"200":
|
||||||
description: ""
|
description: ""
|
||||||
definitions:
|
definitions:
|
||||||
controllers.RemoteKubeconfig:
|
allowed_image.AllowedImage:
|
||||||
title: RemoteKubeconfig
|
title: AllowedImage
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
Data:
|
|
||||||
type: string
|
|
||||||
models.compute:
|
|
||||||
title: compute
|
|
||||||
type: object
|
|
||||||
models.object:
|
|
||||||
title: object
|
|
||||||
type: object
|
type: object
|
||||||
tags:
|
tags:
|
||||||
- name: oc-datacenter/controllersDatacenterController
|
- name: oc-datacenter/controllersDatacenterController
|
||||||
description: |
|
description: |
|
||||||
Operations about workspace
|
Operations about workspace
|
||||||
- name: booking
|
|
||||||
description: |
|
|
||||||
Operations about workspace
|
|
||||||
- name: version
|
- name: version
|
||||||
description: |
|
description: |
|
||||||
VersionController operations for Version
|
VersionController operations for Version
|
||||||
- name: admiralty
|
- name: allowed-image
|
||||||
description: |
|
description: |
|
||||||
Operations about the admiralty objects of the datacenter
|
AllowedImageController gère la liste locale des images autorisées à persister
|
||||||
|
sur ce peer après l'exécution d'un workflow.
|
||||||
|
|
||||||
|
GET /allowed-image/ → tous les utilisateurs authentifiés
|
||||||
|
GET /allowed-image/:id → tous les utilisateurs authentifiés
|
||||||
|
POST /allowed-image/ → peer admin uniquement
|
||||||
|
DELETE /allowed-image/:id → peer admin uniquement (bloqué si IsDefault)
|
||||||
|
|||||||
Reference in New Issue
Block a user