Skip to content

Commit

Permalink
chore: bump deps
Browse files Browse the repository at this point in the history
Updated dependencies

Signed-off-by: Serge Logvinov <serge.logvinov@sinextra.dev>
  • Loading branch information
sergelogvinov committed Jan 20, 2025
1 parent bb868bc commit ca452ad
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 59 deletions.
20 changes: 10 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ module github.com/sergelogvinov/proxmox-cloud-controller-manager
go 1.23.4

require (
github.com/Telmate/proxmox-api-go v0.0.0-20241127232213-af1f4e86b570
github.com/Telmate/proxmox-api-go v0.0.0-20250114172303-4e26f5d24311
github.com/jarcoal/httpmock v1.3.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.10.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.32.0
k8s.io/apimachinery v0.32.0
k8s.io/client-go v0.32.0
k8s.io/cloud-provider v0.32.0
k8s.io/component-base v0.32.0
k8s.io/api v0.32.1
k8s.io/apimachinery v0.32.1
k8s.io/client-go v0.32.1
k8s.io/cloud-provider v0.32.1
k8s.io/component-base v0.32.1
k8s.io/klog/v2 v2.130.1
)

Expand Down Expand Up @@ -98,10 +98,10 @@ require (
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
k8s.io/apiserver v0.32.0 // indirect
k8s.io/component-helpers v0.32.0 // indirect
k8s.io/controller-manager v0.32.0 // indirect
k8s.io/kms v0.32.0 // indirect
k8s.io/apiserver v0.32.1 // indirect
k8s.io/component-helpers v0.32.1 // indirect
k8s.io/controller-manager v0.32.1 // indirect
k8s.io/kms v0.32.1 // indirect
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 // indirect
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1 // indirect
Expand Down
40 changes: 20 additions & 20 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/Telmate/proxmox-api-go v0.0.0-20241127232213-af1f4e86b570 h1:Qln/bkARmiTMLgpQasFHo3NfeQ90dSALjeH41exbSV4=
github.com/Telmate/proxmox-api-go v0.0.0-20241127232213-af1f4e86b570/go.mod h1:Gu6n6vEn1hlyFUkjrvU+X1fdgaSXLoM9HKYYJqy1fsY=
github.com/Telmate/proxmox-api-go v0.0.0-20250114172303-4e26f5d24311 h1:3O5tLwJJNiGyRmIz5V58HldjWLue3fI1lLwVw715Fyk=
github.com/Telmate/proxmox-api-go v0.0.0-20250114172303-4e26f5d24311/go.mod h1:Gu6n6vEn1hlyFUkjrvU+X1fdgaSXLoM9HKYYJqy1fsY=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
Expand Down Expand Up @@ -275,26 +275,26 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs=
k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag=
k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8=
k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8=
k8s.io/cloud-provider v0.32.0 h1:QXYJGmwME2q2rprymbmw2GroMChQYc/MWN6l/I4Kgp8=
k8s.io/cloud-provider v0.32.0/go.mod h1:cz3gVodkhgwi2ugj/JUPglIruLSdDaThxawuDyCHfr8=
k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU=
k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM=
k8s.io/component-helpers v0.32.0 h1:pQEEBmRt3pDJJX98cQvZshDgJFeKRM4YtYkMmfOlczw=
k8s.io/component-helpers v0.32.0/go.mod h1:9RuClQatbClcokXOcDWSzFKQm1huIf0FzQlPRpizlMc=
k8s.io/controller-manager v0.32.0 h1:tpQl1rvH4huFB6Avl1nhowZHtZoCNWqn6OYdZPl7Ybc=
k8s.io/controller-manager v0.32.0/go.mod h1:JRuYnYCkKj3NgBTy+KNQKIUm/lJRoDAvGbfdEmk9LhY=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/apiserver v0.32.1 h1:oo0OozRos66WFq87Zc5tclUX2r0mymoVHRq8JmR7Aak=
k8s.io/apiserver v0.32.1/go.mod h1:UcB9tWjBY7aryeI5zAgzVJB/6k7E97bkr1RgqDz0jPw=
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
k8s.io/cloud-provider v0.32.1 h1:74rRhnfca3o4CsjjnIp/C3ARVuSmyNsxgWPtH0yc9Z0=
k8s.io/cloud-provider v0.32.1/go.mod h1:GECSanFT+EeZ/ToX3xlasjETzMUI+VFu92zHUDUsGHw=
k8s.io/component-base v0.32.1 h1:/5IfJ0dHIKBWysGV0yKTFfacZ5yNV1sulPh3ilJjRZk=
k8s.io/component-base v0.32.1/go.mod h1:j1iMMHi/sqAHeG5z+O9BFNCF698a1u0186zkjMZQ28w=
k8s.io/component-helpers v0.32.1 h1:TwdsSM1vW9GjnfX18lkrZbwE5G9psCIS2/rhenTDXd8=
k8s.io/component-helpers v0.32.1/go.mod h1:1JT1Ei3FD29yFQ18F3laj1WyvxYdHIhyxx6adKMFQXI=
k8s.io/controller-manager v0.32.1 h1:z3oQp1O5l0cSzM/MKf8V4olhJ9TmnELoJRPcV/v1s+Y=
k8s.io/controller-manager v0.32.1/go.mod h1:dVA1UZPbqHH4hEhrrnLvQ4d5qVQCklNB8GEzYV59v/4=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kms v0.32.0 h1:jwOfunHIrcdYl5FRcA+uUKKtg6qiqoPCwmS2T3XTYL4=
k8s.io/kms v0.32.0/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM=
k8s.io/kms v0.32.1 h1:TW6cswRI/fawoQRFGWLmEceO37rZXupdoRdmO019jCc=
k8s.io/kms v0.32.1/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
Expand Down
30 changes: 22 additions & 8 deletions pkg/cluster/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ limitations under the License.
package cluster

import (
"context"
"crypto/tls"
"encoding/base64"
"fmt"
Expand All @@ -27,6 +28,8 @@ import (
"strings"

pxapi "github.com/Telmate/proxmox-api-go/proxmox"

"k8s.io/klog/v2"
)

// Cluster is a Proxmox client.
Expand All @@ -53,7 +56,7 @@ func NewCluster(config *ClustersConfig, hclient *http.Client) (*Cluster, error)
}

if cfg.Username != "" && cfg.Password != "" {
if err := client.Login(cfg.Username, cfg.Password, ""); err != nil {
if err := client.Login(context.Background(), cfg.Username, cfg.Password, ""); err != nil {
return nil, err
}
} else {
Expand All @@ -73,11 +76,22 @@ func NewCluster(config *ClustersConfig, hclient *http.Client) (*Cluster, error)
}

// CheckClusters checks if the Proxmox connection is working.
func (c *Cluster) CheckClusters() error {
func (c *Cluster) CheckClusters(ctx context.Context) error {
for region, client := range c.proxmox {
if _, err := client.GetVersion(); err != nil {
if _, err := client.GetVersion(ctx); err != nil {
return fmt.Errorf("failed to initialized proxmox client in region %s, error: %v", region, err)
}

vms, err := client.GetVmList(ctx)
if err != nil {
return fmt.Errorf("failed to get list of VMs in region %s, error: %v", region, err)
}

if len(vms) > 0 {
klog.V(4).InfoS("Proxmox cluster has VMs", "region", region, "count", len(vms))
} else {
klog.InfoS("Proxmox cluster has no VMs, or check the account permission", "region", region)
}
}

return nil
Expand All @@ -93,9 +107,9 @@ func (c *Cluster) GetProxmoxCluster(region string) (*pxapi.Client, error) {
}

// FindVMByName find a VM by name in all Proxmox clusters.
func (c *Cluster) FindVMByName(name string) (*pxapi.VmRef, string, error) {
func (c *Cluster) FindVMByName(ctx context.Context, name string) (*pxapi.VmRef, string, error) {
for region, px := range c.proxmox {
vmr, err := px.GetVmRefByName(name)
vmr, err := px.GetVmRefByName(ctx, name)
if err != nil {
if strings.Contains(err.Error(), "not found") {
continue
Expand All @@ -111,9 +125,9 @@ func (c *Cluster) FindVMByName(name string) (*pxapi.VmRef, string, error) {
}

// FindVMByUUID find a VM by uuid in all Proxmox clusters.
func (c *Cluster) FindVMByUUID(uuid string) (*pxapi.VmRef, string, error) {
func (c *Cluster) FindVMByUUID(ctx context.Context, uuid string) (*pxapi.VmRef, string, error) {
for region, px := range c.proxmox {
vms, err := px.GetResourceList("vm")
vms, err := px.GetResourceList(ctx, "vm")
if err != nil {
return nil, "", fmt.Errorf("error get resources %v", err)
}
Expand All @@ -132,7 +146,7 @@ func (c *Cluster) FindVMByUUID(uuid string) (*pxapi.VmRef, string, error) {
vmr.SetNode(vm["node"].(string)) //nolint:errcheck
vmr.SetVmType("qemu")

config, err := px.GetVmConfig(vmr)
config, err := px.GetVmConfig(ctx, vmr)
if err != nil {
return nil, "", err
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/cluster/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package cluster_test

import (
"context"
"fmt"
"net/http"
"strings"
Expand Down Expand Up @@ -78,7 +79,7 @@ func TestCheckClusters(t *testing.T) {
assert.Nil(t, err)
assert.NotNil(t, pxapi)

err = client.CheckClusters()
err = client.CheckClusters(context.Background())
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "failed to initialized proxmox client in region")
}
Expand Down Expand Up @@ -125,7 +126,7 @@ func TestFindVMByNameNonExist(t *testing.T) {
assert.Nil(t, err)
assert.NotNil(t, client)

vmr, cluster, err := client.FindVMByName("non-existing-vm")
vmr, cluster, err := client.FindVMByName(context.Background(), "non-existing-vm")
assert.NotNil(t, err)
assert.Equal(t, "", cluster)
assert.Nil(t, vmr)
Expand Down Expand Up @@ -202,7 +203,7 @@ func TestFindVMByNameExist(t *testing.T) {
testCase := testCase

t.Run(fmt.Sprint(testCase.msg), func(t *testing.T) {
vmr, cluster, err := client.FindVMByName(testCase.vmName)
vmr, cluster, err := client.FindVMByName(context.Background(), testCase.vmName)

if testCase.expectedError == nil {
assert.Nil(t, err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/proxmox/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (c *cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder,
c.ctx = ctx
c.stop = cancel

err := c.client.CheckClusters()
err := c.client.CheckClusters(ctx)
if err != nil {
klog.ErrorS(err, "failed to check proxmox cluster")
}
Expand Down
36 changes: 19 additions & 17 deletions pkg/proxmox/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func newInstances(client *cluster.Cluster, provider cluster.Provider) *instances

// InstanceExists returns true if the instance for the given node exists according to the cloud provider.
// Use the node.name or node.spec.providerID field to find the node in the cloud provider.
func (i *instances) InstanceExists(_ context.Context, node *v1.Node) (bool, error) {
func (i *instances) InstanceExists(ctx context.Context, node *v1.Node) (bool, error) {
klog.V(4).InfoS("instances.InstanceExists() called", "node", klog.KRef("", node.Name))

if node.Spec.ProviderID == "" {
Expand All @@ -63,7 +63,7 @@ func (i *instances) InstanceExists(_ context.Context, node *v1.Node) (bool, erro
}

mc := metrics.NewMetricContext("getVmInfo")
if _, _, err := i.getInstance(node); mc.ObserveRequest(err) != nil {
if _, _, err := i.getInstance(ctx, node); mc.ObserveRequest(err) != nil {
if err == cloudprovider.InstanceNotFound {
klog.V(4).InfoS("instances.InstanceExists() instance not found", "node", klog.KObj(node), "providerID", node.Spec.ProviderID)

Expand All @@ -78,7 +78,7 @@ func (i *instances) InstanceExists(_ context.Context, node *v1.Node) (bool, erro

// InstanceShutdown returns true if the instance is shutdown according to the cloud provider.
// Use the node.name or node.spec.providerID field to find the node in the cloud provider.
func (i *instances) InstanceShutdown(_ context.Context, node *v1.Node) (bool, error) {
func (i *instances) InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) {
klog.V(4).InfoS("instances.InstanceShutdown() called", "node", klog.KRef("", node.Name))

if node.Spec.ProviderID == "" {
Expand Down Expand Up @@ -109,7 +109,7 @@ func (i *instances) InstanceShutdown(_ context.Context, node *v1.Node) (bool, er

mc := metrics.NewMetricContext("getVmState")

vmState, err := px.GetVmState(vmr)
vmState, err := px.GetVmState(ctx, vmr)
if mc.ObserveRequest(err) != nil {
return false, err
}
Expand All @@ -124,7 +124,7 @@ func (i *instances) InstanceShutdown(_ context.Context, node *v1.Node) (bool, er
// InstanceMetadata returns the instance's metadata. The values returned in InstanceMetadata are
// translated into specific fields in the Node object on registration.
// Use the node.name or node.spec.providerID field to find the node in the cloud provider.
func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) {
func (i *instances) InstanceMetadata(ctx context.Context, node *v1.Node) (*cloudprovider.InstanceMetadata, error) {
klog.V(4).InfoS("instances.InstanceMetadata() called", "node", klog.KRef("", node.Name))

if providedIP, ok := node.ObjectMeta.Annotations[cloudproviderapi.AnnotationAlphaProvidedIPAddr]; ok {
Expand All @@ -142,11 +142,11 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr

mc := metrics.NewMetricContext("findVmByName")

vmRef, region, err = i.c.FindVMByName(node.Name)
vmRef, region, err = i.c.FindVMByName(ctx, node.Name)
if mc.ObserveRequest(err) != nil {
mc := metrics.NewMetricContext("findVmByUUID")

vmRef, region, err = i.c.FindVMByUUID(uuid)
vmRef, region, err = i.c.FindVMByUUID(ctx, uuid)
if mc.ObserveRequest(err) != nil {
return nil, fmt.Errorf("instances.InstanceMetadata() - failed to find instance by name/uuid %s: %v, skipped", node.Name, err)
}
Expand All @@ -166,7 +166,7 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
if vmRef == nil {
mc := metrics.NewMetricContext("getVmInfo")

vmRef, region, err = i.getInstance(node)
vmRef, region, err = i.getInstance(ctx, node)
if mc.ObserveRequest(err) != nil {
return nil, err
}
Expand All @@ -180,7 +180,7 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr

addresses = append(addresses, v1.NodeAddress{Type: v1.NodeHostName, Address: node.Name})

instanceType, err := i.getInstanceType(vmRef, region)
instanceType, err := i.getInstanceType(ctx, vmRef, region)
if err != nil {
instanceType = vmRef.GetVmType()
}
Expand All @@ -189,7 +189,7 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
ProviderID: providerID,
NodeAddresses: addresses,
InstanceType: instanceType,
Zone: vmRef.Node(),
Zone: vmRef.Node().String(),
Region: region,
}, nil
}
Expand All @@ -199,19 +199,21 @@ func (i *instances) InstanceMetadata(_ context.Context, node *v1.Node) (*cloudpr
return &cloudprovider.InstanceMetadata{}, nil
}

func (i *instances) getInstance(node *v1.Node) (*pxapi.VmRef, string, error) {
func (i *instances) getInstance(ctx context.Context, node *v1.Node) (*pxapi.VmRef, string, error) {
klog.V(4).InfoS("instances.getInstance() called", "node", klog.KRef("", node.Name), "provider", i.provider)

if i.provider == cluster.ProviderCapmox {
uuid := node.Status.NodeInfo.SystemUUID

vmRef, region, err := i.c.FindVMByUUID(uuid)
vmRef, region, err := i.c.FindVMByUUID(ctx, uuid)
if err != nil {
return nil, "", fmt.Errorf("instances.getInstance() error: %v", err)
}

return vmRef, region, nil
}

vm, region, err := provider.ParseProviderID(node.Spec.ProviderID)
vmRef, region, err := provider.ParseProviderID(node.Spec.ProviderID)
if err != nil {
return nil, "", fmt.Errorf("instances.getInstance() error: %v", err)
}
Expand All @@ -223,7 +225,7 @@ func (i *instances) getInstance(node *v1.Node) (*pxapi.VmRef, string, error) {

mc := metrics.NewMetricContext("getVmInfo")

vmInfo, err := px.GetVmInfo(vm)
vmInfo, err := px.GetVmInfo(ctx, vmRef)
if mc.ObserveRequest(err) != nil {
if strings.Contains(err.Error(), "not found") {
return nil, "", cloudprovider.InstanceNotFound
Expand All @@ -238,18 +240,18 @@ func (i *instances) getInstance(node *v1.Node) (*pxapi.VmRef, string, error) {

klog.V(5).Infof("instances.getInstance() vmInfo %+v", vmInfo)

return vm, region, nil
return vmRef, region, nil
}

func (i *instances) getInstanceType(vmRef *pxapi.VmRef, region string) (string, error) {
func (i *instances) getInstanceType(ctx context.Context, vmRef *pxapi.VmRef, region string) (string, error) {
px, err := i.c.GetProxmoxCluster(region)
if err != nil {
return "", err
}

mc := metrics.NewMetricContext("getVmInfo")

vmInfo, err := px.GetVmInfo(vmRef)
vmInfo, err := px.GetVmInfo(ctx, vmRef)
if mc.ObserveRequest(err) != nil {
return "", err
}
Expand Down

0 comments on commit ca452ad

Please sign in to comment.