Skip to content

Commit

Permalink
feat: add data source vgpu profiles (#2048)
Browse files Browse the repository at this point in the history
Adds a datasource to return available vGPU profiles for an ESXi host.
  • Loading branch information
mristok authored Feb 12, 2024
1 parent c6b790f commit 5a22e9a
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 0 deletions.
164 changes: 164 additions & 0 deletions vsphere/data_source_vsphere_host_vgpu_profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package vsphere

import (
"crypto/sha256"
"fmt"
"log"
"regexp"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/hostsystem"
"github.com/vmware/govmomi/vim25/types"
)

func dataSourceVSphereHostVGpuProfile() *schema.Resource {
return &schema.Resource{
Read: dataSourceVSphereHostVGpuProfileRead,
Schema: map[string]*schema.Schema{
"host_id": {
Type: schema.TypeString,
Required: true,
Description: "The Managed Object ID of the host system.",
},
"name_regex": {
Type: schema.TypeString,
Optional: true,
Description: "A regular expression used to match the vGPU Profile on the host.",
},
"vgpu_profiles": {
Type: schema.TypeList,
Description: "List of vGPU profiles available via the host.",
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"vgpu": {
Type: schema.TypeString,
Computed: true,
Description: "Name of a particular VGPU available as a shared GPU device (vGPU profile).",
},
"disk_snapshot_supported": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether the GPU plugin on this host is capable of disk-only snapshots when VM is not powered off.",
},
"memory_snapshot_supported": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether the GPU plugin on this host is capable of memory snapshots.",
},
"suspend_supported": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether the GPU plugin on this host is capable of suspend-resume.",
},
"migrate_supported": {
Type: schema.TypeBool,
Computed: true,
Description: "Indicates whether the GPU plugin on this host is capable of migration.",
},
},
},
},
},
}
}

func dataSourceVSphereHostVGpuProfileRead(d *schema.ResourceData, meta interface{}) error {
log.Printf("[DEBUG] DataHostVGpuProfile: Beginning vGPU Profile lookup on %s", d.Get("host_id").(string))

client := meta.(*Client).vimClient

host, err := hostsystem.FromID(client, d.Get("host_id").(string))
if err != nil {
return err
}

hprops, err := hostsystem.Properties(host)
if err != nil {
return err
}

// Create unique ID based on the host_id
idsum := sha256.New()
if _, err := idsum.Write([]byte(fmt.Sprintf("%#v", d.Get("host_id").(string)))); err != nil {
return err
}

d.SetId(fmt.Sprintf("%x", idsum.Sum(nil)))

log.Printf("[DEBUG] DataHostVGpuProfile: Looking for available vGPU profiles")

// Retrieve the SharedGpuCapabilities from host properties
vgpusRaw := hprops.Config.SharedGpuCapabilities

// If searching for a specific vGPU profile (by name)
name, ok := d.GetOk("name_regex")
if (ok) && (name.(string) != "") {
return searchVGpuProfileByName(d, vgpusRaw, name.(string))
}

// Loop over all vGPU profiles on host
vgpus := make([]interface{}, len(vgpusRaw))
for i, v := range vgpusRaw {
log.Printf("[DEBUG] DataHostVGpuProfile: Host %s has vGPU profile %s", d.Get("host_id").(string), v.Vgpu)
vgpu := map[string]interface{}{
"vgpu": v.Vgpu,
"disk_snapshot_supported": v.DiskSnapshotSupported,
"memory_snapshot_supported": v.MemorySnapshotSupported,
"suspend_supported": v.SuspendSupported,
"migrate_supported": v.MigrateSupported,
}
vgpus[i] = vgpu
}

// Set the `vgpu_profile` output to all vGPU profiles
if err := d.Set("vgpu_profiles", vgpus); err != nil {
return err
}

log.Printf("[DEBUG] DataHostVGpuProfile: Identified %d vGPU profiles available on %s", len(vgpus), d.Get("host_id").(string))

return nil
}

