Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add data source vgpu profiles #2048

Merged
merged 3 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -158,6 +158,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.