Skip to content

Commit 9837630

Browse files
author
Adam Jasinski
authored
Add vGPU policy support (#633)
Signed-off-by: Adam Jasinski <jasinskia@vmware.com>
1 parent d3f64e4 commit 9837630

File tree

5 files changed

+181
-0
lines changed

5 files changed

+181
-0
lines changed

.changes/v2.22.0/633-features.md

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* Add type `VgpuProfile` and its methods `GetAllVgpuProfiles`, `GetVgpuProfilesByProviderVdc`, `GetVgpuProfileById`, `GetVgpuProfileByName`, `GetVgpuProfileByTenantFacingName`, `Update` and `Refresh` for managing vGPU profiles [GH-633]
2+
* Update `ComputePolicyV2` type with new fields for managing vGPU policies [GH-633]

govcd/openapi_endpoints.go

+3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ var endpointMinApiVersions = map[string]string{
138138
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointServiceAccountGrant: "37.0", // VCD 10.4.0+
139139
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointImportableTransportZones: "33.0",
140140
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVCenterDistributedSwitch: "33.0",
141+
142+
// Endpoint for managing vGPU profiles
143+
types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVgpuProfile: "36.2",
141144
}
142145

143146
// endpointElevatedApiVersions endpoint elevated API versions

govcd/vgpu_profile.go

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
package govcd
2+
3+
/*
4+
* Copyright 2023 VMware, Inc. All rights reserved. Licensed under the Apache v2 License.
5+
*/
6+
7+
import (
8+
"fmt"
9+
"net/url"
10+
11+
"github.com/vmware/go-vcloud-director/v2/types/v56"
12+
)
13+
14+
// VgpuProfile defines a vGPU profile which is fetched from vCenter
15+
type VgpuProfile struct {
16+
VgpuProfile *types.VgpuProfile
17+
client *Client
18+
}
19+
20+
// GetAllVgpuProfiles gets all vGPU profiles that are available to VCD
21+
func (client *VCDClient) GetAllVgpuProfiles(queryParameters url.Values) ([]*VgpuProfile, error) {
22+
return getAllVgpuProfiles(queryParameters, &client.Client)
23+
}
24+
25+
// GetVgpuProfilesByProviderVdc gets all vGPU profiles that are available to a specific provider VDC
26+
func (client *VCDClient) GetVgpuProfilesByProviderVdc(providerVdcUrn string) ([]*VgpuProfile, error) {
27+
queryParameters := url.Values{}
28+
queryParameters = queryParameterFilterAnd(fmt.Sprintf("pvdcId==%s", providerVdcUrn), queryParameters)
29+
return client.GetAllVgpuProfiles(queryParameters)
30+
}
31+
32+
// GetVgpuProfileById gets a vGPU profile by ID
33+
func (client *VCDClient) GetVgpuProfileById(vgpuProfileId string) (*VgpuProfile, error) {
34+
return getVgpuProfileById(vgpuProfileId, &client.Client)
35+
}
36+
37+
// GetVgpuProfileByName gets a vGPU profile by name
38+
func (client *VCDClient) GetVgpuProfileByName(vgpuProfileName string) (*VgpuProfile, error) {
39+
return getVgpuProfileByFilter("name", vgpuProfileName, &client.Client)
40+
}
41+
42+
// GetVgpuProfileByTenantFacingName gets a vGPU profile by its tenant facing name
43+
func (client *VCDClient) GetVgpuProfileByTenantFacingName(tenantFacingName string) (*VgpuProfile, error) {
44+
return getVgpuProfileByFilter("tenantFacingName", tenantFacingName, &client.Client)
45+
}
46+
47+
// Update updates a vGPU profile with new parameters
48+
func (profile *VgpuProfile) Update(newProfile *types.VgpuProfile) error {
49+
client := profile.client
50+
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVgpuProfile
51+
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
52+
if err != nil {
53+
return err
54+
}
55+
56+
urlRef, err := client.OpenApiBuildEndpoint(endpoint, "/", profile.VgpuProfile.Id)
57+
if err != nil {
58+
return err
59+
}
60+
61+
err = client.OpenApiPutItemSync(minimumApiVersion, urlRef, nil, newProfile, nil, nil)
62+
if err != nil {
63+
return err
64+
}
65+
66+
// We need to refresh here, as PUT returns the original struct instead of the updated one
67+
err = profile.Refresh()
68+
if err != nil {
69+
return err
70+
}
71+
72+
return nil
73+
}
74+
75+
// Refresh updates the current state of the vGPU profile
76+
func (profile *VgpuProfile) Refresh() error {
77+
var err error
78+
newProfile, err := getVgpuProfileById(profile.VgpuProfile.Id, profile.client)
79+
if err != nil {
80+
return err
81+
}
82+
profile.VgpuProfile = newProfile.VgpuProfile
83+
84+
return nil
85+
}
86+
87+
func getVgpuProfileByFilter(filter, filterValue string, client *Client) (*VgpuProfile, error) {
88+
queryParameters := url.Values{}
89+
queryParameters = queryParameterFilterAnd(fmt.Sprintf("%s==%s", filter, filterValue), queryParameters)
90+
vgpuProfiles, err := getAllVgpuProfiles(queryParameters, client)
91+
if err != nil {
92+
return nil, err
93+
}
94+
95+
vgpuProfile, err := oneOrError(filter, filterValue, vgpuProfiles)
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
return vgpuProfile, nil
101+
}
102+
103+
func getVgpuProfileById(vgpuProfileId string, client *Client) (*VgpuProfile, error) {
104+
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVgpuProfile
105+
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
106+
if err != nil {
107+
return nil, err
108+
}
109+
110+
urlRef, err := client.OpenApiBuildEndpoint(endpoint, "/", vgpuProfileId)
111+
if err != nil {
112+
return nil, err
113+
}
114+
115+
profile := &VgpuProfile{
116+
client: client,
117+
}
118+
err = client.OpenApiGetItem(minimumApiVersion, urlRef, nil, &profile.VgpuProfile, nil)
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
return profile, nil
124+
}
125+
126+
func getAllVgpuProfiles(queryParameters url.Values, client *Client) ([]*VgpuProfile, error) {
127+
endpoint := types.OpenApiPathVersion1_0_0 + types.OpenApiEndpointVgpuProfile
128+
minimumApiVersion, err := client.checkOpenApiEndpointCompatibility(endpoint)
129+
if err != nil {
130+
return nil, err
131+
}
132+
133+
urlRef, err := client.OpenApiBuildEndpoint(endpoint)
134+
if err != nil {
135+
return nil, err
136+
}
137+
138+
responses := []*types.VgpuProfile{{}}
139+
140+
err = client.OpenApiGetAllItems(minimumApiVersion, urlRef, queryParameters, &responses, nil)
141+
if err != nil {
142+
return nil, err
143+
}
144+
145+
wrappedVgpuProfiles := make([]*VgpuProfile, len(responses))
146+
for index, response := range responses {
147+
wrappedVgpuProfile := &VgpuProfile{
148+
client: client,
149+
VgpuProfile: response,
150+
}
151+
wrappedVgpuProfiles[index] = wrappedVgpuProfile
152+
}
153+
154+
return wrappedVgpuProfiles, nil
155+
}

types/v56/constants.go

+3
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@ const (
482482
OpenApiEndpointServiceAccountGrant = "deviceLookup/grant"
483483
OpenApiEndpointTokens = "tokens/"
484484
OpenApiEndpointServiceAccounts = "serviceAccounts/"
485+
486+
// OpenApiEndpointVgpuProfile is used to query vGPU profiles
487+
OpenApiEndpointVgpuProfile = "vgpuProfiles"
485488
)
486489

487490
// Header keys to run operations in tenant context

types/v56/openapi.go

+18
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ type VdcComputePolicyV2 struct {
221221
IsVgpuPolicy bool `json:"isVgpuPolicy,omitempty"`
222222
PvdcNamedVmGroupsMap []PvdcNamedVmGroupsMap `json:"pvdcNamedVmGroupsMap,omitempty"`
223223
PvdcLogicalVmGroupsMap []PvdcLogicalVmGroupsMap `json:"pvdcLogicalVmGroupsMap,omitempty"`
224+
PvdcVgpuClustersMap []PvdcVgpuClustersMap `json:"pvdcVgpuClustersMap,omitempty"`
225+
VgpuProfiles []VgpuProfile `json:"vgpuProfiles,omitempty"`
224226
}
225227

226228
// PvdcNamedVmGroupsMap is a combination of a reference to a Provider VDC and a list of references to Named VM Groups.
@@ -237,6 +239,11 @@ type PvdcLogicalVmGroupsMap struct {
237239
Pvdc OpenApiReference `json:"pvdc,omitempty"`
238240
}
239241

242+
type PvdcVgpuClustersMap struct {
243+
Clusters []string `json:"clusters,omitempty"`
244+
Pvdc OpenApiReference `json:"pvdc,omitempty"`
245+
}
246+
240247
// OpenApiReference is a generic reference type commonly used throughout OpenAPI endpoints
241248
type OpenApiReference struct {
242249
Name string `json:"name,omitempty"`
@@ -672,3 +679,14 @@ type OpenApiMetadataTypedValue struct {
672679
Value interface{} `json:"value,omitempty"` // The Value is anything because it depends on the Type field.
673680
Type string `json:"type,omitempty"`
674681
}
682+
683+
// VgpuProfile uniquely represents a type of vGPU
684+
// vGPU Profiles are fetched from your NVIDIA GRID GPU enabled Clusters in vCenter.
685+
type VgpuProfile struct {
686+
Id string `json:"id"`
687+
Name string `json:"name"`
688+
TenantFacingName string `json:"tenantFacingName"`
689+
Instructions string `json:"instructions,omitempty"`
690+
AllowMultiplePerVm bool `json:"allowMultiplePerVm"`
691+
Count int `json:"count,omitempty"`
692+
}

0 commit comments

Comments
 (0)