diff --git a/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMSpecHandler.go b/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMSpecHandler.go index 19abcf8e..b1901683 100644 --- a/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMSpecHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/alibaba/resources/VMSpecHandler.go @@ -3,7 +3,6 @@ package resources //20211104 개선안 I에 의해 Region 파라메터 대신 세션의 Region 정보로 대체함. import ( "errors" - "reflect" "strconv" "strings" @@ -31,21 +30,49 @@ func ExtractVMSpecInfo(Region string, instanceTypeInfo ecs.InstanceType) irs.VMS //cblogger.Debug(instanceTypeInfo) vCpuInfo := irs.VCpuInfo{ - Clock: "N/A", + Clock: "0", } - gpuInfoList := []irs.GpuInfo{ - { - Count: strconv.Itoa(instanceTypeInfo.GPUAmount), - Model: instanceTypeInfo.GPUSpec, - }, + // gpuInfoList := []irs.GpuInfo{ + // { + // Count: strconv.Itoa(instanceTypeInfo.GPUAmount), + // Model: instanceTypeInfo.GPUSpec, + // }, + // } + gpuInfoList := []irs.GpuInfo{} + + // 기본 값 설정 + gpuInfo := irs.GpuInfo{ + Count: "-1", + Model: "NA", + Mfr: "NA", + Mem: "0", } - if !reflect.ValueOf(&instanceTypeInfo.GPUSpec).IsNil() { - gpu := strings.Split(instanceTypeInfo.GPUSpec, " ") //"Nvidia Tesla P4" - cblogger.Infof("Manufacturer Information Extraction: Original[%s] / Extracted[%s]", instanceTypeInfo.GPUSpec, gpu[0]) - gpuInfoList[0].Mfr = gpu[0] + if instanceTypeInfo.GPUAmount != 0 { + gpuInfo.Count = strconv.Itoa(instanceTypeInfo.GPUAmount) } + if instanceTypeInfo.GPUSpec != "" { + gpuInfo.Model = strings.ToUpper(instanceTypeInfo.GPUSpec) + gpu := strings.Split(instanceTypeInfo.GPUSpec, " ") // "Nvidia Tesla P4" + if len(gpu) > 0 { + gpuInfo.Mfr = strings.ToUpper(gpu[0]) + cblogger.Infof("Manufacturer Information Extraction: Original[%s] / Extracted[%s]", instanceTypeInfo.GPUSpec, gpuInfo.Mfr) + } + } + + if instanceTypeInfo.GPUMemorySize != 0 { + gpuInfo.Mem = strconv.FormatFloat(instanceTypeInfo.GPUMemorySize, 'f', -1, 64) + } + + gpuInfoList = append(gpuInfoList, gpuInfo) + + // if !reflect.ValueOf(&instanceTypeInfo.GPUSpec).IsNil() { + // gpu := strings.Split(instanceTypeInfo.GPUSpec, " ") //"Nvidia Tesla P4" + // cblogger.Infof("Manufacturer Information Extraction: Original[%s] / Extracted[%s]", instanceTypeInfo.GPUSpec, gpu[0]) + // gpuInfoList[0].Mfr = gpu[0] + // } + //결과에 리전 정보는 없기 때문에 조회한 리전 정보를 전달 받아서 처리함. vmSpecInfo := irs.VMSpecInfo{ Region: Region, @@ -69,6 +96,14 @@ func ExtractVMSpecInfo(Region string, instanceTypeInfo ecs.InstanceType) irs.VMS vmSpecInfo.Mem = strconv.FormatFloat(instanceTypeInfo.MemorySize*1024, 'f', 0, 64) // GB->MB로 변환 //} + // LocalStorageCapacity -> GIB + if instanceTypeInfo.LocalStorageCapacity > 0 { + gb := float64(instanceTypeInfo.LocalStorageCapacity) * 1.073741824 + vmSpecInfo.Disk = strconv.FormatFloat(gb, 'f', 2, 64) + } else { + vmSpecInfo.Disk = "-1" + } + //KeyValue 목록 처리 keyValueList, errKeyValue := ConvertKeyValueList(instanceTypeInfo) if errKeyValue != nil { diff --git a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go index 739eb2e0..dd362282 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/main/Test_Resources.go @@ -1227,7 +1227,6 @@ func handleVMSpec() { cblogger.Error(reqVMSpec, " VMSpec Info Lookup Failed : ", err) } else { cblogger.Debugf("VMSpec[%s] Info Lookup Result", reqVMSpec) - //spew.Dump(result) cblogger.Debug(result) } fmt.Println("Finish GetVMSpec()") @@ -2349,17 +2348,17 @@ func main() { //handleTag() // handlePublicIP() // PublicIP 생성 후 conf - handleVPC() - handleSecurity() - handleKeyPair() - handleVM() - handleDisk() - handleMyImage() - handleNLB() - handleCluster() + //handleVPC() + //handleSecurity() + //handleKeyPair() + //handleVM() + //handleDisk() + //handleMyImage() + //handleNLB() + //handleCluster() // handleImage() //AMI // handleVNic() //Lancard - // handleVMSpec() + handleVMSpec() //handleRegionZone() //handlePriceInfo() //handleTag() diff --git a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMSpecHandler.go b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMSpecHandler.go index 836ea13d..63e49270 100644 --- a/cloud-control-manager/cloud-driver/drivers/aws/resources/VMSpecHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/aws/resources/VMSpecHandler.go @@ -5,6 +5,7 @@ import ( "errors" "reflect" "strconv" + "strings" //sdk2 "github.com/aws/aws-sdk-go-v2" "github.com/aws/aws-sdk-go/aws" @@ -25,11 +26,42 @@ func ExtractGpuInfo(gpuDeviceInfo *ec2.GpuDeviceInfo) irs.GpuInfo { //cblogger.Info("================") //cblogger.Debug(gpuDeviceInfo) - gpuInfo := irs.GpuInfo{ - Count: strconv.FormatInt(*gpuDeviceInfo.Count, 10), - Mfr: *gpuDeviceInfo.Manufacturer, - Model: *gpuDeviceInfo.Name, - Mem: strconv.FormatInt(*gpuDeviceInfo.MemoryInfo.SizeInMiB, 10), + // gpuInfo := irs.GpuInfo{ + // Count: strconv.FormatInt(*gpuDeviceInfo.Count, 10), + // Mfr: strings.ToUpper(*gpuDeviceInfo.Manufacturer), + // Model: strings.ToUpper(*gpuDeviceInfo.Name), + // Mem: strconv.FormatInt(*gpuDeviceInfo.MemoryInfo.SizeInMiB, 10), + // } + + // GPU Struct + gpuInfo := irs.GpuInfo{} + + // Check Count + if gpuDeviceInfo.Count != nil { + gpuInfo.Count = strconv.FormatInt(*gpuDeviceInfo.Count, 10) + } else { + gpuInfo.Count = "-1" // Set number values to "-1" if nil + } + + // Check Manufacturer + if gpuDeviceInfo.Manufacturer != nil { + gpuInfo.Mfr = strings.ToUpper(*gpuDeviceInfo.Manufacturer) + } else { + gpuInfo.Mfr = "NA" // Set string values to "NA" if nil + } + + // Check Model + if gpuDeviceInfo.Name != nil { + gpuInfo.Model = strings.ToUpper(*gpuDeviceInfo.Name) + } else { + gpuInfo.Model = "NA" // Set string values to "NA" if nil + } + + // Check MemoryInfo + if gpuDeviceInfo.MemoryInfo != nil && gpuDeviceInfo.MemoryInfo.SizeInMiB != nil { + gpuInfo.Mem = strconv.FormatInt(*gpuDeviceInfo.MemoryInfo.SizeInMiB, 10) + } else { + gpuInfo.Mem = "-1" // Set number values to "-1" if nil } return gpuInfo @@ -48,14 +80,21 @@ func ExtractVMSpecInfo(Region string, instanceTypeInfo *ec2.InstanceTypeInfo) ir Region: Region, } - //VCPU 정보 처리 - Count + //Check Disk Info (Root volume information is only provided in AMI information) + vmSpecInfo.Disk = "-1" + + // Check VCPU - Count if !reflect.ValueOf(instanceTypeInfo.VCpuInfo.DefaultVCpus).IsNil() { vCpuInfo.Count = strconv.FormatInt(*instanceTypeInfo.VCpuInfo.DefaultVCpus, 10) + } else { + vCpuInfo.Count = "-1" } - //VCPU 정보 처리 - Clock + // Check VCPU - Clock if !reflect.ValueOf(instanceTypeInfo.ProcessorInfo.SustainedClockSpeedInGhz).IsNil() { vCpuInfo.Clock = strconv.FormatFloat(*instanceTypeInfo.ProcessorInfo.SustainedClockSpeedInGhz, 'f', 1, 64) + } else { + vCpuInfo.Clock = "-1" } vmSpecInfo.VCpu = vCpuInfo @@ -72,10 +111,14 @@ func ExtractVMSpecInfo(Region string, instanceTypeInfo *ec2.InstanceTypeInfo) ir if !reflect.ValueOf(instanceTypeInfo.InstanceType).IsNil() { vmSpecInfo.Name = *instanceTypeInfo.InstanceType + } else { + vmSpecInfo.Name = "NA" } if !reflect.ValueOf(instanceTypeInfo.MemoryInfo.SizeInMiB).IsNil() { vmSpecInfo.Mem = strconv.FormatInt(*instanceTypeInfo.MemoryInfo.SizeInMiB, 10) + } else { + vmSpecInfo.Mem = "-1" } //KeyValue 목록 처리 diff --git a/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMSpecHandler.go b/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMSpecHandler.go index 924d8049..4774f9cb 100644 --- a/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMSpecHandler.go +++ b/cloud-control-manager/cloud-driver/drivers/gcp/resources/VMSpecHandler.go @@ -59,14 +59,29 @@ func (vmSpecHandler *GCPVMSpecHandler) ListVMSpec() ([]*irs.VMSpecInfo, error) { callogger.Info(call.String(callLogInfo)) var vmSpecInfo []*irs.VMSpecInfo for _, i := range resp.Items { + + gpuInfoList := []irs.GpuInfo{} + if i.Accelerators != nil { + gpuInfoList = acceleratorsToGPUInfoList(i.Accelerators) + + } info := irs.VMSpecInfo{ Region: zone, Name: i.Name, VCpu: irs.VCpuInfo{ Count: strconv.FormatInt(i.GuestCpus, 10), }, - Mem: strconv.FormatInt(i.MemoryMb, 10), + Mem: strconv.FormatInt(i.MemoryMb, 10), + Disk: "-1", + Gpu: gpuInfoList, + } + + info.KeyValueList, err = ConvertKeyValueList(i) + if err != nil { + info.KeyValueList = nil + cblogger.Error(err) } + vmSpecInfo = append(vmSpecInfo, &info) } return vmSpecInfo, nil @@ -101,6 +116,12 @@ func (vmSpecHandler *GCPVMSpecHandler) GetVMSpec(Name string) (irs.VMSpecInfo, e } callogger.Info(call.String(callLogInfo)) + gpuInfoList := []irs.GpuInfo{} + if info.Accelerators != nil { + gpuInfoList = acceleratorsToGPUInfoList(info.Accelerators) + + } + vmSpecInfo := irs.VMSpecInfo{ Region: vmSpecHandler.Region.Region, Name: Name, @@ -108,17 +129,16 @@ func (vmSpecHandler *GCPVMSpecHandler) GetVMSpec(Name string) (irs.VMSpecInfo, e Count: strconv.FormatInt(info.GuestCpus, 10), Clock: "", }, - Mem: strconv.FormatInt(info.MemoryMb, 10), - Gpu: []irs.GpuInfo{ - { - Count: "", - Mfr: "", - Model: "", - Mem: "", - }, - }, + Mem: strconv.FormatInt(info.MemoryMb, 10), + Disk: "-1", + Gpu: gpuInfoList, } + vmSpecInfo.KeyValueList, err = ConvertKeyValueList(vmSpecInfo) + if err != nil { + vmSpecInfo.KeyValueList = nil + cblogger.Error(err) + } return vmSpecInfo, nil } @@ -185,6 +205,99 @@ func (vmSpecHandler *GCPVMSpecHandler) GetOrgVMSpec(Name string) (string, error) return string(j), err } +// type GpuInfo struct { +// Count string `json:"Count" validate:"required" example:"1"` // Number of GPUs, "-1" when not applicable +// Mfr string `json:"Mfr,omitempty" validate:"omitempty" example:"NVIDIA"` // Manufacturer of the GPU, NA when not applicable +// Model string `json:"Model,omitempty" validate:"omitempty" example:"Tesla K80"` // Model of the GPU, NA when not applicable +// Mem string `json:"Mem,omitempty" validate:"omitempty" example:"8192"` // Memory size of the GPU in MB, "-1" when not applicable +// } + +// accerators 목록을 GPU목록으로 변경 +// 이름에서 발견된 규칙 +// +// 0번째는 제조사 +// 마지막에 gb면 용량 +// 가운데는 모델 +// "name": "nvidia-tesla-a100", +// "name": "nvidia-h100-80gb", +// "name": "nvidia-h100-mega-80gb", +// "name": "nvidia-l4" +// "name": "nvidia-l4-vws" +func acceleratorsToGPUInfoList(accerators []*compute.MachineTypeAccelerators) []irs.GpuInfo { + gpuInfoList := []irs.GpuInfo{} + for _, accelerator := range accerators { + gpuInfo := irs.GpuInfo{} + + accrType := strings.Split(accelerator.GuestAcceleratorType, "-") + if len(accrType) >= 3 { + // 첫 번째 요소를 Mfr에 할당 + gpuInfo.Mfr = strings.ToUpper(accrType[0]) + + // 마지막 요소를 확인 + lastElement := accrType[len(accrType)-1] + if strings.HasSuffix(lastElement, "gb") { + // "gb"를 제거하고 숫자만 추출 + numStr := strings.TrimSuffix(lastElement, "gb") + if num, err := strconv.Atoi(numStr); err == nil { + gpuInfo.Mem = strconv.Itoa(num * 1024) // GB를 MB로 변환 후 숫자만 string으로 저장 + } + // 첫 번째와 마지막 요소를 제외한 나머지를 Model에 할당 + if len(accrType) > 2 { + gpuInfo.Model = strings.ToUpper(strings.Join(accrType[1:len(accrType)-1], " ")) + } + } else { + // 마지막 요소가 "gb"로 끝나지 않는 경우 + gpuInfo.Mem = "" // Mem은 빈 문자열로 설정 + if len(accrType) > 1 { + // 첫 번째 요소를 제외한 나머지를 Model에 할당 + gpuInfo.Model = strings.ToUpper(strings.Join(accrType[1:], " ")) + } + } + } + + gpuCount := accelerator.GuestAcceleratorCount + if gpuCount == 0 { // 값이 0이라면 기본값 -1 + gpuCount = -1 + } + gpuInfo.Count = strconv.FormatInt(gpuCount, 10) + + gpuInfoList = append(gpuInfoList, gpuInfo) + } + return gpuInfoList +} + +// GPU 정보조회 미구현 +// accelerator 정보를 조회하여 set하려했으나, 해당정보안에 gpuInfo에 넣을 값이 없어서 미구현. +// func getAcceleratorType(client *compute.Service, project string, region string, zone string, acceleratorNames []string)(irs.GpuInfo, error){ +// // logger for HisCall +// callogger := call.GetLogger("HISCALL") +// callLogInfo := call.CLOUDLOGSCHEMA{ +// CloudOS: call.GCP, +// RegionZone: zone, +// ResourceType: call.VMSPEC, +// ResourceName: "VMSpec", +// CloudOSAPI: "AcceleratorTypes.Get()", +// ElapsedTime: "", +// ErrorMSG: "", +// } +// callLogStart := call.Start() +// +// for _, i := range acceleratorNames { +// info, err := client.AcceleratorTypes.Get(project, zone, AcceleratorName).Do() +// callLogInfo.ElapsedTime = call.Elapsed(callLogStart) +// +// if err != nil { +// callLogInfo.ErrorMSG = err.Error() +// callogger.Info(call.String(callLogInfo)) +// cblogger.Error(err) +// return irs.GpuInfo{}, err +// } +// callogger.Info(call.String(callLogInfo)) +// +// gpuInfo := irs.GpuInfo{} +// +// } + // gcp 같은경우 n1 타입만 그래픽 카드가 추가 되며 // 1. n1타입인지 확인하는 로직 필요 // 2. 해당 카드에 관련된 정보를 조회하는 로직필요.