Skip to content

Commit

Permalink
fix(controller): Use v3 VM VG Reference for v4 detachVGFromVM (#473)
Browse files Browse the repository at this point in the history
AOS 6.5 does not support v4 VMM APIs but does support v4 volume group
APIs.
  • Loading branch information
thunderboltsid authored Aug 14, 2024
1 parent 237138a commit d1217b9
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 35 deletions.
27 changes: 7 additions & 20 deletions controllers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
prismclientv4 "github.com/nutanix-cloud-native/prism-go-client/v4"
prismcommonconfig "github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4/models/common/v1/config"
prismapi "github.com/nutanix/ntnx-api-golang-clients/prism-go-client/v4/models/prism/v4/config"
vmconfig "github.com/nutanix/ntnx-api-golang-clients/vmm-go-client/v4/models/vmm/v4/ahv/config"
prismconfig "github.com/nutanix/ntnx-api-golang-clients/volumes-go-client/v4/models/prism/v4/config"
volumesconfig "github.com/nutanix/ntnx-api-golang-clients/volumes-go-client/v4/models/volumes/v4/config"
"k8s.io/apimachinery/pkg/api/resource"
Expand Down Expand Up @@ -878,38 +877,26 @@ func getPrismCentralVersion(ctx context.Context, v3Client *prismclientv3.Client)
return *pcInfo.Resources.Version, nil
}

