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

Korean CSP supports (MCIS dynamic hold option and preserve regionname case) #1567

Merged
merged 1 commit into from
May 15, 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
16 changes: 15 additions & 1 deletion src/api/rest/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,9 @@ const docTemplate = `{
"resume",
"reboot",
"terminate",
"refine"
"refine",
"continue",
"withdraw"
],
"type": "string",
"description": "Action to MCIS",
Expand Down Expand Up @@ -4214,6 +4216,15 @@ const docTemplate = `{
"schema": {
"$ref": "#/definitions/mcis.TbMcisDynamicReq"
}
},
{
"enum": [
"hold"
],
"type": "string",
"description": "Option for MCIS creation",
"name": "option",
"in": "query"
}
],
"responses": {
Expand Down Expand Up @@ -8397,6 +8408,9 @@ const docTemplate = `{
"location": {
"$ref": "#/definitions/common.Location"
},
"regionId": {
"type": "string"
},
"regionName": {
"type": "string"
},
Expand Down
16 changes: 15 additions & 1 deletion src/api/rest/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2014,7 +2014,9 @@
"resume",
"reboot",
"terminate",
"refine"
"refine",
"continue",
"withdraw"
],
"type": "string",
"description": "Action to MCIS",
Expand Down Expand Up @@ -4207,6 +4209,15 @@
"schema": {
"$ref": "#/definitions/mcis.TbMcisDynamicReq"
}
},
{
"enum": [
"hold"
],
"type": "string",
"description": "Option for MCIS creation",
"name": "option",
"in": "query"
}
],
"responses": {
Expand Down Expand Up @@ -8390,6 +8401,9 @@
"location": {
"$ref": "#/definitions/common.Location"
},
"regionId": {
"type": "string"
},
"regionName": {
"type": "string"
},
Expand Down
10 changes: 10 additions & 0 deletions src/api/rest/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ definitions:
type: string
location:
$ref: '#/definitions/common.Location'
regionId:
type: string
regionName:
type: string
zones:
Expand Down Expand Up @@ -4211,6 +4213,8 @@ paths:
- reboot
- terminate
- refine
- continue
- withdraw
in: query
name: action
required: true
Expand Down Expand Up @@ -5702,6 +5706,12 @@ paths:
required: true
schema:
$ref: '#/definitions/mcis.TbMcisDynamicReq'
- description: Option for MCIS creation
enum:
- hold
in: query
name: option
type: string
produces:
- application/json
responses:
Expand Down
6 changes: 3 additions & 3 deletions src/api/rest/server/mcis/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
// @Produce json
// @Param nsId path string true "Namespace ID" default(ns01)
// @Param mcisId path string true "MCIS ID" default(mcis01)
// @Param action query string true "Action to MCIS" Enums(suspend, resume, reboot, terminate, refine)
// @Param action query string true "Action to MCIS" Enums(suspend, resume, reboot, terminate, refine, continue, withdraw)
// @Param force query string false "Force control to skip checking controllable status" Enums(false, true)
// @Success 200 {object} common.SimpleMsg
// @Failure 404 {object} common.SimpleMsg
Expand All @@ -53,7 +53,7 @@ func RestGetControlMcis(c echo.Context) error {
}
returnObj := common.SimpleMsg{}

if action == "suspend" || action == "resume" || action == "reboot" || action == "terminate" || action == "refine" {
if action == "suspend" || action == "resume" || action == "reboot" || action == "terminate" || action == "refine" || action == "continue" || action == "withdraw" {

resultString, err := mcis.HandleMcisAction(nsId, mcisId, action, forceOption)
if err != nil {
Expand All @@ -63,7 +63,7 @@ func RestGetControlMcis(c echo.Context) error {
return common.EndRequestWithLog(c, reqID, err, returnObj)

} else {
err := fmt.Errorf("'action' should be one of these: suspend, resume, reboot, terminate, refine")
err := fmt.Errorf("'action' should be one of these: suspend, resume, reboot, terminate, refine, continue, withdraw")
return common.EndRequestWithLog(c, reqID, err, returnObj)
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/api/rest/server/mcis/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func RestPostSystemMcis(c echo.Context) error {
// @Produce json
// @Param nsId path string true "Namespace ID" default(ns01)
// @Param mcisReq body TbMcisDynamicReq true "Request body to provision MCIS dynamically"
// @Param option query string false "Option for MCIS creation" Enums(hold)
// @Success 200 {object} TbMcisInfo
// @Failure 404 {object} common.SimpleMsg
// @Failure 500 {object} common.SimpleMsg
Expand All @@ -125,13 +126,14 @@ func RestPostMcisDynamic(c echo.Context) error {
return c.JSON(http.StatusBadRequest, map[string]string{"message": idErr.Error()})
}
nsId := c.Param("nsId")
option := c.QueryParam("option")

req := &mcis.TbMcisDynamicReq{}
if err := c.Bind(req); err != nil {
return common.EndRequestWithLog(c, reqID, err, nil)
}

result, err := mcis.CreateMcisDynamic(nsId, req)
result, err := mcis.CreateMcisDynamic(nsId, req, option)
return common.EndRequestWithLog(c, reqID, err, result)
}

Expand Down
5 changes: 5 additions & 0 deletions src/core/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type CSPDetail struct {

// RegionDetail is structure for region information
type RegionDetail struct {
RegionId string `mapstructure:"id" json:"regionId"`
RegionName string `mapstructure:"regionName" json:"regionName"`
Description string `mapstructure:"description" json:"description"`
Location Location `mapstructure:"location" json:"location"`
Expand Down Expand Up @@ -73,6 +74,10 @@ func AdjustKeysToLowercase(cloudInfo *CloudInfo) {
for regionKey, regionDetail := range cspDetail.Regions {
lowerRegionKey := strings.ToLower(regionKey)
regionDetail.RegionName = lowerRegionKey
// keep the original regionId if it is not empty (some CSP uses regionName case-sensitive)
if regionDetail.RegionId == "" {
regionDetail.RegionId = regionKey
}
newRegions[lowerRegionKey] = regionDetail
}
cspDetail.Regions = newRegions
Expand Down
7 changes: 4 additions & 3 deletions src/core/common/utility.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,14 +596,15 @@ func RegisterRegionZone(providerName string, regionName string) error {
// register representative regionZone (region only)
requestBody.RegionName = providerName + "-" + regionName
keyValueInfoList := []KeyValue{}

if len(RuntimeCloudInfo.CSPs[providerName].Regions[regionName].Zones) > 0 {
keyValueInfoList = []KeyValue{
{Key: "Region", Value: regionName},
{Key: "Region", Value: RuntimeCloudInfo.CSPs[providerName].Regions[regionName].RegionId},
{Key: "Zone", Value: RuntimeCloudInfo.CSPs[providerName].Regions[regionName].Zones[0]},
}
} else {
keyValueInfoList = []KeyValue{
{Key: "Region", Value: regionName},
{Key: "Region", Value: RuntimeCloudInfo.CSPs[providerName].Regions[regionName].RegionId},
{Key: "Zone", Value: "N/A"},
}
}
Expand All @@ -629,7 +630,7 @@ func RegisterRegionZone(providerName string, regionName string) error {
for _, zoneName := range RuntimeCloudInfo.CSPs[providerName].Regions[regionName].Zones {
requestBody.RegionName = providerName + "-" + regionName + "-" + zoneName
keyValueInfoList := []KeyValue{
{Key: "Region", Value: regionName},
{Key: "Region", Value: RuntimeCloudInfo.CSPs[providerName].Regions[regionName].RegionId},
{Key: "Zone", Value: zoneName},
}
requestBody.AvailableZoneList = RuntimeCloudInfo.CSPs[providerName].Regions[regionName].Zones
Expand Down
11 changes: 5 additions & 6 deletions src/core/mcir/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -1651,12 +1651,12 @@ func LoadCommonResource() (common.IdList, error) {
// Update registered Spec object with Cost info
costPerHour, err2 := strconv.ParseFloat(strings.ReplaceAll(row[3], " ", ""), 32)
if err2 != nil {
log.Error().Err(err2).Msg("Not valid CostPerHour value in the asset")
log.Error().Msgf("Not valid CostPerHour value in the asset: %s", specInfoId)
costPerHour = 99999999.9
}
evaluationScore01, err2 := strconv.ParseFloat(strings.ReplaceAll(row[4], " ", ""), 32)
if err2 != nil {
log.Error().Err(err2).Msg("Not valid evaluationScore01 value in the asset")
log.Error().Msgf("Not valid evaluationScore01 value in the asset: %s", specInfoId)
evaluationScore01 = -99.9
}
specUpdateRequest :=
Expand Down Expand Up @@ -1912,12 +1912,12 @@ func LoadDefaultResource(nsId string, resType string, connectionName string) err

common.PrintJsonPretty(reqTmp)

resultInfo, err := CreateSshKey(nsId, &reqTmp, "")
_, err := CreateSshKey(nsId, &reqTmp, "")
if err != nil {
log.Error().Err(err).Msg("Failed to create SshKey")
return err
}
common.PrintJsonPretty(resultInfo)
// common.PrintJsonPretty(resultInfo)
} else {
return errors.New("Not valid option (provide sg, sshkey, vnet, or all)")
}
Expand Down Expand Up @@ -1981,9 +1981,8 @@ func ToNamingRuleCompatible(rawName string) string {
// UpdateResourceObject is func to update the resource object
func UpdateResourceObject(nsId string, resourceType string, resourceObject interface{}) {
resourceId, err := GetIdFromStruct(resourceObject)
fmt.Printf("in UpdateResourceObject; extracted resourceId: %s \n", resourceId) // for debug
if resourceId == "" || err != nil {
fmt.Printf("in UpdateResourceObject; failed to extract resourceId. \n") // for debug
log.Debug().Msgf("in UpdateResourceObject; failed to extract resourceId") // for debug
return
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/mcir/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ func FilterSpecsByRange(nsId string, filter FilterSpecsByRangeRequest) ([]TbSpec

// Convert the first letter of the field name to lowercase to match typical database column naming conventions
dbFieldName := strings.ToLower(field.Name[:1]) + field.Name[1:]
log.Info().Msgf("Field: %s, Value: %v", dbFieldName, value)
log.Debug().Msgf("Field: %s, Value: %v", dbFieldName, value)

if value.Kind() == reflect.Struct {
// Handle range filters like VCPU, MemoryGiB, etc.
Expand Down
14 changes: 14 additions & 0 deletions src/core/mcis/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ func HandleMcisAction(nsId string, mcisId string, action string, force bool) (st

return "Terminated the MCIS", nil

} else if action == "continue" {
log.Debug().Msg("[continue MCIS provisioning]")
key := common.GenMcisKey(nsId, mcisId, "")
holdingMcisMap.Store(key, action)

return "Continue the holding MCIS", nil

} else if action == "withdraw" {
log.Debug().Msg("[withdraw MCIS provisioning]")
key := common.GenMcisKey(nsId, mcisId, "")
holdingMcisMap.Store(key, action)

return "Withdraw the holding MCIS", nil

} else if action == "refine" { // refine delete VMs in StatusFailed or StatusUndefined
log.Debug().Msg("[refine MCIS]")

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
38 changes: 35 additions & 3 deletions src/core/mcis/provisioning.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,8 @@ type TbVmRecommendInfo struct {
PlacementParam []common.KeyValue `json:"placementParam"`
}

var holdingMcisMap sync.Map

// MCIS and VM Provisioning

// CreateMcisVm is func to post (create) McisVm
Expand Down Expand Up @@ -957,6 +959,32 @@ func CreateMcis(nsId string, req *TbMcisReq, option string) (*TbMcisInfo, error)
}
}

// hold option will hold the MCIS creation process until the user releases it.
if option == "hold" {
key := common.GenMcisKey(nsId, mcisId, "")
holdingMcisMap.Store(key, "holding")
for {
value, ok := holdingMcisMap.Load(key)
if !ok {
break
}
if value == "continue" {
holdingMcisMap.Delete(key)
break
} else if value == "withdraw" {
holdingMcisMap.Delete(key)
DelMcis(nsId, mcisId, "force")
err := fmt.Errorf("Withdrawed MCIS creation")
log.Error().Err(err).Msg("")
return nil, err
}

log.Info().Msgf("MCIS: %s (holding)", key)
time.Sleep(5 * time.Second)
}
option = "create"
}

//goroutin
var wg sync.WaitGroup

Expand Down Expand Up @@ -1222,11 +1250,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) (*TbMcisInfo, error) {
func CreateMcisDynamic(nsId string, req *TbMcisDynamicReq, deployOption string) (*TbMcisInfo, error) {

mcisReq := TbMcisReq{}
mcisReq.Name = req.Name
Expand Down Expand Up @@ -1290,6 +1318,9 @@ func CreateMcisDynamic(nsId string, req *TbMcisDynamicReq) (*TbMcisInfo, error)

// Run create MCIS with the generated MCIS request (option != register)
option := "create"
if deployOption == "hold" {
option = "hold"
}
return CreateMcis(nsId, &mcisReq, option)
}

Expand Down Expand Up @@ -1643,6 +1674,7 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e
// Try lookup customImage
requestBody.ReqInfo.ImageName, err = common.GetCspResourceId(nsId, common.StrCustomImage, vmInfoData.ImageId)
if requestBody.ReqInfo.ImageName == "" || err != nil {
log.Warn().Msgf("Not found the Image: %s in nsId: %s, find it from SystemCommonNs", vmInfoData.ImageId, nsId)
errAgg := err.Error()
// If customImage doesn't exist, then try lookup image
requestBody.ReqInfo.ImageName, err = common.GetCspResourceId(nsId, common.StrImage, vmInfoData.ImageId)
Expand All @@ -1668,7 +1700,7 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e

requestBody.ReqInfo.VMSpecName, err = common.GetCspResourceId(nsId, common.StrSpec, vmInfoData.SpecId)
if requestBody.ReqInfo.VMSpecName == "" || err != nil {
log.Warn().Msg(err.Error())
log.Warn().Msgf("Not found the Spec: %s in nsId: %s, find it from SystemCommonNs", vmInfoData.SpecId, nsId)
errAgg := err.Error()
// If cannot find the resource, use common resource
requestBody.ReqInfo.VMSpecName, err = common.GetCspResourceId(common.SystemCommonNs, common.StrSpec, vmInfoData.SpecId)
Expand Down
2 changes: 1 addition & 1 deletion src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func setConfig() {

for attempt < maxAttempts {
if common.CheckSpiderReady() == nil {
log.Info().Msg("CB-Spider is now ready.")
log.Info().Msg("CB-Spider is now ready. Initializing CB-Tumblebug...")
break
}
log.Info().Msgf("CB-Spider at %s is not ready. Attempt %d/%d", common.SpiderRestUrl, attempt+1, maxAttempts)
Expand Down