diff --git a/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/RegionZoneHandler.go b/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/RegionZoneHandler.go index 026977f99..57007a385 100644 --- a/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/RegionZoneHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/RegionZoneHandler.go @@ -9,6 +9,7 @@ package resources import ( + "sort" "strings" "sync" // "errors" @@ -96,6 +97,10 @@ func (regionZoneHandler *NhnCloudRegionZoneHandler) ListRegionZone() ([]*irs.Reg return nil, rtnErr } + sort.Slice(regionZoneInfoList, func(i, j int) bool { + return strings.Compare(regionZoneInfoList[i].Name, regionZoneInfoList[j].Name) < 0 + }) + return regionZoneInfoList, nil } @@ -211,15 +216,20 @@ func (regionZoneHandler NhnCloudRegionZoneHandler) getZoneInfoList(regionCode st } zoneInfo := irs.ZoneInfo{ - Name: zone.ZoneName, - // DisplayName: "N/A", - Status: zoneStatus, + Name: zone.ZoneName, + DisplayName: zone.ZoneName, + Status: zoneStatus, // KeyValueList: []irs.KeyValue{ // {Key: "ZoneCode", Value: zone.ZoneName}, // }, } zoneInfoList = append(zoneInfoList, zoneInfo) } + + sort.Slice(zoneInfoList, func(i, j int) bool { + return strings.Compare(zoneInfoList[i].Name, zoneInfoList[j].Name) < 0 + }) + return zoneInfoList, nil } diff --git a/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VMHandler.go b/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VMHandler.go index d1ca55d99..71210dae2 100644 --- a/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VMHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VMHandler.go @@ -13,8 +13,13 @@ package resources import ( + "crypto/tls" + "encoding/json" "errors" "fmt" + "github.com/cloud-barista/nhncloud-sdk-go/openstack/compute/v2/extensions/bootfromvolume" + "io" + "net/http" "os" "strconv" "strings" @@ -24,7 +29,6 @@ import ( nhnsdk "github.com/cloud-barista/nhncloud-sdk-go" "github.com/cloud-barista/nhncloud-sdk-go/openstack/blockstorage/v2/volumes" - "github.com/cloud-barista/nhncloud-sdk-go/openstack/compute/v2/extensions/bootfromvolume" "github.com/cloud-barista/nhncloud-sdk-go/openstack/compute/v2/extensions/floatingips" "github.com/cloud-barista/nhncloud-sdk-go/openstack/compute/v2/extensions/keypairs" "github.com/cloud-barista/nhncloud-sdk-go/openstack/compute/v2/extensions/startstop" @@ -286,8 +290,12 @@ func (vmHandler *NhnCloudVMHandler) StartVM(vmReqInfo irs.VMReqInfo) (irs.VMInfo Networks: []servers.Network{ {UUID: vpc.ID}, }, - AvailabilityZone: vmHandler.RegionInfo.Zone, - UserData: []byte(*initUserData), // Apply cloud-init script + UserData: []byte(*initUserData), // Apply cloud-init script + } + if vmHandler.RegionInfo.TargetZone != "" { + serverCreateOpts.AvailabilityZone = vmHandler.RegionInfo.TargetZone + } else if vmHandler.RegionInfo.Zone != "" { + serverCreateOpts.AvailabilityZone = vmHandler.RegionInfo.Zone } // Add KeyPair Name @@ -938,6 +946,43 @@ func getVmStatus(vmStatus string) irs.VMStatus { return irs.VMStatus(resultStatus) } +func getAvailabilityZoneFromAPI(computeClient *nhnsdk.ServiceClient, serverID string) (string, error) { + url := computeClient.ServiceURL("servers", serverID) + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return "", err + } + req.Header.Add("X-Auth-Token", computeClient.TokenID) + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer func() { + _ = resp.Body.Close() + }() + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to get server details: %s", resp.Status) + } + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + var serverResponse map[string]interface{} + if err := json.Unmarshal(body, &serverResponse); err != nil { + return "", err + } + if server, ok := serverResponse["server"].(map[string]interface{}); ok { + if zone, ok := server["OS-EXT-AZ:availability_zone"].(string); ok { + return zone, nil + } + } + return "", fmt.Errorf("availability zone not found") +} + func (vmHandler *NhnCloudVMHandler) mappingVMInfo(server servers.Server) (irs.VMInfo, error) { cblogger.Info("NHN Cloud Driver: called mappingVMInfo()") // cblogger.Infof("\n\n### Server from NHN :") @@ -957,7 +1002,6 @@ func (vmHandler *NhnCloudVMHandler) mappingVMInfo(server servers.Server) (irs.VM }, Region: irs.RegionInfo{ Region: vmHandler.RegionInfo.Region, - Zone: vmHandler.RegionInfo.Zone, }, KeyPairIId: irs.IID{ NameId: server.KeyName, @@ -968,6 +1012,18 @@ func (vmHandler *NhnCloudVMHandler) mappingVMInfo(server servers.Server) (irs.VM } vmInfo.StartTime = convertedTime + zone, err := getAvailabilityZoneFromAPI(vmHandler.VMClient, server.ID) + if err != nil { + cblogger.Warn(err) + } + if zone != "" { + vmInfo.Region.Zone = zone + } else if vmHandler.RegionInfo.TargetZone != "" { + vmInfo.Region.Zone = vmHandler.RegionInfo.TargetZone + } else { + vmInfo.Region.Zone = vmHandler.RegionInfo.Zone + } + // Image Info imageId := server.Image["id"].(string) nhnImage, err := comimages.Get(vmHandler.VMClient, imageId).Extract() // Caution!!) Wtih VMClient (Not Like ImageHandler) @@ -983,25 +1039,27 @@ func (vmHandler *NhnCloudVMHandler) mappingVMInfo(server servers.Server) (irs.VM // Flavor Info var vRam string var vCPU string - flavorId := server.Flavor["id"].(string) - nhnFlavor, err := flavors.Get(vmHandler.VMClient, flavorId).Extract() - if err != nil { - newErr := fmt.Errorf("Failed to Get the Flavor info from NHN Cloud!! : [%v] ", err) - cblogger.Error(newErr.Error()) - return irs.VMInfo{}, newErr - } else if nhnFlavor != nil { - // spew.Dump(flavor) - vmInfo.VMSpecName = nhnFlavor.Name - if vmInfo.RootDiskSize == "" { // In case of u2 VMSpec type - vmInfo.RootDiskType = "General_HDD" // u2 type VMSpec only supports 'General_HHD'. - vmInfo.RootDiskSize = strconv.Itoa(nhnFlavor.Disk) - vmInfo.RootDeviceName = "/dev/vda" - } - if strconv.Itoa(nhnFlavor.VCPUs) != "" { - vCPU = strconv.Itoa(nhnFlavor.VCPUs) - } - if strconv.Itoa(nhnFlavor.RAM) != "" { - vRam = strconv.Itoa(nhnFlavor.RAM) + flavorId, ok := server.Flavor["id"].(string) + if ok { + nhnFlavor, err := flavors.Get(vmHandler.VMClient, flavorId).Extract() + if err != nil { + newErr := fmt.Errorf("Failed to Get the Flavor info from NHN Cloud!! : [%v] ", err) + cblogger.Error(newErr.Error()) + return irs.VMInfo{}, newErr + } else if nhnFlavor != nil { + // spew.Dump(flavor) + vmInfo.VMSpecName = nhnFlavor.Name + if vmInfo.RootDiskSize == "" { // In case of u2 VMSpec type + vmInfo.RootDiskType = "General_HDD" // u2 type VMSpec only supports 'General_HHD'. + vmInfo.RootDiskSize = strconv.Itoa(nhnFlavor.Disk) + vmInfo.RootDeviceName = "/dev/vda" + } + if strconv.Itoa(nhnFlavor.VCPUs) != "" { + vCPU = strconv.Itoa(nhnFlavor.VCPUs) + } + if strconv.Itoa(nhnFlavor.RAM) != "" { + vRam = strconv.Itoa(nhnFlavor.RAM) + } } } diff --git a/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VPCHandler.go b/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VPCHandler.go index 8c547ae9d..d92e59592 100644 --- a/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VPCHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/nhncloud/resources/VPCHandler.go @@ -278,7 +278,26 @@ func (vpcHandler *NhnCloudVPCHandler) DeleteVPC(vpcIID irs.IID) (bool, error) { return false, newErr } + var subnets []vpcs.Subnet + + // Remove duplicated subnets (NHN provide duplicated subnets) for _, subnet := range vpc.Subnets { + var skip bool + + for _, sb := range subnets { + if sb.ID == subnet.ID { + skip = true + break + } + } + if skip { + continue + } + + subnets = append(subnets, subnet) + } + + for _, subnet := range subnets { if _, err := vpcHandler.RemoveSubnet(irs.IID{SystemId: vpc.ID}, irs.IID{SystemId: subnet.ID}); err != nil { newErr := fmt.Errorf("Failed to Remove the Subnet with the SystemID. : [%s] : [%v]", subnet.ID, err) cblogger.Error(newErr.Error()) @@ -424,7 +443,26 @@ func (vpcHandler *NhnCloudVPCHandler) RemoveSubnet(vpcIID irs.IID, subnetIID irs vpcIID.SystemId = vpc.ID if subnetIID.SystemId == "" { + var subnets []vpcs.Subnet + + // Remove duplicated subnets (NHN provide duplicated subnets) for _, subnet := range vpc.Subnets { + var skip bool + + for _, sb := range subnets { + if sb.ID == subnet.ID { + skip = true + break + } + } + if skip { + continue + } + + subnets = append(subnets, subnet) + } + + for _, subnet := range subnets { if subnet.Name == subnetIID.NameId { subnetIID.SystemId = subnet.ID break @@ -460,9 +498,40 @@ func (vpcHandler *NhnCloudVPCHandler) mappingVpcInfo(vpc vpcs.VPC) (*irs.VPCInfo } vpcInfo.IPv4_CIDR = vpc.CIDRv4 + var subnets []vpcs.Subnet + + // Remove duplicated subnets (NHN provide duplicated subnets) + for _, subnet := range vpc.Subnets { + var skip bool + + for _, sb := range subnets { + if sb.ID == subnet.ID { + skip = true + break + } + } + if skip { + continue + } + + subnets = append(subnets, subnet) + } + // Get Subnet info list. var subnetInfoList []irs.SubnetInfo - for _, subnet := range vpc.Subnets { // Because of vpcs.Subnet type (Not subnets.Subnet type), need to getSubnet() + for _, subnet := range subnets { // Because of vpcs.Subnet type (Not subnets.Subnet type), need to getSubnet() + var skip bool + + for _, subnetInfo := range subnetInfoList { + if subnetInfo.IId.SystemId == subnet.ID { + skip = true + break + } + } + if skip { + continue + } + subnetInfo, err := vpcHandler.getSubnet(irs.IID{SystemId: subnet.ID}) if err != nil { newErr := fmt.Errorf("Failed to Get Subnet info with the subnetId [%s]. [%v]", subnet.ID, err)