func searchVGpuProfileByName(d *schema.ResourceData, vgpusRaw []types.HostSharedGpuCapabilities, name string) error {
log.Printf("[DEBUG] DataHostVGpuProfile: Selecting devices which match name regex")

vgpus := make([]interface{}, 0, len(vgpusRaw))

re, err := regexp.Compile(name)
if err != nil {
return err
}

// Loop over all vGPU profile and attempt to match by name
for _, v := range vgpusRaw {
if re.Match([]byte(v.Vgpu)) {
// Identified matching vGPU profile
log.Printf("[DEBUG] DataHostVGpuProfile: Host %s has vGPU profile %s", d.Get("host_id").(string), v.Vgpu)
vgpu := map[string]interface{}{
"vgpu": v.Vgpu,
"disk_snapshot_supported": v.DiskSnapshotSupported,
"memory_snapshot_supported": v.MemorySnapshotSupported,
"suspend_supported": v.SuspendSupported,
"migrate_supported": v.MigrateSupported,
}
vgpus = append(vgpus, vgpu)
}
}

if len(vgpus) == 0 {
log.Printf("[DEBUG] DataHostVGpuProfile: Host %s does not support vGPU profile name regex [%s]", d.Get("host_id").(string), name)
}

// Set the `vgpu_profile` output to located vGPU.
// If a matching vGPU profile is not found, return null
if err := d.Set("vgpu_profiles", vgpus); err != nil {
return err
}

return nil
}
1 change: 1 addition & 0 deletions vsphere/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func Provider() *schema.Provider {
"vsphere_host": dataSourceVSphereHost(),
"vsphere_host_pci_device": dataSourceVSphereHostPciDevice(),
"vsphere_host_thumbprint": dataSourceVSphereHostThumbprint(),
"vsphere_host_vgpu_profile": dataSourceVSphereHostVGpuProfile(),
"vsphere_license": dataSourceVSphereLicense(),
"vsphere_network": dataSourceVSphereNetwork(),
"vsphere_ovf_vm_template": dataSourceVSphereOvfVMTemplate(),
Expand Down
79 changes: 79 additions & 0 deletions website/docs/d/host_vgpu_profile.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
subcategory: "Host and Cluster Management"
layout: "vsphere"
page_title: "VMware vSphere: vsphere_host_vgpu_profile"
sidebar_current: "docs-vsphere-data-source-host_vgpu_profile"
description: |-
A data source that can be used to get information for
one or all vGPU profiles available on an ESXi host.
---

# vsphere_host_vgpu_profile

The `vsphere_host_vgpu_profile` data source can be used to discover the
available vGPU profiles of a vSphere host.

## Example Usage to return all vGPU profiles

```hcl
data "vsphere_datacenter" "datacenter" {
name = "dc-01"
}
data "vsphere_host" "host" {
name = "esxi-01.example.com"
datacenter_id = data.vsphere_datacenter.datacenter.id
}
data "vsphere_host_vgpu_profile" "vgpu_profile" {
host_id = data.vsphere_host.host.id
}
```

## Example Usage with vGPU profile name_regex

```hcl
data "vsphere_datacenter" "datacenter" {
name = "dc-01"
}
data "vsphere_host" "host" {
name = "esxi-01.example.com"
datacenter_id = data.vsphere_datacenter.datacenter.id
}
data "vsphere_host_vgpu_profile" "vgpu_profile" {
host_id = data.vsphere_host.host.id
name_regex = "a100"
}
```

## Argument Reference

The following arguments are supported:

* `host_id` - (Required) The [managed object reference ID][docs-about-morefs] of a host.
* `name_regex` - (Optional) A regular expression that will be used to match the
host vGPU profile name.

[docs-about-morefs]: /docs/providers/vsphere/index.html#use-of-managed-object-references-by-the-vsphere-provider

## Attribute Reference

The following attributes are exported:

* `host_id` - The [managed objectID][docs-about-morefs] of the ESXi host.
* `id` - Unique (SHA256) id based on the host_id if the ESXi host.
* `name_regex` - (Optional) A regular expression that will be used to match the
host vGPU profile name.
* `vgpu_profiles` - The list of available vGPU profiles on the ESXi host.
This may be and empty array if no vGPU profile are identified.
* `vgpu` - Name of a particular vGPU available as a shared GPU device (vGPU profile).
* `disk_snapshot_supported` - Indicates whether the GPU plugin on this host is
capable of disk-only snapshots when VM is not powered off.
* `memory_snapshot_supported` - Indicates whether the GPU plugin on this host is
capable of memory snapshots.
* `migrate_supported` - Indicates whether the GPU plugin on this host is capable
of migration.
* `suspend_supported` - Indicates whether the GPU plugin on this host is capable
of suspend-resume.

0 comments on commit 5a22e9a

Please sign in to comment.