initial commit
This commit is contained in:
77
controllers/computing.go
Normal file
77
controllers/computing.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// All operations related to the rType computing
|
||||
type ComputingController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// @Title Get computing by ID
|
||||
// @Description Find a computing resource based on ID
|
||||
// @Param ID path string true "The ID of the resource"
|
||||
// @Success 200 {object} models.ComputingModel
|
||||
// @Failure 403 ID is empty
|
||||
// @router /:ID [get]
|
||||
func (o *ComputingController) GetOneComputing(ID string) {
|
||||
if ID != "" {
|
||||
ob, err := models.GetOneComputing(ID)
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Add computing
|
||||
// @Description Submit a computing object
|
||||
// @Param body body models.ComputingNEWModel true "The object content"
|
||||
// @Success 200 {string} ID
|
||||
// @Failure 403 Missing body or fields
|
||||
// @router / [post]
|
||||
func (o *ComputingController) PostComputing(body models.ComputingNEWModel) {
|
||||
err := validate.Struct(body)
|
||||
// validationErrors := err.(validator.ValidationErrors)
|
||||
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
o.Ctx.Output.Status = 403
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
ID, err := models.PostOneComputing(body)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
return
|
||||
}
|
||||
|
||||
o.Data["json"] = map[string]string{"ID": ID}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Get multiple computing by IDs
|
||||
// @Description Return Computing objects if found in the DB. Not found IDs will be ignored
|
||||
// @Param IDs path []string true "List of computing IDs"
|
||||
// @Success 200 {object} []models.ComputingModel
|
||||
// @Failure 403 IDs are empty
|
||||
// @router /multi/:IDs [get]
|
||||
func (o *ComputingController) GetMultipleComputing(IDs []string) {
|
||||
if len(IDs) != 0 {
|
||||
ob, err := models.GetMultipleComputing(IDs)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
} else {
|
||||
o.Ctx.Output.SetStatus(403)
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
85
controllers/data.go
Normal file
85
controllers/data.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
// All operations related to the rType data
|
||||
type DataController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
var validate *validator.Validate
|
||||
|
||||
func init() {
|
||||
validate = validator.New()
|
||||
}
|
||||
|
||||
// @Title Get data by ID
|
||||
// @Description Find rType data based on ID
|
||||
// @Param ID path string true "The ID of the data resource"
|
||||
// @Success 200 {object} models.DataModel
|
||||
// @Failure 403 ID is empty
|
||||
// @router /:ID [get]
|
||||
func (o *DataController) GetOneData(ID string) {
|
||||
if ID != "" {
|
||||
ob, err := models.GetOneData(ID)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
} else {
|
||||
o.Ctx.Output.SetStatus(403)
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Get multiple data by IDs
|
||||
// @Description Return Data object if found in the DB. Not found IDs will be ignored
|
||||
// @Param IDs path []string true "List of data IDs"
|
||||
// @Success 200 {object} []models.DataModel
|
||||
// @Failure 403 IDs are empty
|
||||
// @router /multi/:IDs [get]
|
||||
func (o *DataController) GetMultipleData(IDs []string) {
|
||||
if len(IDs) != 0 {
|
||||
ob, err := models.GetMultipleData(IDs)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
} else {
|
||||
o.Ctx.Output.SetStatus(403)
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Create Data
|
||||
// @Description Submit data object
|
||||
// @Param body body models.DataNEWModel true "The object content"
|
||||
// @Success 200 {string} ID
|
||||
// @Failure 403 Missing body or fields
|
||||
// @router / [post]
|
||||
func (o *DataController) PostData(body models.DataNEWModel) {
|
||||
err := validate.Struct(body)
|
||||
// validationErrors := err.(validator.ValidationErrors)
|
||||
|
||||
if err != nil {
|
||||
o.Ctx.Output.Status = 403
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
ID, err := models.PostOneData(body)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
return
|
||||
}
|
||||
|
||||
o.Data["json"] = map[string]string{"ID": ID}
|
||||
o.ServeJSON()
|
||||
}
|
||||
82
controllers/datacenter.go
Normal file
82
controllers/datacenter.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
// DatacenterController operations about datacenters
|
||||
type DatacenterController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
func init() {
|
||||
validate = validator.New()
|
||||
}
|
||||
|
||||
// @Title Get multiple datacenters by IDs
|
||||
// @Description Return Datacenter objects if found in the DB. Not found IDs will be ignored
|
||||
// @Param IDs path []string true "List of datacenter IDs"
|
||||
// @Success 200 {object} []models.ComputingModel
|
||||
// @Failure 403 IDs are empty
|
||||
// @router /multi/:IDs [get]
|
||||
func (o *DatacenterController) GetMultipleDatacenter(IDs []string) {
|
||||
if len(IDs) != 0 {
|
||||
ob, err := models.GetMultipleDatacenter(IDs)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
} else {
|
||||
o.Ctx.Output.SetStatus(403)
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title GetOneDatacenter
|
||||
// @Description find datacenter by ID
|
||||
// @Param ID path string true "the ID you want to get"
|
||||
// @Success 200 {object} models.DatacenterModel
|
||||
// @Failure 403 ID is empty
|
||||
// @router /:ID [get]
|
||||
func (o *DatacenterController) GetOneDatacenter(ID string) {
|
||||
if ID != "" {
|
||||
ob, err := models.GetOneDatacenter(ID)
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Create Datacenter
|
||||
// @Description submit Datacenter object
|
||||
// @Param body body models.DatacenterNEWModel true "The object content"
|
||||
// @Success 200 {string} models.DatacenterModel
|
||||
// @Failure 403 Missing body or fields
|
||||
// @router / [post]
|
||||
func (o *DatacenterController) PostDatacenter(body models.DatacenterNEWModel) {
|
||||
err := validate.Struct(body)
|
||||
// validationErrors := err.(validator.ValidationErrors)
|
||||
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
o.Ctx.Output.Status = 403
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
ID, err := models.PostOneDatacenter(body)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
return
|
||||
}
|
||||
|
||||
o.Data["json"] = map[string]string{"ID": ID}
|
||||
o.ServeJSON()
|
||||
}
|
||||
163
controllers/schedule.go
Normal file
163
controllers/schedule.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
type ScheduleController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// @Title Create schedule
|
||||
// @Description Create schedule for a workflow. It will return some future executions just as information
|
||||
// @Param dcName query string true "Name of the node (oc-catalog) from where the workflow comes."
|
||||
// @Param workflowName query string true "Workflow Name"
|
||||
// @Param cron query string true "Cron syntax with year. If no year is specified, will use the current"
|
||||
// @Param duration query uint true "Duration in seconds"
|
||||
// @Param startDate query time.Time true "RFC3339 time for startDate"
|
||||
// @Param stopDate query time.Time true "RFC3339 time for stopDate"
|
||||
// @Param requirements body models.ExecutionRequirementsModel true "The object content"
|
||||
// @Success 200 {object} models.ScheduleInfo
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 workflowName not found or empty
|
||||
// // @Security jwtAPIToken
|
||||
// @router /book [post]
|
||||
func (u *ScheduleController) CreateSchedule(dcName, workflowName, cron string, duration uint, startDate, stopDate time.Time, requirements models.ExecutionRequirementsModel) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
//FIXME: Passing a date as "2021-07-15 00:00:00 0000 UTC" break the controller but return 200. Should return 4xx
|
||||
|
||||
username := "asd"
|
||||
|
||||
nextIters, err := models.CreateScheduleWorkflow(dcName, username, workflowName, cron, duration, startDate, stopDate, requirements)
|
||||
if err != nil {
|
||||
u.CustomAbort(400, err.Error())
|
||||
}
|
||||
|
||||
u.Data["json"] = nextIters
|
||||
u.ServeJSON()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//TODO: This node corresponds to a unique DC, which it owns. We must restructure the code in order to
|
||||
// allow a unique DC. And maybe discuss more this point
|
||||
|
||||
// @Title Check if schedule can be created in this DC
|
||||
// @Description Check for availability of this DC
|
||||
// @Param cron query string true "Cron syntax"
|
||||
// @Param duration query uint true "Duration in seconds"
|
||||
// @Param startDate query time.Time true "RFC3339 time for startDate"
|
||||
// @Param stopDate query time.Time true "RFC3339 time for stopDate"
|
||||
// @Param requirements body models.ExecutionRequirementsModel true "The object content"
|
||||
// @Success 200 The schedule can be created
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 Other error. Check the output
|
||||
// // @Security jwtAPIToken
|
||||
// @router /check [post]
|
||||
func (u *ScheduleController) CheckSchedule(cron string, duration uint, startDate, stopDate time.Time, requirements models.ExecutionRequirementsModel) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// username := "asd"
|
||||
|
||||
if cron == "" {
|
||||
u.CustomAbort(400, "Tasks cronString must not be empty")
|
||||
}
|
||||
|
||||
// Check Dates
|
||||
if startDate.After(stopDate) || startDate.Equal(stopDate) {
|
||||
u.CustomAbort(400, "startDate must be before stopDate")
|
||||
}
|
||||
|
||||
if startDate.Before(time.Now().UTC()) {
|
||||
u.CustomAbort(400, "Current server time ("+time.Now().UTC().String()+") is after the startDate ("+startDate.String()+")")
|
||||
}
|
||||
|
||||
err := models.CheckSchedule(cron, duration, startDate, stopDate, requirements)
|
||||
if err != nil {
|
||||
logs.Warning(err)
|
||||
u.CustomAbort(400, err.Error())
|
||||
}
|
||||
|
||||
// u.Data["json"] = nextIters
|
||||
// u.ServeJSON()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// @Title Get schedules
|
||||
// @Description Get a list of next startDates schedules (inclusive). If timezone is not specified, will assume UTC
|
||||
// @Param startDate query time.Time true "Start date"
|
||||
// @Param stopDate query time.Time true "End date"
|
||||
// @Success 200 {object} []models.ScheduleDB
|
||||
// @Success 201 Too much elements within the range of dates
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 Other error. Check the output
|
||||
// // @Security jwtAPIToken
|
||||
// @router / [get]
|
||||
func (u *ScheduleController) GetSchedules(startDate time.Time, stopDate time.Time) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// username := "asd"
|
||||
|
||||
data, maxLimit, err := models.GetSchedules(startDate, stopDate)
|
||||
if err != nil {
|
||||
logs.Warning(err)
|
||||
u.CustomAbort(400, err.Error())
|
||||
}
|
||||
|
||||
if maxLimit {
|
||||
u.Ctx.Output.Status = 201
|
||||
}
|
||||
|
||||
u.Data["json"] = data
|
||||
u.ServeJSON()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// @Title Get next schedule
|
||||
// @Description Give a date, get the next date where there are at least on schedule. If no hours specified, will assume 00:00
|
||||
// @Param baseDate query time.Time true "Base date"
|
||||
// @Success 200 {object} *time.Time
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 Other error. Check the output
|
||||
// // @Security jwtAPIToken
|
||||
// @router /next [get]
|
||||
func (u *ScheduleController) GetNextSchedules(baseDate time.Time) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// username := "asd"
|
||||
|
||||
futureDate := models.GetFarSchedules(baseDate, true)
|
||||
|
||||
u.Data["json"] = futureDate
|
||||
u.ServeJSON()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// @Title Get previous schedule
|
||||
// @Description Give a date, get the previous date where there are at least on schedule. If no hours specified, will assume 00:00
|
||||
// @Param baseDate query time.Time true "Base date"
|
||||
// @Success 200 {object} *time.Time
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 Other error. Check the output
|
||||
// // @Security jwtAPIToken
|
||||
// @router /previous [get]
|
||||
func (u *ScheduleController) GetPreviousSchedules(baseDate time.Time) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// username := "asd"
|
||||
|
||||
futureDate := models.GetFarSchedules(baseDate, false)
|
||||
|
||||
u.Data["json"] = futureDate
|
||||
u.ServeJSON()
|
||||
|
||||
return
|
||||
}
|
||||
31
controllers/search.go
Normal file
31
controllers/search.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
type SearchController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// TODO: Search by word is very very inneficent for not small databases
|
||||
// @Title Search by word
|
||||
// @Description find resources by word
|
||||
// @Param word query string true "Word to search across all resources"
|
||||
// @Success 200 {object} models.SearchResult
|
||||
// @Failure 503 Internal error
|
||||
// @router /byWord [get]
|
||||
func (o *SearchController) FindByWord(word string) {
|
||||
if word != "" {
|
||||
ob, err := models.FindByWord(word)
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
o.Ctx.Output.Status = 503
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
77
controllers/storage.go
Normal file
77
controllers/storage.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// StorageController operations about storage
|
||||
type StorageController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// @Title Get
|
||||
// @Description find storage by ID
|
||||
// @Param ID path string true "the ID you want to get"
|
||||
// @Success 200 {object} models.StorageModel
|
||||
// @Failure 403 ID is empty
|
||||
// @router /:ID [get]
|
||||
func (o *StorageController) GetOneStorage(ID string) {
|
||||
if ID != "" {
|
||||
ob, err := models.GetOneStorage(ID)
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Get multiple storages by IDs
|
||||
// @Description Return Storage objects if found in the DB. Not found IDs will be ignored
|
||||
// @Param IDs path []string true "List of storage IDs"
|
||||
// @Success 200 {object} []models.ComputingModel
|
||||
// @Failure 403 IDs are empty
|
||||
// @router /multi/:IDs [get]
|
||||
func (o *StorageController) GetMultipleStorage(IDs []string) {
|
||||
if len(IDs) != 0 {
|
||||
ob, err := models.GetMultipleStorage(IDs)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
} else {
|
||||
o.Data["json"] = ob
|
||||
}
|
||||
} else {
|
||||
o.Ctx.Output.SetStatus(403)
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Create Storage
|
||||
// @Description submit storage object
|
||||
// @Param body body models.StorageNEWModel true "The object content"
|
||||
// @Success 200 {string} models.StorageModel
|
||||
// @Failure 403 Missing body or fields
|
||||
// @router / [post]
|
||||
func (o *StorageController) PostStorage(body models.StorageNEWModel) {
|
||||
err := validate.Struct(body)
|
||||
// validationErrors := err.(validator.ValidationErrors)
|
||||
|
||||
if err != nil {
|
||||
o.Data["json"] = err.Error()
|
||||
o.Ctx.Output.Status = 403
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
ID, err := models.PostOneStorage(body)
|
||||
if err != nil {
|
||||
o.Ctx.Output.SetStatus(500)
|
||||
return
|
||||
}
|
||||
|
||||
o.Data["json"] = map[string]string{"ID": ID}
|
||||
o.ServeJSON()
|
||||
}
|
||||
68
controllers/tokens.go
Normal file
68
controllers/tokens.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const mySuperSecretKey = "jdnfksdmfksd"
|
||||
|
||||
func CreateToken(userId string) (string, error) {
|
||||
var err error
|
||||
//Creating Access Token
|
||||
// os.Setenv("ACCESS_SECRET", "jdnfksdmfksd") //this should be in an env file
|
||||
atClaims := jwt.MapClaims{}
|
||||
atClaims["authorized"] = true
|
||||
atClaims["user_id"] = userId
|
||||
atClaims["exp"] = time.Now().UTC().Add(time.Hour * 15).Unix()
|
||||
at := jwt.NewWithClaims(jwt.SigningMethodHS256, atClaims)
|
||||
token, err := at.SignedString([]byte(mySuperSecretKey))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func IsValidToken(jwtToken string) (*jwt.Token, error) {
|
||||
token, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) {
|
||||
//TODO: Validate expected algorithm
|
||||
return []byte(mySuperSecretKey), nil
|
||||
})
|
||||
|
||||
var message string
|
||||
|
||||
if err == nil && token.Valid {
|
||||
return token, nil
|
||||
} else if ve, ok := err.(*jwt.ValidationError); ok {
|
||||
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
|
||||
message = "Token " + jwtToken + " is not even a token"
|
||||
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
|
||||
message = "Token is either expired or not active yet"
|
||||
} else {
|
||||
message = "Couldn't handle this token: " + err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
logs.Debug(message)
|
||||
return nil, errors.New(message)
|
||||
}
|
||||
|
||||
func GetUsernameFromToken(token string) (string, error) {
|
||||
|
||||
tokenObj, err := IsValidToken(token)
|
||||
if err != nil {
|
||||
logs.Debug(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
if claims, ok := tokenObj.Claims.(jwt.MapClaims); ok {
|
||||
return claims["user_id"].(string), nil
|
||||
}
|
||||
|
||||
logs.Debug("Unknow JWT error")
|
||||
return "", errors.New("Unknow JWT error")
|
||||
|
||||
}
|
||||
54
controllers/user.go
Normal file
54
controllers/user.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
type UserController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// @Title Login
|
||||
// @Description Logs user into the system
|
||||
// @Param username query string true "The username for login"
|
||||
// @Param password query string true "The password for login"
|
||||
// @Success 200 {string} login success
|
||||
// @Failure 403 user not exist
|
||||
// @router /login [get]
|
||||
func (u *UserController) Login() {
|
||||
username := u.GetString("username")
|
||||
password := u.GetString("password")
|
||||
|
||||
if models.Login(username, password) {
|
||||
token, err := CreateToken(username)
|
||||
|
||||
if err != nil {
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 503
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
u.Ctx.SetCookie("token", token)
|
||||
u.Ctx.Output.Header("Authorization", token) //FIXME: Some more generic way to use the name of the header
|
||||
u.Data["json"] = "login success"
|
||||
u.ServeJSON()
|
||||
return
|
||||
|
||||
}
|
||||
u.Ctx.Output.Status = 403
|
||||
u.Data["json"] = "user not exist"
|
||||
u.ServeJSON()
|
||||
|
||||
}
|
||||
|
||||
// @Title logout
|
||||
// @Description Logs out current logged in user session
|
||||
// @Success 200 {string} logout success
|
||||
// // @Security mySecurityPathNameApiKey
|
||||
// @router /logout [get]
|
||||
func (u *UserController) Logout() {
|
||||
u.Data["json"] = "logout success"
|
||||
u.ServeJSON()
|
||||
}
|
||||
337
controllers/workflow.go
Normal file
337
controllers/workflow.go
Normal file
@@ -0,0 +1,337 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
"github.com/beego/beego/v2/core/logs"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
"github.com/vk496/cron"
|
||||
)
|
||||
|
||||
type WorkflowController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// @Title Create a new workflow
|
||||
// @Description Create a name for the new workflow
|
||||
// @Param workflowName query string true "Name of the workflow"
|
||||
// @Success 200 {string} Workflow created succeful
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router / [post]
|
||||
func (u *WorkflowController) CreateWorkflow(workflowName string) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// //TODO: Implement as swagger security definition (api key?)
|
||||
// username, err := GetUsernameFromToken(token)
|
||||
// if err != nil {
|
||||
// u.Data["json"] = "No valid token"
|
||||
// u.Ctx.Output.Status = 403
|
||||
// u.ServeJSON()
|
||||
// return
|
||||
// }
|
||||
|
||||
username := "asd"
|
||||
|
||||
if err := models.CreateWorkflow(username, workflowName); err != nil {
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// @Title List workflows
|
||||
// @Description List available workflows
|
||||
// @Success 200 []string List of workflows
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router / [get]
|
||||
func (u *WorkflowController) ListWorkflows() {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
username := "asd"
|
||||
|
||||
w := models.GetWorkspace(username)
|
||||
|
||||
if w == nil {
|
||||
// No username
|
||||
u.Data["json"] = "Workspace doesn't exist"
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
}
|
||||
|
||||
u.Data["json"] = w.GetWorkflows()
|
||||
u.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Get Workflow
|
||||
// @Description Get a workflow by name
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Success 200 {object} models.Workflow
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router /:workflowName [get]
|
||||
func (u *WorkflowController) GetWorkflow(workflowName string) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
username := "asd"
|
||||
|
||||
proj, err := models.GetWorkflow(username, workflowName)
|
||||
if err != nil {
|
||||
u.SetData(err.Error())
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
u.Data["json"] = proj
|
||||
u.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Add new object to a Workflow
|
||||
// @Description Create a Rtype object from already added resources to the workspace
|
||||
// @Param workflowName path string true "workflow Name"
|
||||
// @Param rID query string true "rID of already existing item in Workspace"
|
||||
// @Success 200 {string} ID of the new object (rObjID)
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router /:workflowName/add [post]
|
||||
func (u *WorkflowController) AddElementWorkflow(workflowName, rID string) {
|
||||
username := "asd"
|
||||
|
||||
rObjID, err := models.CreateObjectInWorkflow(username, workflowName, rID)
|
||||
if err != nil {
|
||||
logs.Debug(err.Error())
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
u.Data["json"] = rObjID
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// @Title Parse mxGraph
|
||||
// @Description If we use this aproach to transofrm mxgraph representation in our representation, we should not use other API calls for modify the project structure or we'll have inconsistencies.
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Param xmlData body string true "Xml representation of the workflow"
|
||||
// @Success 200 The xmlgraph consumed correctly
|
||||
// @Success 201 The xmlgraph consumed with issues
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// @router /:workflowName/mxGraphParser [post]
|
||||
func (u *WorkflowController) MxGraphParser(workflowName, xmlData string) {
|
||||
username := "asd"
|
||||
err, mxissues := models.ParseMxGraph(username, workflowName, xmlData)
|
||||
if err != nil {
|
||||
logs.Debug(err.Error())
|
||||
u.CustomAbort(400, err.Error())
|
||||
}
|
||||
|
||||
if len(mxissues) > 0 {
|
||||
strErrors := make([]string, len(mxissues))
|
||||
|
||||
for i, err := range mxissues {
|
||||
strErrors[i] = err.Error()
|
||||
}
|
||||
|
||||
u.Data["json"] = strErrors
|
||||
u.Ctx.Output.Status = 201
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// @Title Get mxGraph last status
|
||||
// @Description Obtain the last mxgraph XML status from the workflow
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Success 200 The xmlgraph
|
||||
// @Success 201 Empty workflow
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// @router /:workflowName/mxGraphParser [get]
|
||||
func (u *WorkflowController) MxGraphParserConsume(workflowName string) {
|
||||
username := "asd"
|
||||
xmlData, err := models.GetMxGraph(username, workflowName)
|
||||
if err != nil {
|
||||
logs.Debug(err.Error())
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
if xmlData == nil {
|
||||
u.Ctx.Output.Status = 201
|
||||
} else {
|
||||
u.Ctx.Output.Status = 200
|
||||
u.Ctx.Output.Body([]byte(*xmlData))
|
||||
u.ServeXML()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// @Title Create a realtionship between two Robjects
|
||||
// @Description Create a Rtype object from already added resources to the workspace
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Param rObjIDsource query string true "Robject source. Usually Data"
|
||||
// @Param isInput query bool true "If the operation is for input (true) linkage or output (false)"
|
||||
// @Param rObjIDtarger query string true "Robject where will be written the association"
|
||||
// @Success 200 {string} ID of the new object (rObjID)
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router /:workflowName/link [post]
|
||||
func (u *WorkflowController) LinkElementsWorkflow(workflowName, rObjIDsource, rObjIDtarger string, isInput bool) {
|
||||
username := "asd"
|
||||
|
||||
err := models.LinkObjectsInWorkspace(username, workflowName, rObjIDsource, isInput, rObjIDtarger)
|
||||
if err != nil {
|
||||
logs.Debug(err.Error())
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// @Title Get Schedule
|
||||
// @Description Obtain the desired schedule of this workflow
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Success 200 {object} models.ScheduleTime
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 Workflow doesn't exist
|
||||
// @Failure 401 Other error
|
||||
// @router /:workflowName/schedule [get]
|
||||
func (u *WorkflowController) GetWorkflowSchedule(workflowName string) {
|
||||
username := "asd"
|
||||
sched, err := models.GetWorkflowSchedule(username, workflowName)
|
||||
|
||||
// Some error
|
||||
if err != nil {
|
||||
u.CustomAbort(401, err.Error())
|
||||
}
|
||||
|
||||
// No workflow
|
||||
if sched == nil {
|
||||
u.Ctx.Output.Status = 400
|
||||
return
|
||||
}
|
||||
|
||||
u.Ctx.Output.Status = 200
|
||||
u.Data["json"] = sched
|
||||
u.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Set Schedule
|
||||
// @Description Set desired schedule by the user. No other effects a part of saving the user input
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Param isService query bool true "True: Service, False: Task"
|
||||
// @Param startDate query time.Time true "RFC3339 time for startDate"
|
||||
// @Param stopDate query time.Time true "RFC3339 time for stopDate"
|
||||
// @Param events query string false "List of events separated by comma"
|
||||
// @Param cronString query string false "Cron string"
|
||||
// @Param duration query uint false "Duration in seconds"
|
||||
// @Success 200 {object} models.ScheduleInfo
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 Workflow doesn't exist
|
||||
// @Failure 401 Other error
|
||||
// @Failure 402 Bad user input
|
||||
// @router /:workflowName/schedule [put]
|
||||
func (u *WorkflowController) SetWorkflowSchedule(workflowName, cronString, events string, isService bool, startDate, stopDate time.Time, duration uint) {
|
||||
username := "asd"
|
||||
|
||||
// Check Dates
|
||||
if startDate.After(stopDate) || startDate.Equal(stopDate) {
|
||||
u.CustomAbort(402, "startDate must be before stopDate")
|
||||
}
|
||||
|
||||
if startDate.Before(time.Now().UTC()) {
|
||||
u.CustomAbort(402, "Current server time ("+time.Now().UTC().String()+") is after the startDate ("+startDate.String()+")")
|
||||
}
|
||||
|
||||
// Tasks must have cron and duration
|
||||
if !isService {
|
||||
if cronString == "" {
|
||||
u.CustomAbort(402, "Tasks cronString must not be empty")
|
||||
}
|
||||
|
||||
if duration == 0 {
|
||||
u.CustomAbort(402, "Tasks duration musn't be 0")
|
||||
}
|
||||
|
||||
_, err := cron.Parse(cronString)
|
||||
// Check cron
|
||||
if err != nil {
|
||||
u.CustomAbort(402, "Bad cron message: "+err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
schedInfo, err := models.SetWorkflowSchedule(username, workflowName, cronString, events, isService, startDate, stopDate, duration)
|
||||
|
||||
// Some error
|
||||
if err != nil {
|
||||
u.CustomAbort(401, err.Error())
|
||||
}
|
||||
|
||||
// No workflow
|
||||
if schedInfo == nil {
|
||||
u.CustomAbort(400, "")
|
||||
}
|
||||
|
||||
u.Ctx.Output.Status = 200
|
||||
u.Data["json"] = schedInfo
|
||||
u.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Check Schedule
|
||||
// @Description Check if we can schedule the project in other DCs. Must set a desired schedule first!
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Success 200 {object} []models.DCstatus
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 401 Other error
|
||||
// @router /:workflowName/schedule/check [get]
|
||||
func (u *WorkflowController) CheckWorkflowSchedule(workflowName string) {
|
||||
username := "asd"
|
||||
|
||||
data, err := models.CheckAndBookWorkflowSchedule(username, workflowName, false)
|
||||
if err != nil {
|
||||
u.CustomAbort(401, err.Error())
|
||||
}
|
||||
|
||||
u.Ctx.Output.Status = 200
|
||||
u.Data["json"] = data
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// @Title Book Schedule
|
||||
// @Description Book a schedule in all DCs of the workflow. Must set a desired schedule first!
|
||||
// @Param workflowName path string true "Workflow Name"
|
||||
// @Success 200 {object} []models.DCstatus
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 401 Other error. Check output
|
||||
// @router /:workflowName/schedule/book [post]
|
||||
func (u *WorkflowController) BookWorkflowSchedule(workflowName string) {
|
||||
username := "asd"
|
||||
|
||||
data, err := models.CheckAndBookWorkflowSchedule(username, workflowName, true)
|
||||
if err != nil {
|
||||
u.CustomAbort(401, err.Error())
|
||||
}
|
||||
|
||||
u.Ctx.Output.Status = 200
|
||||
u.Data["json"] = data
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
151
controllers/workspace.go
Normal file
151
controllers/workspace.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"cloud.o-forge.io/core/oc-catalog/models"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
type WorkspaceController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// @Title Add model to workspace
|
||||
// @Description Insert a resource in the workspace
|
||||
// @Param id query string true "ID of a resource"
|
||||
// @Param rtype query string true "Type of resource"
|
||||
// @Success 200 {string} login success
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router / [post]
|
||||
func (u *WorkspaceController) AddModel(id, rtype string) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// //TODO: Implement as swagger security definition (api key?)
|
||||
// username, err := GetUsernameFromToken(token)
|
||||
// if err != nil {
|
||||
// u.Data["json"] = "No valid token"
|
||||
// u.Ctx.Output.Status = 403
|
||||
// u.ServeJSON()
|
||||
// return
|
||||
// }
|
||||
|
||||
var err error
|
||||
username := "asd"
|
||||
|
||||
w := models.GetWorkspace(username)
|
||||
|
||||
if w == nil {
|
||||
w, err = models.NewWorkspace(username)
|
||||
if err != nil {
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// w.NewResource(id, rtype)
|
||||
|
||||
if err := models.AddResource(username, id, rtype); err != nil {
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// @Title Get workspace
|
||||
// @Description Get workspace elements based on user_id token
|
||||
// @Success 200 {object} models.Workspace
|
||||
// @Failure 403 Authentication issue
|
||||
// // @Security jwtAPIToken
|
||||
// @router /list [get]
|
||||
func (u *WorkspaceController) ListWorkspace() {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// //TODO: Implement as swagger security definition (api key?)
|
||||
// username, err := GetUsernameFromToken(token)
|
||||
// if err != nil {
|
||||
// u.Data["json"] = "No valid token"
|
||||
// u.Ctx.Output.Status = 403
|
||||
// u.ServeJSON()
|
||||
// return
|
||||
// }
|
||||
|
||||
username := "asd"
|
||||
|
||||
ws := models.GetWorkspace(username)
|
||||
|
||||
// if ws == nil {
|
||||
// u.Ctx.Output.Status = 503
|
||||
// return
|
||||
// }
|
||||
|
||||
u.Data["json"] = ws
|
||||
u.ServeJSON()
|
||||
|
||||
}
|
||||
|
||||
// @Title Get full workspace
|
||||
// @Description Get full workspace elements based on user_id token
|
||||
// @Success 200 {object} models.WorkspaceModel
|
||||
// @Failure 403 Authentication issue
|
||||
// // @Security jwtAPIToken
|
||||
// @router /list_model [get]
|
||||
func (u *WorkspaceController) ListWorkspaceModel() {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// //TODO: Implement as swagger security definition (api key?)
|
||||
// username, err := GetUsernameFromToken(token)
|
||||
// if err != nil {
|
||||
// u.Data["json"] = "No valid token"
|
||||
// u.Ctx.Output.Status = 403
|
||||
// u.ServeJSON()
|
||||
// return
|
||||
// }
|
||||
|
||||
username := "asd"
|
||||
|
||||
val, err := models.ListFullWorkspace(username)
|
||||
|
||||
if err != nil {
|
||||
u.Ctx.Output.Status = 503
|
||||
return
|
||||
}
|
||||
|
||||
u.Data["json"] = val
|
||||
u.ServeJSON()
|
||||
|
||||
}
|
||||
|
||||
// @Title Delete element from user workspace
|
||||
// @Description Remove a resource from the workspace
|
||||
// @Param id query string true "ID of a resource"
|
||||
// @Param rtype query string true "Type of resource"
|
||||
// @Success 200 {string} Removed succeful
|
||||
// @Failure 403 Authentication issue
|
||||
// @Failure 400 {string} Other error
|
||||
// // @Security jwtAPIToken
|
||||
// @router / [delete]
|
||||
func (u *WorkspaceController) DeleteElement(id, rtype string) {
|
||||
// token := u.Ctx.Input.GetData("jwtAPIToken").(string)
|
||||
|
||||
// //TODO: Implement as swagger security definition (api key?)
|
||||
// username, err := GetUsernameFromToken(token)
|
||||
// if err != nil {
|
||||
// u.Data["json"] = "No valid token"
|
||||
// u.Ctx.Output.Status = 403
|
||||
// u.ServeJSON()
|
||||
// return
|
||||
// }
|
||||
|
||||
username := "asd"
|
||||
|
||||
if err := models.RemoveResource(username, id, rtype); err != nil {
|
||||
u.Data["json"] = err.Error()
|
||||
u.Ctx.Output.Status = 400
|
||||
u.ServeJSON()
|
||||
return
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user