diff --git a/src/api/rest/docs/docs.go b/src/api/rest/docs/docs.go index aec9096eb..50a8ac6fa 100644 --- a/src/api/rest/docs/docs.go +++ b/src/api/rest/docs/docs.go @@ -8690,6 +8690,9 @@ const docTemplate = `{ "imageName": { "type": "string" }, + "imageType": { + "type": "string" + }, "keyPairIId": { "$ref": "#/definitions/common.IID" }, @@ -9393,6 +9396,7 @@ const docTemplate = `{ "example": "i-014fa6ede6ada0b2c" }, "imageId": { + "description": "ImageType string ` + "`" + `json:\"imageType\"` + "`" + `", "type": "string" }, "label": { diff --git a/src/api/rest/docs/swagger.json b/src/api/rest/docs/swagger.json index 5a360170b..c00e6d2de 100644 --- a/src/api/rest/docs/swagger.json +++ b/src/api/rest/docs/swagger.json @@ -8682,6 +8682,9 @@ "imageName": { "type": "string" }, + "imageType": { + "type": "string" + }, "keyPairIId": { "$ref": "#/definitions/common.IID" }, @@ -9385,6 +9388,7 @@ "example": "i-014fa6ede6ada0b2c" }, "imageId": { + "description": "ImageType string `json:\"imageType\"`", "type": "string" }, "label": { diff --git a/src/api/rest/docs/swagger.yaml b/src/api/rest/docs/swagger.yaml index 473138b80..223ca9c84 100644 --- a/src/api/rest/docs/swagger.yaml +++ b/src/api/rest/docs/swagger.yaml @@ -1515,6 +1515,8 @@ definitions: $ref: '#/definitions/common.IID' imageName: type: string + imageType: + type: string keyPairIId: $ref: '#/definitions/common.IID' keyPairName: @@ -2029,6 +2031,7 @@ definitions: example: i-014fa6ede6ada0b2c type: string imageId: + description: ImageType string `json:"imageType"` type: string label: type: string diff --git a/src/api/rest/server/mcis/control.go b/src/api/rest/server/mcis/control.go index 55eb6f08e..e74fa451b 100644 --- a/src/api/rest/server/mcis/control.go +++ b/src/api/rest/server/mcis/control.go @@ -134,9 +134,9 @@ func RestPutMcisVmWithCmd(c echo.Context) error { } switch command { - case "attachDataDisk": + case mcis.AttachDataDisk: fallthrough - case "detachDataDisk": + case mcis.DetachDataDisk: result, err := mcis.AttachDetachDataDisk(nsId, mcisId, vmId, command, u.DataDiskId) if err != nil { mapA := map[string]string{"message": err.Error()} diff --git a/src/core/common/utility.go b/src/core/common/utility.go index f292ad97a..c1a54501a 100644 --- a/src/core/common/utility.go +++ b/src/core/common/utility.go @@ -242,7 +242,7 @@ func GetCspResourceId(nsId string, resourceType string, resourceId string) (stri case StrCustomImage: content := mcirIds{} json.Unmarshal([]byte(keyValue.Value), &content) - return content.CspCustomImageId, nil + return content.CspCustomImageName, nil case StrSSHKey: content := mcirIds{} json.Unmarshal([]byte(keyValue.Value), &content) @@ -934,3 +934,29 @@ func CheckElement(a string, list []string) bool { } return false } + +const ( + // Random string generation + letterBytes = "abcdefghijklmnopqrstuvwxyz1234567890" + letterIdxBits = 6 + letterIdxMask = 1<= 0; { + if remain == 0 { + cache, remain = randSrc.Int63(), letterIdxMax + } + if idx := int(cache & letterIdxMask); idx < len(letterBytes) { + b[i] = letterBytes[idx] + i-- + } + cache >>= letterIdxBits + remain-- + } + return string(b) +} diff --git a/src/core/mcir/common.go b/src/core/mcir/common.go index cacb1f179..89fb0d506 100644 --- a/src/core/mcir/common.go +++ b/src/core/mcir/common.go @@ -155,6 +155,7 @@ func DelResource(nsId string, resourceType string, resourceId string, forceFlag // In CheckResource() above, calling 'CBStore.Get()' and checking err parts exist. // So, in here, we don't need to check whether keyValue == nil or err != nil. + /* Disabled the deletion protection feature associatedList, _ := GetAssociatedObjectList(nsId, resourceType, resourceId) if len(associatedList) == 0 { // continue @@ -164,6 +165,7 @@ func DelResource(nsId string, resourceType string, resourceId string, forceFlag common.CBLog.Error(err) return err } + */ //cspType := common.GetResourcesCspType(nsId, resourceType, resourceId) diff --git a/src/core/mcis/control.go b/src/core/mcis/control.go index 1215081da..fcb0db467 100644 --- a/src/core/mcis/control.go +++ b/src/core/mcis/control.go @@ -577,7 +577,11 @@ func ControlVmAsync(wg *sync.WaitGroup, nsId string, mcisId string, vmId string, //When VM is restared, temporal PublicIP will be chanaged. Need update. UpdateVmPublicIp(nsId, mcisId, temp) } else { // if action == ActionTerminate - mcir.UpdateAssociatedObjectList(nsId, common.StrImage, temp.ImageId, common.StrDelete, key) + _, err = mcir.UpdateAssociatedObjectList(nsId, common.StrImage, temp.ImageId, common.StrDelete, key) + if err != nil { + mcir.UpdateAssociatedObjectList(nsId, common.StrCustomImage, temp.ImageId, common.StrDelete, key) + } + mcir.UpdateAssociatedObjectList(nsId, common.StrSpec, temp.SpecId, common.StrDelete, key) mcir.UpdateAssociatedObjectList(nsId, common.StrSSHKey, temp.SshKeyId, common.StrDelete, key) mcir.UpdateAssociatedObjectList(nsId, common.StrVNet, temp.VNetId, common.StrDelete, key) diff --git a/src/core/mcis/manageInfo.go b/src/core/mcis/manageInfo.go index b6a95faae..aea59b99b 100644 --- a/src/core/mcis/manageInfo.go +++ b/src/core/mcis/manageInfo.go @@ -1465,6 +1465,12 @@ func UpdateVmInfo(nsId string, mcisId string, vmInfoData TbVmInfo) { } } +// type DataDiskCmd string +const ( + AttachDataDisk string = "attachDataDisk" + DetachDataDisk string = "detachDataDisk" +) + // AttachDetachDataDisk is func to attach/detach DataDisk to/from VM func AttachDetachDataDisk(nsId string, mcisId string, vmId string, command string, dataDiskId string) (TbVmInfo, error) { vmKey := common.GenMcisKey(nsId, mcisId, vmId) @@ -1481,11 +1487,11 @@ func AttachDetachDataDisk(nsId string, mcisId string, vmId string, command strin json.Unmarshal([]byte(keyValue.Value), &vm) isDataDiskAttached := common.CheckElement(dataDiskId, vm.DataDiskIds) - if command == "detachDataDisk" && isDataDiskAttached == false { + if command == DetachDataDisk && isDataDiskAttached == false { err := fmt.Errorf("Failed to find the dataDisk %s in the attached dataDisk list.", dataDiskId) common.CBLog.Error(err) return TbVmInfo{}, err - } else if command == "attachDataDisk" && isDataDiskAttached == true { + } else if command == AttachDataDisk && isDataDiskAttached == true { err := fmt.Errorf("The dataDisk %s is already in the attached dataDisk list.", dataDiskId) common.CBLog.Error(err) return TbVmInfo{}, err @@ -1520,23 +1526,26 @@ func AttachDetachDataDisk(nsId string, mcisId string, vmId string, command strin var url string var cmdToUpdateAsso string + var resp *resty.Response switch command { - case "attachDataDisk": + case AttachDataDisk: req = req.SetResult(&mcir.SpiderDiskInfo{}) url = fmt.Sprintf("%s/disk/%s/attach", common.SpiderRestUrl, dataDisk.CspDataDiskName) cmdToUpdateAsso = common.StrAdd - case "detachDataDisk": + + case DetachDataDisk: // req = req.SetResult(&bool) url = fmt.Sprintf("%s/disk/%s/detach", common.SpiderRestUrl, dataDisk.CspDataDiskName) cmdToUpdateAsso = common.StrDelete + default: } - resp, err := req.Put(url) + resp, err = req.Put(url) fmt.Printf("HTTP Status code: %d \n", resp.StatusCode()) switch { @@ -1548,10 +1557,10 @@ func AttachDetachDataDisk(nsId string, mcisId string, vmId string, command strin } switch command { - case "attachDataDisk": + case AttachDataDisk: vm.DataDiskIds = append(vm.DataDiskIds, dataDiskId) - mcir.UpdateAssociatedObjectList(nsId, common.StrDataDisk, dataDiskId, common.StrAdd, vmKey) - case "detachDataDisk": + // mcir.UpdateAssociatedObjectList(nsId, common.StrDataDisk, dataDiskId, common.StrAdd, vmKey) + case DetachDataDisk: oldDataDiskIds := vm.DataDiskIds newDataDiskIds := oldDataDiskIds @@ -1743,7 +1752,11 @@ func DelMcis(nsId string, mcisId string, option string) error { return err } - mcir.UpdateAssociatedObjectList(nsId, common.StrImage, vmInfo.ImageId, common.StrDelete, vmKey) + _, err = mcir.UpdateAssociatedObjectList(nsId, common.StrImage, vmInfo.ImageId, common.StrDelete, vmKey) + if err != nil { + mcir.UpdateAssociatedObjectList(nsId, common.StrCustomImage, vmInfo.ImageId, common.StrDelete, vmKey) + } + mcir.UpdateAssociatedObjectList(nsId, common.StrSpec, vmInfo.SpecId, common.StrDelete, vmKey) mcir.UpdateAssociatedObjectList(nsId, common.StrSSHKey, vmInfo.SshKeyId, common.StrDelete, vmKey) mcir.UpdateAssociatedObjectList(nsId, common.StrVNet, vmInfo.VNetId, common.StrDelete, vmKey) @@ -1837,7 +1850,11 @@ func DelMcisVm(nsId string, mcisId string, vmId string, option string) error { return err } - mcir.UpdateAssociatedObjectList(nsId, common.StrImage, vmInfo.ImageId, common.StrDelete, key) + _, err = mcir.UpdateAssociatedObjectList(nsId, common.StrImage, vmInfo.ImageId, common.StrDelete, key) + if err != nil { + mcir.UpdateAssociatedObjectList(nsId, common.StrCustomImage, vmInfo.ImageId, common.StrDelete, key) + } + mcir.UpdateAssociatedObjectList(nsId, common.StrSpec, vmInfo.SpecId, common.StrDelete, key) mcir.UpdateAssociatedObjectList(nsId, common.StrSSHKey, vmInfo.SshKeyId, common.StrDelete, key) mcir.UpdateAssociatedObjectList(nsId, common.StrVNet, vmInfo.VNetId, common.StrDelete, key) diff --git a/src/core/mcis/provisioning.go b/src/core/mcis/provisioning.go index 345853fca..cdbeaf0de 100644 --- a/src/core/mcis/provisioning.go +++ b/src/core/mcis/provisioning.go @@ -196,8 +196,9 @@ type TbVmReq struct { Description string `json:"description" example:"Description"` - ConnectionName string `json:"connectionName" validate:"required" example:"testcloud01-seoul"` - SpecId string `json:"specId" validate:"required"` + ConnectionName string `json:"connectionName" validate:"required" example:"testcloud01-seoul"` + SpecId string `json:"specId" validate:"required"` + // ImageType string `json:"imageType"` ImageId string `json:"imageId" validate:"required"` VNetId string `json:"vNetId" validate:"required"` SubnetId string `json:"subnetId" validate:"required"` @@ -280,6 +281,14 @@ type SpiderVMReqInfoWrapper struct { ReqInfo SpiderVMInfo } +type SpiderImageType string + +const ( + PublicImage SpiderImageType = "PublicImage" + MyImage SpiderImageType = "MyImage" +) + +// Ref: cb-spider/cloud-control-manager/cloud-driver/interfaces/resources/VMHandler.go // SpiderVMInfo is struct from CB-Spider for VM information type SpiderVMInfo struct { // Fields for request @@ -298,6 +307,7 @@ type SpiderVMInfo struct { VMUserPasswd string RootDiskType string // "SSD(gp2)", "Premium SSD", ... RootDiskSize string // "default", "50", "1000" (GB) + ImageType SpiderImageType // Fields for response IId common.IID // {NameId, SystemId} @@ -1443,20 +1453,30 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e tempReq.ReqInfo.Name = fmt.Sprintf("%s-%s-%s", nsId, mcisId, vmInfoData.Name) err := fmt.Errorf("") + customImageFlag := false if option == "register" { tempReq.ReqInfo.CSPid = vmInfoData.IdByCSP } else { - tempReq.ReqInfo.ImageName, err = common.GetCspResourceId(nsId, common.StrImage, vmInfoData.ImageId) + // Try lookup customImage + tempReq.ReqInfo.ImageName, err = common.GetCspResourceId(nsId, common.StrCustomImage, vmInfoData.ImageId) if tempReq.ReqInfo.ImageName == "" || err != nil { common.CBLog.Error(err) - // If cannot find the resource, use common resource - tempReq.ReqInfo.ImageName, err = common.GetCspResourceId(common.SystemCommonNs, common.StrImage, vmInfoData.ImageId) + // If customImage doesn't exist, then try lookup image + tempReq.ReqInfo.ImageName, err = common.GetCspResourceId(nsId, common.StrImage, vmInfoData.ImageId) if tempReq.ReqInfo.ImageName == "" || err != nil { common.CBLog.Error(err) - return err + // If cannot find the resource, use common resource + tempReq.ReqInfo.ImageName, err = common.GetCspResourceId(common.SystemCommonNs, common.StrImage, vmInfoData.ImageId) + if tempReq.ReqInfo.ImageName == "" || err != nil { + common.CBLog.Error(err) + return err + } } + } else { + customImageFlag = true + tempReq.ReqInfo.ImageType = MyImage } tempReq.ReqInfo.VMSpecName, err = common.GetCspResourceId(nsId, common.StrSpec, vmInfoData.SpecId) @@ -1568,7 +1588,7 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e } defer res.Body.Close() - tempSpiderVMInfo = SpiderVMInfo{} // FYI; SpiderVMInfo: the struct in CB-Spider + // tempSpiderVMInfo = SpiderVMInfo{} // FYI; SpiderVMInfo: the struct in CB-Spider err = json.Unmarshal(body, &tempSpiderVMInfo) if err != nil { @@ -1622,21 +1642,14 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e common.PrintJsonPretty(tempSpiderVMInfo) fmt.Println("[Finished calling CB-Spider]") - // Fill vmInfoData from the cb-spider response vmInfoData.CspViewVmDetail = tempSpiderVMInfo vmInfoData.VmUserAccount = tempSpiderVMInfo.VMUserId vmInfoData.VmUserPassword = tempSpiderVMInfo.VMUserPasswd //vmInfoData.Location = vmInfoData.Location - //vmInfoData.VcpuSize = vmInfoData.VcpuSize - //vmInfoData.MemorySize = vmInfoData.MemorySize - //vmInfoData.DiskSize = vmInfoData.DiskSize - //vmInfoData.Disk_type = vmInfoData.Disk_type - //vmInfoData.PlacementAlgo = vmInfoData.PlacementAlgo - // 2. Provided by CB-Spider //vmInfoData.CspVmId = temp.Id //vmInfoData.StartTime = temp.StartTime vmInfoData.Region = tempSpiderVMInfo.Region @@ -1650,6 +1663,12 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e vmInfoData.RootDeviceName = tempSpiderVMInfo.RootDeviceName //vmInfoData.KeyValueList = temp.KeyValueList + /* Dummy code + if customImageFlag == true { + vmInfoData.ImageType = "custom" + } + */ + //configTmp, _ := common.GetConnConfig(vmInfoData.ConnectionName) //vmInfoData.Location = GetCloudLocation(strings.ToLower(configTmp.ProviderName), strings.ToLower(tempSpiderVMInfo.Region.Region)) @@ -1685,7 +1704,13 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e } else { vmKey := common.GenMcisKey(nsId, mcisId, vmInfoData.Id) - mcir.UpdateAssociatedObjectList(nsId, common.StrImage, vmInfoData.ImageId, common.StrAdd, vmKey) + + if customImageFlag == false { + mcir.UpdateAssociatedObjectList(nsId, common.StrImage, vmInfoData.ImageId, common.StrAdd, vmKey) + } else { + mcir.UpdateAssociatedObjectList(nsId, common.StrCustomImage, vmInfoData.ImageId, common.StrAdd, vmKey) + } + mcir.UpdateAssociatedObjectList(nsId, common.StrSpec, vmInfoData.SpecId, common.StrAdd, vmKey) mcir.UpdateAssociatedObjectList(nsId, common.StrSSHKey, vmInfoData.SshKeyId, common.StrAdd, vmKey) mcir.UpdateAssociatedObjectList(nsId, common.StrVNet, vmInfoData.VNetId, common.StrAdd, vmKey) @@ -1699,6 +1724,26 @@ func CreateVm(nsId string, mcisId string, vmInfoData *TbVmInfo, option string) e } } + // Register dataDisks which are created with the creation of VM + for _, v := range tempSpiderVMInfo.DataDiskIIDs { + tbDataDiskReq := mcir.TbDataDiskReq{ + Name: v.NameId, + ConnectionName: vmInfoData.ConnectionName, + // CspDataDiskId: v.NameId, // v.SystemId ? IdByCsp ? + } + + dataDisk, err := mcir.CreateDataDisk(nsId, &tbDataDiskReq, "register") + if err != nil { + err = fmt.Errorf("After starting VM %s, failed to register dataDisk %s. \n", vmInfoData.Name, v.NameId) + // continue + } + + vmInfoData.DataDiskIds = append(vmInfoData.DataDiskIds, dataDisk.Id) + + vmKey := common.GenMcisKey(nsId, mcisId, vmInfoData.Id) + mcir.UpdateAssociatedObjectList(nsId, common.StrDataDisk, dataDisk.Id, common.StrAdd, vmKey) + } + UpdateVmInfo(nsId, mcisId, *vmInfoData) return nil diff --git a/src/core/mcis/snapshot.go b/src/core/mcis/snapshot.go index 40e9f4247..d1c6cc11d 100644 --- a/src/core/mcis/snapshot.go +++ b/src/core/mcis/snapshot.go @@ -17,8 +17,6 @@ package mcis import ( "encoding/json" "fmt" - "math/rand" - "time" "github.com/cloud-barista/cb-tumblebug/src/core/common" "github.com/cloud-barista/cb-tumblebug/src/core/mcir" @@ -45,7 +43,7 @@ func CreateVmSnapshot(nsId string, mcisId string, vmId string, snapshotName stri json.Unmarshal([]byte(keyValue.Value), &vm) if snapshotName == "" { - snapshotName = fmt.Sprintf("%s-%s", vm.Name, GenerateNewRandomString(5)) + snapshotName = fmt.Sprintf("%s-%s", vm.Name, common.GenerateNewRandomString(5)) } tempReq := mcir.SpiderMyImageReq{ @@ -134,7 +132,7 @@ func CreateVmSnapshot(nsId string, mcisId string, vmId string, snapshotName stri // // create 'n' dataDisks // for _, v := range difference_dataDisks { // tempTbDataDiskReq := mcir.TbDataDiskReq{ - // Name: fmt.Sprintf("%s-%s", vm.Name, GenerateNewRandomString(5)), + // Name: fmt.Sprintf("%s-%s", vm.Name, common.GenerateNewRandomString(5)), // ConnectionName: vm.ConnectionName, // CspDataDiskId: v.IdByCsp, // } @@ -163,29 +161,3 @@ func Difference_dataDisks(a, b []resourceOnTumblebugInfo) []resourceOnTumblebugI } return diff } - -const ( - // Random string generation - letterBytes = "abcdefghijklmnopqrstuvwxyz1234567890" - letterIdxBits = 6 - letterIdxMask = 1<= 0; { - if remain == 0 { - cache, remain = randSrc.Int63(), letterIdxMax - } - if idx := int(cache & letterIdxMask); idx < len(letterBytes) { - b[i] = letterBytes[idx] - i-- - } - cache >>= letterIdxBits - remain-- - } - return string(b) -} diff --git a/src/testclient/scripts/8.mcis/add-vm-to-mcis.sh b/src/testclient/scripts/8.mcis/add-vm-to-mcis.sh index 3c49d784c..c5287e9ff 100755 --- a/src/testclient/scripts/8.mcis/add-vm-to-mcis.sh +++ b/src/testclient/scripts/8.mcis/add-vm-to-mcis.sh @@ -1,32 +1,26 @@ #!/bin/bash -#function add-vm-to-mcis() { +echo "####################################################################" +echo "## 8. vm: Add VM to MCIS" +echo "####################################################################" +source ../init.sh - TestSetFile=${5:-../testSet.env} - - if [ ! -f "$TestSetFile" ]; then - echo "$TestSetFile does not exist." - exit - fi - source $TestSetFile - source ../conf.env - - echo "####################################################################" - echo "## 8. vm: Create MCIS" - echo "####################################################################" +# NUMVM=${OPTION01:-1} - CSP=${1} - REGION=${2:-1} - POSTFIX=${3:-developer} - MCISPREFIX=${4:-avengers} - MCISID=${POSTFIX} +if [[ -z "${DISK_TYPE[$INDEX,$REGION]}" ]]; then + RootDiskType="default" +else + RootDiskType="${DISK_TYPE[$INDEX,$REGION]}" +fi - source ../common-functions.sh - getCloudIndex $CSP +if [[ -z "${DISK_SIZE[$INDEX,$REGION]}" ]]; then + RootDiskSize="default" +else + RootDiskSize="${DISK_SIZE[$INDEX,$REGION]}" +fi - - curl -H "${AUTH}" -sX POST http://$TumblebugServer/tumblebug/ns/$NSID/mcis/$MCISID/vm -H 'Content-Type: application/json' -d \ +curl -H "${AUTH}" -sX POST http://$TumblebugServer/tumblebug/ns/$NSID/mcis/$MCISID/vm -H 'Content-Type: application/json' -d \ '{ "name": "'${CONN_CONFIG[$INDEX,$REGION]}'", "imageId": "'${CONN_CONFIG[$INDEX,$REGION]}'-'${POSTFIX}'", @@ -41,7 +35,4 @@ "subnetId": "'${CONN_CONFIG[$INDEX,$REGION]}'-'${POSTFIX}'", "description": "description", "vmUserPassword": "" - }' | jq '' -#} - -#add-vm-to-mcis \ No newline at end of file + }' | jq ''