diff --git a/controllers/booking.go b/controllers/booking.go index 3c165a3..891576e 100644 --- a/controllers/booking.go +++ b/controllers/booking.go @@ -6,15 +6,18 @@ import ( "fmt" "net/http" "oc-datacenter/infrastructure" + "strconv" "time" oclib "cloud.o-forge.io/core/oc-lib" "cloud.o-forge.io/core/oc-lib/dbs" "cloud.o-forge.io/core/oc-lib/models/booking" b "cloud.o-forge.io/core/oc-lib/models/booking" + "cloud.o-forge.io/core/oc-lib/models/utils" "cloud.o-forge.io/core/oc-lib/tools" beego "github.com/beego/beego/v2/server/web" "github.com/gorilla/websocket" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) @@ -323,6 +326,116 @@ func (o *BookingController) Post() { o.ServeJSON() } +// @Title ExtendForNamespace +// @Description ExtendForNamespace booking +// @Param namespace path string "targetted namespace" +// @Param resource_id path string "resource id" +// @Param end_date path string "the booking end date" format "2006-01-02T15:04:05" +// @Param is_draft query string false "draft wished" +// @Success 200 {object} models.object +// @router /extend/:resource_id/from_namespace/:namespace/to/:duration [post] +func (o *BookingController) ExtendForNamespace() { + user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request) + resourceID := o.Ctx.Input.Param(":resource_id") + namespace := o.Ctx.Input.Param(":namespace") + duration, err := strconv.Atoi(o.Ctx.Input.Param(":duration")) + if err != nil { + o.Data["json"] = map[string]interface{}{ + "data": map[string]interface{}{ + "is_available": false, + }, + "code": 400, + "error": errors.New("invalid date format"), + } + } else { + o.extend(duration, resourceID, "executions_id", namespace, user, peerID, groups) + } +} + +// @Title ExtendForExecution +// @Description ExtendForExecution booking +// @Param namespace path string "targetted namespace" +// @Param resource_id path string "resource id" +// @Param end_date path string "the booking end date" format "2006-01-02T15:04:05" +// @Param is_draft query string false "draft wished" +// @Success 200 {object} models.object +// @router /extend/:resource_id/from_execution/:execution_id/to/:duration [post] +func (o *BookingController) ExtendForExecution() { + user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request) + resourceID := o.Ctx.Input.Param(":resource_id") + executionID := o.Ctx.Input.Param(":execution_id") + duration, err := strconv.Atoi(o.Ctx.Input.Param(":duration")) + if err != nil { + o.Data["json"] = map[string]interface{}{ + "data": map[string]interface{}{ + "is_available": false, + }, + "code": 400, + "error": errors.New("invalid date format"), + } + } else { + o.extend(duration, resourceID, "execution_id", executionID, user, peerID, groups) + } +} + +func (o *BookingController) extend(duration int, resourceID string, key string, namespace string, user string, peerID string, groups []string) { + /* + * This function is used to check if a booking is available for a specific datacenter. + * It takes the following parameters: + * - id: the id of the datacenter + * - start_date: the start date of the booking/search/execution/:id + * - end_date: the end date of the booking + */ + + req := oclib.NewRequest(oclib.LibDataEnum(oclib.BOOKING), user, peerID, groups, nil) + res := req.Search(&dbs.Filters{ + Or: map[string][]dbs.Filter{ + "expected_end_date": { + {Operator: dbs.GTE.String(), Value: time.Now()}, + {Operator: dbs.EQUAL.String(), Value: bson.TypeNull}, + }, + }, + And: map[string][]dbs.Filter{ + "resource_id": {{Operator: dbs.EQUAL.String(), Value: resourceID}}, + key: {{Operator: dbs.EQUAL.String(), Value: namespace}}, + "expected_start_date": {{Operator: dbs.GTE.String(), Value: time.Now()}}, + }, + }, "", false) + if res.Err == "" && len(res.Data) > 0 { + var id string + datas := []utils.DBObject{} + for _, b := range res.Data { + book := b.(*booking.Booking) + if book.ExpectedEndDate != nil { + bb := book.ExpectedEndDate.Add(time.Duration(duration) * time.Second) + if isAvailable, err := (&booking.Booking{}).Check(id, (*book.ExpectedEndDate).Add(1*time.Second), &bb, 1); isAvailable && err == nil { + book.ExpectedEndDate = &bb + result := req.UpdateOne(book.Serialize(book), book.GetID()) + datas = append(datas, result.Data) + } + } + } + o.Data["json"] = map[string]interface{}{ + "data": datas, + "code": 200, + "error": "", + } + o.ServeJSON() + return + } else if res.Err == "" { + o.Data["json"] = map[string]interface{}{ + "data": map[string]interface{}{ + "is_available": false, + }, + "code": 400, + "error": errors.New("can't find any booking to extend"), + } + } else { + o.Data["json"] = res + } + o.ServeJSON() +} + func (o *BookingController) createNamespace(ns string) error { /* * This function is used to create a namespace.