Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide mcis dynamic interal progress using requestlog #1599

Merged
merged 1 commit into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/api/rest/server/mcis/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,14 @@ func RestPostSystemMcis(c echo.Context) error {
// @Param nsId path string true "Namespace ID" default(ns01)
// @Param mcisReq body TbMcisDynamicReq true "Request body to provision MCIS dynamically. Must include commonSpec and commonImage info of each VM request.(ex: {name: mcis01,vm: [{commonImage: aws+ap-northeast-2+ubuntu22.04,commonSpec: aws+ap-northeast-2+t2.small}]} ) You can use /mcisRecommendVm and /mcisDynamicCheckRequest to get it) Check the guide: https://github.com/cloud-barista/cb-tumblebug/discussions/1570"
// @Param option query string false "Option for MCIS creation" Enums(hold)
// @Param x-request-id header string false "Custom request ID"
// @Success 200 {object} TbMcisInfo
// @Failure 404 {object} common.SimpleMsg
// @Failure 500 {object} common.SimpleMsg
// @Router /ns/{nsId}/mcisDynamic [post]
func RestPostMcisDynamic(c echo.Context) error {
reqID, idErr := common.StartRequestWithLog(c)
if idErr != nil {
return c.JSON(http.StatusBadRequest, map[string]string{"message": idErr.Error()})
}
reqID := c.Request().Header.Get(echo.HeaderXRequestID)

nsId := c.Param("nsId")
option := c.QueryParam("option")

Expand All @@ -137,8 +136,11 @@ func RestPostMcisDynamic(c echo.Context) error {
return common.EndRequestWithLog(c, reqID, err, nil)
}

result, err := mcis.CreateMcisDynamic(nsId, req, option)
return common.EndRequestWithLog(c, reqID, err, result)
result, err := mcis.CreateMcisDynamic(reqID, nsId, req, option)
if err != nil {
return common.EndRequestWithLog(c, reqID, err, nil)
}
return c.JSON(http.StatusOK, result)
}

// RestPostMcisVmDynamic godoc
Expand Down
25 changes: 25 additions & 0 deletions src/core/common/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ type RequestDetails struct {
// RequestMap is a map for request details
var RequestMap = sync.Map{}

// ProgressInfo contains the progress information of a request.
type ProgressInfo struct {
Title string `json:"title"`
Info interface{} `json:"info"`
Time time.Time `json:"time"`
}

// ExtractRequestInfo extracts necessary information from http.Request
func ExtractRequestInfo(r *http.Request) RequestInfo {
headerInfo := make(map[string]string)
Expand Down Expand Up @@ -326,6 +333,24 @@ func EndRequestWithLog(c echo.Context, reqID string, err error, responseData int
return c.JSON(http.StatusNotFound, map[string]string{"message": "Invalid Request ID"})
}

// UpdateRequestProgress updates the handling status of the request.
func UpdateRequestProgress(reqID string, progressData interface{}) {
if v, ok := RequestMap.Load(reqID); ok {
details := v.(RequestDetails)

var responseData []interface{}
if details.ResponseData != nil {
// Convert existing ResponseData to []interface{}
responseData = details.ResponseData.([]interface{})
}
// Append the new progressData to the existing ResponseData
responseData = append(responseData, progressData)
details.ResponseData = responseData

RequestMap.Store(reqID, details)
}
}

// ForwardRequestToAny forwards the given request to the specified path
func ForwardRequestToAny(reqPath string, method string, requestBody interface{}) (interface{}, error) {
client := resty.New()
Expand Down
2 changes: 1 addition & 1 deletion src/core/mcis/nlb.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func CreateMcSwNlb(nsId string, mcisId string, req *TbNLBReq, option string) (Mc
vmDynamicReq := TbVmDynamicReq{Name: vmGroupName, CommonSpec: commonSpec, CommonImage: commonImage, SubGroupSize: subGroupSize}
mcisDynamicReq.Vm = append(mcisDynamicReq.Vm, vmDynamicReq)

mcisInfo, err := CreateMcisDynamic(nsId, &mcisDynamicReq, "")
mcisInfo, err := CreateMcisDynamic("", nsId, &mcisDynamicReq, "")
if err != nil {
log.Error().Err(err).Msg("")
return emptyObj, err
Expand Down
21 changes: 16 additions & 5 deletions src/core/mcis/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -1255,11 +1255,11 @@ func CreateSystemMcisDynamic(option string) (*TbMcisInfo, error) {
return nil, err
}

return CreateMcisDynamic(nsId, req, "")
return CreateMcisDynamic("", nsId, req, "")
}

// CreateMcisDynamic is func to create MCIS obeject and deploy requested VMs in a dynamic way
func CreateMcisDynamic(nsId string, req *TbMcisDynamicReq, deployOption string) (*TbMcisInfo, error) {
func CreateMcisDynamic(reqID string, nsId string, req *TbMcisDynamicReq, deployOption string) (*TbMcisInfo, error) {

mcisReq := TbMcisReq{}
mcisReq.Name = req.Name
Expand Down Expand Up @@ -1301,7 +1301,7 @@ func CreateMcisDynamic(nsId string, req *TbMcisDynamicReq, deployOption string)

//If not, generate default resources dynamically.
for _, k := range vmRequest {
vmReq, err := getVmReqFromDynamicReq(nsId, &k)
vmReq, err := getVmReqFromDynamicReq(reqID, nsId, &k)
if err != nil {
log.Error().Err(err).Msg("Failed to prefare resources for dynamic MCIS creation")
// Rollback created default resources
Expand All @@ -1320,6 +1320,8 @@ func CreateMcisDynamic(nsId string, req *TbMcisDynamicReq, deployOption string)
}

common.PrintJsonPretty(mcisReq)
common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Prepared all resources for provisioning MCIS:" + mcisReq.Name, Info: mcisReq, Time: time.Now()})
common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Start provisioning", Time: time.Now()})

// Run create MCIS with the generated MCIS request (option != register)
option := "create"
Expand All @@ -1344,7 +1346,7 @@ func CreateMcisVmDynamic(nsId string, mcisId string, req *TbVmDynamicReq) (*TbMc
return emptyMcis, err
}

vmReq, err := getVmReqFromDynamicReq(nsId, req)
vmReq, err := getVmReqFromDynamicReq("", nsId, req)
if err != nil {
log.Error().Err(err).Msg("")
return emptyMcis, err
Expand Down Expand Up @@ -1408,7 +1410,7 @@ func checkCommonResAvailable(req *TbVmDynamicReq) error {
}

// getVmReqForDynamicMcis is func to getVmReqFromDynamicReq
func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error) {
func getVmReqFromDynamicReq(reqID string, nsId string, req *TbVmDynamicReq) (*TbVmReq, error) {

onDemand := true

Expand Down Expand Up @@ -1464,6 +1466,8 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
return &TbVmReq{}, err
}

common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Setting vNet:" + resourceName, Time: time.Now()})

vmReq.VNetId = resourceName
tempInterface, err = mcir.GetResource(nsId, common.StrVNet, vmReq.VNetId)
if err != nil {
Expand All @@ -1472,6 +1476,7 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
log.Error().Err(err).Msg("Failed to get the vNet")
return &TbVmReq{}, err
}
common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Loading default vNet:" + resourceName, Time: time.Now()})
err2 := mcir.LoadDefaultResource(nsId, common.StrVNet, vmReq.ConnectionName)
if err2 != nil {
log.Error().Err(err2).Msg("Failed to create new default vNet " + vmReq.VNetId + " from " + vmReq.ConnectionName)
Expand All @@ -1484,6 +1489,7 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
}
vmReq.SubnetId = resourceName

common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Setting SSHKey:" + resourceName, Time: time.Now()})
vmReq.SshKeyId = resourceName
tempInterface, err = mcir.GetResource(nsId, common.StrSSHKey, vmReq.SshKeyId)
if err != nil {
Expand All @@ -1492,6 +1498,7 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
log.Error().Err(err).Msg("Failed to get the SSHKey")
return &TbVmReq{}, err
}
common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Loading default SSHKey:" + resourceName, Time: time.Now()})
err2 := mcir.LoadDefaultResource(nsId, common.StrSSHKey, vmReq.ConnectionName)
if err2 != nil {
log.Error().Err(err2).Msg("Failed to create new default SSHKey " + vmReq.SshKeyId + " from " + vmReq.ConnectionName)
Expand All @@ -1502,6 +1509,8 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
} else {
log.Info().Msg("Found and utilize default SSHKey: " + vmReq.VNetId)
}

common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Setting securityGroup:" + resourceName, Time: time.Now()})
securityGroup := resourceName
vmReq.SecurityGroupIds = append(vmReq.SecurityGroupIds, securityGroup)
tempInterface, err = mcir.GetResource(nsId, common.StrSecurityGroup, securityGroup)
Expand All @@ -1511,6 +1520,7 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
log.Error().Err(err).Msg("Failed to get the securityGroup")
return &TbVmReq{}, err
}
common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Loading default securityGroup:" + resourceName, Time: time.Now()})
err2 := mcir.LoadDefaultResource(nsId, common.StrSecurityGroup, vmReq.ConnectionName)
if err2 != nil {
log.Error().Err(err2).Msg("Failed to create new default securityGroup " + securityGroup + " from " + vmReq.ConnectionName)
Expand All @@ -1534,6 +1544,7 @@ func getVmReqFromDynamicReq(nsId string, req *TbVmDynamicReq) (*TbVmReq, error)
vmReq.VmUserPassword = k.VmUserPassword

common.PrintJsonPretty(vmReq)
common.UpdateRequestProgress(reqID, common.ProgressInfo{Title: "Prepared resources for VM:" + vmReq.Name, Info: vmReq, Time: time.Now()})

return vmReq, nil
}
Expand Down