@@ -14,6 +14,8 @@ import (
1414 "github.com/nutanix-cloud-native/prism-go-client/utils"
1515 nutanixclientv3 "github.com/nutanix-cloud-native/prism-go-client/v3"
1616 "github.com/pkg/errors"
17+
18+ machinev1 "github.com/openshift/api/machine/v1"
1719)
1820
1921const (
@@ -194,3 +196,94 @@ func CategoryKey(infraID string) string {
194196 categoryKey := fmt .Sprintf ("%s%s" , categoryKeyPrefix , infraID )
195197 return categoryKey
196198}
199+
200+ // GetGPUList returns a list of VMGpus for the given list of GPU identifiers in the Prism Element (uuid).
201+ func GetGPUList (ctx context.Context , client * nutanixclientv3.Client , gpus []machinev1.NutanixGPU , peUUID string ) ([]* nutanixclientv3.VMGpu , error ) {
202+ vmGPUs := make ([]* nutanixclientv3.VMGpu , 0 )
203+
204+ if len (gpus ) == 0 {
205+ return vmGPUs , nil
206+ }
207+
208+ peGPUs , err := GetGPUsForPE (ctx , client , peUUID )
209+ if err != nil {
210+ return nil , fmt .Errorf ("failed to retrieve GPUs of the Prism Element cluster (uuid: %v): %w" , peUUID , err )
211+ }
212+ if len (peGPUs ) == 0 {
213+ return nil , fmt .Errorf ("no available GPUs found in Prism Element cluster (uuid: %s)" , peUUID )
214+ }
215+
216+ for _ , gpu := range gpus {
217+ foundGPU , err := GetGPUFromList (ctx , client , gpu , peGPUs )
218+ if err != nil {
219+ return nil , err
220+ }
221+ vmGPUs = append (vmGPUs , foundGPU )
222+ }
223+
224+ return vmGPUs , nil
225+ }
226+
227+ // GetGPUFromList returns the VMGpu matching the input reqirements from the provided list of GPU devices.
228+ func GetGPUFromList (ctx context.Context , client * nutanixclientv3.Client , gpu machinev1.NutanixGPU , gpuDevices []* nutanixclientv3.GPU ) (* nutanixclientv3.VMGpu , error ) {
229+ for _ , gd := range gpuDevices {
230+ if gd .Status != "UNUSED" {
231+ continue
232+ }
233+
234+ if (gpu .Type == machinev1 .NutanixGPUIdentifierDeviceID && gd .DeviceID != nil && * gpu .DeviceID == int32 (* gd .DeviceID )) ||
235+ (gpu .Type == machinev1 .NutanixGPUIdentifierName && * gpu .Name == gd .Name ) {
236+ return & nutanixclientv3.VMGpu {
237+ DeviceID : gd .DeviceID ,
238+ Mode : & gd .Mode ,
239+ Vendor : & gd .Vendor ,
240+ }, nil
241+ }
242+ }
243+
244+ return nil , fmt .Errorf ("no available GPU found that matches required GPU inputs" )
245+ }
246+
247+ // GetGPUsForPE returns all the GPU devices for the given Prism Element (uuid).
248+ func GetGPUsForPE (ctx context.Context , client * nutanixclientv3.Client , peUUID string ) ([]* nutanixclientv3.GPU , error ) {
249+ gpus := make ([]* nutanixclientv3.GPU , 0 )
250+ hosts , err := client .V3 .ListAllHost (ctx )
251+ if err != nil {
252+ return gpus , fmt .Errorf ("failed to get hosts from Prism Central: %w" , err )
253+ }
254+
255+ for _ , host := range hosts .Entities {
256+ if host == nil ||
257+ host .Status == nil ||
258+ host .Status .ClusterReference == nil ||
259+ host .Status .ClusterReference .UUID != peUUID ||
260+ host .Status .Resources == nil ||
261+ len (host .Status .Resources .GPUList ) == 0 {
262+ continue
263+ }
264+
265+ for _ , peGpu := range host .Status .Resources .GPUList {
266+ if peGpu != nil {
267+ gpus = append (gpus , peGpu )
268+ }
269+ }
270+ }
271+
272+ return gpus , nil
273+ }
274+
275+ // FindImageUUIDByName retrieves the image resource uuid by the given image name from PC.
276+ func FindImageUUIDByName (ctx context.Context , ntnxclient * nutanixclientv3.Client , imageName string ) (* string , error ) {
277+ res , err := ntnxclient .V3 .ListImage (ctx , & nutanixclientv3.DSMetadata {
278+ Filter : utils .StringPtr (fmt .Sprintf ("name==%s" , imageName )),
279+ })
280+ if err != nil || len (res .Entities ) == 0 {
281+ return nil , fmt .Errorf ("failed to find image by name %q. err: %w" , imageName , err )
282+ }
283+
284+ if len (res .Entities ) > 1 {
285+ return nil , fmt .Errorf ("found more than one (%v) images with name %q" , len (res .Entities ), imageName )
286+ }
287+
288+ return res .Entities [0 ].Metadata .UUID , nil
289+ }
0 commit comments