func detachVolumeGroupsFromVM(ctx context.Context, v4Client *prismclientv4.Client, vmUUID string) error {
func detachVolumeGroupsFromVM(ctx context.Context, v4Client *prismclientv4.Client, vm *prismclientv3.VMIntentResponse) error {
log := ctrl.LoggerFrom(ctx)
vmResp, err := v4Client.VmApiInstance.GetVmById(&vmUUID)
if err != nil {
return fmt.Errorf("failed to get virtual machine: %w", err)
}

data := vmResp.GetData()
vm, ok := data.(vmconfig.Vm)
if !ok {
return fmt.Errorf("failed to cast response to VM")
}

volumeGroupsToDetach := make([]string, 0)
for _, disk := range vm.Disks {
backingInfo, ok := disk.GetBackingInfo().(vmconfig.ADSFVolumeGroupReference)
if !ok {
for _, disk := range vm.Spec.Resources.DiskList {
if disk.VolumeGroupReference == nil {
continue
}

volumeGroupsToDetach = append(volumeGroupsToDetach, *backingInfo.VolumeGroupExtId)
volumeGroupsToDetach = append(volumeGroupsToDetach, *disk.VolumeGroupReference.UUID)
}

// Detach the volume groups from the virtual machine
for _, volumeGroup := range volumeGroupsToDetach {
log.Info(fmt.Sprintf("detaching volume group %s from virtual machine %s", volumeGroup, vmUUID))
log.Info(fmt.Sprintf("detaching volume group %s from virtual machine %s", volumeGroup, *vm.Status.Name))
body := &volumesconfig.VmAttachment{
ExtId: &vmUUID,
ExtId: vm.Metadata.UUID,
}
resp, err := v4Client.VolumeGroupsApiInstance.DetachVm(&volumeGroup, body)
if err != nil {
return fmt.Errorf("failed to detach volume group %s from virtual machine %s: %w", volumeGroup, vmUUID, err)
return fmt.Errorf("failed to detach volume group %s from virtual machine %s: %w", volumeGroup, *vm.Metadata.UUID, err)
}

data := resp.GetData()
Expand Down
8 changes: 4 additions & 4 deletions controllers/nutanixmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func (r *NutanixMachineReconciler) reconcileDelete(rctx *nctx.MachineContext) (r
}

if vgDetachNeeded {
if err := r.detachVolumeGroups(rctx, vmUUID); err != nil {
if err := r.detachVolumeGroups(rctx, vm); err != nil {
err := fmt.Errorf("failed to detach volume groups from VM %s with UUID %s: %v", vmName, vmUUID, err)
log.Error(err, "failed to detach volume groups from VM")
conditions.MarkFalse(rctx.NutanixMachine, infrav1.VMProvisionedCondition, infrav1.VolumeGroupDetachFailed, capiv1.ConditionSeverityWarning, err.Error())
Expand All @@ -401,7 +401,7 @@ func (r *NutanixMachineReconciler) reconcileDelete(rctx *nctx.MachineContext) (r
return reconcile.Result{RequeueAfter: 5 * time.Second}, nil
}

func (r *NutanixMachineReconciler) detachVolumeGroups(rctx *nctx.MachineContext, vmUUID string) error {
func (r *NutanixMachineReconciler) detachVolumeGroups(rctx *nctx.MachineContext, vm *prismclientv3.VMIntentResponse) error {
createV4Client, err := isPrismCentralV4Compatible(rctx.Context, rctx.NutanixClient)
if err != nil {
return fmt.Errorf("error occurred while checking compatibility for Prism Central v4 APIs: %w", err)
Expand All @@ -416,8 +416,8 @@ func (r *NutanixMachineReconciler) detachVolumeGroups(rctx *nctx.MachineContext,
return fmt.Errorf("error occurred while fetching Prism Central v4 client: %w", err)
}

if err := detachVolumeGroupsFromVM(rctx.Context, v4Client, vmUUID); err != nil {
return fmt.Errorf("failed to detach volume groups from VM %s with UUID %s: %w", rctx.Machine.Name, vmUUID, err)
if err := detachVolumeGroupsFromVM(rctx.Context, v4Client, vm); err != nil {
return fmt.Errorf("failed to detach volume groups from VM %s with UUID %s: %w", rctx.Machine.Name, *vm.Metadata.UUID, err)
}

return nil
Expand Down
42 changes: 31 additions & 11 deletions controllers/nutanixmachine_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (

"github.com/golang/mock/gomock"
credentialTypes "github.com/nutanix-cloud-native/prism-go-client/environment/credentials"
v3 "github.com/nutanix-cloud-native/prism-go-client/v3"
prismclientv3 "github.com/nutanix-cloud-native/prism-go-client/v3"
"github.com/nutanix-cloud-native/prism-go-client/v3/models"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -246,12 +246,16 @@ func TestNutanixMachineReconciler(t *testing.T) {
mockv3Service := mocknutanixv3.NewMockService(mockctrl)
mockv3Service.EXPECT().GetPrismCentral(gomock.Any()).Return(nil, errors.New("error"))

v3Client := &v3.Client{
v3Client := &prismclientv3.Client{
V3: mockv3Service,
}
err := reconciler.detachVolumeGroups(&nctx.MachineContext{
NutanixClient: v3Client,
}, ntnxMachine.Status.VmUUID)
}, &prismclientv3.VMIntentResponse{
Metadata: &prismclientv3.Metadata{
UUID: &ntnxMachine.Status.VmUUID,
},
})
g.Expect(err).To(HaveOccurred())
})

Expand All @@ -262,12 +266,16 @@ func TestNutanixMachineReconciler(t *testing.T) {
Version: ptr.To(""),
}}, nil)

v3Client := &v3.Client{
v3Client := &prismclientv3.Client{
V3: mockv3Service,
}
err := reconciler.detachVolumeGroups(&nctx.MachineContext{
NutanixClient: v3Client,
}, ntnxMachine.Status.VmUUID)
}, &prismclientv3.VMIntentResponse{
Metadata: &prismclientv3.Metadata{
UUID: &ntnxMachine.Status.VmUUID,
},
})
g.Expect(err).To(HaveOccurred())
})

Expand All @@ -278,12 +286,16 @@ func TestNutanixMachineReconciler(t *testing.T) {
Version: ptr.To("pc."),
}}, nil)

v3Client := &v3.Client{
v3Client := &prismclientv3.Client{
V3: mockv3Service,
}
err := reconciler.detachVolumeGroups(&nctx.MachineContext{
NutanixClient: v3Client,
}, ntnxMachine.Status.VmUUID)
}, &prismclientv3.VMIntentResponse{
Metadata: &prismclientv3.Metadata{
UUID: &ntnxMachine.Status.VmUUID,
},
})
g.Expect(err).To(HaveOccurred())
})

Expand All @@ -294,12 +306,16 @@ func TestNutanixMachineReconciler(t *testing.T) {
Version: ptr.To("not.a.valid.version"),
}}, nil)

v3Client := &v3.Client{
v3Client := &prismclientv3.Client{
V3: mockv3Service,
}
err := reconciler.detachVolumeGroups(&nctx.MachineContext{
NutanixClient: v3Client,
}, ntnxMachine.Status.VmUUID)
}, &prismclientv3.VMIntentResponse{
Metadata: &prismclientv3.Metadata{
UUID: &ntnxMachine.Status.VmUUID,
},
})
g.Expect(err).To(HaveOccurred())
})

Expand All @@ -310,12 +326,16 @@ func TestNutanixMachineReconciler(t *testing.T) {
Version: ptr.To("pc.2023.4.0.1"),
}}, nil)

v3Client := &v3.Client{
v3Client := &prismclientv3.Client{
V3: mockv3Service,
}
err := reconciler.detachVolumeGroups(&nctx.MachineContext{
NutanixClient: v3Client,
}, ntnxMachine.Status.VmUUID)
}, &prismclientv3.VMIntentResponse{
Metadata: &prismclientv3.Metadata{
UUID: &ntnxMachine.Status.VmUUID,
},
})
g.Expect(err).To(Not(HaveOccurred()))
})
})
Expand Down

0 comments on commit d1217b9

Please sign in to comment.