Skip to content

Instantly share code, notes, and snippets.

@sneal
Created August 11, 2022 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sneal/d512b0f5f3c64459fd41fb2b5d5f1b2a to your computer and use it in GitHub Desktop.
Save sneal/d512b0f5f3c64459fd41fb2b5d5f1b2a to your computer and use it in GitHub Desktop.
Set vSphere EVC mode on a VM using govmomi
package main
import (
"context"
"fmt"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"net/url"
"os"
)
func main() {
err := doThings(context.Background(), "vc01", "vc01cl01", "vm-428bbf39-c769-4b31-a362-dfe07bd8f7f5", "intel-sandybridge")
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "error: %s\n", err)
os.Exit(1)
}
fmt.Println("done")
}
func doThings(ctx context.Context, dc, cluster, vm, evcMode string) error {
c, err := createClient(ctx)
if err != nil {
return err
}
// find the VM
finder := find.NewFinder(c.Client)
dcObj, err := finder.Datacenter(ctx, dc)
finder.SetDatacenter(dcObj)
vmObj, err := finder.VirtualMachine(ctx, vm)
if err != nil {
return fmt.Errorf("failed to find virtual machine %s: %w", vm, err)
}
// make sure it's powered off
ps, err := vmObj.PowerState(ctx)
if err != nil {
return err
}
if ps != types.VirtualMachinePowerStatePoweredOff {
return fmt.Errorf("error virtual machine %s is not powered off", vm)
}
// find a cluster
clusterObj, err := find.NewFinder(c.Client).ClusterComputeResourceOrDefault(ctx, cluster)
if err != nil {
return err
}
// get it's EVC manager
evcMgrRes, err := methods.EvcManager(ctx, c.RoundTripper, &types.EvcManager{
This: clusterObj.Reference(),
})
if err != nil {
return err
}
var evcMgr mo.ClusterEVCManager
pc := property.DefaultCollector(c.Client)
err = pc.RetrieveOne(ctx, *evcMgrRes.Returnval, nil, &evcMgr)
if err != nil {
return err
}
// build a list of target EVC mode feature flags
var masks []types.HostFeatureMask
for _, e := range evcMgr.EvcState.SupportedEVCMode {
if e.ElementDescription.Key == evcMode {
masks = e.FeatureMask
break
}
}
if len(masks) == 0 {
return fmt.Errorf("error finding EVC feature masks for %s", evcMode)
}
isComplete := true
req := types.ApplyEvcModeVM_Task{
This: vmObj.Reference(),
Mask: masks,
CompleteMasks: &isComplete,
}
// apply the EVC mode to the VM
applyEvcRes, err := methods.ApplyEvcModeVM_Task(ctx, c.Client, &req)
if err != nil {
return err
}
t := object.NewTask(c.Client, applyEvcRes.Returnval)
return t.Wait(ctx)
}
func createClient(ctx context.Context) (*govmomi.Client, error) {
u := &url.URL{
Scheme: "https",
Host: os.Getenv("GOVC_URL"),
Path: "/sdk",
}
u.User = url.UserPassword(os.Getenv("GOVC_USERNAME"), os.Getenv("GOVC_PASSWORD"))
soapClient := soap.NewClient(u, true)
vimClient, err := vim25.NewClient(ctx, soapClient)
if err != nil {
return nil, fmt.Errorf("could not create new vim25 govmomi client: %w", err)
}
m := session.NewManager(vimClient)
err = m.Login(ctx, u.User)
if err != nil {
return nil, fmt.Errorf("could not login via vim25 session manager: %w", err)
}
c := &govmomi.Client{
Client: vimClient,
SessionManager: m,
}
return c, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment