diff --git a/go.mod b/go.mod index eb95dd81f2..cf27e821dd 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/pkg/sftp v1.13.6 github.com/prometheus/client_golang v1.22.0 github.com/stretchr/testify v1.10.0 - github.com/vmware-tanzu/vm-operator/api v1.9.1-0.20250923172217-bf5a74e51c65 + github.com/vmware-tanzu/vm-operator/api v1.8.7-0.20250509154507-b93e51fc90fa github.com/vmware-tanzu/vm-operator/external/byok v0.0.0-20250509154507-b93e51fc90fa github.com/vmware/govmomi v0.52.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index 5dc7727dab..eeeb3f6d54 100644 --- a/go.sum +++ b/go.sum @@ -287,8 +287,8 @@ github.com/thecodeteam/gofsutil v0.1.2 h1:FL87mBzZeeuDMZm8hpYLFcYylQdq6bbm8UQ1oc github.com/thecodeteam/gofsutil v0.1.2/go.mod h1:7bDOpr2aMnmdm9RTdxBEeqdOr+8RpnQhsB/VUEI3DgM= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= -github.com/vmware-tanzu/vm-operator/api v1.9.1-0.20250923172217-bf5a74e51c65 h1:oby5iJHxU5KgtajXxT8B8VxUUPH20Zh0KTYlI+18AYs= -github.com/vmware-tanzu/vm-operator/api v1.9.1-0.20250923172217-bf5a74e51c65/go.mod h1:nWTPpxfe4gHuuYuFcrs86+NMxfkqPk3a3IlvI8TCWak= +github.com/vmware-tanzu/vm-operator/api v1.8.7-0.20250509154507-b93e51fc90fa h1:LRfm1EMc+L96FzMOwujwbifo6pd/dkBJ4QhofuYNzBw= +github.com/vmware-tanzu/vm-operator/api v1.8.7-0.20250509154507-b93e51fc90fa/go.mod h1:V0JbH4beGCU+q7yqnWUYYOuDij0ut5i1iBO4cyzg+tM= github.com/vmware-tanzu/vm-operator/external/byok v0.0.0-20250509154507-b93e51fc90fa h1:4MKu14YJ7J54O6QKmT4ds5EUpysWLLtQRMff73cVkmU= github.com/vmware-tanzu/vm-operator/external/byok v0.0.0-20250509154507-b93e51fc90fa/go.mod h1:8tiuyYslzjLIUmOlXZuGKQdQP2ZgWGCVhVeyptmZYnk= github.com/vmware/govmomi v0.52.0 h1:JyxQ1IQdllrY7PJbv2am9mRsv3p9xWlIQ66bv+XnyLw= diff --git a/pkg/common/utils/utils.go b/pkg/common/utils/utils.go index 56a1ecb045..ef632165df 100644 --- a/pkg/common/utils/utils.go +++ b/pkg/common/utils/utils.go @@ -26,7 +26,6 @@ import ( vmoperatorv1alpha2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" vmoperatorv1alpha3 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" vmoperatorv1alpha4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" - vmoperatorv1alpha5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" cnstypes "github.com/vmware/govmomi/cns/types" "google.golang.org/grpc/codes" "k8s.io/apimachinery/pkg/types" @@ -54,7 +53,7 @@ var getLatestCRDVersion = kubernetes.GetLatestCRDVersion // Since, VM Operator converts all the older API versions to the latest version, // this function determines the latest API version of the VirtualMachine CRD and lists the resources. func ListVirtualMachines(ctx context.Context, clt client.Client, - namespace string) (*vmoperatorv1alpha5.VirtualMachineList, error) { + namespace string) (*vmoperatorv1alpha4.VirtualMachineList, error) { log := logger.GetLogger(ctx) version, err := getLatestCRDVersion(ctx, virtualMachineCRDName) @@ -63,7 +62,7 @@ func ListVirtualMachines(ctx context.Context, clt client.Client, return nil, err } - vmList := &vmoperatorv1alpha5.VirtualMachineList{} + vmList := &vmoperatorv1alpha4.VirtualMachineList{} log.Info("Attempting to list virtual machines with the latest API version ", version) switch version { case "v1alpha1": @@ -74,10 +73,10 @@ func ListVirtualMachines(ctx context.Context, clt client.Client, return nil, err } - err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachineList_To_v1alpha5_VirtualMachineList( + err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachineList_To_v1alpha4_VirtualMachineList( vmAlpha1List, vmList, nil) if err != nil { - log.Fatal("Error converting v1alpha1 virtual machines to v1alpha5: ", err) + log.Fatal("Error converting v1alpha1 virtual machines to v1alpha4: ", err) return nil, err } case "v1alpha2": @@ -88,10 +87,10 @@ func ListVirtualMachines(ctx context.Context, clt client.Client, return nil, err } - err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachineList_To_v1alpha5_VirtualMachineList( + err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachineList_To_v1alpha4_VirtualMachineList( vmAlpha2List, vmList, nil) if err != nil { - log.Fatal("Error converting v1alpha2 virtual machines to v1alpha5: ", err) + log.Fatal("Error converting v1alpha2 virtual machines to v1alpha4: ", err) return nil, err } case "v1alpha3": @@ -102,23 +101,10 @@ func ListVirtualMachines(ctx context.Context, clt client.Client, return nil, err } - err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachineList_To_v1alpha5_VirtualMachineList( + err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachineList_To_v1alpha4_VirtualMachineList( vmAlpha3List, vmList, nil) if err != nil { - log.Error("Error converting v1alpha3 virtual machines to v1alpha5: ", err) - return nil, err - } - case "v1alpha4": - vmAlpha4List := &vmoperatorv1alpha4.VirtualMachineList{} - err := clt.List(ctx, vmAlpha4List, client.InNamespace(namespace)) - if err != nil { - log.Error("failed listing virtual machines for v1alpha4: ", err) - return nil, err - } - err = vmoperatorv1alpha4.Convert_v1alpha4_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmAlpha4List, vmList, nil) - if err != nil { - log.Error("Error converting v1alpha4 virtual machines to v1alpha5: ", err) + log.Error("Error converting v1alpha3 virtual machines to v1alpha4: ", err) return nil, err } default: @@ -365,67 +351,54 @@ func QueryAllVolumesForCluster(ctx context.Context, m cnsvolume.Manager, cluster } func GetVirtualMachineAllApiVersions(ctx context.Context, vmKey types.NamespacedName, - vmOperatorClient client.Client) (*vmoperatorv1alpha5.VirtualMachine, string, error) { + vmOperatorClient client.Client) (*vmoperatorv1alpha4.VirtualMachine, string, error) { log := logger.GetLogger(ctx) vmV1alpha1 := &vmoperatorv1alpha1.VirtualMachine{} vmV1alpha2 := &vmoperatorv1alpha2.VirtualMachine{} vmV1alpha3 := &vmoperatorv1alpha3.VirtualMachine{} - vmV1alpha4 := &vmoperatorv1alpha4.VirtualMachine{} - vm := &vmoperatorv1alpha5.VirtualMachine{} + vm := &vmoperatorv1alpha4.VirtualMachine{} var err error - log.Infof("get machine with vm-operator api version v1alpha5 name: %s, namespace: %s", + log.Infof("get machine with vm-operator api version v1alpha4 name: %s, namespace: %s", vmKey.Name, vmKey.Namespace) - apiVersion := vmOperatorApiVersionPrefix + "/v1alpha5" + apiVersion := vmOperatorApiVersionPrefix + "/v1alpha4" err = vmOperatorClient.Get(ctx, vmKey, vm) if err != nil && isKindNotFound(err.Error()) { - err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha4) + log.Warnf("failed to get VirtualMachines. %s", err.Error()) + err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha3) if err != nil && isKindNotFound(err.Error()) { log.Warnf("failed to get VirtualMachines. %s", err.Error()) - err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha3) + err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha2) if err != nil && isKindNotFound(err.Error()) { log.Warnf("failed to get VirtualMachines. %s", err.Error()) - err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha2) + err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha1) if err != nil && isKindNotFound(err.Error()) { log.Warnf("failed to get VirtualMachines. %s", err.Error()) - err = vmOperatorClient.Get(ctx, vmKey, vmV1alpha1) - if err != nil && isKindNotFound(err.Error()) { - log.Warnf("failed to get VirtualMachines. %s", err.Error()) - } else if err == nil { - log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha1 VirtualMachine "+ - "to v1alpha5 VirtualMachine, name %s", vmV1alpha1.Name) - apiVersion = vmOperatorApiVersionPrefix + "/v1alpha1" - err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachine_To_v1alpha5_VirtualMachine( - vmV1alpha1, vm, nil) - if err != nil { - return nil, apiVersion, err - } - } } else if err == nil { - log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha2 VirtualMachine "+ - "to v1alpha5 VirtualMachine, name %s", vmV1alpha2.Name) - apiVersion = vmOperatorApiVersionPrefix + "/v1alpha2" - err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachine_To_v1alpha5_VirtualMachine( - vmV1alpha2, vm, nil) + log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha1 VirtualMachine "+ + "to v1alpha4 VirtualMachine, name %s", vmV1alpha1.Name) + apiVersion = vmOperatorApiVersionPrefix + "/v1alpha1" + err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachine_To_v1alpha4_VirtualMachine( + vmV1alpha1, vm, nil) if err != nil { return nil, apiVersion, err } } } else if err == nil { - log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha3 VirtualMachine "+ - "to v1alpha5 VirtualMachine, name %s", vmV1alpha3.Name) - apiVersion = vmOperatorApiVersionPrefix + "/v1alpha3" - err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachine_To_v1alpha5_VirtualMachine( - vmV1alpha3, vm, nil) + log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha2 VirtualMachine "+ + "to v1alpha4 VirtualMachine, name %s", vmV1alpha2.Name) + apiVersion = vmOperatorApiVersionPrefix + "/v1alpha2" + err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachine_To_v1alpha4_VirtualMachine( + vmV1alpha2, vm, nil) if err != nil { return nil, apiVersion, err } } } else if err == nil { - log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha4 VirtualMachine "+ - "to v1alpha5 VirtualMachine, name %s", vmV1alpha4.Name) - apiVersion = vmOperatorApiVersionPrefix + "/v1alpha4" - err = vmoperatorv1alpha4.Convert_v1alpha5_VirtualMachine_To_v1alpha4_VirtualMachine( - vm, vmV1alpha4, nil) + log.Debugf("GetVirtualMachineAllApiVersions: converting v1alpha3 VirtualMachine "+ + "to v1alpha4 VirtualMachine, name %s", vmV1alpha3.Name) + apiVersion = vmOperatorApiVersionPrefix + "/v1alpha3" + err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachine_To_v1alpha4_VirtualMachine( + vmV1alpha3, vm, nil) if err != nil { return nil, apiVersion, err } @@ -437,7 +410,7 @@ func GetVirtualMachineAllApiVersions(ctx context.Context, vmKey types.Namespaced return nil, apiVersion, err } log.Infof("successfully fetched the virtual machines with name %s and namespace %s", - vmKey.Name, vmKey.Namespace) + vm.Name, vm.Namespace) return vm, apiVersion, nil } func isKindNotFound(errMsg string) bool { @@ -445,13 +418,12 @@ func isKindNotFound(errMsg string) bool { } func PatchVirtualMachine(ctx context.Context, vmOperatorClient client.Client, - vm, old_vm *vmoperatorv1alpha5.VirtualMachine) error { + vm, old_vm *vmoperatorv1alpha4.VirtualMachine) error { log := logger.GetLogger(ctx) vmV1alpha1, old_vmV1alpha1 := &vmoperatorv1alpha1.VirtualMachine{}, &vmoperatorv1alpha1.VirtualMachine{} vmV1alpha2, old_vmV1alpha2 := &vmoperatorv1alpha2.VirtualMachine{}, &vmoperatorv1alpha2.VirtualMachine{} vmV1alpha3, old_vmV1alpha3 := &vmoperatorv1alpha3.VirtualMachine{}, &vmoperatorv1alpha3.VirtualMachine{} - vmV1alpha4, old_vmV1alpha4 := &vmoperatorv1alpha4.VirtualMachine{}, &vmoperatorv1alpha4.VirtualMachine{} - log.Infof("PatchVirtualMachine: patch virtualmachine name: %s", vmV1alpha4.Name) + log.Infof("PatchVirtualMachine: patch virtualmachine name: %s", vm.Name) // try patch virtualmachine with latest api version vmPatch := client.MergeFromWithOptions( old_vm.DeepCopy(), @@ -459,73 +431,56 @@ func PatchVirtualMachine(ctx context.Context, vmOperatorClient client.Client, err := vmOperatorClient.Patch(ctx, vm, vmPatch) if err != nil && isKindNotFound(err.Error()) { log.Infof("PatchVirtualMachine: converting VirtualMachine to "+ - "v1alpha4 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha4.Convert_v1alpha5_VirtualMachine_To_v1alpha4_VirtualMachine( - vm, vmV1alpha4, nil) + "v1alpha3 VirtualMachine, name: %s", vm.Name) + err = vmoperatorv1alpha3.Convert_v1alpha4_VirtualMachine_To_v1alpha3_VirtualMachine( + vm, vmV1alpha3, nil) if err != nil { return err } - err = vmoperatorv1alpha4.Convert_v1alpha5_VirtualMachine_To_v1alpha4_VirtualMachine( - old_vm, old_vmV1alpha4, nil) + err = vmoperatorv1alpha3.Convert_v1alpha4_VirtualMachine_To_v1alpha3_VirtualMachine( + old_vm, old_vmV1alpha3, nil) if err != nil { return err } - vmPatch4 := client.MergeFromWithOptions(old_vmV1alpha4.DeepCopy(), + vmPatch3 := client.MergeFromWithOptions(old_vmV1alpha3.DeepCopy(), client.MergeFromWithOptimisticLock{}) - err := vmOperatorClient.Patch(ctx, vmV1alpha4, vmPatch4) + err = vmOperatorClient.Patch(ctx, vmV1alpha3, vmPatch3) if err != nil && isKindNotFound(err.Error()) { log.Infof("PatchVirtualMachine: converting VirtualMachine to "+ - "v1alpha3 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha3.Convert_v1alpha5_VirtualMachine_To_v1alpha3_VirtualMachine( - vm, vmV1alpha3, nil) + "v1alpha2 VirtualMachine, name: %s", vm.Name) + err = vmoperatorv1alpha2.Convert_v1alpha4_VirtualMachine_To_v1alpha2_VirtualMachine( + vm, vmV1alpha2, nil) if err != nil { return err } - err = vmoperatorv1alpha3.Convert_v1alpha5_VirtualMachine_To_v1alpha3_VirtualMachine( - old_vm, old_vmV1alpha3, nil) + err = vmoperatorv1alpha2.Convert_v1alpha4_VirtualMachine_To_v1alpha2_VirtualMachine( + old_vm, old_vmV1alpha2, nil) if err != nil { return err } - vmPatch3 := client.MergeFromWithOptions(old_vmV1alpha3.DeepCopy(), + vmPatch2 := client.MergeFromWithOptions(old_vmV1alpha2.DeepCopy(), client.MergeFromWithOptimisticLock{}) - err = vmOperatorClient.Patch(ctx, vmV1alpha3, vmPatch3) + // try patch virtualmachine with api version v1alpha2 + err := vmOperatorClient.Patch(ctx, vmV1alpha2, vmPatch2) if err != nil && isKindNotFound(err.Error()) { log.Infof("PatchVirtualMachine: converting VirtualMachine to "+ - "v1alpha2 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha2.Convert_v1alpha5_VirtualMachine_To_v1alpha2_VirtualMachine( - vm, vmV1alpha2, nil) + "v1alpha1 VirtualMachine, name: %s", vm.Name) + err = vmoperatorv1alpha1.Convert_v1alpha4_VirtualMachine_To_v1alpha1_VirtualMachine( + vm, vmV1alpha1, nil) if err != nil { return err } - err = vmoperatorv1alpha2.Convert_v1alpha5_VirtualMachine_To_v1alpha2_VirtualMachine( - old_vm, old_vmV1alpha2, nil) + err = vmoperatorv1alpha1.Convert_v1alpha4_VirtualMachine_To_v1alpha1_VirtualMachine( + old_vm, old_vmV1alpha1, nil) if err != nil { return err } - vmPatch2 := client.MergeFromWithOptions(old_vmV1alpha2.DeepCopy(), + vmPatch1 := client.MergeFromWithOptions(old_vmV1alpha1.DeepCopy(), client.MergeFromWithOptimisticLock{}) - // try patch virtualmachine with api version v1alpha2 - err := vmOperatorClient.Patch(ctx, vmV1alpha2, vmPatch2) - if err != nil && isKindNotFound(err.Error()) { - log.Infof("PatchVirtualMachine: converting VirtualMachine to "+ - "v1alpha1 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha1.Convert_v1alpha5_VirtualMachine_To_v1alpha1_VirtualMachine( - vm, vmV1alpha1, nil) - if err != nil { - return err - } - err = vmoperatorv1alpha1.Convert_v1alpha5_VirtualMachine_To_v1alpha1_VirtualMachine( - old_vm, old_vmV1alpha1, nil) - if err != nil { - return err - } - vmPatch1 := client.MergeFromWithOptions(old_vmV1alpha1.DeepCopy(), - client.MergeFromWithOptimisticLock{}) - // try patch virtualmachine with api version v1alpha1 - err := vmOperatorClient.Patch(ctx, vmV1alpha1, vmPatch1) - if err != nil { - return err - } + // try patch virtualmachine with api version v1alpha1 + err := vmOperatorClient.Patch(ctx, vmV1alpha1, vmPatch1) + if err != nil { + return err } } } @@ -540,56 +495,45 @@ func PatchVirtualMachine(ctx context.Context, vmOperatorClient client.Client, } func UpdateVirtualMachine(ctx context.Context, vmOperatorClient client.Client, - vm *vmoperatorv1alpha5.VirtualMachine) error { + vm *vmoperatorv1alpha4.VirtualMachine) error { vmV1alpha1 := &vmoperatorv1alpha1.VirtualMachine{} vmV1alpha2 := &vmoperatorv1alpha2.VirtualMachine{} vmV1alpha3 := &vmoperatorv1alpha3.VirtualMachine{} - vmV1alpha4 := &vmoperatorv1alpha4.VirtualMachine{} log := logger.GetLogger(ctx) log.Infof("UpdateVirtualMachine: update virtualmachine name: %s", vm.Name) // try update virtualmachine with api version v1alpha4 err := vmOperatorClient.Update(ctx, vm) if err != nil && isKindNotFound(err.Error()) { log.Infof("UpdateVirtualMachine: converting VirtualMachine to "+ - "v1alpha4 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha4.Convert_v1alpha5_VirtualMachine_To_v1alpha4_VirtualMachine( - vm, vmV1alpha4, nil) + "v1alpha3 VirtualMachine, name: %s", vm.Name) + err = vmoperatorv1alpha3.Convert_v1alpha4_VirtualMachine_To_v1alpha3_VirtualMachine( + vm, vmV1alpha3, nil) if err != nil { return err } - err = vmOperatorClient.Update(ctx, vmV1alpha4) + err := vmOperatorClient.Update(ctx, vmV1alpha3) if err != nil && isKindNotFound(err.Error()) { log.Infof("UpdateVirtualMachine: converting VirtualMachine to "+ - "v1alpha3 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha3.Convert_v1alpha5_VirtualMachine_To_v1alpha3_VirtualMachine( - vm, vmV1alpha3, nil) + "v1alpha2 VirtualMachine, name: %s", vm.Name) + err = vmoperatorv1alpha2.Convert_v1alpha4_VirtualMachine_To_v1alpha2_VirtualMachine( + vm, vmV1alpha2, nil) if err != nil { return err } - err := vmOperatorClient.Update(ctx, vmV1alpha3) + // try update virtualmachine with api version v1alpha2 + err := vmOperatorClient.Update(ctx, vmV1alpha2) if err != nil && isKindNotFound(err.Error()) { log.Infof("UpdateVirtualMachine: converting VirtualMachine to "+ - "v1alpha2 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha2.Convert_v1alpha5_VirtualMachine_To_v1alpha2_VirtualMachine( - vm, vmV1alpha2, nil) + "v1alpha1 VirtualMachine, name: %s", vm.Name) + err = vmoperatorv1alpha1.Convert_v1alpha4_VirtualMachine_To_v1alpha1_VirtualMachine( + vm, vmV1alpha1, nil) if err != nil { return err } - // try update virtualmachine with api version v1alpha2 - err := vmOperatorClient.Update(ctx, vmV1alpha2) - if err != nil && isKindNotFound(err.Error()) { - log.Infof("UpdateVirtualMachine: converting VirtualMachine to "+ - "v1alpha1 VirtualMachine, name: %s", vm.Name) - err = vmoperatorv1alpha1.Convert_v1alpha5_VirtualMachine_To_v1alpha1_VirtualMachine( - vm, vmV1alpha1, nil) - if err != nil { - return err - } - // try update virtualmachine with api version v1alpha1 - err := vmOperatorClient.Update(ctx, vmV1alpha1) - if err != nil { - return err - } + // try update virtualmachine with api version v1alpha1 + err := vmOperatorClient.Update(ctx, vmV1alpha1) + if err != nil { + return err } } } @@ -605,56 +549,45 @@ func UpdateVirtualMachine(ctx context.Context, vmOperatorClient client.Client, // GetVirtualMachineListAllApiVersions get lists of all the virtual machines func GetVirtualMachineListAllApiVersions(ctx context.Context, namespace string, - vmOperatorClient client.Client) (*vmoperatorv1alpha5.VirtualMachineList, error) { + vmOperatorClient client.Client) (*vmoperatorv1alpha4.VirtualMachineList, error) { log := logger.GetLogger(ctx) vmListV1alpha1 := &vmoperatorv1alpha1.VirtualMachineList{} vmListV1alpha2 := &vmoperatorv1alpha2.VirtualMachineList{} vmListV1alpha3 := &vmoperatorv1alpha3.VirtualMachineList{} vmListV1alpha4 := &vmoperatorv1alpha4.VirtualMachineList{} - vmListV1alpha5 := &vmoperatorv1alpha5.VirtualMachineList{} var err error if namespace != "" { // get list of virtualmachine for specific namespace log.Infof("list virtualmachines for namespace %s", namespace) - err = vmOperatorClient.List(ctx, vmListV1alpha5, client.InNamespace(namespace)) + err = vmOperatorClient.List(ctx, vmListV1alpha4, client.InNamespace(namespace)) if err != nil && isKindNotFound(err.Error()) { - err = vmOperatorClient.List(ctx, vmListV1alpha4, client.InNamespace(namespace)) + err = vmOperatorClient.List(ctx, vmListV1alpha3, client.InNamespace(namespace)) if err != nil && isKindNotFound(err.Error()) { - err = vmOperatorClient.List(ctx, vmListV1alpha3, client.InNamespace(namespace)) + err := vmOperatorClient.List(ctx, vmListV1alpha2, client.InNamespace(namespace)) if err != nil && isKindNotFound(err.Error()) { - err := vmOperatorClient.List(ctx, vmListV1alpha2, client.InNamespace(namespace)) - if err != nil && isKindNotFound(err.Error()) { - err := vmOperatorClient.List(ctx, vmListV1alpha1, client.InNamespace(namespace)) - if err != nil { - return nil, err - } else { - log.Info("converting v1alpha1 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha1, vmListV1alpha5, nil) - if err != nil { - return nil, err - } - } - } else if err == nil { - log.Info("converting v1alpha2 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha2, vmListV1alpha5, nil) + err := vmOperatorClient.List(ctx, vmListV1alpha1, client.InNamespace(namespace)) + if err != nil { + return nil, err + } else { + log.Info("converting v1alpha1 VirtualMachineList to v1alpha4 VirtualMachineList") + err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachineList_To_v1alpha4_VirtualMachineList( + vmListV1alpha1, vmListV1alpha4, nil) if err != nil { return nil, err } } } else if err == nil { - log.Info("converting v1alpha3 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha3, vmListV1alpha5, nil) + log.Info("converting v1alpha2 VirtualMachineList to v1alpha4 VirtualMachineList") + err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachineList_To_v1alpha4_VirtualMachineList( + vmListV1alpha2, vmListV1alpha4, nil) if err != nil { return nil, err } } - } else if err != nil { - log.Info("converting v1alpha4 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha4.Convert_v1alpha4_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha4, vmListV1alpha5, nil) + } else if err == nil { + log.Info("converting v1alpha3 VirtualMachineList to v1alpha4 VirtualMachineList") + err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachineList_To_v1alpha4_VirtualMachineList( + vmListV1alpha3, vmListV1alpha4, nil) if err != nil { return nil, err } @@ -663,45 +596,35 @@ func GetVirtualMachineListAllApiVersions(ctx context.Context, namespace string, } else { // get list of virtualmachine without providing namespace (all) log.Info("list all virtualmachines") - err = vmOperatorClient.List(ctx, vmListV1alpha5) + err = vmOperatorClient.List(ctx, vmListV1alpha4) if err != nil && isKindNotFound(err.Error()) { - err = vmOperatorClient.List(ctx, vmListV1alpha4) + err = vmOperatorClient.List(ctx, vmListV1alpha3) if err != nil && isKindNotFound(err.Error()) { - err = vmOperatorClient.List(ctx, vmListV1alpha3) + err := vmOperatorClient.List(ctx, vmListV1alpha2) if err != nil && isKindNotFound(err.Error()) { - err := vmOperatorClient.List(ctx, vmListV1alpha2) - if err != nil && isKindNotFound(err.Error()) { - err := vmOperatorClient.List(ctx, vmListV1alpha1) - if err != nil { - return nil, err - } else { - log.Info("converting v1alpha1 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha1, vmListV1alpha5, nil) - if err != nil { - return nil, err - } - } - } else if err == nil { - log.Info("converting v1alpha2 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha2, vmListV1alpha5, nil) + err := vmOperatorClient.List(ctx, vmListV1alpha1) + if err != nil { + return nil, err + } else { + log.Info("converting v1alpha1 VirtualMachineList to v1alpha4 VirtualMachineList") + err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachineList_To_v1alpha4_VirtualMachineList( + vmListV1alpha1, vmListV1alpha4, nil) if err != nil { return nil, err } } } else if err == nil { - log.Info("converting v1alpha3 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha3, vmListV1alpha5, nil) + log.Info("converting v1alpha2 VirtualMachineList to v1alpha4 VirtualMachineList") + err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachineList_To_v1alpha4_VirtualMachineList( + vmListV1alpha2, vmListV1alpha4, nil) if err != nil { return nil, err } } } else if err == nil { - log.Info("converting v1alpha4 VirtualMachineList to v1alpha5 VirtualMachineList") - err = vmoperatorv1alpha4.Convert_v1alpha4_VirtualMachineList_To_v1alpha5_VirtualMachineList( - vmListV1alpha4, vmListV1alpha5, nil) + log.Info("converting v1alpha3 VirtualMachineList to v1alpha4 VirtualMachineList") + err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachineList_To_v1alpha4_VirtualMachineList( + vmListV1alpha3, vmListV1alpha4, nil) if err != nil { return nil, err } @@ -713,5 +636,5 @@ func GetVirtualMachineListAllApiVersions(ctx context.Context, namespace string, return nil, err } log.Infof("successfully fetched the virtual machines for namespace %s", namespace) - return vmListV1alpha5, nil + return vmListV1alpha4, nil } diff --git a/pkg/common/utils/utils_test.go b/pkg/common/utils/utils_test.go index 0fbf6005ee..8cbc327793 100644 --- a/pkg/common/utils/utils_test.go +++ b/pkg/common/utils/utils_test.go @@ -15,7 +15,6 @@ import ( vmoperatorv1alpha2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" vmoperatorv1alpha3 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" vmoperatorv1alpha4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" - vmoperatorv1alpha5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" cnssim "github.com/vmware/govmomi/cns/simulator" "github.com/vmware/govmomi/cns/types" "github.com/vmware/govmomi/simulator" @@ -299,22 +298,22 @@ func TestListVirtualMachines(t *testing.T) { vmoperatorv1alpha1.AddToScheme, }) clientBuilder.WithRuntimeObjects(namespace, otherNamespace, vm1, vm2, vm3) - v1Alpha4VM1 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM1 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm1", Namespace: namespace.Name, }, } - v1Alpha4VM2 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM2 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm2", Namespace: namespace.Name, }, } - exp := vmoperatorv1alpha5.VirtualMachineList{ + exp := vmoperatorv1alpha4.VirtualMachineList{ TypeMeta: metav1.TypeMeta{}, ListMeta: metav1.ListMeta{}, - Items: []vmoperatorv1alpha5.VirtualMachine{ + Items: []vmoperatorv1alpha4.VirtualMachine{ v1Alpha4VM1, v1Alpha4VM2, }, @@ -395,22 +394,22 @@ func TestListVirtualMachines(t *testing.T) { vmoperatorv1alpha2.AddToScheme, }) clientBuilder.WithRuntimeObjects(namespace, vm1, vm2) - v1Alpha4VM1 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM1 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm1", Namespace: namespace.Name, }, } - v1Alpha4VM2 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM2 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm2", Namespace: namespace.Name, }, } - exp := vmoperatorv1alpha5.VirtualMachineList{ + exp := vmoperatorv1alpha4.VirtualMachineList{ TypeMeta: metav1.TypeMeta{}, ListMeta: metav1.ListMeta{}, - Items: []vmoperatorv1alpha5.VirtualMachine{ + Items: []vmoperatorv1alpha4.VirtualMachine{ v1Alpha4VM1, v1Alpha4VM2, }, @@ -491,22 +490,22 @@ func TestListVirtualMachines(t *testing.T) { vmoperatorv1alpha3.AddToScheme, }) clientBuilder.WithRuntimeObjects(namespace, vm1, vm2) - v1Alpha4VM1 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM1 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm1", Namespace: namespace.Name, }, } - v1Alpha4VM2 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM2 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm2", Namespace: namespace.Name, }, } - exp := vmoperatorv1alpha5.VirtualMachineList{ + exp := vmoperatorv1alpha4.VirtualMachineList{ TypeMeta: metav1.TypeMeta{}, ListMeta: metav1.ListMeta{}, - Items: []vmoperatorv1alpha5.VirtualMachine{ + Items: []vmoperatorv1alpha4.VirtualMachine{ v1Alpha4VM1, v1Alpha4VM2, }, @@ -586,22 +585,22 @@ func TestListVirtualMachines(t *testing.T) { vmoperatorv1alpha4.AddToScheme, }) clientBuilder.WithRuntimeObjects(namespace, vm1, vm2) - v1Alpha4VM1 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM1 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm1", Namespace: namespace.Name, }, } - v1Alpha4VM2 := vmoperatorv1alpha5.VirtualMachine{ + v1Alpha4VM2 := vmoperatorv1alpha4.VirtualMachine{ ObjectMeta: metav1.ObjectMeta{ Name: "vm2", Namespace: namespace.Name, }, } - exp := vmoperatorv1alpha5.VirtualMachineList{ + exp := vmoperatorv1alpha4.VirtualMachineList{ TypeMeta: metav1.TypeMeta{}, ListMeta: metav1.ListMeta{}, - Items: []vmoperatorv1alpha5.VirtualMachine{ + Items: []vmoperatorv1alpha4.VirtualMachine{ v1Alpha4VM1, v1Alpha4VM2, }, @@ -616,9 +615,9 @@ func TestListVirtualMachines(t *testing.T) { assert.True(tt, compareVirtualMachineLists(exp, *actual)) }) }) - t.Run("WhenLatestCRDVersionIsV1Alpha5OrAbove", func(tt *testing.T) { + t.Run("WhenLatestCRDVersionIsV1Alpha4OrAbove", func(tt *testing.T) { getLatestCRDVersion = func(ctx context.Context, crdName string) (string, error) { - return "v1alpha5", nil + return "v1alpha4", nil } tt.Run("WhenListFails", func(ttt *testing.T) { // Setup @@ -654,20 +653,20 @@ func TestListVirtualMachines(t *testing.T) { Phase: v1.NamespaceActive, }, } - vm1 := &vmoperatorv1alpha5.VirtualMachine{ + vm1 := &vmoperatorv1alpha4.VirtualMachine{ TypeMeta: metav1.TypeMeta{ Kind: "VirtualMachine", - APIVersion: "vmoperator.vmware.com/v1alpha5", + APIVersion: "vmoperator.vmware.com/v1alpha4", }, ObjectMeta: metav1.ObjectMeta{ Name: "vm1", Namespace: namespace.Name, }, } - vm2 := &vmoperatorv1alpha5.VirtualMachine{ + vm2 := &vmoperatorv1alpha4.VirtualMachine{ TypeMeta: metav1.TypeMeta{ Kind: "VirtualMachine", - APIVersion: "vmoperator.vmware.com/v1alpha5", + APIVersion: "vmoperator.vmware.com/v1alpha4", }, ObjectMeta: metav1.ObjectMeta{ Name: "vm2", @@ -678,13 +677,13 @@ func TestListVirtualMachines(t *testing.T) { scheme := runtime.NewScheme() clientBuilder = registerSchemes(context.Background(), clientBuilder, scheme, runtime.SchemeBuilder{ v1.AddToScheme, - vmoperatorv1alpha5.AddToScheme, + vmoperatorv1alpha4.AddToScheme, }) clientBuilder.WithRuntimeObjects(namespace, vm1, vm2) - exp := vmoperatorv1alpha5.VirtualMachineList{ + exp := vmoperatorv1alpha4.VirtualMachineList{ TypeMeta: metav1.TypeMeta{}, ListMeta: metav1.ListMeta{}, - Items: []vmoperatorv1alpha5.VirtualMachine{ + Items: []vmoperatorv1alpha4.VirtualMachine{ *vm1, *vm2, }, @@ -712,7 +711,7 @@ func registerSchemes(ctx context.Context, clientBuilder *fake.ClientBuilder, sch return clientBuilder } -func compareVirtualMachineLists(exp, actual vmoperatorv1alpha5.VirtualMachineList) bool { +func compareVirtualMachineLists(exp, actual vmoperatorv1alpha4.VirtualMachineList) bool { // since the list output may not be in the same order, we will compare the items // using brute force. if len(exp.Items) != len(actual.Items) { diff --git a/pkg/csi/service/common/constants.go b/pkg/csi/service/common/constants.go index f0e5bb8791..0b1d532a08 100644 --- a/pkg/csi/service/common/constants.go +++ b/pkg/csi/service/common/constants.go @@ -456,9 +456,6 @@ const ( LinkedCloneSupport = "supports_FCD_linked_clone" // LinkedCloneSupportFSS is an FSS for LinkedClone support in pvcsi LinkedCloneSupportFSS = "linked-clone-support" - // WCPVMServiceVMSnapshots is a supervisor capability indicating - // if supports_VM_service_VM_snapshots FSS is enabled - WCPVMServiceVMSnapshots = "supports_VM_service_VM_snapshots" ) var WCPFeatureStates = map[string]struct{}{ @@ -470,7 +467,6 @@ var WCPFeatureStates = map[string]struct{}{ SharedDiskFss: {}, LinkedCloneSupport: {}, StoragePolicyReservationSupport: {}, - WCPVMServiceVMSnapshots: {}, BYOKEncryption: {}, FCDTransactionSupport: {}, MultipleClustersPerVsphereZone: {}, @@ -485,7 +481,6 @@ var WCPFeatureStatesSupportsLateEnablement = map[string]struct{}{ WorkloadDomainIsolation: {}, LinkedCloneSupport: {}, MultipleClustersPerVsphereZone: {}, - WCPVMServiceVMSnapshots: {}, BYOKEncryption: {}, SharedDiskFss: {}, FileVolumesWithVmService: {}, diff --git a/pkg/csi/service/wcp/controller_helper.go b/pkg/csi/service/wcp/controller_helper.go index 541e4493e6..7b827d4a73 100644 --- a/pkg/csi/service/wcp/controller_helper.go +++ b/pkg/csi/service/wcp/controller_helper.go @@ -24,7 +24,7 @@ import ( "strings" "github.com/container-storage-interface/spec/lib/go/csi" - vmoperatorv1alpha5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatorv1alpha4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" "github.com/vmware/govmomi/object" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/vim25/mo" @@ -165,10 +165,10 @@ func validateWCPControllerExpandVolumeRequest(ctx context.Context, req *csi.Cont return logger.LogNewErrorCodef(log, codes.Internal, "failed to get config with error: %+v", err) } - vmOperatorClient, err := k8s.NewClientForGroup(ctx, cfg, vmoperatorv1alpha5.GroupName) + vmOperatorClient, err := k8s.NewClientForGroup(ctx, cfg, vmoperatorv1alpha4.GroupName) if err != nil { return logger.LogNewErrorCodef(log, codes.Internal, - "failed to get client for group %s with error: %+v", vmoperatorv1alpha5.GroupName, err) + "failed to get client for group %s with error: %+v", vmoperatorv1alpha4.GroupName, err) } vmList, err := utils.ListVirtualMachines(ctx, vmOperatorClient, "") if err != nil { diff --git a/pkg/csi/service/wcpguest/controller.go b/pkg/csi/service/wcpguest/controller.go index a2dc6a787e..572f1cba67 100644 --- a/pkg/csi/service/wcpguest/controller.go +++ b/pkg/csi/service/wcpguest/controller.go @@ -36,7 +36,6 @@ import ( vmoperatorv1alpha2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" vmoperatorv1alpha3 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" vmoperatorv1alpha4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" - vmoperatorv1alpha5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" cnstypes "github.com/vmware/govmomi/cns/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -130,7 +129,7 @@ func (c *controller) Init(config *commonconfig.Config, version string) error { return err } - c.vmOperatorClient, err = k8s.NewClientForGroup(ctx, c.restClientConfig, vmoperatorv1alpha5.GroupName) + c.vmOperatorClient, err = k8s.NewClientForGroup(ctx, c.restClientConfig, vmoperatorv1alpha4.GroupName) if err != nil { log.Errorf("failed to create vmOperatorClient. Error: %+v", err) return err @@ -268,7 +267,7 @@ func (c *controller) ReloadConfiguration() error { return err } log.Infof("successfully re-created supervisorClient using updated configuration") - c.vmOperatorClient, err = k8s.NewClientForGroup(ctx, c.restClientConfig, vmoperatorv1alpha5.GroupName) + c.vmOperatorClient, err = k8s.NewClientForGroup(ctx, c.restClientConfig, vmoperatorv1alpha4.GroupName) if err != nil { log.Errorf("failed to create vmOperatorClient. Error: %+v", err) return err @@ -756,7 +755,7 @@ func controllerPublishForBlockVolume(ctx context.Context, req *csi.ControllerPub var diskUUID string var err error - virtualMachine := &vmoperatorv1alpha5.VirtualMachine{} + virtualMachine := &vmoperatorv1alpha4.VirtualMachine{} vmKey := types.NamespacedName{ Namespace: c.supervisorNamespace, Name: req.NodeId, @@ -787,10 +786,10 @@ func controllerPublishForBlockVolume(ctx context.Context, req *csi.ControllerPub old_virtualMachine := virtualMachine.DeepCopy() // Volume is not present in the virtualMachine.Spec.Volumes, so adding // volume in the spec and patching virtualMachine instance. - vmvolumes := vmoperatorv1alpha5.VirtualMachineVolume{ + vmvolumes := vmoperatorv1alpha4.VirtualMachineVolume{ Name: req.VolumeId, - VirtualMachineVolumeSource: vmoperatorv1alpha5.VirtualMachineVolumeSource{ - PersistentVolumeClaim: &vmoperatorv1alpha5.PersistentVolumeClaimVolumeSource{ + VirtualMachineVolumeSource: vmoperatorv1alpha4.VirtualMachineVolumeSource{ + PersistentVolumeClaim: &vmoperatorv1alpha4.PersistentVolumeClaimVolumeSource{ PersistentVolumeClaimVolumeSource: corev1.PersistentVolumeClaimVolumeSource{ ClaimName: req.VolumeId, }, @@ -809,9 +808,11 @@ func controllerPublishForBlockVolume(ctx context.Context, req *csi.ControllerPub log.Error(msg) return nil, csifault.CSIInternalFault, status.Error(codes.Internal, msg) } - virtualMachine = &vmoperatorv1alpha5.VirtualMachine{} + virtualMachine = &vmoperatorv1alpha4.VirtualMachine{} } + log.Infof("check if volume attached to virtualmachine name %s, namespace %s", + virtualMachine.Name, virtualMachine.Namespace) for _, volume := range virtualMachine.Status.Volumes { if volume.Name == req.VolumeId && volume.Attached && volume.DiskUUID != "" { diskUUID = volume.DiskUUID @@ -839,55 +840,46 @@ func controllerPublishForBlockVolume(ctx context.Context, req *csi.ControllerPub // blocking wait for update event log.Debugf("waiting for update on virtualmachine: %q", virtualMachine.Name) event := <-watchVirtualMachine.ResultChan() - vm := &vmoperatorv1alpha5.VirtualMachine{} - vm5, ok := event.Object.(*vmoperatorv1alpha5.VirtualMachine) + vm := &vmoperatorv1alpha4.VirtualMachine{} + vm4, ok := event.Object.(*vmoperatorv1alpha4.VirtualMachine) if !ok { - vm4, ok := event.Object.(*vmoperatorv1alpha4.VirtualMachine) + vm3, ok := event.Object.(*vmoperatorv1alpha3.VirtualMachine) if !ok { - vm3, ok := event.Object.(*vmoperatorv1alpha3.VirtualMachine) + vm2, ok := event.Object.(*vmoperatorv1alpha2.VirtualMachine) if !ok { - vm2, ok := event.Object.(*vmoperatorv1alpha2.VirtualMachine) + vm1, ok := event.Object.(*vmoperatorv1alpha1.VirtualMachine) if !ok { - vm1, ok := event.Object.(*vmoperatorv1alpha1.VirtualMachine) - if !ok { - msg := fmt.Sprintf("Watch on virtualmachine %q timed out", virtualMachine.Name) - log.Error(msg) - return nil, csifault.CSIInternalFault, status.Error(codes.Internal, msg) - } else { - log.Infof("converting v1alpha1 VirtualMachine to v1alpha5 VirtualMachine, name %s", vm1.Name) - err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachine_To_v1alpha5_VirtualMachine( - vm1, vm, nil) - if err != nil { - return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) - } - } + msg := fmt.Sprintf("Watch on virtualmachine %q timed out", virtualMachine.Name) + log.Error(msg) + return nil, csifault.CSIInternalFault, status.Error(codes.Internal, msg) } else { - log.Infof("converting v1alpha2 VirtualMachine to v1alpha5 VirtualMachine, name %s", vm2.Name) - err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachine_To_v1alpha5_VirtualMachine( - vm2, vm, nil) + log.Infof("converting v1alpha1 VirtualMachine to v1alpha4 VirtualMachine, name %s", vm1.Name) + err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachine_To_v1alpha4_VirtualMachine( + vm1, vm, nil) if err != nil { return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) } } } else { - log.Infof("converting v1alpha3 VirtualMachine to v1alpha5 VirtualMachine, name %s", vm3.Name) - err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachine_To_v1alpha5_VirtualMachine( - vm3, vm, nil) + log.Infof("converting v1alpha2 VirtualMachine to v1alpha4 VirtualMachine, name %s", vm2.Name) + err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachine_To_v1alpha4_VirtualMachine( + vm2, vm, nil) if err != nil { return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) } } } else { - log.Infof("converting v1alpha4 VirtualMachine to v1alpha5 VirtualMachine, name %s", vm4.Name) - err = vmoperatorv1alpha4.Convert_v1alpha4_VirtualMachine_To_v1alpha5_VirtualMachine( - vm4, vm, nil) + log.Infof("converting v1alpha3 VirtualMachine to v1alpha4 VirtualMachine, name %s", vm3.Name) + err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachine_To_v1alpha4_VirtualMachine( + vm3, vm, nil) if err != nil { return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) } } } else { - vm = vm5 + vm = vm4 } + if vm.Name != virtualMachine.Name { log.Debugf("Observed vm name: %q, expecting vm name: %q, volumeID: %q", vm.Name, virtualMachine.Name, req.VolumeId) @@ -1147,7 +1139,7 @@ func (c *controller) ControllerUnpublishVolume(ctx context.Context, req *csi.Con func controllerUnpublishForBlockVolume(ctx context.Context, req *csi.ControllerUnpublishVolumeRequest, c *controller) ( *csi.ControllerUnpublishVolumeResponse, string, error) { log := logger.GetLogger(ctx) - virtualMachine := &vmoperatorv1alpha5.VirtualMachine{} + virtualMachine := &vmoperatorv1alpha4.VirtualMachine{} vmKey := types.NamespacedName{ Namespace: c.supervisorNamespace, Name: req.NodeId, @@ -1189,7 +1181,7 @@ func controllerUnpublishForBlockVolume(ctx context.Context, req *csi.ControllerU log.Error(msg) return nil, csifault.CSIInternalFault, status.Error(codes.Internal, msg) } - virtualMachine = &vmoperatorv1alpha5.VirtualMachine{} + virtualMachine = &vmoperatorv1alpha4.VirtualMachine{} } isVolumePresentInVMStatus := false for _, volume := range virtualMachine.Status.Volumes { @@ -1225,50 +1217,41 @@ func controllerUnpublishForBlockVolume(ctx context.Context, req *csi.ControllerU log.Debugf("Waiting for update on VirtualMachine: %q", virtualMachine.Name) // Block on update events event := <-watchVirtualMachine.ResultChan() - vm := &vmoperatorv1alpha5.VirtualMachine{} - vm5, ok := event.Object.(*vmoperatorv1alpha5.VirtualMachine) + vm := &vmoperatorv1alpha4.VirtualMachine{} + vm4, ok := event.Object.(*vmoperatorv1alpha4.VirtualMachine) if !ok { - vm4, ok := event.Object.(*vmoperatorv1alpha4.VirtualMachine) + vm3, ok := event.Object.(*vmoperatorv1alpha3.VirtualMachine) if !ok { - vm3, ok := event.Object.(*vmoperatorv1alpha3.VirtualMachine) + vm2, ok := event.Object.(*vmoperatorv1alpha2.VirtualMachine) if !ok { - vm2, ok := event.Object.(*vmoperatorv1alpha2.VirtualMachine) + vm1, ok := event.Object.(*vmoperatorv1alpha1.VirtualMachine) if !ok { - vm1, ok := event.Object.(*vmoperatorv1alpha1.VirtualMachine) - if !ok { - msg := fmt.Sprintf("Watch on virtualmachine %q timed out", virtualMachine.Name) - log.Error(msg) - return nil, csifault.CSIInternalFault, status.Error(codes.Internal, msg) - } else { - err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachine_To_v1alpha5_VirtualMachine( - vm1, vm, nil) - if err != nil { - return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) - } - } + msg := fmt.Sprintf("Watch on virtualmachine %q timed out", virtualMachine.Name) + log.Error(msg) + return nil, csifault.CSIInternalFault, status.Error(codes.Internal, msg) } else { - err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachine_To_v1alpha5_VirtualMachine( - vm2, vm, nil) + err = vmoperatorv1alpha1.Convert_v1alpha1_VirtualMachine_To_v1alpha4_VirtualMachine( + vm1, vm, nil) if err != nil { return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) } } } else { - err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachine_To_v1alpha5_VirtualMachine( - vm3, vm, nil) + err = vmoperatorv1alpha2.Convert_v1alpha2_VirtualMachine_To_v1alpha4_VirtualMachine( + vm2, vm, nil) if err != nil { return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) } } } else { - err = vmoperatorv1alpha4.Convert_v1alpha4_VirtualMachine_To_v1alpha5_VirtualMachine( - vm4, vm, nil) + err = vmoperatorv1alpha3.Convert_v1alpha3_VirtualMachine_To_v1alpha4_VirtualMachine( + vm3, vm, nil) if err != nil { return nil, csifault.CSIInternalFault, status.Error(codes.Internal, err.Error()) } } } else { - vm = vm5 + vm = vm4 } if vm.Name != virtualMachine.Name { diff --git a/pkg/csi/service/wcpguest/controller_test.go b/pkg/csi/service/wcpguest/controller_test.go index c444f07507..2b7dcc4e55 100644 --- a/pkg/csi/service/wcpguest/controller_test.go +++ b/pkg/csi/service/wcpguest/controller_test.go @@ -24,7 +24,7 @@ import ( "testing" "time" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" diff --git a/pkg/kubernetes/kubernetes.go b/pkg/kubernetes/kubernetes.go index f710598ec7..271fa171c3 100644 --- a/pkg/kubernetes/kubernetes.go +++ b/pkg/kubernetes/kubernetes.go @@ -30,7 +30,6 @@ import ( vmoperatorv1alpha2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" vmoperatorv1alpha3 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" vmoperatorv1alpha4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" - vmoperatorv1alpha5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" v1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" @@ -238,7 +237,7 @@ func NewClientForGroup(ctx context.Context, config *restclient.Config, groupName log.Errorf("failed to add to scheme with err: %+v", err) return nil, err } - case vmoperatorv1alpha5.GroupName: + case vmoperatorv1alpha4.GroupName: log.Info("adding scheme for vm-operator version v1alpha1") err = vmoperatorv1alpha1.AddToScheme(scheme) if err != nil { @@ -263,12 +262,6 @@ func NewClientForGroup(ctx context.Context, config *restclient.Config, groupName log.Errorf("failed to add to scheme with err: %+v", err) return nil, err } - log.Info("adding scheme for vm-operator version v1alpha5") - err = vmoperatorv1alpha5.AddToScheme(scheme) - if err != nil { - log.Errorf("failed to add to scheme with err: %+v", err) - return nil, err - } case cnsoperatorv1alpha1.GroupName: err = cnsoperatorv1alpha1.AddToScheme(scheme) if err != nil { @@ -358,11 +351,7 @@ func NewVirtualMachineWatcher(ctx context.Context, config *restclient.Config, log := logger.GetLogger(ctx) scheme := runtime.NewScheme() - log.Info("adding scheme for vm-operator versions v1alpha1, v1alpha2, v1alpha3, v1alpha4, v1alpha5") - err = vmoperatorv1alpha5.AddToScheme(scheme) - if err != nil { - log.Errorf("failed to add to scheme with err: %+v", err) - } + log.Info("adding scheme for vm-operator versions v1alpha1, v1alpha2, v1alpha3, v1alpha4") err = vmoperatorv1alpha4.AddToScheme(scheme) if err != nil { log.Errorf("failed to add to scheme with err: %+v", err) diff --git a/pkg/syncer/admissionhandler/cnscsi_admissionhandler.go b/pkg/syncer/admissionhandler/cnscsi_admissionhandler.go index aff3c9e804..f4fc41dfaf 100644 --- a/pkg/syncer/admissionhandler/cnscsi_admissionhandler.go +++ b/pkg/syncer/admissionhandler/cnscsi_admissionhandler.go @@ -13,7 +13,7 @@ import ( "strconv" "strings" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" "sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco/k8sorchestrator" admissionv1 "k8s.io/api/admission/v1" diff --git a/pkg/syncer/cnsoperator/controller/add_virtualmachinesnapshot.go b/pkg/syncer/cnsoperator/controller/add_virtualmachinesnapshot.go deleted file mode 100644 index e933050656..0000000000 --- a/pkg/syncer/cnsoperator/controller/add_virtualmachinesnapshot.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2025 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controller - -import ( - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/syncer/cnsoperator/controller/virtualmachinesnapshot" -) - -func init() { - // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. - AddToManagerFuncs = append(AddToManagerFuncs, virtualmachinesnapshot.Add) -} diff --git a/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller.go b/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller.go index e7fdf39ebf..3b816c0344 100644 --- a/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller.go +++ b/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller.go @@ -25,7 +25,7 @@ import ( "sync" "time" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" cnstypes "github.com/vmware/govmomi/cns/types" vsanfstypes "github.com/vmware/govmomi/vsan/vsanfs/types" v1 "k8s.io/api/core/v1" diff --git a/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller_test.go b/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller_test.go index 26ef59f3a5..3e0c9bcb6c 100644 --- a/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller_test.go +++ b/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/cnsfileaccessconfig_controller_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/util.go b/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/util.go index cbffe32737..c894f7351f 100644 --- a/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/util.go +++ b/pkg/syncer/cnsoperator/controller/cnsfileaccessconfig/util.go @@ -21,7 +21,7 @@ import ( "fmt" "reflect" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apitypes "k8s.io/apimachinery/pkg/types" diff --git a/pkg/syncer/cnsoperator/controller/cnsnodevmattachment/cnsnodevmattachment_controller.go b/pkg/syncer/cnsoperator/controller/cnsnodevmattachment/cnsnodevmattachment_controller.go index f5ee96586a..665dc2c0c9 100644 --- a/pkg/syncer/cnsoperator/controller/cnsnodevmattachment/cnsnodevmattachment_controller.go +++ b/pkg/syncer/cnsoperator/controller/cnsnodevmattachment/cnsnodevmattachment_controller.go @@ -24,7 +24,7 @@ import ( "sync" "time" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" cnstypes "github.com/vmware/govmomi/cns/types" "github.com/vmware/govmomi/object" vimtypes "github.com/vmware/govmomi/vim25/types" diff --git a/pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_controller.go b/pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_controller.go index 1cd4227fd9..d8e62f66e8 100644 --- a/pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_controller.go +++ b/pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_controller.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco" cnsoperatortypes "sigs.k8s.io/vsphere-csi-driver/v3/pkg/syncer/cnsoperator/types" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" cnstypes "github.com/vmware/govmomi/cns/types" v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/pkg/syncer/cnsoperator/controller/cnsunregistervolume/util.go b/pkg/syncer/cnsoperator/controller/cnsunregistervolume/util.go index 4bd0bc1207..92bc602dd0 100644 --- a/pkg/syncer/cnsoperator/controller/cnsunregistervolume/util.go +++ b/pkg/syncer/cnsoperator/controller/cnsunregistervolume/util.go @@ -22,7 +22,7 @@ import ( "strings" snapshotclient "github.com/kubernetes-csi/external-snapshotter/client/v8/clientset/versioned" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/pkg/syncer/cnsoperator/controller/csinodetopology/csinodetopology_controller.go b/pkg/syncer/cnsoperator/controller/csinodetopology/csinodetopology_controller.go index 367dd61d25..e082bedda3 100644 --- a/pkg/syncer/cnsoperator/controller/csinodetopology/csinodetopology_controller.go +++ b/pkg/syncer/cnsoperator/controller/csinodetopology/csinodetopology_controller.go @@ -23,7 +23,7 @@ import ( "sync" "time" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" cnstypes "github.com/vmware/govmomi/cns/types" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/pkg/syncer/cnsoperator/controller/virtualmachinesnapshot/virtualmachinesnapshot_controller.go b/pkg/syncer/cnsoperator/controller/virtualmachinesnapshot/virtualmachinesnapshot_controller.go deleted file mode 100644 index 57845fba4c..0000000000 --- a/pkg/syncer/cnsoperator/controller/virtualmachinesnapshot/virtualmachinesnapshot_controller.go +++ /dev/null @@ -1,522 +0,0 @@ -/* -Copyright 2025 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package virtualmachinesnapshot - -import ( - "context" - "encoding/json" - "fmt" - "strings" - "sync" - "time" - - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" - cnstypes "github.com/vmware/govmomi/cns/types" - "go.uber.org/zap" - syncgroup "golang.org/x/sync/errgroup" - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - apitypes "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" - typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/tools/record" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" - "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" - "sigs.k8s.io/controller-runtime/pkg/manager" - "sigs.k8s.io/controller-runtime/pkg/predicate" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - apis "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator" - volumes "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/cns-lib/volume" - commonconfig "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/config" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/common/utils" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/common/commonco" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/csi/service/logger" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/internalapis/cnsvolumeinfo" - k8s "sigs.k8s.io/vsphere-csi-driver/v3/pkg/kubernetes" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/syncer" - "sigs.k8s.io/vsphere-csi-driver/v3/pkg/syncer/cnsoperator/util" -) - -const ( - MaxBackOffDurationForReconciler = 5 * time.Minute - workerThreadsEnvVar = "WORKER_THREADS_VIRTUAL_MACHINE_SNAPSHOT" - defaultMaxWorkerThreads = 10 - allowedRetriesToPatchCNSVolumeInfo = 5 - SyncVolumeFinalizer = "cns.vmware.com/syncvolume" - VMSnapshotFinalizer = "vmoperator.vmware.com/virtualmachinesnapshot" -) - -var ( - // backOffDuration is a map of virtualmachinesnapshot name's to the time after which - // a request for this instance will be requeued. - // Initialized to 1 second for new instances and for instances whose latest - // reconcile operation succeeded. - // If the reconcile fails, backoff is incremented exponentially. - backOffDuration map[apitypes.NamespacedName]time.Duration - backOffDurationMapMutex = sync.Mutex{} -) - -// Add creates a new VirtualMachineSnapshot Controller and adds it to the Manager, -// ConfigurationInfo and VirtualCenterTypes. The Manager will set fields on the -// Controller and start it when the Manager is Started. -func Add(mgr manager.Manager, clusterFlavor cnstypes.CnsClusterFlavor, - configInfo *commonconfig.ConfigurationInfo, volumeManager volumes.Manager) error { - ctx, log := logger.GetNewContextWithLogger() - - var coCommonInterface commonco.COCommonInterface - var err error - var volumeInfoService cnsvolumeinfo.VolumeInfoService - // VirtualMachineSnapshot quota validation is only supported on WCP. - if clusterFlavor == cnstypes.CnsClusterFlavorWorkload { - coCommonInterface, err = commonco.GetContainerOrchestratorInterface(ctx, - common.Kubernetes, clusterFlavor, &syncer.COInitParams) - if err != nil { - log.Errorf("failed to create CO agnostic interface. error: %v", err) - return err - } - var err error - if !coCommonInterface.IsFSSEnabled(ctx, common.WCPVMServiceVMSnapshots) { - log.Info("Not initializing the VirtualMachineSnapshot Controller as " + - "this feature is disabled on the cluster") - return nil - } - log.Info("Creating CnsVolumeInfo Service to persist mapping for VolumeID to storage policy info") - volumeInfoService, err = cnsvolumeinfo.InitVolumeInfoService(ctx) - if err != nil { - return logger.LogNewErrorf(log, "error initializing volumeInfoService. error: %+v", err) - } - log.Info("Successfully initialized VolumeInfoService") - } else { - log.Info("Not initializing VirtualMachineSnapshot Controller as guest/vanilla cluster is detected.") - return nil - } - // Initializes kubernetes client. - k8sclient, err := k8s.NewClient(ctx) - if err != nil { - log.Errorf("Creating Kubernetes client failed. error: %v", err) - return err - } - restClientConfig, err := k8s.GetKubeConfig(ctx) - if err != nil { - msg := fmt.Sprintf("Failed to initialize rest clientconfig. error: %+v", err) - log.Error(msg) - return err - } - vmOperatorClient, err := k8s.NewClientForGroup(ctx, restClientConfig, vmoperatortypes.GroupName) - if err != nil { - msg := fmt.Sprintf("Failed to initialize vmOperatorClient. error: %+v", err) - log.Error(msg) - return err - } - - // eventBroadcaster broadcasts events on virtualmachinesnapshot instances to the - // event sink. - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartRecordingToSink( - &typedcorev1.EventSinkImpl{ - Interface: k8sclient.CoreV1().Events(""), - }, - ) - recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: apis.GroupName}) - return add(mgr, newReconciler(mgr, configInfo, volumeManager, - recorder, vmOperatorClient, volumeInfoService)) -} - -// newReconciler returns a new reconcile.Reconciler. -func newReconciler(mgr manager.Manager, configInfo *commonconfig.ConfigurationInfo, - volumeManager volumes.Manager, recorder record.EventRecorder, vmOperatorClient client.Client, - volumeInfoService cnsvolumeinfo.VolumeInfoService) reconcile.Reconciler { - return &ReconcileVirtualMachineSnapshot{ - client: mgr.GetClient(), - scheme: mgr.GetScheme(), - configInfo: configInfo, - volumeManager: volumeManager, - recorder: recorder, - vmOperatorClient: vmOperatorClient, - volumeInfoService: volumeInfoService, - } -} - -// add adds a new Controller to mgr with r as the reconcile.Reconciler. -func add(mgr manager.Manager, r reconcile.Reconciler) error { - ctx, log := logger.GetNewContextWithLogger() - maxWorkerThreads := util.GetMaxWorkerThreads(ctx, - workerThreadsEnvVar, defaultMaxWorkerThreads) - // Create a new controller. - err := ctrl.NewControllerManagedBy(mgr).Named("virtualmachinesnapshot-controller"). - WithEventFilter(predicate.GenerationChangedPredicate{}). - WithOptions(controller.Options{MaxConcurrentReconciles: maxWorkerThreads}). - Complete(r) - if err != nil { - log.Errorf("Failed to build application controller. Err: %v", err) - return err - } - - backOffDuration = make(map[apitypes.NamespacedName]time.Duration) - return nil -} - -// blank assignment to verify that ReconcileVirtualMachineSnapshot implements -// reconcile.Reconciler. -var _ reconcile.Reconciler = &ReconcileVirtualMachineSnapshot{} - -// ReconcileVirtualMachineSnapshot reconciles a VirtualMachineSnapshot object. -type ReconcileVirtualMachineSnapshot struct { - // This client, initialized using mgr.Client() above, is a split client - // that reads objects from the cache and writes to the apiserver. - client client.Client - scheme *runtime.Scheme - configInfo *commonconfig.ConfigurationInfo - volumeManager volumes.Manager - recorder record.EventRecorder - volumeInfoService cnsvolumeinfo.VolumeInfoService - vmOperatorClient client.Client -} - -// Reconcile reads that state of the cluster for a VirtualMachineSnapshot object and -// makes changes based on the state read and what is in VirtualMachineSnapshot.Spec. -// Note: -// The Controller will requeue the Request to be processed again if the returned -// error is non-nil or Result.Requeue is true. Otherwise, upon completion it -// will remove the work from the queue. -func (r *ReconcileVirtualMachineSnapshot) Reconcile(ctx context.Context, - request reconcile.Request) (reconcile.Result, error) { - _, log := logger.GetNewContextWithLogger() - now := time.Now() - log.Infof("Reconcile Started for VirtualMachineSnapshot %s/%s", request.Namespace, request.Name) - defer func() { - log.Infof("Reconcile Completed for virtualmachinesnapshot %s/%s Time Taken %v", - request.Namespace, request.Name, time.Since(now)) - }() - // Fetch the VirtualMachineSnapshot instance. - vmSnapshot := &vmoperatortypes.VirtualMachineSnapshot{} - err := r.client.Get(ctx, request.NamespacedName, vmSnapshot) - if err != nil { - if apierrors.IsNotFound(err) { - log.Infof("resource not found. Ignoring since object must be deleted for vmsnapshot %s/%s", - request.Namespace, request.Name) - return reconcile.Result{}, nil - } - log.Errorf("error while fetch the virtualmachinesnapshot %s/%s. error: %v", - request.Namespace, request.Name, err) - // Error reading the object - return with err. - return reconcile.Result{}, err - } - - // Initialize backOffDuration for the instance, if required. - backOffDurationMapMutex.Lock() - var timeout time.Duration - if _, exists := backOffDuration[request.NamespacedName]; !exists { - backOffDuration[request.NamespacedName] = time.Second - } - timeout = backOffDuration[request.NamespacedName] - backOffDurationMapMutex.Unlock() - - log.Infof("Reconciling virtualmachinesnapshot %s/%s", - request.Namespace, request.Name) - err = r.reconcileNormal(ctx, log, vmSnapshot) - if err != nil { - recordEvent(ctx, r, vmSnapshot, corev1.EventTypeWarning, err.Error()) - log.Errorf("error while processing virtualmachinesnapshot %s/%s set backOffDuration: %v. error: %v", - request.Namespace, request.Name, backOffDuration[request.NamespacedName], err) - return reconcile.Result{RequeueAfter: timeout}, nil - } - - msg := fmt.Sprintf("Successfully successfully processed vmsnapshot %s/%s", - vmSnapshot.Namespace, vmSnapshot.Name) - recordEvent(ctx, r, vmSnapshot, corev1.EventTypeNormal, msg) - - backOffDurationMapMutex.Lock() - delete(backOffDuration, request.NamespacedName) - backOffDurationMapMutex.Unlock() - log.Info(msg) - return reconcile.Result{}, nil -} -func (r *ReconcileVirtualMachineSnapshot) reconcileNormal(ctx context.Context, log *zap.SugaredLogger, - vmsnapshot *vmoperatortypes.VirtualMachineSnapshot) error { - deleteVMSnapshot := false - if vmsnapshot.DeletionTimestamp.IsZero() { - vmSnapshotPatch := client.MergeFrom(vmsnapshot.DeepCopy()) - // If the finalizer is not present, add it. - if controllerutil.AddFinalizer(vmsnapshot, SyncVolumeFinalizer) { - log.Infof("reconcileNormal: Adding finalizer %s on virtualmachinesnapshot cr %s/%s", - SyncVolumeFinalizer, vmsnapshot.Namespace, vmsnapshot.Name) - err := r.client.Patch(ctx, vmsnapshot, vmSnapshotPatch) - if err != nil { - log.Errorf("reconcileNormal: error while add finalizer to "+ - "virtualmachinesnapshot %s/%s. error: %v", vmsnapshot.Name, vmsnapshot.Name, err) - return err - } - return nil - } - } - if !vmsnapshot.DeletionTimestamp.IsZero() && - controllerutil.ContainsFinalizer(vmsnapshot, SyncVolumeFinalizer) { - if !controllerutil.ContainsFinalizer(vmsnapshot, VMSnapshotFinalizer) { - log.Infof("reconcileNormal: virtualmachinesnapshot %s/%s is set to delete", - vmsnapshot.Namespace, vmsnapshot.Name) - deleteVMSnapshot = true - } else { - log.Infof("reconcileNormal: virtualmachinesnapshot %s/%s is set to delete, "+ - "expecting to remove %s first", vmsnapshot.Namespace, vmsnapshot.Name, - VMSnapshotFinalizer) - return nil - } - } - // Check for the annotation "csi.vsphere.volume.sync: Requested" - syncVolumeAnnotation := strings.ToLower(vmsnapshot.Annotations["csi.vsphere.volume.sync"]) - // process quota validation if annotation value is "Requested" - // annotation value is set to "Requested" by vm-service when snapshot is completed successfully. - if syncVolumeAnnotation == "requested" || deleteVMSnapshot { - // if found fetch vmsnapshot and pvcs and pvs - vmKey := apitypes.NamespacedName{ - Namespace: vmsnapshot.Namespace, - Name: vmsnapshot.Spec.VMName, - } - log.Infof("reconcileNormal: get virtulal machine %s/%s", vmKey.Namespace, vmKey.Name) - virtualMachine, _, err := utils.GetVirtualMachineAllApiVersions(ctx, vmKey, - r.vmOperatorClient) - // case when underlying virtualmachine is deleted after creating vmsnapshot cr, - // when delete snapshot we ignore the error, so that vmsnapshot cr does not stuck deletion pahse - if err != nil && !deleteVMSnapshot { - log.Errorf("reconcileNormal: could not get VirtualMachine %s/%s. error: %v", - vmKey.Namespace, vmKey.Name, err) - return err - } - log.Infof("reconcileNormal: sync and update storage quota for vmsnapshot %s/%s", - vmsnapshot.Namespace, vmsnapshot.Name) - if virtualMachine != nil { - err = r.syncVolumesAndUpdateCNSVolumeInfo(ctx, log, virtualMachine) - if err != nil { - log.Errorf("reconcileNormal: failed to validate VirtualMachineSnapshot %s/%s. error: %v", - vmsnapshot.Namespace, vmsnapshot.Name, err) - return err - } - log.Infof("reconcileNormal: successfully synced and updated storage quota for vmsnapshot %s/%s", - vmsnapshot.Namespace, vmsnapshot.Name) - } else { - if deleteVMSnapshot { - log.Infof("reconcileNormal: VirtualMachine %s/%s not found. skipping volume sync.", - vmKey.Namespace, vmKey.Name) - } else { - err = fmt.Errorf("VirtualMachine %s/%s not found", vmKey.Namespace, vmKey.Name) - log.Errorf("reconcileNormal: unable to sync volumes. error %v", err) - return err - } - } - if deleteVMSnapshot { - log.Infof("reconcileNormal: remove finalizer %s for virtualmachinesnapshot %s/%s", - SyncVolumeFinalizer, vmsnapshot.Namespace, vmsnapshot.Name) - vmSnapshotPatch := client.MergeFrom(vmsnapshot.DeepCopy()) - if controllerutil.RemoveFinalizer(vmsnapshot, SyncVolumeFinalizer) { - err = r.client.Patch(ctx, vmsnapshot, vmSnapshotPatch) - if err != nil { - log.Errorf("reconcileNormal: failed to remove finalizer for "+ - "virtualmachinesnapshot %s/%s. error: %v", vmsnapshot.Namespace, - vmsnapshot.Name, err) - return err - } - return nil - } - } - // Update VMSnapshot CR annotation to "csi.vsphere.volume.sync: completed" - log.Infof("reconcileNormal: update annotation value for vmsnapshot %s/%s to 'completed'", - vmsnapshot.Namespace, vmsnapshot.Name) - vmSnapshotPatch := client.MergeFrom(vmsnapshot.DeepCopy()) - vmsnapshot.Annotations["csi.vsphere.volume.sync"] = "completed" - err = r.client.Patch(ctx, vmsnapshot, vmSnapshotPatch) - if err != nil { - log.Errorf("reconcileNormal: could not update virtualmachinesnapshot %s/%s. error: %v", - vmsnapshot.Namespace, vmsnapshot.Name, err) - return err - } - log.Infof("reconcileNormal: successfully updated vmsnapshot %s/%s", - vmsnapshot.Namespace, vmsnapshot.Name) - } - return nil -} - -// recordEvent records the event, sets the backOffDuration for the instance -// appropriately and logs the message. -// backOffDuration is reset to 1 second on success and doubled on failure. -func recordEvent(ctx context.Context, r *ReconcileVirtualMachineSnapshot, - instance *vmoperatortypes.VirtualMachineSnapshot, eventtype string, msg string) { - log := logger.GetLogger(ctx) - log.Debugf("Event type is %s", eventtype) - namespacedName := apitypes.NamespacedName{ - Name: instance.Name, - Namespace: instance.Namespace, - } - switch eventtype { - case corev1.EventTypeWarning: - // Double backOff duration. - backOffDurationMapMutex.Lock() - backOffDuration[namespacedName] = min(backOffDuration[namespacedName]*2, - MaxBackOffDurationForReconciler) - r.recorder.Event(instance, corev1.EventTypeWarning, "VirtualMachineSnapshotFailed", msg) - backOffDurationMapMutex.Unlock() - case corev1.EventTypeNormal: - // Reset backOff duration to one second. - backOffDurationMapMutex.Lock() - backOffDuration[namespacedName] = time.Second - r.recorder.Event(instance, corev1.EventTypeNormal, "VirtualMachineSnapshotSucceeded", msg) - backOffDurationMapMutex.Unlock() - } -} - -// syncVolumesAndUpdateCNSVolumeInfo will fetch the volume-ids attached to virtualmachine -// will call SyncVolume API with sync mode SPACE_USAGE and volume-id list -// after volume sync is successful it will fetch the aggregated size of all related volumes -// will update the relevant CNSVolumeInfo for each volume which will update the storage policy usage. -func (r *ReconcileVirtualMachineSnapshot) syncVolumesAndUpdateCNSVolumeInfo(ctx context.Context, - log *zap.SugaredLogger, vm *vmoperatortypes.VirtualMachine) error { - var err error - cnsVolumeIds := []cnstypes.CnsVolumeId{} - syncMode := []string{string(cnstypes.CnsSyncVolumeModeSPACE_USAGE)} - syncgrp, sgctx := syncgroup.WithContext(ctx) - for _, vmVolume := range vm.Spec.Volumes { - if vmVolume.VirtualMachineVolumeSource.PersistentVolumeClaim == nil { - continue - } - pvcKey := apitypes.NamespacedName{ - Namespace: vm.Namespace, - Name: vmVolume.VirtualMachineVolumeSource.PersistentVolumeClaim.ClaimName, - } - pvc := &corev1.PersistentVolumeClaim{} - err = r.client.Get(ctx, pvcKey, pvc, &client.GetOptions{}) - if err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: failed get pvc %s/%s. error: %v", - vm.Namespace, vmVolume.Name, err) - return err - } - if pvc.Spec.VolumeName != "" { - pvKey := apitypes.NamespacedName{ - Name: pvc.Spec.VolumeName, - } - pv := &corev1.PersistentVolume{} - err = r.client.Get(ctx, pvKey, pv, &client.GetOptions{}) - if err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: could not get the volume "+ - "for pvc %s/%s error: %v", pvc.Namespace, vm.Name, err) - return err - } - if pv.Spec.CSI != nil && pv.Spec.CSI.VolumeHandle != "" { - cnsVolId := cnstypes.CnsVolumeId{Id: pv.Spec.CSI.VolumeHandle} - cnsVolumeIds = append(cnsVolumeIds, cnsVolId) - syncVolumeSpecs := []cnstypes.CnsSyncVolumeSpec{ - { - VolumeId: cnsVolId, - SyncMode: syncMode, - }, - } - // parallelize sync volume api calls - syncgrp.Go(func() error { - return r.invokeSyncVolume(sgctx, log, syncVolumeSpecs) - }) - } - } else { - err = fmt.Errorf("could not find the PV associated with PVC %s/%s", - vm.Namespace, vmVolume.Name) - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: pv not found error: %v", err) - return err - } - } - // if syncvolume api is not invoked for any volume, no need to update CNSVolumeInfos - if len(cnsVolumeIds) == 0 { - log.Info("syncVolumesAndUpdateCNSVolumeInfo: no volumes found to sync, skipped volume sync") - return nil - } - log.Info("syncVolumesAndUpdateCNSVolumeInfo: wait for syncvolume operation to be completed") - if err := syncgrp.Wait(); err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: error while sync volume "+ - "error: %v", err) - return err - } - log.Info("syncVolumesAndUpdateCNSVolumeInfo: volumes are synced successfully. " + - "will update related CNSVolumeInfos") - // fetch updated cns volumes - queryFilter := cnstypes.CnsQueryFilter{ - VolumeIds: cnsVolumeIds, - } - queryResult, err := r.volumeManager.QueryVolume(ctx, queryFilter) - if err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: error while query volumes from cns. error: %v", err) - return err - } - if queryResult != nil && len(queryResult.Volumes) > 0 { - for _, cnsvolume := range queryResult.Volumes { - val, ok := cnsvolume.BackingObjectDetails.(*cnstypes.CnsBlockBackingDetails) - if ok { - log.Infof("syncVolumesAndUpdateCNSVolumeInfo: fetched aggregated capacity for volume %s "+ - "AggregatedSnapshotCapacityInMb %d", cnsvolume.VolumeId.Id, val.AggregatedSnapshotCapacityInMb) - - // Update CNSVolumeInfo with latest aggregated Size and Update SPU used value. - patch, err := common.GetCNSVolumeInfoPatch(ctx, val.AggregatedSnapshotCapacityInMb, - cnsvolume.VolumeId.Id) - if err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: failed to get cnsvolumeinfo patch for "+ - "volume %s, error: %v", cnsvolume.VolumeId.Id, err) - return err - } - patchBytes, err := json.Marshal(patch) - if err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: error while json marshal. error: %v", err) - return err - } - err = r.volumeInfoService.PatchVolumeInfo(ctx, cnsvolume.VolumeId.Id, - patchBytes, allowedRetriesToPatchCNSVolumeInfo) - if err != nil { - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: failed to patch cnsvolumeinfo for volume "+ - "volume %s, error: %v", cnsvolume.VolumeId.Id, err) - return err - } - } else { - err = fmt.Errorf("unable to retrieve CnsBlockBackingDetails for volumeID %s", - cnsvolume.VolumeId.Id) - log.Errorf("syncVolumesAndUpdateCNSVolumeInfo: could not retrieve CnsBlockBackingDetails. "+ - "error: %v", err) - return err - } - } - } - return nil -} - -func (r *ReconcileVirtualMachineSnapshot) invokeSyncVolume(ctx context.Context, log *zap.SugaredLogger, - syncVolumeSpecs []cnstypes.CnsSyncVolumeSpec) error { - select { - case <-ctx.Done(): - log.Infof("invokeSyncVolume: Sync Volume Operation cancelled for volume %s", - syncVolumeSpecs[0]) - return ctx.Err() - default: - // Trigger CNS VolumeSync API for identified volume-lds and Fetch Latest Aggregated snapshot size - log.Infof("invokeSyncVolume: Trigger CNS SyncVolume API for volume %s", - syncVolumeSpecs[0]) - syncVolumeFaultType, err := r.volumeManager.SyncVolume(ctx, syncVolumeSpecs) - if err != nil { - log.Errorf("invokeSyncVolume: error while sync volume %s "+ - "cnsfault %s. error: %v", syncVolumeSpecs[0], syncVolumeFaultType, err) - return err - } - return nil - } -} diff --git a/pkg/syncer/cnsoperator/manager/init.go b/pkg/syncer/cnsoperator/manager/init.go index 0bb7559a8b..62d58d21fe 100644 --- a/pkg/syncer/cnsoperator/manager/init.go +++ b/pkg/syncer/cnsoperator/manager/init.go @@ -30,7 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/config" "sigs.k8s.io/controller-runtime/pkg/manager" - vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha5" + vmoperatortypes "github.com/vmware-tanzu/vm-operator/api/v1alpha4" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" cnsoperatorv1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator" cnsvolumemetadatav1alpha1 "sigs.k8s.io/vsphere-csi-driver/v3/pkg/apis/cnsoperator/cnsvolumemetadata/v1alpha1" diff --git a/tests/e2e/vmservice_late_binding.go b/tests/e2e/vmservice_late_binding.go index c88ac893ab..fd5d5d1de6 100644 --- a/tests/e2e/vmservice_late_binding.go +++ b/tests/e2e/vmservice_late_binding.go @@ -30,7 +30,6 @@ import ( vmopv2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" vmopv3 "github.com/vmware-tanzu/vm-operator/api/v1alpha3" vmopv4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" - vmopv5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" "github.com/vmware/govmomi/find" "github.com/vmware/govmomi/object" v1 "k8s.io/api/core/v1" @@ -118,7 +117,6 @@ var _ bool = ginkgo.Describe("[vmsvc] VM-Service-VM-LateBinding", func() { gomega.Expect(vmopv2.AddToScheme(vmopScheme)).Should(gomega.Succeed()) gomega.Expect(vmopv3.AddToScheme(vmopScheme)).Should(gomega.Succeed()) gomega.Expect(vmopv4.AddToScheme(vmopScheme)).Should(gomega.Succeed()) - gomega.Expect(vmopv5.AddToScheme(vmopScheme)).Should(gomega.Succeed()) vmopC, err = ctlrclient.New(f.ClientConfig(), ctlrclient.Options{Scheme: vmopScheme}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -529,10 +527,10 @@ var _ bool = ginkgo.Describe("[vmsvc] VM-Service-VM-LateBinding", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) // Append new volume with a required Name field vm1v5.Spec.Volumes = append(vm1v5.Spec.Volumes, - vmopv5.VirtualMachineVolume{ + vmopv4.VirtualMachineVolume{ Name: pvclaim2.Name, - VirtualMachineVolumeSource: vmopv5.VirtualMachineVolumeSource{ - PersistentVolumeClaim: &vmopv5.PersistentVolumeClaimVolumeSource{ + VirtualMachineVolumeSource: vmopv4.VirtualMachineVolumeSource{ + PersistentVolumeClaim: &vmopv4.PersistentVolumeClaimVolumeSource{ PersistentVolumeClaimVolumeSource: v1.PersistentVolumeClaimVolumeSource{ ClaimName: pvclaim2.Name, }, @@ -667,10 +665,10 @@ var _ bool = ginkgo.Describe("[vmsvc] VM-Service-VM-LateBinding", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) // Append new volume with a required Name field vm1v5.Spec.Volumes = append(vm1v5.Spec.Volumes, - vmopv5.VirtualMachineVolume{ + vmopv4.VirtualMachineVolume{ Name: pvclaim2.Name, - VirtualMachineVolumeSource: vmopv5.VirtualMachineVolumeSource{ - PersistentVolumeClaim: &vmopv5.PersistentVolumeClaimVolumeSource{ + VirtualMachineVolumeSource: vmopv4.VirtualMachineVolumeSource{ + PersistentVolumeClaim: &vmopv4.PersistentVolumeClaimVolumeSource{ PersistentVolumeClaimVolumeSource: v1.PersistentVolumeClaimVolumeSource{ ClaimName: pvclaim2.Name, }, diff --git a/tests/e2e/vmservice_utils.go b/tests/e2e/vmservice_utils.go index 97aa37d345..73701ce5ad 100644 --- a/tests/e2e/vmservice_utils.go +++ b/tests/e2e/vmservice_utils.go @@ -42,7 +42,6 @@ import ( vmopv3common "github.com/vmware-tanzu/vm-operator/api/v1alpha3/common" vmopv4 "github.com/vmware-tanzu/vm-operator/api/v1alpha4" vmopv4common "github.com/vmware-tanzu/vm-operator/api/v1alpha4/common" - vmopv5 "github.com/vmware-tanzu/vm-operator/api/v1alpha5" "golang.org/x/crypto/ssh" v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" @@ -1655,9 +1654,9 @@ func getVmsvcVM4( // getVmsvcVM fetches the vm from the specified ns func getVmsvcVM5( - ctx context.Context, c ctlrclient.Client, namespace string, vmName string) (*vmopv5.VirtualMachine, error) { + ctx context.Context, c ctlrclient.Client, namespace string, vmName string) (*vmopv4.VirtualMachine, error) { instanceKey := ctlrclient.ObjectKey{Name: vmName, Namespace: namespace} - vm := &vmopv5.VirtualMachine{} + vm := &vmopv4.VirtualMachine{} err := c.Get(ctx, instanceKey, vm) return vm, err }