initial commit

This commit is contained in:
ycc
2023-03-03 14:43:11 +01:00
parent 7229007847
commit 88c21d1828
142 changed files with 13975 additions and 22 deletions

77
controllers/computing.go Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
}
}