From b28c32ebda8a3ab1c07fcc43158cfd44a010571c Mon Sep 17 00:00:00 2001 From: shashank-netapp <108022276+shashank-netapp@users.noreply.github.com> Date: Tue, 21 May 2024 14:24:36 +0530 Subject: [PATCH] Refactoring the ONTAP REST client to replace wildcards with the needed parameters Co-authored-by: Ravi Kumar M --- .../mock_ontap/mock_ontap_rest_interface.go | 207 +++++----- storage_drivers/ontap/api/abstraction_rest.go | 281 +++++++++++--- .../ontap/api/abstraction_rest_test.go | 282 +++++++------- storage_drivers/ontap/api/ontap_rest.go | 354 ++++++++++-------- .../ontap/api/ontap_rest_interface.go | 121 +++--- storage_drivers/ontap/api/ontap_rest_test.go | 109 +++--- storage_drivers/ontap/ontap_common_test.go | 36 +- 7 files changed, 828 insertions(+), 562 deletions(-) diff --git a/mocks/mock_storage_drivers/mock_ontap/mock_ontap_rest_interface.go b/mocks/mock_storage_drivers/mock_ontap/mock_ontap_rest_interface.go index e27bb4f09..9497bc8fd 100644 --- a/mocks/mock_storage_drivers/mock_ontap/mock_ontap_rest_interface.go +++ b/mocks/mock_storage_drivers/mock_ontap/mock_ontap_rest_interface.go @@ -45,18 +45,18 @@ func (m *MockRestClientInterface) EXPECT() *MockRestClientInterfaceMockRecorder } // AggregateList mocks base method. -func (m *MockRestClientInterface) AggregateList(arg0 context.Context, arg1 string) (*storage.AggregateCollectionGetOK, error) { +func (m *MockRestClientInterface) AggregateList(arg0 context.Context, arg1 string, arg2 []string) (*storage.AggregateCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AggregateList", arg0, arg1) + ret := m.ctrl.Call(m, "AggregateList", arg0, arg1, arg2) ret0, _ := ret[0].(*storage.AggregateCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // AggregateList indicates an expected call of AggregateList. -func (mr *MockRestClientInterfaceMockRecorder) AggregateList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) AggregateList(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AggregateList", reflect.TypeOf((*MockRestClientInterface)(nil).AggregateList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AggregateList", reflect.TypeOf((*MockRestClientInterface)(nil).AggregateList), arg0, arg1, arg2) } // ClientConfig mocks base method. @@ -266,33 +266,33 @@ func (mr *MockRestClientInterfaceMockRecorder) FlexGroupExists(arg0, arg1 interf } // FlexGroupGetAll mocks base method. -func (m *MockRestClientInterface) FlexGroupGetAll(arg0 context.Context, arg1 string) (*storage.VolumeCollectionGetOK, error) { +func (m *MockRestClientInterface) FlexGroupGetAll(arg0 context.Context, arg1 string, arg2 []string) (*storage.VolumeCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlexGroupGetAll", arg0, arg1) + ret := m.ctrl.Call(m, "FlexGroupGetAll", arg0, arg1, arg2) ret0, _ := ret[0].(*storage.VolumeCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // FlexGroupGetAll indicates an expected call of FlexGroupGetAll. -func (mr *MockRestClientInterfaceMockRecorder) FlexGroupGetAll(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) FlexGroupGetAll(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlexGroupGetAll", reflect.TypeOf((*MockRestClientInterface)(nil).FlexGroupGetAll), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlexGroupGetAll", reflect.TypeOf((*MockRestClientInterface)(nil).FlexGroupGetAll), arg0, arg1, arg2) } // FlexGroupGetByName mocks base method. -func (m *MockRestClientInterface) FlexGroupGetByName(arg0 context.Context, arg1 string) (*models.Volume, error) { +func (m *MockRestClientInterface) FlexGroupGetByName(arg0 context.Context, arg1 string, arg2 []string) (*models.Volume, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FlexGroupGetByName", arg0, arg1) + ret := m.ctrl.Call(m, "FlexGroupGetByName", arg0, arg1, arg2) ret0, _ := ret[0].(*models.Volume) ret1, _ := ret[1].(error) return ret0, ret1 } // FlexGroupGetByName indicates an expected call of FlexGroupGetByName. -func (mr *MockRestClientInterfaceMockRecorder) FlexGroupGetByName(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) FlexGroupGetByName(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlexGroupGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).FlexGroupGetByName), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FlexGroupGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).FlexGroupGetByName), arg0, arg1, arg2) } // FlexGroupModifyUnixPermissions mocks base method. @@ -539,33 +539,33 @@ func (mr *MockRestClientInterfaceMockRecorder) IgroupGet(arg0, arg1 interface{}) } // IgroupGetByName mocks base method. -func (m *MockRestClientInterface) IgroupGetByName(arg0 context.Context, arg1 string) (*models.Igroup, error) { +func (m *MockRestClientInterface) IgroupGetByName(arg0 context.Context, arg1 string, arg2 []string) (*models.Igroup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IgroupGetByName", arg0, arg1) + ret := m.ctrl.Call(m, "IgroupGetByName", arg0, arg1, arg2) ret0, _ := ret[0].(*models.Igroup) ret1, _ := ret[1].(error) return ret0, ret1 } // IgroupGetByName indicates an expected call of IgroupGetByName. -func (mr *MockRestClientInterfaceMockRecorder) IgroupGetByName(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) IgroupGetByName(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IgroupGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).IgroupGetByName), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IgroupGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).IgroupGetByName), arg0, arg1, arg2) } // IgroupList mocks base method. -func (m *MockRestClientInterface) IgroupList(arg0 context.Context, arg1 string) (*s_a_n.IgroupCollectionGetOK, error) { +func (m *MockRestClientInterface) IgroupList(arg0 context.Context, arg1 string, arg2 []string) (*s_a_n.IgroupCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IgroupList", arg0, arg1) + ret := m.ctrl.Call(m, "IgroupList", arg0, arg1, arg2) ret0, _ := ret[0].(*s_a_n.IgroupCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // IgroupList indicates an expected call of IgroupList. -func (mr *MockRestClientInterfaceMockRecorder) IgroupList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) IgroupList(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IgroupList", reflect.TypeOf((*MockRestClientInterface)(nil).IgroupList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IgroupList", reflect.TypeOf((*MockRestClientInterface)(nil).IgroupList), arg0, arg1, arg2) } // IgroupRemove mocks base method. @@ -642,19 +642,33 @@ func (mr *MockRestClientInterfaceMockRecorder) IsVserverDRSource(arg0 interface{ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsVserverDRSource", reflect.TypeOf((*MockRestClientInterface)(nil).IsVserverDRSource), arg0) } +// IsVserverInSVMDR mocks base method. +func (m *MockRestClientInterface) IsVserverInSVMDR(arg0 context.Context) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsVserverInSVMDR", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsVserverInSVMDR indicates an expected call of IsVserverInSVMDR. +func (mr *MockRestClientInterfaceMockRecorder) IsVserverInSVMDR(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsVserverInSVMDR", reflect.TypeOf((*MockRestClientInterface)(nil).IsVserverInSVMDR), arg0) +} + // IscsiInitiatorGetDefaultAuth mocks base method. -func (m *MockRestClientInterface) IscsiInitiatorGetDefaultAuth(arg0 context.Context) (*s_a_n.IscsiCredentialsCollectionGetOK, error) { +func (m *MockRestClientInterface) IscsiInitiatorGetDefaultAuth(arg0 context.Context, arg1 []string) (*s_a_n.IscsiCredentialsCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IscsiInitiatorGetDefaultAuth", arg0) + ret := m.ctrl.Call(m, "IscsiInitiatorGetDefaultAuth", arg0, arg1) ret0, _ := ret[0].(*s_a_n.IscsiCredentialsCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // IscsiInitiatorGetDefaultAuth indicates an expected call of IscsiInitiatorGetDefaultAuth. -func (mr *MockRestClientInterfaceMockRecorder) IscsiInitiatorGetDefaultAuth(arg0 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) IscsiInitiatorGetDefaultAuth(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IscsiInitiatorGetDefaultAuth", reflect.TypeOf((*MockRestClientInterface)(nil).IscsiInitiatorGetDefaultAuth), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IscsiInitiatorGetDefaultAuth", reflect.TypeOf((*MockRestClientInterface)(nil).IscsiInitiatorGetDefaultAuth), arg0, arg1) } // IscsiInitiatorSetDefaultAuth mocks base method. @@ -672,48 +686,48 @@ func (mr *MockRestClientInterfaceMockRecorder) IscsiInitiatorSetDefaultAuth(arg0 } // IscsiInterfaceGet mocks base method. -func (m *MockRestClientInterface) IscsiInterfaceGet(arg0 context.Context) (*s_a_n.IscsiServiceCollectionGetOK, error) { +func (m *MockRestClientInterface) IscsiInterfaceGet(arg0 context.Context, arg1 []string) (*s_a_n.IscsiServiceCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IscsiInterfaceGet", arg0) + ret := m.ctrl.Call(m, "IscsiInterfaceGet", arg0, arg1) ret0, _ := ret[0].(*s_a_n.IscsiServiceCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // IscsiInterfaceGet indicates an expected call of IscsiInterfaceGet. -func (mr *MockRestClientInterfaceMockRecorder) IscsiInterfaceGet(arg0 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) IscsiInterfaceGet(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IscsiInterfaceGet", reflect.TypeOf((*MockRestClientInterface)(nil).IscsiInterfaceGet), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IscsiInterfaceGet", reflect.TypeOf((*MockRestClientInterface)(nil).IscsiInterfaceGet), arg0, arg1) } // IscsiNodeGetName mocks base method. -func (m *MockRestClientInterface) IscsiNodeGetName(arg0 context.Context) (*s_a_n.IscsiServiceGetOK, error) { +func (m *MockRestClientInterface) IscsiNodeGetName(arg0 context.Context, arg1 []string) (*s_a_n.IscsiServiceGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IscsiNodeGetName", arg0) + ret := m.ctrl.Call(m, "IscsiNodeGetName", arg0, arg1) ret0, _ := ret[0].(*s_a_n.IscsiServiceGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // IscsiNodeGetName indicates an expected call of IscsiNodeGetName. -func (mr *MockRestClientInterfaceMockRecorder) IscsiNodeGetName(arg0 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) IscsiNodeGetName(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IscsiNodeGetName", reflect.TypeOf((*MockRestClientInterface)(nil).IscsiNodeGetName), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IscsiNodeGetName", reflect.TypeOf((*MockRestClientInterface)(nil).IscsiNodeGetName), arg0, arg1) } // JobGet mocks base method. -func (m *MockRestClientInterface) JobGet(arg0 context.Context, arg1 string) (*cluster.JobGetOK, error) { +func (m *MockRestClientInterface) JobGet(arg0 context.Context, arg1 string, arg2 []string) (*cluster.JobGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "JobGet", arg0, arg1) + ret := m.ctrl.Call(m, "JobGet", arg0, arg1, arg2) ret0, _ := ret[0].(*cluster.JobGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // JobGet indicates an expected call of JobGet. -func (mr *MockRestClientInterfaceMockRecorder) JobGet(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) JobGet(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JobGet", reflect.TypeOf((*MockRestClientInterface)(nil).JobGet), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JobGet", reflect.TypeOf((*MockRestClientInterface)(nil).JobGet), arg0, arg1, arg2) } // JobScheduleExists mocks base method. @@ -804,18 +818,18 @@ func (mr *MockRestClientInterfaceMockRecorder) LunGetAttribute(arg0, arg1, arg2 } // LunGetByName mocks base method. -func (m *MockRestClientInterface) LunGetByName(arg0 context.Context, arg1 string) (*models.Lun, error) { +func (m *MockRestClientInterface) LunGetByName(arg0 context.Context, arg1 string, arg2 []string) (*models.Lun, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LunGetByName", arg0, arg1) + ret := m.ctrl.Call(m, "LunGetByName", arg0, arg1, arg2) ret0, _ := ret[0].(*models.Lun) ret1, _ := ret[1].(error) return ret0, ret1 } // LunGetByName indicates an expected call of LunGetByName. -func (mr *MockRestClientInterfaceMockRecorder) LunGetByName(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) LunGetByName(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LunGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).LunGetByName), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LunGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).LunGetByName), arg0, arg1, arg2) } // LunGetComment mocks base method. @@ -834,18 +848,18 @@ func (mr *MockRestClientInterfaceMockRecorder) LunGetComment(arg0, arg1 interfac } // LunList mocks base method. -func (m *MockRestClientInterface) LunList(arg0 context.Context, arg1 string) (*s_a_n.LunCollectionGetOK, error) { +func (m *MockRestClientInterface) LunList(arg0 context.Context, arg1 string, arg2 []string) (*s_a_n.LunCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LunList", arg0, arg1) + ret := m.ctrl.Call(m, "LunList", arg0, arg1, arg2) ret0, _ := ret[0].(*s_a_n.LunCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // LunList indicates an expected call of LunList. -func (mr *MockRestClientInterfaceMockRecorder) LunList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) LunList(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LunList", reflect.TypeOf((*MockRestClientInterface)(nil).LunList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LunList", reflect.TypeOf((*MockRestClientInterface)(nil).LunList), arg0, arg1, arg2) } // LunMap mocks base method. @@ -894,18 +908,18 @@ func (mr *MockRestClientInterfaceMockRecorder) LunMapInfo(arg0, arg1, arg2 inter } // LunMapList mocks base method. -func (m *MockRestClientInterface) LunMapList(arg0 context.Context, arg1, arg2 string) (*s_a_n.LunMapCollectionGetOK, error) { +func (m *MockRestClientInterface) LunMapList(arg0 context.Context, arg1, arg2 string, arg3 []string) (*s_a_n.LunMapCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LunMapList", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "LunMapList", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*s_a_n.LunMapCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // LunMapList indicates an expected call of LunMapList. -func (mr *MockRestClientInterfaceMockRecorder) LunMapList(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) LunMapList(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LunMapList", reflect.TypeOf((*MockRestClientInterface)(nil).LunMapList), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LunMapList", reflect.TypeOf((*MockRestClientInterface)(nil).LunMapList), arg0, arg1, arg2, arg3) } // LunOptions mocks base method. @@ -1098,33 +1112,33 @@ func (mr *MockRestClientInterfaceMockRecorder) NVMeNamespaceCreate(arg0, arg1 in } // NVMeNamespaceGetByName mocks base method. -func (m *MockRestClientInterface) NVMeNamespaceGetByName(arg0 context.Context, arg1 string) (*models.NvmeNamespace, error) { +func (m *MockRestClientInterface) NVMeNamespaceGetByName(arg0 context.Context, arg1 string, arg2 []string) (*models.NvmeNamespace, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NVMeNamespaceGetByName", arg0, arg1) + ret := m.ctrl.Call(m, "NVMeNamespaceGetByName", arg0, arg1, arg2) ret0, _ := ret[0].(*models.NvmeNamespace) ret1, _ := ret[1].(error) return ret0, ret1 } // NVMeNamespaceGetByName indicates an expected call of NVMeNamespaceGetByName. -func (mr *MockRestClientInterfaceMockRecorder) NVMeNamespaceGetByName(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) NVMeNamespaceGetByName(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeNamespaceGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeNamespaceGetByName), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeNamespaceGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeNamespaceGetByName), arg0, arg1, arg2) } // NVMeNamespaceList mocks base method. -func (m *MockRestClientInterface) NVMeNamespaceList(arg0 context.Context, arg1 string) (*n_v_me.NvmeNamespaceCollectionGetOK, error) { +func (m *MockRestClientInterface) NVMeNamespaceList(arg0 context.Context, arg1 string, arg2 []string) (*n_v_me.NvmeNamespaceCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NVMeNamespaceList", arg0, arg1) + ret := m.ctrl.Call(m, "NVMeNamespaceList", arg0, arg1, arg2) ret0, _ := ret[0].(*n_v_me.NvmeNamespaceCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // NVMeNamespaceList indicates an expected call of NVMeNamespaceList. -func (mr *MockRestClientInterfaceMockRecorder) NVMeNamespaceList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) NVMeNamespaceList(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeNamespaceList", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeNamespaceList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeNamespaceList", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeNamespaceList), arg0, arg1, arg2) } // NVMeNamespaceSetSize mocks base method. @@ -1214,33 +1228,33 @@ func (mr *MockRestClientInterfaceMockRecorder) NVMeSubsystemDelete(arg0, arg1 in } // NVMeSubsystemGetByName mocks base method. -func (m *MockRestClientInterface) NVMeSubsystemGetByName(arg0 context.Context, arg1 string) (*models.NvmeSubsystem, error) { +func (m *MockRestClientInterface) NVMeSubsystemGetByName(arg0 context.Context, arg1 string, arg2 []string) (*models.NvmeSubsystem, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NVMeSubsystemGetByName", arg0, arg1) + ret := m.ctrl.Call(m, "NVMeSubsystemGetByName", arg0, arg1, arg2) ret0, _ := ret[0].(*models.NvmeSubsystem) ret1, _ := ret[1].(error) return ret0, ret1 } // NVMeSubsystemGetByName indicates an expected call of NVMeSubsystemGetByName. -func (mr *MockRestClientInterfaceMockRecorder) NVMeSubsystemGetByName(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) NVMeSubsystemGetByName(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeSubsystemGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeSubsystemGetByName), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeSubsystemGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeSubsystemGetByName), arg0, arg1, arg2) } // NVMeSubsystemList mocks base method. -func (m *MockRestClientInterface) NVMeSubsystemList(arg0 context.Context, arg1 string) (*n_v_me.NvmeSubsystemCollectionGetOK, error) { +func (m *MockRestClientInterface) NVMeSubsystemList(arg0 context.Context, arg1 string, arg2 []string) (*n_v_me.NvmeSubsystemCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NVMeSubsystemList", arg0, arg1) + ret := m.ctrl.Call(m, "NVMeSubsystemList", arg0, arg1, arg2) ret0, _ := ret[0].(*n_v_me.NvmeSubsystemCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // NVMeSubsystemList indicates an expected call of NVMeSubsystemList. -func (mr *MockRestClientInterfaceMockRecorder) NVMeSubsystemList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) NVMeSubsystemList(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeSubsystemList", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeSubsystemList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NVMeSubsystemList", reflect.TypeOf((*MockRestClientInterface)(nil).NVMeSubsystemList), arg0, arg1, arg2) } // NVMeSubsystemRemoveNamespace mocks base method. @@ -1436,33 +1450,33 @@ func (mr *MockRestClientInterfaceMockRecorder) QtreeGetByName(arg0, arg1, arg2 i } // QtreeGetByPath mocks base method. -func (m *MockRestClientInterface) QtreeGetByPath(arg0 context.Context, arg1 string) (*models.Qtree, error) { +func (m *MockRestClientInterface) QtreeGetByPath(arg0 context.Context, arg1 string, arg2 []string) (*models.Qtree, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QtreeGetByPath", arg0, arg1) + ret := m.ctrl.Call(m, "QtreeGetByPath", arg0, arg1, arg2) ret0, _ := ret[0].(*models.Qtree) ret1, _ := ret[1].(error) return ret0, ret1 } // QtreeGetByPath indicates an expected call of QtreeGetByPath. -func (mr *MockRestClientInterfaceMockRecorder) QtreeGetByPath(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) QtreeGetByPath(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QtreeGetByPath", reflect.TypeOf((*MockRestClientInterface)(nil).QtreeGetByPath), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QtreeGetByPath", reflect.TypeOf((*MockRestClientInterface)(nil).QtreeGetByPath), arg0, arg1, arg2) } // QtreeList mocks base method. -func (m *MockRestClientInterface) QtreeList(arg0 context.Context, arg1, arg2 string) (*storage.QtreeCollectionGetOK, error) { +func (m *MockRestClientInterface) QtreeList(arg0 context.Context, arg1, arg2 string, arg3 []string) (*storage.QtreeCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QtreeList", arg0, arg1, arg2) + ret := m.ctrl.Call(m, "QtreeList", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*storage.QtreeCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // QtreeList indicates an expected call of QtreeList. -func (mr *MockRestClientInterfaceMockRecorder) QtreeList(arg0, arg1, arg2 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) QtreeList(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QtreeList", reflect.TypeOf((*MockRestClientInterface)(nil).QtreeList), arg0, arg1, arg2) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QtreeList", reflect.TypeOf((*MockRestClientInterface)(nil).QtreeList), arg0, arg1, arg2, arg3) } // QtreeModifyExportPolicy mocks base method. @@ -1760,18 +1774,18 @@ func (mr *MockRestClientInterfaceMockRecorder) SnapmirrorDeleteViaDestination(ar } // SnapmirrorGet mocks base method. -func (m *MockRestClientInterface) SnapmirrorGet(arg0 context.Context, arg1, arg2, arg3, arg4 string) (*models.SnapmirrorRelationship, error) { +func (m *MockRestClientInterface) SnapmirrorGet(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) (*models.SnapmirrorRelationship, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SnapmirrorGet", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "SnapmirrorGet", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(*models.SnapmirrorRelationship) ret1, _ := ret[1].(error) return ret0, ret1 } // SnapmirrorGet indicates an expected call of SnapmirrorGet. -func (mr *MockRestClientInterfaceMockRecorder) SnapmirrorGet(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) SnapmirrorGet(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapmirrorGet", reflect.TypeOf((*MockRestClientInterface)(nil).SnapmirrorGet), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapmirrorGet", reflect.TypeOf((*MockRestClientInterface)(nil).SnapmirrorGet), arg0, arg1, arg2, arg3, arg4, arg5) } // SnapmirrorInitialize mocks base method. @@ -1788,6 +1802,21 @@ func (mr *MockRestClientInterfaceMockRecorder) SnapmirrorInitialize(arg0, arg1, return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapmirrorInitialize", reflect.TypeOf((*MockRestClientInterface)(nil).SnapmirrorInitialize), arg0, arg1, arg2, arg3, arg4) } +// SnapmirrorListDestinations mocks base method. +func (m *MockRestClientInterface) SnapmirrorListDestinations(arg0 context.Context, arg1, arg2, arg3, arg4 string) (*models.SnapmirrorRelationship, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SnapmirrorListDestinations", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(*models.SnapmirrorRelationship) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SnapmirrorListDestinations indicates an expected call of SnapmirrorListDestinations. +func (mr *MockRestClientInterfaceMockRecorder) SnapmirrorListDestinations(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SnapmirrorListDestinations", reflect.TypeOf((*MockRestClientInterface)(nil).SnapmirrorListDestinations), arg0, arg1, arg2, arg3, arg4) +} + // SnapmirrorPolicyExists mocks base method. func (m *MockRestClientInterface) SnapmirrorPolicyExists(arg0 context.Context, arg1 string) (bool, error) { m.ctrl.T.Helper() @@ -2196,33 +2225,33 @@ func (mr *MockRestClientInterfaceMockRecorder) VolumeExists(arg0, arg1 interface } // VolumeGetByName mocks base method. -func (m *MockRestClientInterface) VolumeGetByName(arg0 context.Context, arg1 string) (*models.Volume, error) { +func (m *MockRestClientInterface) VolumeGetByName(arg0 context.Context, arg1 string, arg2 []string) (*models.Volume, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VolumeGetByName", arg0, arg1) + ret := m.ctrl.Call(m, "VolumeGetByName", arg0, arg1, arg2) ret0, _ := ret[0].(*models.Volume) ret1, _ := ret[1].(error) return ret0, ret1 } // VolumeGetByName indicates an expected call of VolumeGetByName. -func (mr *MockRestClientInterfaceMockRecorder) VolumeGetByName(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) VolumeGetByName(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).VolumeGetByName), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeGetByName", reflect.TypeOf((*MockRestClientInterface)(nil).VolumeGetByName), arg0, arg1, arg2) } // VolumeList mocks base method. -func (m *MockRestClientInterface) VolumeList(arg0 context.Context, arg1 string) (*storage.VolumeCollectionGetOK, error) { +func (m *MockRestClientInterface) VolumeList(arg0 context.Context, arg1 string, arg2 []string) (*storage.VolumeCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VolumeList", arg0, arg1) + ret := m.ctrl.Call(m, "VolumeList", arg0, arg1, arg2) ret0, _ := ret[0].(*storage.VolumeCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // VolumeList indicates an expected call of VolumeList. -func (mr *MockRestClientInterfaceMockRecorder) VolumeList(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) VolumeList(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeList", reflect.TypeOf((*MockRestClientInterface)(nil).VolumeList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeList", reflect.TypeOf((*MockRestClientInterface)(nil).VolumeList), arg0, arg1, arg2) } // VolumeListAllBackedBySnapshot mocks base method. @@ -2241,18 +2270,18 @@ func (mr *MockRestClientInterfaceMockRecorder) VolumeListAllBackedBySnapshot(arg } // VolumeListByAttrs mocks base method. -func (m *MockRestClientInterface) VolumeListByAttrs(arg0 context.Context, arg1 *api.Volume) (api.Volumes, error) { +func (m *MockRestClientInterface) VolumeListByAttrs(arg0 context.Context, arg1 *api.Volume, arg2 []string) (*storage.VolumeCollectionGetOK, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VolumeListByAttrs", arg0, arg1) - ret0, _ := ret[0].(api.Volumes) + ret := m.ctrl.Call(m, "VolumeListByAttrs", arg0, arg1, arg2) + ret0, _ := ret[0].(*storage.VolumeCollectionGetOK) ret1, _ := ret[1].(error) return ret0, ret1 } // VolumeListByAttrs indicates an expected call of VolumeListByAttrs. -func (mr *MockRestClientInterfaceMockRecorder) VolumeListByAttrs(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockRestClientInterfaceMockRecorder) VolumeListByAttrs(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeListByAttrs", reflect.TypeOf((*MockRestClientInterface)(nil).VolumeListByAttrs), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VolumeListByAttrs", reflect.TypeOf((*MockRestClientInterface)(nil).VolumeListByAttrs), arg0, arg1, arg2) } // VolumeModifyExportPolicy mocks base method. diff --git a/storage_drivers/ontap/api/abstraction_rest.go b/storage_drivers/ontap/api/abstraction_rest.go index 6f7107451..549bcfdbd 100644 --- a/storage_drivers/ontap/api/abstraction_rest.go +++ b/storage_drivers/ontap/api/abstraction_rest.go @@ -187,7 +187,12 @@ func (d OntapAPIREST) VolumeDestroy(ctx context.Context, name string, force bool } func (d OntapAPIREST) VolumeInfo(ctx context.Context, name string) (*Volume, error) { - volumeGetResponse, err := d.api.VolumeGetByName(ctx, name) + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", + "snapshot_policy", "snapshot_directory_access_enabled", + "space.snapshot.used", "space.snapshot.reserve_percent", + } + volumeGetResponse, err := d.api.VolumeGetByName(ctx, name, fields) if err != nil { Logc(ctx).Errorf("Could not find volume with name: %v, error: %v", name, err.Error()) return nil, err @@ -206,6 +211,48 @@ func (d OntapAPIREST) VolumeInfo(ctx context.Context, name string) (*Volume, err return volumeInfo, nil } +func FlexVolInfoFromRestAttrsHelper(volume *models.Volume) (*Volume, error) { + aggregates := []string{} + for _, aggr := range volume.VolumeInlineAggregates { + if aggr.Name != nil { + aggregates = append(aggregates, *aggr.Name) + } + } + + snapshotDirAccessEnabled := false + if volume.SnapshotDirectoryAccessEnabled != nil { + snapshotDirAccessEnabled = *volume.SnapshotDirectoryAccessEnabled + } + + tieringPolicy := models.VolumeInlineTieringPolicyNone + if volume.Movement != nil && volume.Movement.TieringPolicy != nil { + tieringPolicy = *volume.Movement.TieringPolicy + } + + encryption := false + if volume.Encryption != nil && volume.Encryption.Enabled != nil { + encryption = *volume.Encryption.Enabled + } + + v := &Volume{ + Aggregates: aggregates, + Encrypt: &encryption, + TieringPolicy: tieringPolicy, + SnapshotDir: snapshotDirAccessEnabled, + } + if volume.Name != nil { + v.Name = *volume.Name + } + if volume.Guarantee != nil && volume.Guarantee.Type != nil { + v.SpaceReserve = *volume.Guarantee.Type + } + if volume.SnapshotPolicy != nil && volume.SnapshotPolicy.Name != nil { + v.SnapshotPolicy = *volume.SnapshotPolicy.Name + } + + return v, nil +} + func VolumeInfoFromRestAttrsHelper(volumeGetResponse *models.Volume) (*Volume, error) { var responseAccessType string var responseAggregates []string @@ -237,9 +284,6 @@ func VolumeInfoFromRestAttrsHelper(volumeGetResponse *models.Volume) (*Volume, e *volumeGetResponse.VolumeInlineAggregates[0].Name, } } - } else { - return nil, VolumeIdAttributesReadError(fmt.Sprintf("error reading aggregates for volume %s", - *volumeGetResponse.Name)) } if volumeGetResponse.Comment != nil { @@ -329,9 +373,6 @@ func lunInfoFromRestAttrsHelper(lunGetResponse *models.Lun) (*Lun, error) { if lunGetResponse == nil { return nil, fmt.Errorf("lun response is nil") } - if lunGetResponse.Comment != nil { - responseComment = *lunGetResponse.Comment - } var lunMap LunMap for _, record := range lunGetResponse.LunInlineLunMaps { @@ -356,7 +397,7 @@ func lunInfoFromRestAttrsHelper(lunGetResponse *models.Lun) (*Lun, error) { responseQos = *lunGetResponse.QosPolicy.Name } - if lunGetResponse.Status.Mapped != nil { + if lunGetResponse.Status != nil && lunGetResponse.Status.Mapped != nil { responseMapped = *lunGetResponse.Status.Mapped } @@ -560,7 +601,11 @@ func (d OntapAPIREST) FlexgroupModifySnapshotDirectoryAccess(ctx context.Context } func (d OntapAPIREST) FlexgroupInfo(ctx context.Context, volumeName string) (*Volume, error) { - volumeGetResponse, err := d.api.FlexGroupGetByName(ctx, volumeName) + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", "snapshot_policy", + "snapshot_directory_access_enabled", "space.snapshot.used", "space.snapshot.reserve_percent", + } + volumeGetResponse, err := d.api.FlexGroupGetByName(ctx, volumeName, fields) if err != nil { Logc(ctx).Errorf("Could not find volume with name: %v, error: %v", volumeName, err.Error()) return nil, err @@ -694,7 +739,12 @@ func (d OntapAPIREST) FlexgroupListByPrefix(ctx context.Context, prefix string) prefix += "*" } - flexgroupsResponse, err := d.api.FlexGroupGetAll(ctx, prefix) + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", + "snapshot_policy", "snapshot_directory_access_enabled", + "space.snapshot.used", "space.snapshot.reserve_percent", + } + flexgroupsResponse, err := d.api.FlexGroupGetAll(ctx, prefix, fields) if err != nil { return nil, err } @@ -759,7 +809,8 @@ func (d OntapAPIREST) GetSVMAggregateAttributes(ctx context.Context) (aggrList m } }() - result, err := d.api.AggregateList(ctx, "*") + fields := []string{"block_storage.primary.disk_type"} + result, err := d.api.AggregateList(ctx, "*", fields) if result == nil || result.Payload.NumRecords == nil || *result.Payload.NumRecords == 0 || result.Payload.AggregateResponseInlineRecords == nil { return nil, fmt.Errorf("could not retrieve aggregate information") } @@ -818,7 +869,8 @@ func hasRestAggrSpaceInformation(ctx context.Context, aggrSpace *models.Aggregat } func (d OntapAPIREST) GetSVMAggregateSpace(ctx context.Context, aggregate string) ([]SVMAggregateSpace, error) { - response, aggrSpaceErr := d.api.AggregateList(ctx, aggregate) + fields := []string{"space.footprint", "space.block_storage.size", "space.block_storage.used"} + response, aggrSpaceErr := d.api.AggregateList(ctx, aggregate, fields) if aggrSpaceErr != nil { return nil, aggrSpaceErr } @@ -974,7 +1026,12 @@ func (d OntapAPIREST) VolumeListByPrefix(ctx context.Context, prefix string) (Vo prefix += "*" } - volumesResponse, err := d.api.VolumeList(ctx, prefix) + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", + "snapshot_policy", "snapshot_directory_access_enabled", + "space.snapshot.used", "space.snapshot.reserve_percent", + } + volumesResponse, err := d.api.VolumeList(ctx, prefix, fields) if err != nil { return nil, err } @@ -997,7 +1054,40 @@ func (d OntapAPIREST) VolumeListByPrefix(ctx context.Context, prefix string) (Vo // VolumeListByAttrs is used to find bucket volumes for nas-eco and san-eco func (d OntapAPIREST) VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume) (Volumes, error) { - return d.api.VolumeListByAttrs(ctx, volumeAttrs) + fields := []string{ + "aggregates", + "snapshot_directory_access_enabled", + "encryption.enabled", + "guarantee.type", + "snapshot_policy.name", + } + volumesResponse, err := d.api.VolumeListByAttrs(ctx, volumeAttrs, fields) + if err != nil { + return nil, err + } + + if volumesResponse == nil { + if volumeAttrs.Name != "" { + Logc(ctx).Errorf("Could not find volume with name: %v", volumeAttrs.Name) + } else { + Logc(ctx).Errorf("Could not find volume") + } + } + + volumes := Volumes{} + + if volumesResponse.Payload != nil { + payload := *volumesResponse.Payload + for _, volume := range payload.VolumeResponseInlineRecords { + volumeInfo, err := FlexVolInfoFromRestAttrsHelper(volume) + if err != nil { + return nil, err + } + volumes = append(volumes, volumeInfo) + } + } + + return volumes, nil } func (d OntapAPIREST) ExportRuleCreate(ctx context.Context, policyName, desiredPolicyRules, nasProtocol string) error { @@ -1140,7 +1230,8 @@ func (d OntapAPIREST) QtreeCount(ctx context.Context, volumeName string) (int, e } func (d OntapAPIREST) QtreeListByPrefix(ctx context.Context, prefix, volumePrefix string) (Qtrees, error) { - qtreeList, err := d.api.QtreeList(ctx, prefix, volumePrefix) + fields := []string{"name", "volume"} + qtreeList, err := d.api.QtreeList(ctx, prefix, volumePrefix, fields) if err != nil { msg := fmt.Sprintf("Error listing qtrees; %v", err) Logc(ctx).Errorf(msg) @@ -1230,7 +1321,8 @@ func (d OntapAPIREST) QuotaResize(context.Context, string) error { } func (d OntapAPIREST) QuotaStatus(ctx context.Context, volumeName string) (string, error) { - volume, err := d.api.VolumeGetByName(ctx, volumeName) + fields := []string{"quota"} + volume, err := d.api.VolumeGetByName(ctx, volumeName, fields) if err != nil { return "", fmt.Errorf("error getting quota status for Flexvol %s: %v", volumeName, err) } @@ -1357,7 +1449,7 @@ func (d OntapAPIREST) VolumeWaitForStates(ctx context.Context, volumeName string var volumeState string checkVolumeState := func() error { - vol, err := d.api.VolumeGetByName(ctx, volumeName) + vol, err := d.api.VolumeGetByName(ctx, volumeName, []string{"state"}) if err != nil { volumeState = "" return fmt.Errorf("error getting volume %v; %v", volumeName, err) @@ -1421,7 +1513,6 @@ func (d OntapAPIREST) VolumeWaitForStates(ctx context.Context, volumeName string func (d OntapAPIREST) VolumeSnapshotInfo(ctx context.Context, snapshotName, sourceVolume string) (Snapshot, error) { emptyResult := Snapshot{} - volume, err := d.VolumeInfo(ctx, sourceVolume) if err != nil { return emptyResult, fmt.Errorf("error looking up source volume; %v", err) @@ -1679,8 +1770,20 @@ func (d OntapAPIREST) SnapmirrorGet( ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string, ) (*Snapmirror, error) { + fields := []string{ + "state", + "last_transfer_type", + "transfer.state", + "transfer.end_time", + "healthy", + "unhealthy_reason", + "policy.name", + "transfer_schedule.name", + "source.path", + "destination.path", + } snapmirrorResponse, err := d.api.SnapmirrorGet(ctx, localInternalVolumeName, localSVMName, remoteFlexvolName, - remoteSVMName) + remoteSVMName, fields) if err != nil { return nil, err } @@ -1909,7 +2012,21 @@ func (d OntapAPIREST) GetSVMPeers(ctx context.Context) ([]string, error) { } func (d OntapAPIREST) LunList(ctx context.Context, pattern string) (Luns, error) { - lunsResponse, err := d.api.LunList(ctx, pattern) + fields := []string{ + "lun_maps.igroup.name", + "lun_maps.logical_unit_number", + "space.size", + "comment", + "qos_policy.name", + "status.mapped", + "location.volume.name", + "create_time", + "enabled", + "serial_number", + "status.state", + "os_type", + } + lunsResponse, err := d.api.LunList(ctx, pattern, fields) if err != nil { return nil, err } @@ -1952,16 +2069,17 @@ func (d OntapAPIREST) LunCreate(ctx context.Context, lun Lun) error { } func (d OntapAPIREST) LunDestroy(ctx context.Context, lunPath string) error { - fields := LogFields{ + logFields := LogFields{ "Method": "LunDestroy", "Type": "OntapAPIREST", "Name": lunPath, } - Logd(ctx, d.driverName, d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> LunDestroy") + Logd(ctx, d.driverName, d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> LunDestroy") defer Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< LunDestroy") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< LunDestroy") - lun, err := d.api.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := d.api.LunGetByName(ctx, lunPath, fields) if err != nil { return fmt.Errorf("error getting LUN: %v", lunPath) } @@ -2057,7 +2175,7 @@ func (d OntapAPIREST) LunCloneCreate( fullCloneLunPath = fmt.Sprintf("/vol/%s/%s", flexvol, lunPath) } - fields := LogFields{ + logFields := LogFields{ "Method": "LunCloneCreate", "Type": "OntapAPIREST", "flexvol": flexvol, @@ -2067,11 +2185,12 @@ func (d OntapAPIREST) LunCloneCreate( "fullCloneLunPath": fullCloneLunPath, } Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> LunCloneCreate") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> LunCloneCreate") defer Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< LunCloneCreate") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< LunCloneCreate") - lunResponse, err := d.api.LunGetByName(ctx, fullSourceLunPath) + fields := []string{"os_type", "space.size"} + lunResponse, err := d.api.LunGetByName(ctx, fullSourceLunPath, fields) if err != nil { return err } @@ -2142,17 +2261,32 @@ func (d OntapAPIREST) LunSetQosPolicyGroup(ctx context.Context, lunPath string, } func (d OntapAPIREST) LunGetByName(ctx context.Context, name string) (*Lun, error) { - fields := LogFields{ + logFields := LogFields{ "Method": "LunGetByName", "Type": "OntapAPIREST", "LunPath": name, } Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> LunGetByName") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> LunGetByName") defer Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< LunGetByName") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< LunGetByName") + + fields := []string{ + "lun_maps.igroup.name", + "lun_maps.logical_unit_number", + "space.size", + "comment", + "qos_policy.name", + "status.mapped", + "location.volume.name", + "create_time", + "enabled", + "serial_number", + "status.state", + "os_type", + } - lunResponse, err := d.api.LunGetByName(ctx, name) + lunResponse, err := d.api.LunGetByName(ctx, name, fields) if err != nil { return nil, err } @@ -2238,7 +2372,8 @@ func (d OntapAPIREST) isLunMapped( ).Debug("LUN already mapped.") break } else { - lun, err := d.api.LunGetByName(ctx, lunPath) + fields := []string{"lun_maps.logical_unit_number"} + lun, err := d.api.LunGetByName(ctx, lunPath, fields) if err != nil { return alreadyMapped, lunID, err } @@ -2319,7 +2454,8 @@ func (d OntapAPIREST) LunUnmap(ctx context.Context, initiatorGroupName, lunPath func (d OntapAPIREST) LunListIgroupsMapped(ctx context.Context, lunPath string) ([]string, error) { var names []string - results, err := d.api.LunMapList(ctx, "*", lunPath) + fields := []string{""} + results, err := d.api.LunMapList(ctx, "*", lunPath, fields) if err != nil { return names, err } @@ -2339,7 +2475,8 @@ func (d OntapAPIREST) LunListIgroupsMapped(ctx context.Context, lunPath string) func (d OntapAPIREST) IgroupListLUNsMapped(ctx context.Context, initiatorGroupName string) ([]string, error) { var names []string - results, err := d.api.LunMapList(ctx, initiatorGroupName, "*") + fields := []string{""} + results, err := d.api.LunMapList(ctx, initiatorGroupName, "*", fields) if err != nil { return names, err } @@ -2384,7 +2521,14 @@ func (d OntapAPIREST) LunSetSize(ctx context.Context, lunPath, newSize string) ( func (d OntapAPIREST) IscsiInitiatorGetDefaultAuth(ctx context.Context) (IscsiInitiatorAuth, error) { authInfo := IscsiInitiatorAuth{} - response, err := d.api.IscsiInitiatorGetDefaultAuth(ctx) + fields := []string{ + "svm.name", + "chap.inbound.user", + "chap.outbound.user", + "initiator", + "authentication_type", + } + response, err := d.api.IscsiInitiatorGetDefaultAuth(ctx, fields) if err != nil { return authInfo, err } @@ -2449,7 +2593,8 @@ func (d OntapAPIREST) IscsiInitiatorSetDefaultAuth( func (d OntapAPIREST) IscsiInterfaceGet(ctx context.Context, svm string) ([]string, error) { var iSCSINodeNames []string - interfaceResponse, err := d.api.IscsiInterfaceGet(ctx) + fields := []string{"target.name", "enabled"} + interfaceResponse, err := d.api.IscsiInterfaceGet(ctx, fields) if err != nil { return nil, fmt.Errorf("could not get SVM iSCSI node name; %v", err) } @@ -2473,7 +2618,8 @@ func (d OntapAPIREST) IscsiInterfaceGet(ctx context.Context, svm string) ([]stri } func (d OntapAPIREST) IscsiNodeGetNameRequest(ctx context.Context) (string, error) { - result, err := d.api.IscsiNodeGetName(ctx) + fields := []string{"target.name"} + result, err := d.api.IscsiNodeGetName(ctx, fields) if err != nil { return "", err } @@ -2493,7 +2639,7 @@ func (d OntapAPIREST) IscsiNodeGetNameRequest(ctx context.Context) (string, erro } func (d OntapAPIREST) IgroupCreate(ctx context.Context, initiatorGroupName, initiatorGroupType, osType string) error { - fields := LogFields{ + logFields := LogFields{ "Method": "IgroupCreate", "Type": "OntapAPIREST", "InitiatorGroupName": initiatorGroupName, @@ -2501,11 +2647,12 @@ func (d OntapAPIREST) IgroupCreate(ctx context.Context, initiatorGroupName, init "OsType": osType, } Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> IgroupCreate") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> IgroupCreate") defer Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< IgroupCreate") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< IgroupCreate") - igroup, err := d.api.IgroupGetByName(ctx, initiatorGroupName) + fields := []string{""} + igroup, err := d.api.IgroupGetByName(ctx, initiatorGroupName, fields) if err != nil { return err } @@ -2574,7 +2721,8 @@ func (d OntapAPIREST) EnsureIgroupAdded( func (d OntapAPIREST) isIgroupAdded(ctx context.Context, initiator, initiatorGroupName string) (bool, error) { alreadyAdded := false - igroup, err := d.api.IgroupGetByName(ctx, initiatorGroupName) + fields := []string{"initiators.name"} + igroup, err := d.api.IgroupGetByName(ctx, initiatorGroupName, fields) if err != nil { return alreadyAdded, err } @@ -2591,16 +2739,17 @@ func (d OntapAPIREST) isIgroupAdded(ctx context.Context, initiator, initiatorGro } func (d OntapAPIREST) IgroupList(ctx context.Context) ([]string, error) { - fields := LogFields{ + logFields := LogFields{ "Method": "IgroupList", "Type": "OntapAPIREST", } Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> IgroupList") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> IgroupList") defer Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< IgroupList") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< IgroupList") - igroupsResponse, err := d.api.IgroupList(ctx, "") + fields := []string{""} + igroupsResponse, err := d.api.IgroupList(ctx, "", fields) if err != nil { return nil, err } @@ -2637,7 +2786,8 @@ func (d OntapAPIREST) IgroupGetByName(ctx context.Context, initiatorGroupName st error, ) { // Discover mapped initiators - iGroupResponse, err := d.api.IgroupGetByName(ctx, initiatorGroupName) + fields := []string{"initiators.name"} + iGroupResponse, err := d.api.IgroupGetByName(ctx, initiatorGroupName, fields) if err != nil { return nil, fmt.Errorf("failed to read igroup info; %v", err) } @@ -2760,17 +2910,25 @@ func (d OntapAPIREST) NVMeNamespaceSetSize(ctx context.Context, nsUUID string, n // NVMeNamespaceGetByName returns NVMe namespace with the specified name. func (d OntapAPIREST) NVMeNamespaceGetByName(ctx context.Context, name string) (*NVMeNamespace, error) { - fields := LogFields{ + logFields := LogFields{ "Method": "NVMeNamespaceGetByName", "Type": "OntapAPIREST", "LunPath": name, } Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> NVMeNamespaceGetByName") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> NVMeNamespaceGetByName") defer Logd(ctx, d.driverName, - d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< NVMeNamespaceGetByName") + d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< NVMeNamespaceGetByName") - nsResponse, err := d.api.NVMeNamespaceGetByName(ctx, name) + fields := []string{ + "os_type", + "location.volume.name", + "space.size", + "space.block_size", + "status.state", + "comment", + } + nsResponse, err := d.api.NVMeNamespaceGetByName(ctx, name, fields) if err != nil { return nil, err } @@ -2783,7 +2941,15 @@ func (d OntapAPIREST) NVMeNamespaceGetByName(ctx context.Context, name string) ( // NVMeNamespaceList returns the list of NVMe namespaces with the specified pattern. func (d OntapAPIREST) NVMeNamespaceList(ctx context.Context, pattern string) (NVMeNamespaces, error) { - nsResponse, err := d.api.NVMeNamespaceList(ctx, pattern) + fields := []string{ + "os_type", + "location.volume.name", + "space.size", + "space.block_size", + "status.state", + "comment", + } + nsResponse, err := d.api.NVMeNamespaceList(ctx, pattern, fields) if err != nil { return nil, err } @@ -2955,15 +3121,16 @@ func (d OntapAPIREST) NVMeRemoveHostFromSubsystem(ctx context.Context, hostNQN, // NVMeSubsystemCreate Checks if the subsystem is already there or not. If not, creates a new one. func (d OntapAPIREST) NVMeSubsystemCreate(ctx context.Context, subsystemName string) (*NVMeSubsystem, error) { - fields := LogFields{ + logFields := LogFields{ "Method": "SubsystemCreate", "Type": "OntapAPIREST", "SubsystemName": subsystemName, } - Logd(ctx, d.driverName, d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> SubsystemCreate") - defer Logd(ctx, d.driverName, d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< SubsystemCreate") + Logd(ctx, d.driverName, d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace(">>>> SubsystemCreate") + defer Logd(ctx, d.driverName, d.api.ClientConfig().DebugTraceFlags["method"]).WithFields(logFields).Trace("<<<< SubsystemCreate") - subsystem, err := d.api.NVMeSubsystemGetByName(ctx, subsystemName) + fields := []string{"target_nqn"} + subsystem, err := d.api.NVMeSubsystemGetByName(ctx, subsystemName, fields) if err != nil { Logc(ctx).Infof("problem getting subsystem; %v", err) return nil, err diff --git a/storage_drivers/ontap/api/abstraction_rest_test.go b/storage_drivers/ontap/api/abstraction_rest_test.go index 312a1aa4f..ba29b629f 100644 --- a/storage_drivers/ontap/api/abstraction_rest_test.go +++ b/storage_drivers/ontap/api/abstraction_rest_test.go @@ -45,19 +45,19 @@ func TestEnsureIGroupAdded(t *testing.T) { // common call for all subtests rsi.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, errors.New("error getting igroup")) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, errors.New("error getting igroup")) err = oapi.EnsureIgroupAdded(ctx, initiatorGroup, initiator) assert.Errorf(t, err, "error getting igroup") // No error and igroup not present - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, nil) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, nil) rsi.EXPECT().IgroupAdd(ctx, initiatorGroup, initiator).Return(nil) err = oapi.EnsureIgroupAdded(ctx, initiatorGroup, initiator) assert.NoError(t, err) // positive test case igroup := &models.Igroup{IgroupInlineInitiators: []*models.IgroupInlineInitiatorsInlineArrayItem{{Name: utils.Ptr(initiator)}}} - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(igroup, nil) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(igroup, nil) err = oapi.EnsureIgroupAdded(ctx, initiatorGroup, initiator) assert.NoError(t, err) } @@ -102,14 +102,14 @@ func TestEnsureLunMapped(t *testing.T) { // positive test case where lun == nil, lunGetByName gets called to find the LUN details lun := &models.Lun{LunInlineLunMaps: []*models.LunInlineLunMapsInlineArrayItem{{LogicalUnitNumber: number}}} - rsi.EXPECT().LunGetByName(ctx, lunPath).Return(lun, nil) + rsi.EXPECT().LunGetByName(ctx, lunPath, gomock.Any()).Return(lun, nil) rsi.EXPECT().LunMapInfo(ctx, "", lunPath).Return(lunMapCollection, nil) resultLun, err = oapi.EnsureLunMapped(ctx, initiatorGroup, lunPath) assert.Nil(t, err) assert.Equal(t, int(*number), resultLun, "lun count does not match") // record.LogicalUnitNumber == nil and lunGetByName returns error - rsi.EXPECT().LunGetByName(ctx, lunPath).Return(nil, errors.New("error getting LUN by name")) + rsi.EXPECT().LunGetByName(ctx, lunPath, gomock.Any()).Return(nil, errors.New("error getting LUN by name")) rsi.EXPECT().LunMapInfo(ctx, "", lunPath).Return(lunMapCollection, nil) resultLun, err = oapi.EnsureLunMapped(ctx, initiatorGroup, lunPath) assert.Errorf(t, err, "error getting LUN by name") @@ -119,7 +119,7 @@ func TestEnsureLunMapped(t *testing.T) { lunMapCreated := &s_a_n.LunMapCreateCreated{ Payload: lunPayload, } - rsi.EXPECT().LunGetByName(ctx, lunPath).Return(nil, nil) + rsi.EXPECT().LunGetByName(ctx, lunPath, gomock.Any()).Return(nil, nil) rsi.EXPECT().LunMapInfo(ctx, "", lunPath).Return(lunMapCollection, nil) rsi.EXPECT().LunMap(ctx, initiatorGroup, lunPath, -1).Return(lunMapCreated, nil) resultLun, err = oapi.EnsureLunMapped(ctx, initiatorGroup, lunPath) @@ -304,7 +304,7 @@ func TestNVMeNamespaceGetByName(t *testing.T) { } // case 1: No error while getting namespace - mock.EXPECT().NVMeNamespaceGetByName(ctx, Name).Return(ns, nil) + mock.EXPECT().NVMeNamespaceGetByName(ctx, Name, gomock.Any()).Return(ns, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() namespace, err := oapi.NVMeNamespaceGetByName(ctx, Name) assert.NoError(t, err) @@ -312,13 +312,13 @@ func TestNVMeNamespaceGetByName(t *testing.T) { assert.Equal(t, Name, namespace.Name, "namespace name does not match") // case 2: error while getting namespace - mock.EXPECT().NVMeNamespaceGetByName(ctx, Name).Return(nil, fmt.Errorf("Error while getting namespace")) + mock.EXPECT().NVMeNamespaceGetByName(ctx, Name, gomock.Any()).Return(nil, fmt.Errorf("Error while getting namespace")) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() namespace, err = oapi.NVMeNamespaceGetByName(ctx, Name) assert.Error(t, err) // case 3: no error while getting namespace but response is nil - mock.EXPECT().NVMeNamespaceGetByName(ctx, Name).Return(nil, nil) + mock.EXPECT().NVMeNamespaceGetByName(ctx, Name, gomock.Any()).Return(nil, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() namespace, err = oapi.NVMeNamespaceGetByName(ctx, Name) assert.Error(t, err) @@ -370,14 +370,14 @@ func TestNVMeNamespaceList(t *testing.T) { } // case 1: No error while getting namespace - mock.EXPECT().NVMeNamespaceList(ctx, Name).Return(nsResp, nil) + mock.EXPECT().NVMeNamespaceList(ctx, Name, gomock.Any()).Return(nsResp, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() namespaces, err := oapi.NVMeNamespaceList(ctx, Name) assert.NoError(t, err) assert.Equal(t, Name, namespaces[0].Name, "namespace does not match") // case 2: error while getting namespace list - mock.EXPECT().NVMeNamespaceList(ctx, Name).Return(nil, fmt.Errorf("Error getting namespace list")) + mock.EXPECT().NVMeNamespaceList(ctx, Name, gomock.Any()).Return(nil, fmt.Errorf("Error getting namespace list")) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() _, err = oapi.NVMeNamespaceList(ctx, Name) assert.Error(t, err) @@ -388,7 +388,7 @@ func TestNVMeNamespaceList(t *testing.T) { NvmeNamespaceResponseInlineRecords: []*models.NvmeNamespace{nil}, }, } - mock.EXPECT().NVMeNamespaceList(ctx, Name).Return(nsResp1, nil).AnyTimes() + mock.EXPECT().NVMeNamespaceList(ctx, Name, gomock.Any()).Return(nsResp1, nil).AnyTimes() mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() _, err = oapi.NVMeNamespaceList(ctx, Name) assert.Error(t, err) @@ -622,7 +622,7 @@ func TestNVMeSubsystemCreate(t *testing.T) { TargetNqn: &targetNQN, } - mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName).Return(subsys, nil) + mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName, gomock.Any()).Return(subsys, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() subsystem, err := oapi.NVMeSubsystemCreate(ctx, subsystemName) assert.NoError(t, err) @@ -631,13 +631,13 @@ func TestNVMeSubsystemCreate(t *testing.T) { assert.Equal(t, subsystem.NQN, targetNQN, "host does not match") // case 2: Error getting susbsystem info from backend - mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName).Return(nil, fmt.Errorf("Error getting susbsystem info")) + mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName, gomock.Any()).Return(nil, fmt.Errorf("Error getting susbsystem info")) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() _, err = oapi.NVMeSubsystemCreate(ctx, subsystemName) assert.Error(t, err) // case 3: Subsystem not present, create a new one successfully - mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName).Return(nil, nil) + mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName, gomock.Any()).Return(nil, nil) mock.EXPECT().NVMeSubsystemCreate(ctx, subsystemName).Return(subsys, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() newsubsys, err := oapi.NVMeSubsystemCreate(ctx, subsystemName) @@ -647,14 +647,14 @@ func TestNVMeSubsystemCreate(t *testing.T) { assert.Equal(t, newsubsys.NQN, targetNQN, "host does not match") // case 4: Subsystem not present, create a new one with failure - mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName).Return(nil, nil) + mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName, gomock.Any()).Return(nil, nil) mock.EXPECT().NVMeSubsystemCreate(ctx, subsystemName).Return(nil, fmt.Errorf("Error creating susbsystem")) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() newsubsys, err = oapi.NVMeSubsystemCreate(ctx, subsystemName) assert.Error(t, err) // case 5: Subsystem not present, create a new one but returned nil - mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName).Return(nil, nil) + mock.EXPECT().NVMeSubsystemGetByName(ctx, subsystemName, gomock.Any()).Return(nil, nil) mock.EXPECT().NVMeSubsystemCreate(ctx, subsystemName).Return(nil, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() newsubsys, err = oapi.NVMeSubsystemCreate(ctx, subsystemName) @@ -907,7 +907,7 @@ func TestVolumeWaitForStates(t *testing.T) { // Test1: Error - While getting the volume mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().VolumeGetByName(ctx, volName).AnyTimes().Return(nil, fmt.Errorf("Error getting the volume")) + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).AnyTimes().Return(nil, fmt.Errorf("Error getting the volume")) currentState, err := oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, abortStates, maxElapsedTime) @@ -923,7 +923,7 @@ func TestVolumeWaitForStates(t *testing.T) { assert.NoError(t, err) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().VolumeGetByName(ctx, volName).AnyTimes().Return(nil, nil) + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).AnyTimes().Return(nil, nil) currentState, err = oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, abortStates, maxElapsedTime) @@ -937,7 +937,7 @@ func TestVolumeWaitForStates(t *testing.T) { mock = mockapi.NewMockRestClientInterface(ctrl) oapi, err = api.NewOntapAPIRESTFromRestClientInterface(mock) - mock.EXPECT().VolumeGetByName(ctx, volName).Return(volume, nil) + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).Return(volume, nil) mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() currentState, err = oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, abortStates, maxElapsedTime) @@ -955,7 +955,7 @@ func TestVolumeWaitForStates(t *testing.T) { abortStates = []string{"error"} volume.State = &errorState - mock.EXPECT().VolumeGetByName(ctx, volName).Return(volume, nil).AnyTimes() + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).Return(volume, nil).AnyTimes() mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() currentState, err = oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, abortStates, maxElapsedTime) @@ -973,7 +973,7 @@ func TestVolumeWaitForStates(t *testing.T) { abortStates = []string{"fakeerrorState"} volume.State = &errorState - mock.EXPECT().VolumeGetByName(ctx, volName).Return(volume, nil).AnyTimes() + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).Return(volume, nil).AnyTimes() mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() currentState, err = oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, abortStates, maxElapsedTime) @@ -992,7 +992,7 @@ func TestVolumeWaitForStates(t *testing.T) { volState := "unknown" volume.State = &volState - mock.EXPECT().VolumeGetByName(ctx, volName).Return(volume, nil).AnyTimes() + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).Return(volume, nil).AnyTimes() mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() currentState, err = oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, newAbortState, maxElapsedTime) @@ -1010,7 +1010,7 @@ func TestVolumeWaitForStates(t *testing.T) { volState = "online" volume.State = &volState - mock.EXPECT().VolumeGetByName(ctx, volName).Return(volume, nil).AnyTimes() + mock.EXPECT().VolumeGetByName(ctx, volName, gomock.Any()).Return(volume, nil).AnyTimes() mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() currentState, err = oapi.VolumeWaitForStates(ctx, "fakeVolName", desiredStates, newAbortState, maxElapsedTime) @@ -1076,7 +1076,7 @@ func TestIgroupList(t *testing.T) { // case 1: No error while getting Igroup list mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().IgroupList(ctx, "").Return(&igroupResponseOK, nil) + mock.EXPECT().IgroupList(ctx, "", gomock.Any()).Return(&igroupResponseOK, nil) igroups, err1 := oapi.IgroupList(ctx) assert.NoError(t, err1, "error while getting Igroup list") @@ -1085,7 +1085,7 @@ func TestIgroupList(t *testing.T) { // case 2: Error returned while getting igroup list mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().IgroupList(ctx, "").Return(nil, fmt.Errorf("failed to get igroup")) + mock.EXPECT().IgroupList(ctx, "", gomock.Any()).Return(nil, fmt.Errorf("failed to get igroup")) _, err1 = oapi.IgroupList(ctx) assert.Error(t, err1, "No error while getting Igroup list") @@ -1093,7 +1093,7 @@ func TestIgroupList(t *testing.T) { // case 3: Empty payload returned while getting igroup list igroupResponseOK = s_a_n.IgroupCollectionGetOK{Payload: nil} mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().IgroupList(ctx, "").Return(&igroupResponseOK, nil) + mock.EXPECT().IgroupList(ctx, "", gomock.Any()).Return(&igroupResponseOK, nil) igroups, err1 = oapi.IgroupList(ctx) assert.NoError(t, err1, "error while getting Igroup list") @@ -1107,7 +1107,7 @@ func TestIgroupList(t *testing.T) { igroupResponseOK = s_a_n.IgroupCollectionGetOK{Payload: igroupResponse} mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().IgroupList(ctx, "").Return(&igroupResponseOK, nil) + mock.EXPECT().IgroupList(ctx, "", gomock.Any()).Return(&igroupResponseOK, nil) igroups, err1 = oapi.IgroupList(ctx) assert.NoError(t, err1, "error while getting Igroup list") @@ -1167,7 +1167,7 @@ func TestIgroupGetByName(t *testing.T) { // case 1: No Error returned while getting igroup by name. mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(&igroup, nil) + mock.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(&igroup, nil) mappedIQNs, err1 := oapi.IgroupGetByName(ctx, initiatorGroup) assert.NoError(t, err1, "error returned while getting igroup by name") @@ -1177,7 +1177,7 @@ func TestIgroupGetByName(t *testing.T) { // case 2: Error returned while getting igroup by name. mock.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() - mock.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, fmt.Errorf("Failed to get igroup by name")) + mock.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, fmt.Errorf("Failed to get igroup by name")) _, err1 = oapi.IgroupGetByName(ctx, initiatorGroup) @@ -1475,31 +1475,24 @@ func TestVolumeInfo(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Get volume. Returned volume list - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) _, err := oapi.VolumeInfo(ctx, "vol1") assert.NoError(t, err, "error returned while getting a volume") // case 2: Get volume. Returned empty list - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(nil, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(nil, nil) _, err = oapi.VolumeInfo(ctx, "vol1") assert.Error(t, err, "no error returned while getting a volume") // case 3: Get volume. Backend returned an error. - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(nil, fmt.Errorf("Failed to get volume")) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("Failed to get volume")) _, err = oapi.VolumeInfo(ctx, "vol1") assert.Error(t, err, "no error returned while getting a volume") // case 4: Get volume. Returned volume list with volume name nil // Want an error from "VolumeInfoFromRestAttrsHelper" function. volume.Name = nil - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) - _, err = oapi.VolumeInfo(ctx, "vol1") - assert.Error(t, err, "no error returned while getting a volume") - - // case 5: Get volume. Returned volume list with volume aggregates nil - volume.Name = utils.Ptr("vol1") - volume.VolumeInlineAggregates = nil - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) _, err = oapi.VolumeInfo(ctx, "vol1") assert.Error(t, err, "no error returned while getting a volume") } @@ -1649,23 +1642,23 @@ func TestFlexgroupInfo(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Flexgroup get by name - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) _, err := oapi.FlexgroupInfo(ctx, "vol1") assert.NoError(t, err, "error returned while getting a flexgroup volume") // case 2: Flexgroup get by name returned volume info nil - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(nil, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(nil, nil) _, err = oapi.FlexgroupInfo(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup volume") // case 3: Flexgroup get by name, returned error. - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(nil, fmt.Errorf("failed to get flexgroup volume")) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("failed to get flexgroup volume")) _, err = oapi.FlexgroupInfo(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup volume") // case 4: Flexgroup get by name. Response contain volume name is nil volume.Name = nil - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) _, err = oapi.FlexgroupInfo(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup volume") } @@ -1760,23 +1753,23 @@ func TestFlexgroupSnapshotCreate(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Flexgroup snapshot create - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotCreateAndWait(ctx, volumeUUID, "fake-snapshot").Return(nil) err := oapi.FlexgroupSnapshotCreate(ctx, "fake-snapshot", "vol1") assert.NoError(t, err, "error returned while creating snapshot of a flexgroup") // case 2: Flexgroup snapshot create. Could not get the volume info - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(nil, fmt.Errorf("Failed to get flexgroup")) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("Failed to get flexgroup")) err = oapi.FlexgroupSnapshotCreate(ctx, "fake-snapshot", "vol1") assert.Error(t, err, "no error returned while creating snapshot of a flexgroup") // case 3: Flexgroup snapshot create returned response nil - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(nil, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(nil, nil) err = oapi.FlexgroupSnapshotCreate(ctx, "fake-snapshot", "vol1") assert.Error(t, err, "no error returned while creating snapshot of a flexgroup") // case 4: Flexgroup snapshot create. Could not create snapshot. - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotCreateAndWait(ctx, volumeUUID, "fake-snapshot").Return(fmt.Errorf("snapshot creation failed")) err = oapi.FlexgroupSnapshotCreate(ctx, "fake-snapshot", "vol1") assert.Error(t, err, "no error returned while creating snapshot of a flexgroup") @@ -1797,7 +1790,7 @@ func TestFlexgroupSnapshotList(t *testing.T) { snapshotResponseOK := storage.SnapshotCollectionGetOK{Payload: &snapshotResponse} // case 1: Flexgroup get info. - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(&snapshotResponseOK, nil) snapshots, err := oapi.FlexgroupSnapshotList(ctx, "vol1") assert.NoError(t, err, "error returned while getting a flexgroup") @@ -1806,30 +1799,30 @@ func TestFlexgroupSnapshotList(t *testing.T) { assert.Equal(t, createTime1.String(), snapshots[0].CreateTime) // case 2: Flexgroup get by name returned error - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(nil, fmt.Errorf("failed to get flexgroup")) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("failed to get flexgroup")) _, err = oapi.FlexgroupSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup") // case 3: Flexgroup get by name returned nil - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(nil, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(nil, nil) _, err = oapi.FlexgroupSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup") // case 4: Flexgroup snapshot list returned nil - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(nil, nil) snapshots, err = oapi.FlexgroupSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup") // case 5: Flexgroup snapshot list returned error - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(nil, fmt.Errorf("failed to get snapshot info")) snapshots, err = oapi.FlexgroupSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup") // case 6: Flexgroup snapshot list returned payload nil snapshotResponseOK = storage.SnapshotCollectionGetOK{Payload: nil} - rsi.EXPECT().FlexGroupGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(&snapshotResponseOK, nil) _, err = oapi.FlexgroupSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a flexgroup") @@ -1900,24 +1893,24 @@ func TestFlexgroupListByPrefix(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Flexgroup get list by prefix - rsi.EXPECT().FlexGroupGetAll(ctx, *volume.Name+"*").Return(&volumeResponse, nil) + rsi.EXPECT().FlexGroupGetAll(ctx, *volume.Name+"*", gomock.Any()).Return(&volumeResponse, nil) volumeInfo, err := oapi.FlexgroupListByPrefix(ctx, *volume.Name) assert.NoError(t, err, "error returned while getting a volume") assert.Equal(t, *volume.Name, volumeInfo[0].Name) // case 2: Flexgroup get returned empty list - rsi.EXPECT().FlexGroupGetAll(ctx, *volume.Name+"*").Return(nil, nil) + rsi.EXPECT().FlexGroupGetAll(ctx, *volume.Name+"*", gomock.Any()).Return(nil, nil) volumeInfo, err = oapi.FlexgroupListByPrefix(ctx, *volume.Name) assert.Error(t, err, "no error returned while getting a volume") // case 3: Flexgroup get returned error - rsi.EXPECT().FlexGroupGetAll(ctx, *volume.Name+"*").Return(nil, fmt.Errorf("failed to get flexgroup")) + rsi.EXPECT().FlexGroupGetAll(ctx, *volume.Name+"*", gomock.Any()).Return(nil, fmt.Errorf("failed to get flexgroup")) volumeInfo, err = oapi.FlexgroupListByPrefix(ctx, *volume.Name) assert.Error(t, err, "no error returned while getting a volume") // case 4: Flexgroup get list, response contain volume name nil volume.Name = nil - rsi.EXPECT().FlexGroupGetAll(ctx, "*").Return(&volumeResponse, nil) + rsi.EXPECT().FlexGroupGetAll(ctx, "*", gomock.Any()).Return(&volumeResponse, nil) volumeInfo, err = oapi.FlexgroupListByPrefix(ctx, "*") assert.Error(t, err, "no error returned while getting a volume") } @@ -2030,13 +2023,13 @@ func TestGetSVMAggregateAttributes(t *testing.T) { aggregateResponse := getAggregateInfo("aggr1", "fc", int64(1), nil) // case 1: Get SVM aggregate - rsi.EXPECT().AggregateList(ctx, gomock.Any()).Return(aggregateResponse, nil) + rsi.EXPECT().AggregateList(ctx, gomock.Any(), gomock.Any()).Return(aggregateResponse, nil) aggrList, err := oapi.GetSVMAggregateAttributes(ctx) assert.NoError(t, err, "error returned while getting a svm aggregate") assert.Equal(t, "fc", aggrList["aggr1"]) // case 2: Get SVM aggregate returned nil list - rsi.EXPECT().AggregateList(ctx, gomock.Any()).Return(nil, nil) + rsi.EXPECT().AggregateList(ctx, gomock.Any(), gomock.Any()).Return(nil, nil) aggrList, err = oapi.GetSVMAggregateAttributes(ctx) assert.Error(t, err, "no error returned while getting a svm aggregate") assert.Nil(t, aggrList) @@ -2044,14 +2037,14 @@ func TestGetSVMAggregateAttributes(t *testing.T) { aggregateResponse = getAggregateInfo("", "fc", int64(1), nil) // case 3: Get SVM aggregate returned empty list - rsi.EXPECT().AggregateList(ctx, gomock.Any()).Return(aggregateResponse, nil) + rsi.EXPECT().AggregateList(ctx, gomock.Any(), gomock.Any()).Return(aggregateResponse, nil) aggrList, err = oapi.GetSVMAggregateAttributes(ctx) assert.NoError(t, err, "error returned while getting a svm aggregate") assert.Empty(t, aggrList) // case 4: Get SVM aggregate returned error aggregateResponse = getAggregateInfo("", "fc", int64(0), nil) - rsi.EXPECT().AggregateList(ctx, gomock.Any()).Return(aggregateResponse, nil) + rsi.EXPECT().AggregateList(ctx, gomock.Any(), gomock.Any()).Return(aggregateResponse, nil) aggrList, err = oapi.GetSVMAggregateAttributes(ctx) assert.Error(t, err, "no error returned while getting a svm aggregate") } @@ -2119,7 +2112,7 @@ func TestGetSVMAggregateSpace(t *testing.T) { aggrResponse := getAggregateInfo("aggr1", "fc", int64(0), &aggrSpace1) // case 1: Get SVM aggregate space - rsi.EXPECT().AggregateList(ctx, "aggr1").Return(aggrResponse, nil) + rsi.EXPECT().AggregateList(ctx, "aggr1", gomock.Any()).Return(aggrResponse, nil) aggrSpaceList, err := oapi.GetSVMAggregateSpace(ctx, "aggr1") assert.NoError(t, err, "error returned while getting a aggregate space") assert.Equal(t, size, aggrSpaceList[0].Size()) @@ -2135,7 +2128,7 @@ func TestGetSVMAggregateSpace(t *testing.T) { // case 2: Get SVM aggregate space, Footprint nil aggrResponse2 := getAggregateInfo("aggr1", "fc", int64(1), &aggrSpace2) - rsi.EXPECT().AggregateList(ctx, "aggr1").Return(aggrResponse2, nil) + rsi.EXPECT().AggregateList(ctx, "aggr1", gomock.Any()).Return(aggrResponse2, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr1") assert.NoError(t, err, "error returned while getting a aggregate space") @@ -2147,7 +2140,7 @@ func TestGetSVMAggregateSpace(t *testing.T) { // case 3: Get SVM aggregate space, Footprint and used size nil aggrResponse3 := getAggregateInfo("aggr1", "fc", int64(1), &aggrSpace3) - rsi.EXPECT().AggregateList(ctx, "aggr1").Return(aggrResponse3, nil) + rsi.EXPECT().AggregateList(ctx, "aggr1", gomock.Any()).Return(aggrResponse3, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr1") assert.NoError(t, err, "error returned while getting a aggregate space") @@ -2155,25 +2148,25 @@ func TestGetSVMAggregateSpace(t *testing.T) { // case 4: Get SVM aggregate space, Size nil aggrResponse4 := getAggregateInfo("aggr1", "fc", int64(1), &aggrSpace4) - rsi.EXPECT().AggregateList(ctx, "aggr1").Return(aggrResponse4, nil) + rsi.EXPECT().AggregateList(ctx, "aggr1", gomock.Any()).Return(aggrResponse4, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr1") assert.NoError(t, err, "error returned while getting a aggregate space") // case 5: Get SVM aggregate space, aggregate space nil aggrResponse5 := getAggregateInfo("aggr1", "fc", int64(1), nil) - rsi.EXPECT().AggregateList(ctx, "aggr1").Return(aggrResponse5, nil) + rsi.EXPECT().AggregateList(ctx, "aggr1", gomock.Any()).Return(aggrResponse5, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr1") assert.NoError(t, err, "error returned while getting a aggregate space") // case 6: Get SVM aggregate space, aggregate name not present aggrResponse6 := getAggregateInfo("aggr1", "fc", int64(1), nil) - rsi.EXPECT().AggregateList(ctx, "aggr2").Return(aggrResponse6, nil) + rsi.EXPECT().AggregateList(ctx, "aggr2", gomock.Any()).Return(aggrResponse6, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr2") assert.NoError(t, err, "error returned while getting a aggregate space") // case 7: Get SVM aggregate space, aggregate name is empty aggrResponse7 := getAggregateInfo("", "fc", int64(1), nil) - rsi.EXPECT().AggregateList(ctx, "aggr2").Return(aggrResponse7, nil) + rsi.EXPECT().AggregateList(ctx, "aggr2", gomock.Any()).Return(aggrResponse7, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr2") assert.NoError(t, err, "error returned while getting a aggregate space") @@ -2181,18 +2174,18 @@ func TestGetSVMAggregateSpace(t *testing.T) { aggrResponse8 := storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{}, } - rsi.EXPECT().AggregateList(ctx, "aggr2").Return(&aggrResponse8, nil) + rsi.EXPECT().AggregateList(ctx, "aggr2", gomock.Any()).Return(&aggrResponse8, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr2") assert.NoError(t, err, "error returned while getting a aggregate space") // case 9: Get SVM aggregate space, payload is nil aggrResponse9 := storage.AggregateCollectionGetOK{} - rsi.EXPECT().AggregateList(ctx, "aggr2").Return(&aggrResponse9, nil) + rsi.EXPECT().AggregateList(ctx, "aggr2", gomock.Any()).Return(&aggrResponse9, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr2") assert.Error(t, err, "no error returned while getting a aggregate space") // case 10: Get SVM aggregate space, aggregate list is nil - rsi.EXPECT().AggregateList(ctx, "aggr2").Return(nil, nil) + rsi.EXPECT().AggregateList(ctx, "aggr2", gomock.Any()).Return(nil, nil) _, err = oapi.GetSVMAggregateSpace(ctx, "aggr2") assert.Error(t, err, "no error returned while getting a aggregate space") } @@ -2358,7 +2351,7 @@ func TestVolumeListByPrefix(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) - rsi.EXPECT().VolumeList(ctx, *volume.Name+"*").Return(&volumeResponse1, nil) + rsi.EXPECT().VolumeList(ctx, *volume.Name+"*", gomock.Any()).Return(&volumeResponse1, nil) volumeInfo, err := oapi.VolumeListByPrefix(ctx, *volume.Name) assert.NoError(t, err, "error returned while getting list of volumes") assert.Equal(t, *volume.Name, volumeInfo[0].Name) @@ -2370,23 +2363,34 @@ func TestVolumeListByPrefix(t *testing.T) { } // case 1: Get volume positive test - rsi.EXPECT().VolumeList(ctx, *volume.Name+"*").Return(&volumeResponse2, nil) + rsi.EXPECT().VolumeList(ctx, *volume.Name+"*", gomock.Any()).Return(&volumeResponse2, nil) _, err = oapi.VolumeListByPrefix(ctx, *volume.Name) assert.Error(t, err, "no error returned while getting a volume info") // case 2: Get volume negative test - rsi.EXPECT().VolumeList(ctx, *volume.Name+"*").Return(nil, fmt.Errorf("failed to get volume")) + rsi.EXPECT().VolumeList(ctx, *volume.Name+"*", gomock.Any()).Return(nil, fmt.Errorf("failed to get volume")) _, err = oapi.VolumeListByPrefix(ctx, *volume.Name) assert.Error(t, err, "no error returned while getting a volume info") } func TestVolumeListByAttrs(t *testing.T) { - volume := api.Volume{Name: "vol1"} - volumes := []*api.Volume{&volume} + volName := "vol1" + volumeResponse := storage.VolumeCollectionGetOK{ + Payload: &models.VolumeResponse{ + VolumeResponseInlineRecords: []*models.Volume{ + { + Name: &volName, + }, + }, + }, + } + volume1 := api.Volume{ + Name: volName, + } oapi, rsi := newMockOntapAPIREST(t) - rsi.EXPECT().VolumeListByAttrs(ctx, &volume).Return(volumes, nil) - volumeList, err := oapi.VolumeListByAttrs(ctx, &volume) + rsi.EXPECT().VolumeListByAttrs(ctx, gomock.Any(), gomock.Any()).Return(&volumeResponse, nil) + volumeList, err := oapi.VolumeListByAttrs(ctx, &volume1) assert.NoError(t, err, "error returned while getting a volume list by attribute") assert.Equal(t, "vol1", volumeList[0].Name) } @@ -2582,13 +2586,13 @@ func TestQtreeListByPrefix(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Get the Qtree list - rsi.EXPECT().QtreeList(ctx, gomock.Any(), gomock.Any()).Return(&qtreeResponse, nil) + rsi.EXPECT().QtreeList(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(&qtreeResponse, nil) volumeInfo, err := oapi.QtreeListByPrefix(ctx, *qtree.Name, *qtree.Volume.Name) assert.NoError(t, err, "error returned while getting a Qtree list") assert.Equal(t, *qtree.Name, volumeInfo[0].Name) // case 2: Get the Qtree list failed. Backend returned an error - rsi.EXPECT().QtreeList(ctx, gomock.Any(), gomock.Any()).Return(nil, + rsi.EXPECT().QtreeList(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("failed to get qtree for given prefix")) _, err = oapi.QtreeListByPrefix(ctx, *qtree.Name, *qtree.Volume.Name) assert.Error(t, err, "no error returned while getting a Qtree list") @@ -2710,26 +2714,26 @@ func TestQuotaStatus(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Quota status positive test - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) quotaStatus, err := oapi.QuotaStatus(ctx, "vol1") assert.NoError(t, err, "error returned while getting a quota status") assert.Equal(t, *volume.Quota.State, quotaStatus) - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(nil, fmt.Errorf("error enabling quota")) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("error enabling quota")) quotaStatus, err = oapi.QuotaStatus(ctx, "vol1") assert.Error(t, err, "no error returned while getting a quota status") volume.Quota.State = nil // case 2: Quota status in volume is nil - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) quotaStatus, err = oapi.QuotaStatus(ctx, "vol1") assert.Error(t, err, "no error returned while getting a quota status") volume.Quota = nil // case 3: Quota in volume is nil - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) quotaStatus, err = oapi.QuotaStatus(ctx, "vol1") assert.Error(t, err, "no error returned while getting a quota status") } @@ -2802,18 +2806,18 @@ func TestVolumeSnapshotCreate(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Create volume snapshot - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotCreateAndWait(ctx, *volume.UUID, "fake-snapshot").Return(nil) err := oapi.VolumeSnapshotCreate(ctx, "fake-snapshot", "vol1") assert.NoError(t, err, "error returned while creating a snapshot") // case 2: Create volume snapshot, parent volume verification returned error - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(nil, fmt.Errorf("Failed to get flexgroup")) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("Failed to get flexgroup")) err = oapi.VolumeSnapshotCreate(ctx, "fake-snapshot", "vol1") assert.Error(t, err, "no error returned while creating a snapshot") // case 3: Create volume snapshot returned error - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotCreateAndWait(ctx, *volume.UUID, "fake-snapshot").Return(fmt.Errorf( "snapshot creation failed")) err = oapi.VolumeSnapshotCreate(ctx, "fake-snapshot", "vol1") @@ -2850,7 +2854,7 @@ func TestVolumeSnapshotList(t *testing.T) { snapshotResponseOK := storage.SnapshotCollectionGetOK{Payload: &snapshotResponse} // case 1: Get volume snapshot list - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(&snapshotResponseOK, nil) snapshots, err := oapi.VolumeSnapshotList(ctx, "vol1") assert.NoError(t, err, "error returned while getting a snapshot list") @@ -2859,18 +2863,18 @@ func TestVolumeSnapshotList(t *testing.T) { assert.Equal(t, createTime1.String(), snapshots[0].CreateTime, "snapshot creation time does not match") // case 2: Get volume snapshot parent volume verification returned error - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(nil, fmt.Errorf("failed to get flexgroup")) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(nil, fmt.Errorf("failed to get flexgroup")) _, err = oapi.VolumeSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a snapshot list") // case 3: Get volume snapshot returned nil response - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(nil, nil) snapshots, err = oapi.VolumeSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a snapshot list") // case 4: Get volume snapshot returned error - rsi.EXPECT().VolumeGetByName(ctx, "vol1").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "vol1", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotList(ctx, volumeUUID).Return(nil, fmt.Errorf("failed to get snapshot info")) snapshots, err = oapi.VolumeSnapshotList(ctx, "vol1") assert.Error(t, err, "no error returned while getting a snapshot list") @@ -3006,7 +3010,7 @@ func TestFlexgroupSnapshotDelete(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Flexgroup Snapshot delete - rsi.EXPECT().FlexGroupGetByName(ctx, "fake-volume").Return(volume, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "fake-volume", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotGetByName(ctx, "fake-volumeUUID", "fake-snapshot").Return(snapshot, nil) rsi.EXPECT().SnapshotDelete(ctx, "fake-volumeUUID", *snapshot.UUID).Return(&snapResponse, nil) rsi.EXPECT().PollJobStatus(ctx, &jobResponse).Return(nil) @@ -3014,12 +3018,12 @@ func TestFlexgroupSnapshotDelete(t *testing.T) { assert.NoError(t, err, "error returned while deleting a snapshot") // case 2: Flexgroup Snapshot verification returned error - rsi.EXPECT().FlexGroupGetByName(ctx, "fake-volume").Return(nil, fmt.Errorf("failed to get volume")) + rsi.EXPECT().FlexGroupGetByName(ctx, "fake-volume", gomock.Any()).Return(nil, fmt.Errorf("failed to get volume")) err = oapi.FlexgroupSnapshotDelete(ctx, "fake-snapshot", "fake-volume") assert.Error(t, err, "no error returned while deleting a snapshot") // case 3: Flexgroup Snapshot verification returned nil - rsi.EXPECT().FlexGroupGetByName(ctx, "fake-volume").Return(nil, nil) + rsi.EXPECT().FlexGroupGetByName(ctx, "fake-volume", gomock.Any()).Return(nil, nil) err = oapi.FlexgroupSnapshotDelete(ctx, "fake-snapshot", "fake-volume") assert.Error(t, err, "no error returned while deleting a snapshot") } @@ -3036,7 +3040,7 @@ func TestVolumeSnapshotDelete(t *testing.T) { oapi, rsi := newMockOntapAPIREST(t) // case 1: Volume Snapshot delete - rsi.EXPECT().VolumeGetByName(ctx, "fake-volume").Return(volume, nil) + rsi.EXPECT().VolumeGetByName(ctx, "fake-volume", gomock.Any()).Return(volume, nil) rsi.EXPECT().SnapshotGetByName(ctx, "fake-volumeUUID", "fake-snapshot").Return(snapshot, nil) rsi.EXPECT().SnapshotDelete(ctx, "fake-volumeUUID", *snapshot.UUID).Return(&snapResponse, nil) rsi.EXPECT().PollJobStatus(ctx, &jobResponse).Return(nil) @@ -3044,12 +3048,12 @@ func TestVolumeSnapshotDelete(t *testing.T) { assert.NoError(t, err, "error returned while deleting a snapshot") // case 2: Volume Snapshot verification returned error - rsi.EXPECT().VolumeGetByName(ctx, "fake-volume").Return(nil, fmt.Errorf("failed to get volume")) + rsi.EXPECT().VolumeGetByName(ctx, "fake-volume", gomock.Any()).Return(nil, fmt.Errorf("failed to get volume")) err = oapi.VolumeSnapshotDelete(ctx, "fake-snapshot", "fake-volume") assert.Error(t, err, "no error returned while deleting a snapshot") // case 3: Volume Snapshot verification returned nil - rsi.EXPECT().VolumeGetByName(ctx, "fake-volume").Return(nil, nil) + rsi.EXPECT().VolumeGetByName(ctx, "fake-volume", gomock.Any()).Return(nil, nil) err = oapi.VolumeSnapshotDelete(ctx, "fake-snapshot", "fake-volume") assert.Error(t, err, "no error returned while deleting a snapshot") } @@ -3152,7 +3156,7 @@ func TestSnapMirrorGet(t *testing.T) { TransferSchedule: &transferSchedule, } rsi.EXPECT().SnapmirrorGet(ctx, "fake-localVolume", "fake-localSvm", "fake-remoteVolume", - "fake-remoteSVM").Return(&snapmirrorRelationship, nil) + "fake-remoteSVM", gomock.Any()).Return(&snapmirrorRelationship, nil) snapmirror, err := oapi.SnapmirrorGet(ctx, "fake-localVolume", "fake-localSvm", "fake-remoteVolume", "fake-remoteSVM") assert.NoError(t, err, "error returned while getting a SnapMirror") @@ -3458,13 +3462,13 @@ func TestLunList(t *testing.T) { } // case 1: Get LUN list - rsi.EXPECT().LunList(ctx, "").Return(&lunResponse, nil) + rsi.EXPECT().LunList(ctx, "", gomock.Any()).Return(&lunResponse, nil) luns, err := oapi.LunList(ctx, "") assert.NoError(t, err, "error returned while getting a LUN info") assert.Equal(t, *lun.Name, luns[0].Name, "LUN name does not match") // case 2: Get LUN list returned error - rsi.EXPECT().LunList(ctx, "").Return(nil, fmt.Errorf("lun not found with given pattern")) + rsi.EXPECT().LunList(ctx, "", gomock.Any()).Return(nil, fmt.Errorf("lun not found with given pattern")) luns, err = oapi.LunList(ctx, "") assert.Error(t, err, "no error returned while getting a LUN info") @@ -3472,7 +3476,7 @@ func TestLunList(t *testing.T) { lunResponse1 := s_a_n.LunCollectionGetOK{ Payload: &models.LunResponse{LunResponseInlineRecords: []*models.Lun{nil}}, } - rsi.EXPECT().LunList(ctx, "").Return(&lunResponse1, nil) + rsi.EXPECT().LunList(ctx, "", gomock.Any()).Return(&lunResponse1, nil) luns, err = oapi.LunList(ctx, "") assert.Error(t, err, "no error returned while getting a LUN info") } @@ -3528,25 +3532,25 @@ func TestLunDestroy(t *testing.T) { rsi.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() // case 1: Delete LUN - rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name).Return(lun, nil) + rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name, gomock.Any()).Return(lun, nil) rsi.EXPECT().LunDelete(ctx, *lun.UUID).Return(nil) err := oapi.LunDestroy(ctx, "/"+*lun.Name) assert.NoError(t, err, "error returned while deleting a LUN") // case 2: Delete LUN returned error - rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name).Return(lun, nil) + rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name, gomock.Any()).Return(lun, nil) rsi.EXPECT().LunDelete(ctx, *lun.UUID).Return(fmt.Errorf("failed to delete lun")) err = oapi.LunDestroy(ctx, "/"+*lun.Name) assert.Error(t, err, "no error returned while deleting a LUN") // case 3: Delete LUN, LUN verification returned error - rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name).Return(nil, fmt.Errorf("failed to get lun")) + rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name, gomock.Any()).Return(nil, fmt.Errorf("failed to get lun")) err = oapi.LunDestroy(ctx, "/"+*lun.Name) assert.Error(t, err, "no error returned while deleting a LUN") lun.UUID = nil // case 4: LUN response contain LUN UUID nil - rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name).Return(lun, nil) + rsi.EXPECT().LunGetByName(ctx, "/"+*lun.Name, gomock.Any()).Return(lun, nil) err = oapi.LunDestroy(ctx, "/"+*lun.Name) assert.Error(t, err, "no error returned while deleting a LUN") } @@ -3608,17 +3612,17 @@ func TestLunCloneCreate(t *testing.T) { // case 1, Positive test, create clone rsi.EXPECT().LunCloneCreate(ctx, gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil) - rsi.EXPECT().LunGetByName(ctx, gomock.Any()).Return(lun, nil) + rsi.EXPECT().LunGetByName(ctx, gomock.Any(), gomock.Any()).Return(lun, nil) err := oapi.LunCloneCreate(ctx, "fake-cloneVolume", "fake-volume", "fake-snaphot", api.QosPolicyGroup{}) assert.NoError(t, err, "error returned while cloning a LUN") // case 2, Negative test, Unable to get LUN info. Beckend returned error - rsi.EXPECT().LunGetByName(ctx, gomock.Any()).Return(lun, fmt.Errorf("failed to get lun")) + rsi.EXPECT().LunGetByName(ctx, gomock.Any(), gomock.Any()).Return(lun, fmt.Errorf("failed to get lun")) err = oapi.LunCloneCreate(ctx, "fake-cloneVolume", "fake-volume", "fake-snaphot", api.QosPolicyGroup{}) assert.Error(t, err, "no error returned while cloning a LUN") // case 3, Negative test, Unable to get LUN info. Getting nil response. - rsi.EXPECT().LunGetByName(ctx, gomock.Any()).Return(nil, nil) + rsi.EXPECT().LunGetByName(ctx, gomock.Any(), gomock.Any()).Return(nil, nil) err = oapi.LunCloneCreate(ctx, "fake-cloneVolume", "fake-volume", "fake-snaphot", api.QosPolicyGroup{}) assert.Error(t, err, "no error returned while cloning a LUN") } @@ -3662,18 +3666,18 @@ func TestLunGetByName(t *testing.T) { rsi.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() // case 1: Positive test, get lun info by name - rsi.EXPECT().LunGetByName(ctx, gomock.Any()).Return(lun, nil) + rsi.EXPECT().LunGetByName(ctx, gomock.Any(), gomock.Any()).Return(lun, nil) lunResponse, err := oapi.LunGetByName(ctx, "fake-lun") assert.NoError(t, err, "error returned while getting a LUN by name") assert.Equal(t, *lun.Name, lunResponse.Name, "Lun name does not match") // case 2: Negative test, backend returned error - rsi.EXPECT().LunGetByName(ctx, gomock.Any()).Return(lun, fmt.Errorf("failed to get lun")) + rsi.EXPECT().LunGetByName(ctx, gomock.Any(), gomock.Any()).Return(lun, fmt.Errorf("failed to get lun")) lunResponse, err = oapi.LunGetByName(ctx, "fake-lun") assert.Error(t, err, "no error returned while getting a LUN by name") // case 3: Negative test, backend returned nil response - rsi.EXPECT().LunGetByName(ctx, gomock.Any()).Return(nil, nil) + rsi.EXPECT().LunGetByName(ctx, gomock.Any(), gomock.Any()).Return(nil, nil) lunResponse, err = oapi.LunGetByName(ctx, "fake-lun") assert.Error(t, err, "no error returned while getting a LUN by name") } @@ -3761,13 +3765,13 @@ func TestLunListIgroupsMapped(t *testing.T) { lunMapResponseList := s_a_n.LunMapCollectionGetOK{Payload: &lunMapResponse} // case 1: Positive test, get ia LUN list mapped with igroup - rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any()).Return(&lunMapResponseList, nil) + rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(&lunMapResponseList, nil) igroupNames, err := oapi.LunListIgroupsMapped(ctx, "/vol/lun0") assert.NoError(t, err, "error returned while getting a LUN list mapped with igroup") assert.Equal(t, igroupName, igroupNames[0]) // case 2: Negative test, get ia LUN list mapped with igroup - rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("failed to get lun map")) + rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("failed to get lun map")) _, err = oapi.LunListIgroupsMapped(ctx, "/vol/lun0") assert.Error(t, err, "no error returned while getting a LUN list mapped with igroup") } @@ -3788,13 +3792,13 @@ func TestIgroupListLUNsMapped(t *testing.T) { lunMapResponseList := s_a_n.LunMapCollectionGetOK{Payload: &lunMapResponse} // case 1: Positive test, get igroup list mapped with LUN. - rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any()).Return(&lunMapResponseList, nil) + rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(&lunMapResponseList, nil) lunNames, err := oapi.IgroupListLUNsMapped(ctx, "/vol/lun0") assert.NoError(t, err, "error returned while getting a igroup mapped with lun") assert.Equal(t, lunName, lunNames[0]) // case 2: Negative test, get igroup list mapped with LUN. - rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("failed to get lun map")) + rsi.EXPECT().LunMapList(ctx, gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("failed to get lun map")) _, err = oapi.IgroupListLUNsMapped(ctx, "/vol/lun0") assert.Error(t, err, "no error returned while getting a igroup mapped with lun") } @@ -3873,13 +3877,13 @@ func TestIscsiInitiatorGetDefaultAuth(t *testing.T) { } // case 1: Get the iscsi initialor default auth. - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(&iscsiCredResponse, nil) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(&iscsiCredResponse, nil) iscsiInitiatorAuth, err := oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.NoError(t, err, "error returned while iscsi initiator default auth") assert.Equal(t, iscsiInitiatorAuth.AuthType, authType, "authType does not match") // case 2: Failed to get the iscsi initialor default auth. - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(nil, fmt.Errorf("failed to get iscsi initiator auth")) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(nil, fmt.Errorf("failed to get iscsi initiator auth")) iscsiInitiatorAuth, err = oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.Error(t, err, "no error returned while iscsi initiator default auth") @@ -3891,7 +3895,7 @@ func TestIscsiInitiatorGetDefaultAuth(t *testing.T) { NumRecords: &numRecords, }, } - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(&iscsiCredResponse1, nil) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(&iscsiCredResponse1, nil) iscsiInitiatorAuth, err = oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.Error(t, err, "no error returned while iscsi initiator default auth") @@ -3903,7 +3907,7 @@ func TestIscsiInitiatorGetDefaultAuth(t *testing.T) { NumRecords: &numRecords2, }, } - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(&iscsiCredResponse2, nil) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(&iscsiCredResponse2, nil) iscsiInitiatorAuth, err = oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.Error(t, err, "no error returned while iscsi initiator default auth") @@ -3913,7 +3917,7 @@ func TestIscsiInitiatorGetDefaultAuth(t *testing.T) { IscsiCredentialsResponseInlineRecords: nil, }, } - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(&iscsiCredResponse3, nil) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(&iscsiCredResponse3, nil) iscsiInitiatorAuth, err = oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.Error(t, err, "no error returned while iscsi initiator default auth") @@ -3921,12 +3925,12 @@ func TestIscsiInitiatorGetDefaultAuth(t *testing.T) { iscsiCredResponse4 := s_a_n.IscsiCredentialsCollectionGetOK{ Payload: nil, } - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(&iscsiCredResponse4, nil) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(&iscsiCredResponse4, nil) iscsiInitiatorAuth, err = oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.Error(t, err, "no error returned while iscsi initiator default auth") // case 7: iSCSI initiator response is nil - rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx).Return(nil, nil) + rsi.EXPECT().IscsiInitiatorGetDefaultAuth(ctx, gomock.Any()).Return(nil, nil) iscsiInitiatorAuth, err = oapi.IscsiInitiatorGetDefaultAuth(ctx) assert.Error(t, err, "no error returned while iscsi initiator default auth") } @@ -3963,18 +3967,18 @@ func TestIscsiInterfaceGet(t *testing.T) { } // case 1: Positive test, get the iscsi interface test. - rsi.EXPECT().IscsiInterfaceGet(ctx).Return(&iscsiServiceResponse, nil) + rsi.EXPECT().IscsiInterfaceGet(ctx, gomock.Any()).Return(&iscsiServiceResponse, nil) iscsiInterface, err := oapi.IscsiInterfaceGet(ctx, svmName) assert.NoError(t, err, "error returned while getting iscsi interface") assert.Equal(t, iscsiInterface[0], targetName) // case 2: Negative test, backend return error in response. - rsi.EXPECT().IscsiInterfaceGet(ctx).Return(nil, fmt.Errorf("failed to get iscsi interface service")) + rsi.EXPECT().IscsiInterfaceGet(ctx, gomock.Any()).Return(nil, fmt.Errorf("failed to get iscsi interface service")) _, err = oapi.IscsiInterfaceGet(ctx, svmName) assert.Error(t, err, "no error returned while getting iscsi interface") // case 3: Negative test, backend return nil response. - rsi.EXPECT().IscsiInterfaceGet(ctx).Return(nil, nil) + rsi.EXPECT().IscsiInterfaceGet(ctx, gomock.Any()).Return(nil, nil) _, err = oapi.IscsiInterfaceGet(ctx, svmName) assert.NoError(t, err, "error returned while getting iscsi interface") @@ -3982,7 +3986,7 @@ func TestIscsiInterfaceGet(t *testing.T) { iscsiServiceResponse = s_a_n.IscsiServiceCollectionGetOK{ Payload: &models.IscsiServiceResponse{}, } - rsi.EXPECT().IscsiInterfaceGet(ctx).Return(&iscsiServiceResponse, nil) + rsi.EXPECT().IscsiInterfaceGet(ctx, gomock.Any()).Return(&iscsiServiceResponse, nil) iscsiInterface, err = oapi.IscsiInterfaceGet(ctx, svmName) assert.Error(t, err, "no error returned while getting iscsi interface") } @@ -3999,7 +4003,7 @@ func TestIscsiNodeGetNameRequest(t *testing.T) { } // case 1: Get the iscsi node name. - rsi.EXPECT().IscsiNodeGetName(ctx).Return(&iscsiServiceResponse, nil) + rsi.EXPECT().IscsiNodeGetName(ctx, gomock.Any()).Return(&iscsiServiceResponse, nil) iscsiInterface, err := oapi.IscsiNodeGetNameRequest(ctx) assert.NoError(t, err, "error returned while getting node name") assert.Equal(t, targetName, iscsiInterface) @@ -4009,7 +4013,7 @@ func TestIscsiNodeGetNameRequest(t *testing.T) { iscsiServiceResponse = s_a_n.IscsiServiceGetOK{ Payload: &iscsiService, } - rsi.EXPECT().IscsiNodeGetName(ctx).Return(&iscsiServiceResponse, nil) + rsi.EXPECT().IscsiNodeGetName(ctx, gomock.Any()).Return(&iscsiServiceResponse, nil) _, err = oapi.IscsiNodeGetNameRequest(ctx) assert.Error(t, err, "no error returned while getting node name") @@ -4018,7 +4022,7 @@ func TestIscsiNodeGetNameRequest(t *testing.T) { iscsiServiceResponse = s_a_n.IscsiServiceGetOK{ Payload: &iscsiService, } - rsi.EXPECT().IscsiNodeGetName(ctx).Return(&iscsiServiceResponse, nil) + rsi.EXPECT().IscsiNodeGetName(ctx, gomock.Any()).Return(&iscsiServiceResponse, nil) _, err = oapi.IscsiNodeGetNameRequest(ctx) assert.Error(t, err, "no error returned while getting node name") @@ -4026,17 +4030,17 @@ func TestIscsiNodeGetNameRequest(t *testing.T) { iscsiServiceResponse = s_a_n.IscsiServiceGetOK{ Payload: nil, } - rsi.EXPECT().IscsiNodeGetName(ctx).Return(&iscsiServiceResponse, nil) + rsi.EXPECT().IscsiNodeGetName(ctx, gomock.Any()).Return(&iscsiServiceResponse, nil) _, err = oapi.IscsiNodeGetNameRequest(ctx) assert.Error(t, err, "no error returned while getting node name") // case 5: backend returned a nil response. - rsi.EXPECT().IscsiNodeGetName(ctx).Return(nil, nil) + rsi.EXPECT().IscsiNodeGetName(ctx, gomock.Any()).Return(nil, nil) _, err = oapi.IscsiNodeGetNameRequest(ctx) assert.Error(t, err, "no error returned while getting node name") // case 6: Unable to get the node name from backend. - rsi.EXPECT().IscsiNodeGetName(ctx).Return(nil, fmt.Errorf("iscsi node name not found")) + rsi.EXPECT().IscsiNodeGetName(ctx, gomock.Any()).Return(nil, fmt.Errorf("iscsi node name not found")) _, err = oapi.IscsiNodeGetNameRequest(ctx) assert.Error(t, err, "no error returned while getting node name") } @@ -4073,30 +4077,30 @@ func TestIgroupCreate(t *testing.T) { rsi.EXPECT().ClientConfig().Return(clientConfig).AnyTimes() // Positive test, igroup created - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(&igroup, nil) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(&igroup, nil) err := oapi.IgroupCreate(ctx, initiatorGroup, initiator1, "Linux") assert.NoError(t, err, "error while creating igroup") // Negative test, Unoble to verify igroup exists - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, fmt.Errorf("failed to verify igroup")) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, fmt.Errorf("failed to verify igroup")) err = oapi.IgroupCreate(ctx, initiatorGroup, initiator1, "Linux") assert.Error(t, err, "no error while verifying igroup") // Negative test, Unoble to verify igroup exists - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, nil) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, nil) rsi.EXPECT().IgroupCreate(ctx, initiatorGroup, initiator1, "Linux").Return(nil) err = oapi.IgroupCreate(ctx, initiatorGroup, initiator1, "Linux") assert.NoError(t, err, "error while verifying igroup") // Negative test, igroup creation failed. - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, nil) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, nil) rsi.EXPECT().IgroupCreate(ctx, initiatorGroup, initiator1, "Linux").Return( fmt.Errorf("failed to create igroup")) err = oapi.IgroupCreate(ctx, initiatorGroup, initiator1, "Linux") assert.Error(t, err, "No error while creating igroup") // Negative test, igroup creation failed. - rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup).Return(nil, nil) + rsi.EXPECT().IgroupGetByName(ctx, initiatorGroup, gomock.Any()).Return(nil, nil) rsi.EXPECT().IgroupCreate(ctx, initiatorGroup, initiator1, "Linux").Return( fmt.Errorf("404 failed to create igroup")) err = oapi.IgroupCreate(ctx, initiatorGroup, initiator1, "Linux") diff --git a/storage_drivers/ontap/api/ontap_rest.go b/storage_drivers/ontap/api/ontap_rest.go index 535af62bd..d552f32b7 100644 --- a/storage_drivers/ontap/api/ontap_rest.go +++ b/storage_drivers/ontap/api/ontap_rest.go @@ -439,9 +439,9 @@ func (c RestClient) getAllVolumePayloadRecords( return payload, nil } -// getAllVolumesByPatternAndStyle returns all relevant details for all volumes of the style specified whose names match the supplied prefix +// getAllVolumesByPatternStyleAndState returns all relevant details for all volumes of the style specified whose names match the supplied prefix func (c RestClient) getAllVolumesByPatternStyleAndState( - ctx context.Context, pattern, style, state string, + ctx context.Context, pattern, style, state string, fields []string, ) (*storage.VolumeCollectionGetOK, error) { if style != models.VolumeStyleFlexvol && style != models.VolumeStyleFlexgroup { return nil, fmt.Errorf("unknown volume style %s", style) @@ -471,7 +471,7 @@ func (c RestClient) getAllVolumesByPatternStyleAndState( params.SetState(utils.Ptr(state)) } params.SetStyle(utils.Ptr(style)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.Storage.VolumeCollectionGet(params, c.authInfo) if err != nil { @@ -494,7 +494,8 @@ func (c RestClient) checkVolumeExistsByNameAndStyle(ctx context.Context, volumeN if volumeName == "" { return false, nil } - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return false, err } @@ -509,8 +510,9 @@ func (c RestClient) getVolumeByNameAndStyle( ctx context.Context, volumeName string, style string, + fields []string, ) (*models.Volume, error) { - result, err := c.getAllVolumesByPatternStyleAndState(ctx, volumeName, style, models.VolumeStateOnline) + result, err := c.getAllVolumesByPatternStyleAndState(ctx, volumeName, style, models.VolumeStateOnline, fields) if err != nil { return nil, err } @@ -529,8 +531,9 @@ func (c RestClient) getVolumeInAnyStateByNameAndStyle( ctx context.Context, volumeName string, style string, + fields []string, ) (*models.Volume, error) { - result, err := c.getAllVolumesByPatternStyleAndState(ctx, volumeName, style, "") + result, err := c.getAllVolumesByPatternStyleAndState(ctx, volumeName, style, "", fields) if err != nil { return nil, err } @@ -546,7 +549,8 @@ func (c RestClient) getVolumeInAnyStateByNameAndStyle( // getVolumeSizeByNameAndStyle retrieves the size of the volume of the style and name specified func (c RestClient) getVolumeSizeByNameAndStyle(ctx context.Context, volumeName, style string) (uint64, error) { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{"size"} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return 0, err } @@ -562,7 +566,8 @@ func (c RestClient) getVolumeSizeByNameAndStyle(ctx context.Context, volumeName, // getVolumeUsedSizeByNameAndStyle retrieves the used bytes of the the volume of the style and name specified func (c RestClient) getVolumeUsedSizeByNameAndStyle(ctx context.Context, volumeName, style string) (int, error) { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{"space.logical_space.used"} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return 0, err } @@ -587,7 +592,8 @@ func (c RestClient) getVolumeUsedSizeByNameAndStyle(ctx context.Context, volumeN // setVolumeSizeByNameAndStyle sets the size of the specified volume of given style func (c RestClient) setVolumeSizeByNameAndStyle(ctx context.Context, volumeName, newSize, style string) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -627,7 +633,8 @@ func (c RestClient) setVolumeSizeByNameAndStyle(ctx context.Context, volumeName, // mountVolumeByNameAndStyle mounts a volume at the specified junction func (c RestClient) mountVolumeByNameAndStyle(ctx context.Context, volumeName, junctionPath, style string) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{"nas.path"} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -673,7 +680,8 @@ func (c RestClient) unmountVolumeByNameAndStyle( ctx context.Context, volumeName, style string, ) error { - volume, err := c.getVolumeInAnyStateByNameAndStyle(ctx, volumeName, style) + fields := []string{"nas.path"} + volume, err := c.getVolumeInAnyStateByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -719,7 +727,8 @@ func (c RestClient) unmountVolumeByNameAndStyle( // RenameVolumeByNameAndStyle changes the name of a FlexVol (but not a FlexGroup!) func (c RestClient) renameVolumeByNameAndStyle(ctx context.Context, volumeName, newVolumeName, style string) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -756,7 +765,8 @@ func (c RestClient) renameVolumeByNameAndStyle(ctx context.Context, volumeName, // destroyVolumeByNameAndStyle destroys a volume func (c RestClient) destroyVolumeByNameAndStyle(ctx context.Context, name, style string) error { - volume, err := c.getVolumeByNameAndStyle(ctx, name, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, name, style, fields) if err != nil { return err } @@ -786,7 +796,8 @@ func (c RestClient) destroyVolumeByNameAndStyle(ctx context.Context, name, style func (c RestClient) modifyVolumeExportPolicyByNameAndStyle( ctx context.Context, volumeName, exportPolicyName, style string, ) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -824,7 +835,8 @@ func (c RestClient) modifyVolumeUnixPermissionsByNameAndStyle( ctx context.Context, volumeName, unixPermissions, style string, ) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -875,7 +887,8 @@ func (c RestClient) setVolumeCommentByNameAndStyle( ctx context.Context, volumeName, newVolumeComment, style string, ) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -953,7 +966,8 @@ func convertUnixPermissions(s string) string { func (c RestClient) setVolumeQosPolicyGroupNameByNameAndStyle( ctx context.Context, volumeName string, qosPolicyGroup QosPolicyGroup, style string, ) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -998,7 +1012,8 @@ func (c RestClient) setVolumeQosPolicyGroupNameByNameAndStyle( // startCloneSplitByNameAndStyle starts splitting the clone func (c RestClient) startCloneSplitByNameAndStyle(ctx context.Context, volumeName, style string) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -1038,7 +1053,8 @@ func (c RestClient) restoreSnapshotByNameAndStyle( ctx context.Context, snapshotName, volumeName, style string, ) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, style, fields) if err != nil { return err } @@ -1312,12 +1328,14 @@ func (c RestClient) waitForFlexgroup(ctx context.Context, volumeName string) err // //////////////////////////////////////////////////////////////////////////// // VolumeList returns the names of all Flexvols whose names match the supplied pattern -func (c RestClient) VolumeList(ctx context.Context, pattern string) (*storage.VolumeCollectionGetOK, error) { - return c.getAllVolumesByPatternStyleAndState(ctx, pattern, models.VolumeStyleFlexvol, models.VolumeStateOnline) +func (c RestClient) VolumeList(ctx context.Context, pattern string, fields []string, +) (*storage.VolumeCollectionGetOK, error) { + return c.getAllVolumesByPatternStyleAndState(ctx, pattern, models.VolumeStyleFlexvol, models.VolumeStateOnline, + fields) } // VolumeListByAttrs is used to find bucket volumes for nas-eco and san-eco -func (c RestClient) VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume) (Volumes, error) { +func (c RestClient) VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume, fields []string) (*storage.VolumeCollectionGetOK, error) { params := storage.NewVolumeCollectionGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient @@ -1370,7 +1388,7 @@ func (c RestClient) VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume) params.SetState(utils.Ptr(state)) } params.SetStyle(utils.Ptr(style)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.Storage.VolumeCollectionGet(params, c.authInfo) if err != nil { @@ -1385,45 +1403,7 @@ func (c RestClient) VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume) return nil, err } - volumes := Volumes{} - for _, volume := range result.Payload.VolumeResponseInlineRecords { - - aggregates := []string{} - for _, aggr := range volume.VolumeInlineAggregates { - if aggr.Name != nil { - aggregates = append(aggregates, *aggr.Name) - } - } - - snapshotDirAccessEnabled := false - if volume.SnapshotDirectoryAccessEnabled != nil { - snapshotDirAccessEnabled = *volume.SnapshotDirectoryAccessEnabled - } - - tieringPolicy := models.VolumeInlineTieringPolicyNone - if volume.Movement != nil && volume.Movement.TieringPolicy != nil { - tieringPolicy = *volume.Movement.TieringPolicy - } - - v := &Volume{ - Aggregates: aggregates, - Encrypt: volume.Encryption.Enabled, - TieringPolicy: tieringPolicy, - SnapshotDir: snapshotDirAccessEnabled, - } - if volume.Name != nil { - v.Name = *volume.Name - } - if volume.Guarantee != nil && volume.Guarantee.Type != nil { - v.SpaceReserve = *volume.Guarantee.Type - } - if volume.SnapshotPolicy != nil && volume.SnapshotPolicy.Name != nil { - v.SnapshotPolicy = *volume.SnapshotPolicy.Name - } - volumes = append(volumes, v) - } - - return volumes, nil + return result, nil } // VolumeCreate creates a volume with the specified options @@ -1448,8 +1428,8 @@ func (c RestClient) VolumeExists(ctx context.Context, volumeName string) (bool, } // VolumeGetByName gets the flexvol with the specified name -func (c RestClient) VolumeGetByName(ctx context.Context, volumeName string) (*models.Volume, error) { - return c.getVolumeByNameAndStyle(ctx, volumeName, models.VolumeStyleFlexvol) +func (c RestClient) VolumeGetByName(ctx context.Context, volumeName string, fields []string) (*models.Volume, error) { + return c.getVolumeByNameAndStyle(ctx, volumeName, models.VolumeStyleFlexvol, fields) } // VolumeMount mounts a flexvol at the specified junction @@ -1673,7 +1653,8 @@ func (c RestClient) SnapshotRestoreFlexgroup(ctx context.Context, snapshotName, // VolumeModifySnapshotDirectoryAccess modifies access to the ".snapshot" directory func (c RestClient) VolumeModifySnapshotDirectoryAccess(ctx context.Context, volumeName string, enable bool) error { - volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, models.VolumeStyleFlexvol) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, volumeName, models.VolumeStyleFlexvol, fields) if err != nil { return err } @@ -1745,7 +1726,7 @@ func (c RestClient) VolumeCloneCreateAsync(ctx context.Context, cloneName, sourc // IscsiInitiatorGetDefaultAuth returns the authorization details for the default initiator // equivalent to filer::> vserver iscsi security show -vserver SVM -initiator-name default -func (c RestClient) IscsiInitiatorGetDefaultAuth(ctx context.Context) (*san.IscsiCredentialsCollectionGetOK, error) { +func (c RestClient) IscsiInitiatorGetDefaultAuth(ctx context.Context, fields []string) (*san.IscsiCredentialsCollectionGetOK, error) { params := san.NewIscsiCredentialsCollectionGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient @@ -1756,8 +1737,7 @@ func (c RestClient) IscsiInitiatorGetDefaultAuth(ctx context.Context) (*san.Iscs params.SvmUUID = utils.Ptr(c.svmUUID) params.Initiator = utils.Ptr("default") - params.SetFields([]string{"**"}) // TODO trim these down to just what we need - + params.SetFields(fields) result, err := c.api.San.IscsiCredentialsCollectionGet(params, c.authInfo) if err != nil { return nil, err @@ -1770,7 +1750,7 @@ func (c RestClient) IscsiInitiatorGetDefaultAuth(ctx context.Context) (*san.Iscs } // IscsiInterfaceGet returns information about the vserver's iSCSI interfaces -func (c RestClient) IscsiInterfaceGet(ctx context.Context) (*san.IscsiServiceCollectionGetOK, +func (c RestClient) IscsiInterfaceGet(ctx context.Context, fields []string) (*san.IscsiServiceCollectionGetOK, error, ) { params := san.NewIscsiServiceCollectionGetParamsWithTimeout(c.httpClient.Timeout) @@ -1779,7 +1759,7 @@ func (c RestClient) IscsiInterfaceGet(ctx context.Context) (*san.IscsiServiceCol params.ReturnRecords = utils.Ptr(true) params.SvmUUID = utils.Ptr(c.svmUUID) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.San.IscsiServiceCollectionGet(params, c.authInfo) if err != nil { @@ -1800,7 +1780,8 @@ func (c RestClient) IscsiInitiatorSetDefaultAuth( ctx context.Context, authType, userName, passphrase, outbountUserName, outboundPassphrase string, ) error { - getDefaultAuthResponse, err := c.IscsiInitiatorGetDefaultAuth(ctx) + fields := []string{"initiator"} + getDefaultAuthResponse, err := c.IscsiInitiatorGetDefaultAuth(ctx, fields) if err != nil { return err } @@ -1855,7 +1836,7 @@ func (c RestClient) IscsiInitiatorSetDefaultAuth( } // IscsiNodeGetName returns information about the vserver's iSCSI node name -func (c RestClient) IscsiNodeGetName(ctx context.Context) (*san.IscsiServiceGetOK, +func (c RestClient) IscsiNodeGetName(ctx context.Context, fields []string) (*san.IscsiServiceGetOK, error, ) { svmResult, err := c.SvmGet(ctx, c.svmUUID) @@ -1873,7 +1854,7 @@ func (c RestClient) IscsiNodeGetName(ctx context.Context) (*san.IscsiServiceGetO params.HTTPClient = c.httpClient params.SvmUUID = *svmInfo.UUID - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.San.IscsiServiceGet(params, c.authInfo) if err != nil { @@ -1934,7 +1915,8 @@ func (c RestClient) IgroupCreate(ctx context.Context, initiatorGroupName, initia // equivalent to filer::> lun igroup add -vserver iscsi_vs -igroup docker -initiator iqn.1993-08.org. // debian:01:9031309bbebd func (c RestClient) IgroupAdd(ctx context.Context, initiatorGroupName, initiator string) error { - igroup, err := c.IgroupGetByName(ctx, initiatorGroupName) + fields := []string{""} + igroup, err := c.IgroupGetByName(ctx, initiatorGroupName, fields) if err != nil { return err } @@ -1967,7 +1949,8 @@ func (c RestClient) IgroupAdd(ctx context.Context, initiatorGroupName, initiator // IgroupRemove removes an initiator from an initiator group func (c RestClient) IgroupRemove(ctx context.Context, initiatorGroupName, initiator string) error { - igroup, err := c.IgroupGetByName(ctx, initiatorGroupName) + fields := []string{""} + igroup, err := c.IgroupGetByName(ctx, initiatorGroupName, fields) if err != nil { return err } @@ -1998,7 +1981,8 @@ func (c RestClient) IgroupRemove(ctx context.Context, initiatorGroupName, initia // IgroupDestroy destroys an initiator group func (c RestClient) IgroupDestroy(ctx context.Context, initiatorGroupName string) error { - igroup, err := c.IgroupGetByName(ctx, initiatorGroupName) + fields := []string{""} + igroup, err := c.IgroupGetByName(ctx, initiatorGroupName, fields) if err != nil { return err } @@ -2031,7 +2015,7 @@ func (c RestClient) IgroupDestroy(ctx context.Context, initiatorGroupName string } // IgroupList lists initiator groups -func (c RestClient) IgroupList(ctx context.Context, pattern string) (*san.IgroupCollectionGetOK, error) { +func (c RestClient) IgroupList(ctx context.Context, pattern string, fields []string) (*san.IgroupCollectionGetOK, error) { if pattern == "" { pattern = "*" } @@ -2042,7 +2026,7 @@ func (c RestClient) IgroupList(ctx context.Context, pattern string) (*san.Igroup params.SvmUUID = utils.Ptr(c.svmUUID) params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.San.IgroupCollectionGet(params, c.authInfo) if err != nil { @@ -2094,8 +2078,8 @@ func (c RestClient) IgroupGet(ctx context.Context, uuid string) (*san.IgroupGetO } // IgroupGetByName gets the igroup with the specified name -func (c RestClient) IgroupGetByName(ctx context.Context, initiatorGroupName string) (*models.Igroup, error) { - result, err := c.IgroupList(ctx, initiatorGroupName) +func (c RestClient) IgroupGetByName(ctx context.Context, initiatorGroupName string, fields []string) (*models.Igroup, error) { + result, err := c.IgroupList(ctx, initiatorGroupName, fields) if err != nil { return nil, err } @@ -2182,7 +2166,8 @@ func (d RestClient) LunOptions( // pollLunCreate polls for the created LUN to appear, with backoff retry logic func (c RestClient) pollLunCreate(ctx context.Context, lunPath string) error { checkCreateStatus := func() error { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return err } @@ -2323,9 +2308,9 @@ func (c RestClient) LunGet(ctx context.Context, uuid string) (*san.LunGetOK, err } // LunGetByName gets the LUN with the specified name -func (c RestClient) LunGetByName(ctx context.Context, name string) (*models.Lun, error) { - result, err := c.LunList(ctx, name) - if err != nil { +func (c RestClient) LunGetByName(ctx context.Context, name string, fields []string) (*models.Lun, error) { + result, err := c.LunList(ctx, name, fields) + if err != nil || result.Payload == nil { return nil, err } @@ -2340,14 +2325,15 @@ func (c RestClient) LunGetByName(ctx context.Context, name string) (*models.Lun, } // LunList finds LUNs with the specified pattern -func (c RestClient) LunList(ctx context.Context, pattern string) (*san.LunCollectionGetOK, error) { +func (c RestClient) LunList(ctx context.Context, pattern string, fields []string) (*san.LunCollectionGetOK, error) { params := san.NewLunCollectionGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient params.SvmUUID = utils.Ptr(c.svmUUID) params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + + params.SetFields(fields) result, err := c.api.San.LunCollectionGet(params, c.authInfo) if err != nil { @@ -2414,7 +2400,8 @@ func (c RestClient) LunGetComment( ctx context.Context, lunPath string, ) (string, error) { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{"comment"} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return "", err } @@ -2433,7 +2420,8 @@ func (c RestClient) LunSetComment( ctx context.Context, lunPath, comment string, ) error { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return err } @@ -2473,7 +2461,8 @@ func (c RestClient) LunGetAttribute( ctx context.Context, lunPath, attributeName string, ) (string, error) { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{"attributes.name", "attributes.value"} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return "", err } @@ -2500,7 +2489,8 @@ func (c RestClient) LunSetAttribute( ctx context.Context, lunPath, attributeName, attributeValue string, ) error { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{"attributes.name"} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return err } @@ -2573,7 +2563,8 @@ func (c RestClient) LunSetQosPolicyGroup( ctx context.Context, lunPath, qosPolicyGroup string, ) error { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return err } @@ -2616,7 +2607,8 @@ func (c RestClient) LunRename( ctx context.Context, lunPath, newLunPath string, ) error { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return err } @@ -2693,7 +2685,8 @@ func (c RestClient) LunUnmap( igroupUUID := *lunMapResponse.Payload.LunMapResponseInlineRecords[0].Igroup.UUID - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return err } @@ -2725,7 +2718,8 @@ func (c RestClient) LunMap( initiatorGroupName, lunPath string, lunID int, ) (*san.LunMapCreateCreated, error) { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return nil, err } @@ -2774,13 +2768,13 @@ func (c RestClient) LunMap( func (c RestClient) LunMapList( ctx context.Context, initiatorGroupName, lunPath string, + fields []string, ) (*san.LunMapCollectionGetOK, error) { params := san.NewLunMapCollectionGetParams() params.Context = ctx params.HTTPClient = c.httpClient - params.SetFields([]string{"**"}) // TODO trim these down to just what we need - + params.SetFields(fields) params.SetIgroupName(utils.Ptr(initiatorGroupName)) params.SetLunName(utils.Ptr(lunPath)) @@ -2793,7 +2787,8 @@ func (c RestClient) LunMapGetReportingNodes( ctx context.Context, initiatorGroupName, lunPath string, ) ([]string, error) { - lun, lunGetErr := c.LunGetByName(ctx, lunPath) + lunFields := []string{""} + lun, lunGetErr := c.LunGetByName(ctx, lunPath, lunFields) if lunGetErr != nil { return nil, lunGetErr } @@ -2805,7 +2800,8 @@ func (c RestClient) LunMapGetReportingNodes( } lunUUID := *lun.UUID - igroup, igroupGetErr := c.IgroupGetByName(ctx, initiatorGroupName) + igroupFields := []string{""} + igroup, igroupGetErr := c.IgroupGetByName(ctx, initiatorGroupName, igroupFields) if igroupGetErr != nil { return nil, igroupGetErr } @@ -2855,7 +2851,8 @@ func (c RestClient) LunSize( ctx context.Context, lunPath string, ) (int, error) { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{"space.size"} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return 0, err } @@ -2878,7 +2875,8 @@ func (c RestClient) LunSetSize( ctx context.Context, lunPath, newSize string, ) (uint64, error) { - lun, err := c.LunGetByName(ctx, lunPath) + fields := []string{""} + lun, err := c.LunGetByName(ctx, lunPath, fields) if err != nil { return 0, err } @@ -2929,7 +2927,9 @@ func (c RestClient) NetworkIPInterfacesList(ctx context.Context) (*networking.Ne params.HTTPClient = c.httpClient params.SvmUUID = utils.Ptr(c.svmUUID) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + + fields := []string{"location.node.name", "ip.address"} + params.SetFields(fields) result, err := c.api.Networking.NetworkIPInterfacesGet(params, c.authInfo) if err != nil { @@ -2980,9 +2980,9 @@ func (c RestClient) NetInterfaceGetDataLIFs(ctx context.Context, protocol string params.HTTPClient = c.httpClient params.Services = utils.Ptr(fmt.Sprintf("data_%v", protocol)) - params.SvmUUID = utils.Ptr(c.svmUUID) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"ip.address", "state"} + params.SetFields(fields) lifResponse, err := c.api.Networking.NetworkIPInterfacesGet(params, c.authInfo) if err != nil { @@ -3010,13 +3010,13 @@ func (c RestClient) NetInterfaceGetDataLIFs(ctx context.Context, protocol string // //////////////////////////////////////////////////////////////////////////// // JobGet returns the job by ID -func (c RestClient) JobGet(ctx context.Context, jobUUID string) (*cluster.JobGetOK, error) { +func (c RestClient) JobGet(ctx context.Context, jobUUID string, fields []string) (*cluster.JobGetOK, error) { params := cluster.NewJobGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient params.UUID = jobUUID - params.SetFields([]string{"**"}) // TODO trim these down to just what we need, this forces ALL fields + params.SetFields(fields) return c.api.Cluster.JobGet(params, c.authInfo) } @@ -3043,7 +3043,8 @@ func (c RestClient) IsJobFinished(ctx context.Context, payload *models.JobLinkRe "jobUUID": jobUUID, }).Debug("IsJobFinished") - jobResult, err := c.JobGet(ctx, string(*jobUUID)) + fields := []string{"state"} + jobResult, err := c.JobGet(ctx, string(*jobUUID), fields) if err != nil { return false, err } @@ -3099,7 +3100,8 @@ func (c RestClient) PollJobStatus(ctx context.Context, payload *models.JobLinkRe } jobStatusBackoff := backoff.NewExponentialBackOff() jobStatusBackoff.InitialInterval = 1 * time.Second - jobStatusBackoff.Multiplier = 2 + jobStatusBackoff.MaxInterval = 2 * time.Second + jobStatusBackoff.Multiplier = 1.414 jobStatusBackoff.RandomizationFactor = 0.1 jobStatusBackoff.MaxElapsedTime = 2 * time.Minute @@ -3111,7 +3113,8 @@ func (c RestClient) PollJobStatus(ctx context.Context, payload *models.JobLinkRe } Logc(ctx).WithField("UUID", jobUUID).Debug("Job completed.") - jobResult, err := c.JobGet(ctx, string(jobUUID)) + fields := []string{"**"} // we need to get all available fields + jobResult, err := c.JobGet(ctx, string(jobUUID), fields) if err != nil { return err } @@ -3167,14 +3170,15 @@ func (c RestClient) PollJobStatus(ctx context.Context, payload *models.JobLinkRe // //////////////////////////////////////////////////////////////////////////// // AggregateList returns the names of all Aggregates whose names match the supplied pattern -func (c RestClient) AggregateList(ctx context.Context, pattern string) (*storage.AggregateCollectionGetOK, error) { +func (c RestClient) AggregateList(ctx context.Context, pattern string, fields []string, +) (*storage.AggregateCollectionGetOK, error) { params := storage.NewAggregateCollectionGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.Storage.AggregateCollectionGet(params, c.authInfo) if err != nil { @@ -3238,7 +3242,8 @@ func (c RestClient) SvmList(ctx context.Context, pattern string) (*svm.SvmCollec params.HTTPClient = c.httpClient params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} + params.SetFields(fields) result, err := c.api.Svm.SvmCollectionGet(params, c.authInfo) if err != nil { @@ -3430,8 +3435,8 @@ func (c RestClient) ClusterInfo( params := cluster.NewClusterGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient - - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"version"} + params.SetFields(fields) return c.api.Cluster.ClusterGet(params, c.authInfo) } @@ -3468,7 +3473,7 @@ func (c RestClient) SystemGetOntapVersion( return c.OntapVersion, nil } -// ClusterInfo returns information about the cluster +// NodeList returns information about nodes func (c RestClient) NodeList(ctx context.Context, pattern string) (*cluster.NodesGetOK, error) { params := cluster.NewNodesGetParamsWithTimeout(c.httpClient.Timeout) @@ -3476,8 +3481,10 @@ func (c RestClient) NodeList(ctx context.Context, pattern string) (*cluster.Node params.HTTPClient = c.httpClient params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"serial_number"} + params.SetFields(fields) + params.SetFields(fields) result, err := c.api.Cluster.NodesGet(params, c.authInfo) if err != nil { return nil, err @@ -3645,7 +3652,8 @@ func (c RestClient) ExportPolicyList(ctx context.Context, pattern string) (*nas. params.SvmUUID = utils.Ptr(c.svmUUID) params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} // default 'none' gives ID + params.SetFields(fields) result, err := c.api.Nas.ExportPolicyCollectionGet(params, c.authInfo) if err != nil { @@ -3736,7 +3744,8 @@ func (c RestClient) ExportRuleList(ctx context.Context, policy string) (*nas.Exp params.HTTPClient = c.httpClient params.PolicyID = *exportPolicy.ID - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"clients"} + params.SetFields(fields) result, err := c.api.Nas.ExportRuleCollectionGet(params, c.authInfo) if err != nil { @@ -3908,7 +3917,8 @@ func (c RestClient) FlexgroupCloneSplitStart(ctx context.Context, volumeName str // FlexGroupDestroy destroys a FlexGroup func (c RestClient) FlexGroupDestroy(ctx context.Context, name string) error { - volume, err := c.FlexGroupGetByName(ctx, name) + fields := []string{""} + volume, err := c.FlexGroupGetByName(ctx, name, fields) if err != nil { return err } @@ -3963,7 +3973,8 @@ func (c RestClient) FlexgroupSetQosPolicyGroupName( func (c RestClient) FlexGroupVolumeModifySnapshotDirectoryAccess( ctx context.Context, flexGroupVolumeName string, enable bool, ) error { - volume, err := c.getVolumeByNameAndStyle(ctx, flexGroupVolumeName, models.VolumeStyleFlexgroup) + fields := []string{""} + volume, err := c.getVolumeByNameAndStyle(ctx, flexGroupVolumeName, models.VolumeStyleFlexgroup, fields) if err != nil { return err } @@ -4006,13 +4017,16 @@ func (c RestClient) FlexGroupSetComment(ctx context.Context, volumeName, newVolu } // FlexGroupGetByName gets the flexgroup with the specified name -func (c RestClient) FlexGroupGetByName(ctx context.Context, volumeName string) (*models.Volume, error) { - return c.getVolumeByNameAndStyle(ctx, volumeName, models.VolumeStyleFlexgroup) +func (c RestClient) FlexGroupGetByName(ctx context.Context, volumeName string, fields []string, +) (*models.Volume, error) { + return c.getVolumeByNameAndStyle(ctx, volumeName, models.VolumeStyleFlexgroup, fields) } // FlexGroupGetAll returns all relevant details for all FlexGroups whose names match the supplied prefix -func (c RestClient) FlexGroupGetAll(ctx context.Context, pattern string) (*storage.VolumeCollectionGetOK, error) { - return c.getAllVolumesByPatternStyleAndState(ctx, pattern, models.VolumeStyleFlexgroup, models.VolumeStateOnline) +func (c RestClient) FlexGroupGetAll(ctx context.Context, pattern string, fields []string, +) (*storage.VolumeCollectionGetOK, error) { + return c.getAllVolumesByPatternStyleAndState(ctx, pattern, models.VolumeStyleFlexgroup, models.VolumeStateOnline, + fields) } // FlexGroupMount mounts a flexgroup at the specified junction @@ -4118,7 +4132,8 @@ func (c RestClient) waitForQtree(ctx context.Context, volumeName, qtreeName stri // QtreeRename renames a qtree // equivalent to filer::> volume qtree rename func (c RestClient) QtreeRename(ctx context.Context, path, newPath string) error { - qtree, err := c.QtreeGetByPath(ctx, path) + fields := []string{""} + qtree, err := c.QtreeGetByPath(ctx, path, fields) if err != nil { return err } @@ -4159,7 +4174,8 @@ func (c RestClient) QtreeRename(ctx context.Context, path, newPath string) error // equivalent to filer::> volume qtree delete -foreground false func (c RestClient) QtreeDestroyAsync(ctx context.Context, path string, force bool) error { // note, force isn't used - qtree, err := c.QtreeGetByPath(ctx, path) + fields := []string{""} + qtree, err := c.QtreeGetByPath(ctx, path, fields) if err != nil { return err } @@ -4192,7 +4208,8 @@ func (c RestClient) QtreeDestroyAsync(ctx context.Context, path string, force bo // QtreeList returns the names of all Qtrees whose names match the supplied prefix // equivalent to filer::> volume qtree show -func (c RestClient) QtreeList(ctx context.Context, prefix, volumePrefix string) (*storage.QtreeCollectionGetOK, error) { +func (c RestClient) QtreeList(ctx context.Context, prefix, volumePrefix string, fields []string, +) (*storage.QtreeCollectionGetOK, error) { namePattern := "*" if prefix != "" { namePattern = prefix + "*" @@ -4213,7 +4230,7 @@ func (c RestClient) QtreeList(ctx context.Context, prefix, volumePrefix string) params.SetSvmUUID(utils.Ptr(c.svmUUID)) params.SetName(utils.Ptr(namePattern)) // Qtree name prefix params.SetVolumeName(utils.Ptr(volumePattern)) // Flexvol name prefix - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4255,7 +4272,7 @@ func (c RestClient) QtreeList(ctx context.Context, prefix, volumePrefix string) } // QtreeGetByPath gets the qtree with the specified path -func (c RestClient) QtreeGetByPath(ctx context.Context, path string) (*models.Qtree, error) { +func (c RestClient) QtreeGetByPath(ctx context.Context, path string, fields []string) (*models.Qtree, error) { // Limit the qtrees to those specified path params := storage.NewQtreeCollectionGetParamsWithTimeout(c.httpClient.Timeout) params.SetContext(ctx) @@ -4265,7 +4282,7 @@ func (c RestClient) QtreeGetByPath(ctx context.Context, path string) (*models.Qt params.SetSvmUUID(utils.Ptr(c.svmUUID)) params.SetPath(utils.Ptr(path)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4300,7 +4317,8 @@ func (c RestClient) QtreeGetByName(ctx context.Context, name, volumeName string) params.SvmUUID = utils.Ptr(c.svmUUID) params.SetName(utils.Ptr(name)) params.SetVolumeName(utils.Ptr(volumeName)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4334,7 +4352,8 @@ func (c RestClient) QtreeCount(ctx context.Context, volumeName string) (int, err params.SetSvmUUID(utils.Ptr(c.svmUUID)) params.SetVolumeName(utils.Ptr(volumeName)) // Flexvol name - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4398,7 +4417,8 @@ func (c RestClient) QtreeExists(ctx context.Context, name, volumePattern string) params.SetSvmUUID(utils.Ptr(c.svmUUID)) params.SetName(utils.Ptr(name)) // Qtree name params.SetVolumeName(utils.Ptr(volumePattern)) // Flexvol name prefix - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4475,7 +4495,8 @@ func (c RestClient) QtreeGet(ctx context.Context, name, volumePrefix string) (*m params.SetSvmUUID(utils.Ptr(c.svmUUID)) params.SetName(utils.Ptr(name)) // qtree name params.SetVolumeName(utils.Ptr(pattern)) // Flexvol name prefix - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4517,7 +4538,8 @@ func (c RestClient) QtreeGetAll(ctx context.Context, volumePrefix string) (*stor params.SvmUUID = utils.Ptr(c.svmUUID) params.SetVolumeName(utils.Ptr(pattern)) // Flexvol name prefix - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{""} + params.SetFields(fields) result, err := c.api.Storage.QtreeCollectionGet(params, c.authInfo) if err != nil { @@ -4613,7 +4635,8 @@ func (c RestClient) QuotaOff(ctx context.Context, volumeName string) error { // quotaModify enables/disables quotas on a Flexvol func (c RestClient) quotaModify(ctx context.Context, volumeName string, quotaEnabled bool) error { - volume, err := c.VolumeGetByName(ctx, volumeName) + fields := []string{"quota"} + volume, err := c.VolumeGetByName(ctx, volumeName, fields) if err != nil { return err } @@ -4888,7 +4911,8 @@ func (c RestClient) GetPeeredVservers(ctx context.Context) ([]string, error) { params.SetContext(ctx) params.SetHTTPClient(c.httpClient) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"peer.svm.name"} + params.SetFields(fields) result, err := c.api.Svm.SvmPeerCollectionGet(params, c.authInfo) if err != nil { @@ -4912,7 +4936,8 @@ func (c RestClient) SnapmirrorRelationshipsList(ctx context.Context) (*snapmirro params.SetContext(ctx) params.SetHTTPClient(c.httpClient) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"soruce", "destination"} + params.SetFields(fields) results, err := c.api.Snapmirror.SnapmirrorRelationshipsGet(params, c.authInfo) if err != nil { @@ -4993,13 +5018,13 @@ func (c RestClient) IsVserverInSVMDR(ctx context.Context) bool { } func (c RestClient) SnapmirrorGet( - ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, + ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, fields []string, ) (*models.SnapmirrorRelationship, error) { params := snapmirror.NewSnapmirrorRelationshipsGetParamsWithTimeout(c.httpClient.Timeout) params.SetContext(ctx) params.SetHTTPClient(c.httpClient) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) results, err := c.api.Snapmirror.SnapmirrorRelationshipsGet(params, c.authInfo) if err != nil { @@ -5046,7 +5071,8 @@ func (c RestClient) SnapmirrorListDestinations( params.SetHTTPClient(c.httpClient) params.WithListDestinationsOnly(utils.Ptr(true)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"source.path", "destination.path"} + params.SetFields(fields) results, err := c.api.Snapmirror.SnapmirrorRelationshipsGet(params, c.authInfo) if err != nil { @@ -5128,7 +5154,8 @@ func (c RestClient) SnapmirrorInitialize( ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, ) error { // first, find the relationship so we can then use the UUID to modify it - relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName) + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName, fields) if err != nil { return err } @@ -5162,7 +5189,8 @@ func (c RestClient) SnapmirrorResync( ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, ) error { // first, find the relationship so we can then use the UUID to modify it - relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName) + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName, fields) if err != nil { return err } @@ -5203,7 +5231,8 @@ func (c RestClient) SnapmirrorBreak( ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName, snapshotName string, ) error { // first, find the relationship so we can then use the UUID to modify it - relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName) + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName, fields) if err != nil { return err } @@ -5242,7 +5271,8 @@ func (c RestClient) SnapmirrorQuiesce( ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, ) error { // first, find the relationship so we can then use the UUID to modify it - relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName) + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName, fields) if err != nil { return err } @@ -5277,7 +5307,8 @@ func (c RestClient) SnapmirrorAbort( ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, ) error { // first, find the relationship so we can then use the UUID to modify it - relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName) + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, c.SVMName(), remoteFlexvolName, remoteSVMName, fields) if err != nil { return err } @@ -5350,7 +5381,8 @@ func (c RestClient) SnapmirrorDeleteViaDestination( relationship, err := c.SnapmirrorListDestinations(ctx, localFlexvolName, localSVMName, "", "") if err != nil { if IsNotFoundError(err) { - relationship, err = c.SnapmirrorGet(ctx, localFlexvolName, localSVMName, "", "") + fields := []string{"destination.path", "source.path"} + relationship, err = c.SnapmirrorGet(ctx, localFlexvolName, localSVMName, "", "", fields) if err != nil { return err } @@ -5412,7 +5444,8 @@ func (c RestClient) SnapmirrorDelete( ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, ) error { // first, find the relationship so we can then use the UUID to delete it - relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName) + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName, fields) if err != nil { return err } @@ -5448,7 +5481,8 @@ func (c RestClient) IsVserverDRCapable(ctx context.Context) (bool, error) { params.SetHTTPClient(c.httpClient) params.SvmUUID = &c.svmUUID - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + fields := []string{"peer.svm.name"} + params.SetFields(fields) result, err := c.api.Svm.SvmPeerCollectionGet(params, c.authInfo) if err != nil { @@ -5551,7 +5585,8 @@ func (c *RestClient) GetSVMState(ctx context.Context) (string, error) { func (c RestClient) SnapmirrorUpdate(ctx context.Context, localInternalVolumeName, snapshotName string) error { // first, find the relationship so we can then use the UUID to update - relationship, err := c.SnapmirrorGet(ctx, localInternalVolumeName, c.SVMName(), "", "") + fields := []string{"destination.path", "source.path"} + relationship, err := c.SnapmirrorGet(ctx, localInternalVolumeName, c.SVMName(), "", "", fields) if err != nil { return err } @@ -5738,14 +5773,14 @@ func (c RestClient) NVMeNamespaceSetSize(ctx context.Context, nsUUID string, new } // NVMeNamespaceList finds Namespaces with the specified pattern. -func (c RestClient) NVMeNamespaceList(ctx context.Context, pattern string) (*nvme.NvmeNamespaceCollectionGetOK, error) { +func (c RestClient) NVMeNamespaceList(ctx context.Context, pattern string, fields []string) (*nvme.NvmeNamespaceCollectionGetOK, error) { params := nvme.NewNvmeNamespaceCollectionGetParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx params.HTTPClient = c.httpClient params.SvmUUID = utils.Ptr(c.svmUUID) params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.NvMe.NvmeNamespaceCollectionGet(params, c.authInfo) if err != nil { @@ -5787,8 +5822,8 @@ func (c RestClient) NVMeNamespaceList(ctx context.Context, pattern string) (*nvm } // NVMeNamespaceGetByName gets the Namespace with the specified name. -func (c RestClient) NVMeNamespaceGetByName(ctx context.Context, name string) (*models.NvmeNamespace, error) { - result, err := c.NVMeNamespaceList(ctx, name) +func (c RestClient) NVMeNamespaceGetByName(ctx context.Context, name string, fields []string) (*models.NvmeNamespace, error) { + result, err := c.NVMeNamespaceList(ctx, name, fields) if err != nil { return nil, err } @@ -5902,7 +5937,7 @@ func (c RestClient) NVMeNamespaceCount(ctx context.Context, subsysUUID string) ( // Subsystem operations // NVMeSubsystemList returns a list of subsystems seen by the host -func (c RestClient) NVMeSubsystemList(ctx context.Context, pattern string) (*nvme.NvmeSubsystemCollectionGetOK, error) { +func (c RestClient) NVMeSubsystemList(ctx context.Context, pattern string, fields []string) (*nvme.NvmeSubsystemCollectionGetOK, error) { if pattern == "" { pattern = "*" } @@ -5913,7 +5948,7 @@ func (c RestClient) NVMeSubsystemList(ctx context.Context, pattern string) (*nvm params.SvmUUID = &c.svmUUID params.SetName(utils.Ptr(pattern)) - params.SetFields([]string{"**"}) // TODO trim these down to just what we need + params.SetFields(fields) result, err := c.api.NvMe.NvmeSubsystemCollectionGet(params, c.authInfo) if err != nil { @@ -5955,8 +5990,8 @@ func (c RestClient) NVMeSubsystemList(ctx context.Context, pattern string) (*nvm } // NVMeSubsystemGetByName gets the subsystem with the specified name -func (c RestClient) NVMeSubsystemGetByName(ctx context.Context, subsystemName string) (*models.NvmeSubsystem, error) { - result, err := c.NVMeSubsystemList(ctx, subsystemName) +func (c RestClient) NVMeSubsystemGetByName(ctx context.Context, subsystemName string, fields []string) (*models.NvmeSubsystem, error) { + result, err := c.NVMeSubsystemList(ctx, subsystemName, fields) if err != nil { return nil, err } @@ -6004,7 +6039,7 @@ func (c RestClient) NVMeSubsystemCreate(ctx context.Context, subsystemName strin return nil, fmt.Errorf("subsystem create failed with error %v", subsysCreated.Error()) } -// NVMeSubsystemCreate deletes a given subsystem +// NVMeSubsystemDelete deletes a given subsystem func (c RestClient) NVMeSubsystemDelete(ctx context.Context, subsysUUID string) error { params := nvme.NewNvmeSubsystemDeleteParamsWithTimeout(c.httpClient.Timeout) params.Context = ctx @@ -6095,7 +6130,8 @@ func (c RestClient) NVMeGetHostsOfSubsystem(ctx context.Context, subsUUID string // NVMeNamespaceSize returns the size of the namespace func (c RestClient) NVMeNamespaceSize(ctx context.Context, namespacePath string) (int, error) { - namespace, err := c.NVMeNamespaceGetByName(ctx, namespacePath) + fields := []string{"space.size"} + namespace, err := c.NVMeNamespaceGetByName(ctx, namespacePath, fields) if err != nil { return 0, err } diff --git a/storage_drivers/ontap/api/ontap_rest_interface.go b/storage_drivers/ontap/api/ontap_rest_interface.go index ff72e771c..a3e1074d2 100644 --- a/storage_drivers/ontap/api/ontap_rest_interface.go +++ b/storage_drivers/ontap/api/ontap_rest_interface.go @@ -26,14 +26,12 @@ type RestClientInterface interface { SVMUUID() string SetSVMName(svmName string) SVMName() string - // GetSVMState gets the latest state of associated vserver - GetSVMState(ctx context.Context) (string, error) // SupportsFeature returns true if the Ontap version supports the supplied feature SupportsFeature(ctx context.Context, feature Feature) bool // VolumeList returns the names of all Flexvols whose names match the supplied pattern - VolumeList(ctx context.Context, pattern string) (*storage.VolumeCollectionGetOK, error) + VolumeList(ctx context.Context, pattern string, fields []string) (*storage.VolumeCollectionGetOK, error) // VolumeListByAttrs is used to find bucket volumes for nas-eco and san-eco - VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume) (Volumes, error) + VolumeListByAttrs(ctx context.Context, volumeAttrs *Volume, fields []string) (*storage.VolumeCollectionGetOK, error) // VolumeCreate creates a volume with the specified options // equivalent to filer::> volume create -vserver iscsi_vs -volume v -aggregate aggr1 -size 1g -state online -type RW // -policy default -unix-permissions ---rwxr-xr-x -space-guarantee none -snapshot-policy none -security-style unix @@ -42,7 +40,7 @@ type RestClientInterface interface { // VolumeExists tests for the existence of a flexvol VolumeExists(ctx context.Context, volumeName string) (bool, error) // VolumeGetByName gets the flexvol with the specified name - VolumeGetByName(ctx context.Context, volumeName string) (*models.Volume, error) + VolumeGetByName(ctx context.Context, volumeName string, fields []string) (*models.Volume, error) // VolumeMount mounts a flexvol at the specified junction VolumeMount(ctx context.Context, volumeName, junctionPath string) error // VolumeRename changes the name of a flexvol @@ -94,16 +92,16 @@ type RestClientInterface interface { VolumeCloneCreateAsync(ctx context.Context, cloneName, sourceVolumeName, snapshot string) error // IscsiInitiatorGetDefaultAuth returns the authorization details for the default initiator // equivalent to filer::> vserver iscsi security show -vserver SVM -initiator-name default - IscsiInitiatorGetDefaultAuth(ctx context.Context) (*san.IscsiCredentialsCollectionGetOK, error) + IscsiInitiatorGetDefaultAuth(ctx context.Context, fields []string) (*san.IscsiCredentialsCollectionGetOK, error) // IscsiInterfaceGet returns information about the vserver's iSCSI interfaces - IscsiInterfaceGet(ctx context.Context) (*san.IscsiServiceCollectionGetOK, error) + IscsiInterfaceGet(ctx context.Context, fields []string) (*san.IscsiServiceCollectionGetOK, error) // IscsiInitiatorSetDefaultAuth sets the authorization details for the default initiator // // equivalent to filer::> vserver iscsi security modify -vserver SVM -initiator-name default \ // -auth-type CHAP -user-name outboundUserName -outbound-user-name outboundPassphrase IscsiInitiatorSetDefaultAuth(ctx context.Context, authType, userName, passphrase, outbountUserName, outboundPassphrase string) error // IscsiNodeGetName returns information about the vserver's iSCSI node name - IscsiNodeGetName(ctx context.Context) (*san.IscsiServiceGetOK, error) + IscsiNodeGetName(ctx context.Context, fields []string) (*san.IscsiServiceGetOK, error) // IgroupCreate creates the specified initiator group // equivalent to filer::> igroup create docker -vserver iscsi_vs -protocol iscsi -ostype linux IgroupCreate(ctx context.Context, initiatorGroupName, initiatorGroupType, osType string) error @@ -116,11 +114,11 @@ type RestClientInterface interface { // IgroupDestroy destroys an initiator group IgroupDestroy(ctx context.Context, initiatorGroupName string) error // IgroupList lists initiator groups - IgroupList(ctx context.Context, pattern string) (*san.IgroupCollectionGetOK, error) + IgroupList(ctx context.Context, pattern string, fields []string) (*san.IgroupCollectionGetOK, error) // IgroupGet gets the igroup with the specified uuid IgroupGet(ctx context.Context, uuid string) (*san.IgroupGetOK, error) // IgroupGetByName gets the igroup with the specified name - IgroupGetByName(ctx context.Context, initiatorGroupName string) (*models.Igroup, error) + IgroupGetByName(ctx context.Context, initiatorGroupName string, fields []string) (*models.Igroup, error) // LunOptions gets the LUN options LunOptions(ctx context.Context) (*LunOptionsResult, error) // LunCloneCreate creates a LUN clone @@ -130,9 +128,9 @@ type RestClientInterface interface { // LunGet gets the LUN with the specified uuid LunGet(ctx context.Context, uuid string) (*san.LunGetOK, error) // LunGetByName gets the LUN with the specified name - LunGetByName(ctx context.Context, name string) (*models.Lun, error) + LunGetByName(ctx context.Context, name string, fields []string) (*models.Lun, error) // LunList finds LUNs with the specified pattern - LunList(ctx context.Context, pattern string) (*san.LunCollectionGetOK, error) + LunList(ctx context.Context, pattern string, fields []string) (*san.LunCollectionGetOK, error) // LunDelete deletes a LUN LunDelete(ctx context.Context, lunUUID string) error // LunGetComment gets the comment for a given LUN. @@ -159,7 +157,7 @@ type RestClientInterface interface { // filer::> lun mapping show -vserver iscsi_vs -path /vol/v/lun0 -igroup trident // filer::> lun mapping show -vserver iscsi_vs -path /vol/v/lun0 -igroup * // filer::> lun mapping show -vserver iscsi_vs -path * -igroup trident - LunMapList(ctx context.Context, initiatorGroupName, lunPath string) (*san.LunMapCollectionGetOK, error) + LunMapList(ctx context.Context, initiatorGroupName, lunPath string, fields []string) (*san.LunMapCollectionGetOK, error) // LunMapGetReportingNodes // equivalent to filer::> lun mapping show -vserver iscsi_vs -path /vol/v/lun0 -igroup trident LunMapGetReportingNodes(ctx context.Context, initiatorGroupName, lunPath string) ([]string, error) @@ -171,29 +169,29 @@ type RestClientInterface interface { NetworkIPInterfacesList(ctx context.Context) (*networking.NetworkIPInterfacesGetOK, error) NetInterfaceGetDataLIFs(ctx context.Context, protocol string) ([]string, error) // JobGet returns the job by ID - JobGet(ctx context.Context, jobUUID string) (*cluster.JobGetOK, error) + JobGet(ctx context.Context, jobUUID string, fields []string) (*cluster.JobGetOK, error) // IsJobFinished lookus up the supplied JobLinkResponse's UUID to see if it's reached a terminal state IsJobFinished(ctx context.Context, payload *models.JobLinkResponse) (bool, error) // PollJobStatus polls for the ONTAP job to complete, with backoff retry logic PollJobStatus(ctx context.Context, payload *models.JobLinkResponse) error // AggregateList returns the names of all Aggregates whose names match the supplied pattern - AggregateList(ctx context.Context, pattern string) (*storage.AggregateCollectionGetOK, error) + AggregateList(ctx context.Context, pattern string, fields []string) (*storage.AggregateCollectionGetOK, error) // SvmGet gets the volume with the specified uuid SvmGet(ctx context.Context, uuid string) (*svm.SvmGetOK, error) // SvmList returns the names of all SVMs whose names match the supplied pattern SvmList(ctx context.Context, pattern string) (*svm.SvmCollectionGetOK, error) - // SvmGetByName gets the volume with the specified name + // SvmGetByName gets the SVM with the specified name SvmGetByName(ctx context.Context, svmName string) (*models.Svm, error) SVMGetAggregateNames(ctx context.Context) ([]string, error) // ClusterInfo returns information about the cluster ClusterInfo(ctx context.Context) (*cluster.ClusterGetOK, error) // SystemGetOntapVersion gets the ONTAP version using the credentials, and caches & returns the result. SystemGetOntapVersion(ctx context.Context) (string, error) - // ClusterInfo returns information about the cluster + // NodeList returns information about nodes NodeList(ctx context.Context, pattern string) (*cluster.NodesGetOK, error) NodeListSerialNumbers(ctx context.Context) ([]string, error) // EmsAutosupportLog generates an auto support message with the supplied parameters - EmsAutosupportLog(ctx context.Context, appVersion string, autoSupport bool, category, computerName, eventDescription string, eventID int, eventSource string, logLevel int) error + EmsAutosupportLog(ctx context.Context, appVersion string, autoSupport bool, category string, computerName string, eventDescription string, eventID int, eventSource string, logLevel int) error TieringPolicyValue(ctx context.Context) string // ExportPolicyCreate creates an export policy // equivalent to filer::> vserver export-policy create @@ -238,9 +236,9 @@ type RestClientInterface interface { // FlexGroupSetComment sets a flexgroup's comment to the supplied value FlexGroupSetComment(ctx context.Context, volumeName, newVolumeComment string) error // FlexGroupGetByName gets the flexgroup with the specified name - FlexGroupGetByName(ctx context.Context, volumeName string) (*models.Volume, error) + FlexGroupGetByName(ctx context.Context, volumeName string, fields []string) (*models.Volume, error) // FlexGroupGetAll returns all relevant details for all FlexGroups whose names match the supplied prefix - FlexGroupGetAll(ctx context.Context, pattern string) (*storage.VolumeCollectionGetOK, error) + FlexGroupGetAll(ctx context.Context, pattern string, fields []string) (*storage.VolumeCollectionGetOK, error) // FlexGroupMount mounts a flexgroup at the specified junction FlexGroupMount(ctx context.Context, volumeName, junctionPath string) error // FlexgroupUnmount unmounts the flexgroup @@ -257,9 +255,9 @@ type RestClientInterface interface { QtreeDestroyAsync(ctx context.Context, path string, force bool) error // QtreeList returns the names of all Qtrees whose names match the supplied prefix // equivalent to filer::> volume qtree show - QtreeList(ctx context.Context, prefix, volumePrefix string) (*storage.QtreeCollectionGetOK, error) + QtreeList(ctx context.Context, prefix, volumePrefix string, fields []string) (*storage.QtreeCollectionGetOK, error) // QtreeGetByPath gets the qtree with the specified path - QtreeGetByPath(ctx context.Context, path string) (*models.Qtree, error) + QtreeGetByPath(ctx context.Context, path string, fields []string) (*models.Qtree, error) // QtreeGetByName gets the qtree with the specified name in the specified volume QtreeGetByName(ctx context.Context, name, volumeName string) (*models.Qtree, error) // QtreeCount returns the number of Qtrees in the specified Flexvol, not including the Flexvol itself @@ -299,60 +297,71 @@ type RestClientInterface interface { IsVserverDRDestination(ctx context.Context) (bool, error) // IsVserverDRSource identifies if the Vserver is a source vserver of Snapmirror relationship (SVM-DR) or not IsVserverDRSource(ctx context.Context) (bool, error) - SnapmirrorGet(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string) (*models.SnapmirrorRelationship, error) - SnapmirrorCreate(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName, repPolicy, repSchedule string) error - SnapmirrorInitialize(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string) error - SnapmirrorResync(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string) error - SnapmirrorBreak(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName, snapshotName string) error - SnapmirrorQuiesce(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string) error - SnapmirrorAbort(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string) error + // IsVserverInSVMDR identifies if the Vserver is in Snapmirror relationship (SVM-DR) or not + IsVserverInSVMDR(ctx context.Context) bool + SnapmirrorGet(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string, fields []string) (*models.SnapmirrorRelationship, error) + SnapmirrorListDestinations(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string) (*models.SnapmirrorRelationship, error) + SnapmirrorCreate(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName, repPolicy, repSchedule string) error + SnapmirrorInitialize(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string) error + SnapmirrorResync(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string) error + SnapmirrorBreak(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName, snapshotName string) error + SnapmirrorQuiesce(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string) error + SnapmirrorAbort(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string) error // SnapmirrorRelease removes all local snapmirror relationship metadata from the source vserver // Intended to be used on the source vserver SnapmirrorRelease(ctx context.Context, sourceFlexvolName, sourceSVMName string) error // Intended to be from the destination vserver - SnapmirrorDeleteViaDestination(ctx context.Context, localInternalVolumeName, localSVMName string) error + SnapmirrorDeleteViaDestination(ctx context.Context, localFlexvolName, localSVMName string) error // Intended to be from the destination vserver - SnapmirrorDelete(ctx context.Context, localInternalVolumeName, localSVMName, remoteFlexvolName, remoteSVMName string) error - SnapmirrorUpdate(ctx context.Context, localInternalVolumeName, snapshotName string) error + SnapmirrorDelete(ctx context.Context, localFlexvolName, localSVMName, remoteFlexvolName, remoteSVMName string) error IsVserverDRCapable(ctx context.Context) (bool, error) SnapmirrorPolicyExists(ctx context.Context, policyName string) (bool, error) SnapmirrorPolicyGet(ctx context.Context, policyName string) (*snapmirror.SnapmirrorPoliciesGetOK, error) JobScheduleExists(ctx context.Context, jobName string) (bool, error) + // GetSVMState returns the SVM state from the backend storage. + GetSVMState(ctx context.Context) (string, error) + SnapmirrorUpdate(ctx context.Context, localInternalVolumeName, snapshotName string) error // SMBShareCreate creates an SMB share with the specified name and path. + // Equivalent to filer::> vserver cifs share create -share-name -path SMBShareCreate(ctx context.Context, shareName, path string) error // SMBShareExists checks for the existence of an SMB share with the given name. - SMBShareExists(ctx context.Context, shareName string) (bool, error) - // SMBShareDestroy deletes an SMB Share. + // Equivalent to filer::> cifs share show + SMBShareExists(ctx context.Context, smbShareName string) (bool, error) + // SMBShareDestroy destroys an SMB share. + // Equivalent to filer::> cifs share delete SMBShareDestroy(ctx context.Context, shareName string) error - // NVMeNamespaceCreate creates a NVMe namespace. + // NVMe Namespace operations + // NVMeNamespaceCreate creates NVMe namespace in the backend's SVM. NVMeNamespaceCreate(ctx context.Context, ns NVMeNamespace) (string, error) // NVMeNamespaceSetSize updates the namespace size to newSize. NVMeNamespaceSetSize(ctx context.Context, nsUUID string, newSize int64) error - // NVMeNamespaceGetByName gets the Namespace with the specified name. - NVMeNamespaceGetByName(ctx context.Context, name string) (*models.NvmeNamespace, error) // NVMeNamespaceList finds Namespaces with the specified pattern. - NVMeNamespaceList(ctx context.Context, pattern string) (*nvme.NvmeNamespaceCollectionGetOK, error) - // NVMeIsNamespaceMapped gets a namespace from subsystem map - NVMeIsNamespaceMapped(ctx context.Context, subsysUUID, nsUUID string) (bool, error) - // NVMeNamespaceCount gives the number of namespaces mapped to a Subsystem with the specified subsystem UUID. + NVMeNamespaceList(ctx context.Context, pattern string, fields []string) (*nvme.NvmeNamespaceCollectionGetOK, error) + // NVMeNamespaceGetByName gets the Namespace with the specified name. + NVMeNamespaceGetByName(ctx context.Context, name string, fields []string) (*models.NvmeNamespace, error) + // NVMe Subsystem operations + // NVMeSubsystemAddNamespace adds namespace to subsystem-map + NVMeSubsystemAddNamespace(ctx context.Context, subsystemUUID, nsUUID string) error + // NVMeSubsystemRemoveNamespace removes a namespace from subsystem-map + NVMeSubsystemRemoveNamespace(ctx context.Context, subsysUUID, nsUUID string) error + // NVMeIsNamespaceMapped retrives a namespace from subsystem-map + NVMeIsNamespaceMapped(ctx context.Context, subsysUUID, namespaceUUID string) (bool, error) + // NVMeNamespaceCount gets the number of namespaces mapped to a subsystem NVMeNamespaceCount(ctx context.Context, subsysUUID string) (int64, error) - // NVMeNamespaceSize gives the size of the namespace. - NVMeNamespaceSize(ctx context.Context, namespacePath string) (int, error) - // NVMeSubsystemList finds Subsystems with the specified pattern. - NVMeSubsystemList(ctx context.Context, pattern string) (*nvme.NvmeSubsystemCollectionGetOK, error) - // NVMeSubsystemGetByName finds Subsystem with the specified subsystem name. - NVMeSubsystemGetByName(ctx context.Context, subsystemName string) (*models.NvmeSubsystem, error) - // NVMeSubsystemCreate creates a Subsystem with the specified subsystem name. + // Subsystem operations + // NVMeSubsystemList returns a list of subsystems seen by the host + NVMeSubsystemList(ctx context.Context, pattern string, fields []string) (*nvme.NvmeSubsystemCollectionGetOK, error) + // NVMeSubsystemGetByName gets the subsystem with the specified name + NVMeSubsystemGetByName(ctx context.Context, subsystemName string, fields []string) (*models.NvmeSubsystem, error) + // NVMeSubsystemCreate creates a new subsystem NVMeSubsystemCreate(ctx context.Context, subsystemName string) (*models.NvmeSubsystem, error) - // NVMeSubsystemDelete deletes a Subsystem with the specified subsystem UUID. + // NVMeSubsystemDelete deletes a given subsystem NVMeSubsystemDelete(ctx context.Context, subsysUUID string) error - // NVMeAddHostNqnToSubsystem adds host's NQN to a Subsystem with the specified subsystem UUID. + // NVMeAddHostNqnToSubsystem adds the NQN of the host to the subsystem NVMeAddHostNqnToSubsystem(ctx context.Context, hostNQN, subsUUID string) error - // NVMeGetHostsOfSubsystem gets all the hosts mapped to a Subsystem with the specified subsystem UUID. + // NVMeRemoveHostFromSubsystem remove the NQN of the host from the subsystem + NVMeRemoveHostFromSubsystem(ctx context.Context, hostNQN, subsUUID string) error + // NVMeGetHostsOfSubsystem retuns all the hosts connected to a subsystem NVMeGetHostsOfSubsystem(ctx context.Context, subsUUID string) ([]*models.NvmeSubsystemHost, error) - // NVMeSubsystemAddNamespace maps a namespace to a Subsystem with the specified subsystem name. - NVMeSubsystemAddNamespace(ctx context.Context, subsystemUUID, nsUUID string) error - // NVMeSubsystemRemoveNamespace ummaps a given namespace from a Subsystem with the specified subsystem UUID. - NVMeSubsystemRemoveNamespace(ctx context.Context, subsysUUID, nsUUID string) error - NVMeRemoveHostFromSubsystem(ctx context.Context, hostNQN, subsystemUUID string) error + NVMeNamespaceSize(ctx context.Context, namespacePath string) (int, error) } diff --git a/storage_drivers/ontap/api/ontap_rest_test.go b/storage_drivers/ontap/api/ontap_rest_test.go index 72a2981a4..7ab10728b 100644 --- a/storage_drivers/ontap/api/ontap_rest_test.go +++ b/storage_drivers/ontap/api/ontap_rest_test.go @@ -246,7 +246,7 @@ func TestOntapREST_IscsiInitiatorGetDefaultAuth(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - _, err := rs.IscsiInitiatorGetDefaultAuth(ctx) + _, err := rs.IscsiInitiatorGetDefaultAuth(ctx, []string{""}) assert.NoError(t, err, "could not get the iscsi initiator default auth") server.Close() @@ -285,7 +285,7 @@ func TestOntapREST_IscsiInterfaceGet(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - iscsi, err := rs.IscsiInterfaceGet(ctx) + iscsi, err := rs.IscsiInterfaceGet(ctx, []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get the iscsi interface") assert.Equal(t, "fake-svm", @@ -423,7 +423,7 @@ func TestOntapREST_IscsiNodeGetName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - iscsi, err := rs.IscsiNodeGetName(ctx) + iscsi, err := rs.IscsiNodeGetName(ctx, []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get the iscsi name") @@ -538,7 +538,7 @@ func TestOntapREST_IgroupList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - igroup, err := rs.IgroupList(ctx, test.pattern) + igroup, err := rs.IgroupList(ctx, test.pattern, []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get igroup") @@ -691,7 +691,7 @@ func TestOntapREST_IgroupListHref(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - igroup, err := rs.IgroupList(ctx, "igroup") + igroup, err := rs.IgroupList(ctx, "igroup", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get igroup") assert.Equal(t, "igroup1", @@ -747,7 +747,7 @@ func TestOntapREST_IgroupGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - igroup, err := rs.IgroupGetByName(ctx, "igroup") + igroup, err := rs.IgroupGetByName(ctx, "igroup", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get igroup") assert.Equal(t, "igroup1", *igroup.Name, "igroup name does not match") @@ -958,7 +958,7 @@ func TestOntapREST_LunListByPattern(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - lunResponse, err := rs.LunList(ctx, "*") + lunResponse, err := rs.LunList(ctx, "*", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get LUN") assert.Equal(t, "fake-lunName", @@ -1108,7 +1108,7 @@ func TestOntapREST_LunGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - lunResponse, err := rs.LunGetByName(ctx, "fake-lunName") + lunResponse, err := rs.LunGetByName(ctx, "fake-lunName", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get LUN by name") if !test.isResponseNil { @@ -1740,7 +1740,7 @@ func TestOntapREST_LunMapList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - lumMapResponse, err := rs.LunMapList(ctx, "fake-initiatorGroupName", "/dev/sda") + lumMapResponse, err := rs.LunMapList(ctx, "fake-initiatorGroupName", "/dev/sda", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get the LUN map") assert.Equal(t, "initiatorGroup", @@ -2936,7 +2936,8 @@ func TestOntapREST_AggregateList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - aggrList, err := rs.AggregateList(ctx, "aggr1") + aggrList, err := rs.AggregateList(ctx, "aggr1", []string{""}) + if !test.isErrorExpected { assert.NoError(t, err, "could not get the aggregate list") assert.Equal(t, "aggr1", *aggrList.Payload.AggregateResponseInlineRecords[0].Name) @@ -2952,7 +2953,7 @@ func mockSVMList(hasNextLink bool, w http.ResponseWriter, r *http.Request) { svmUUID := "1234" svmName := "svm0" - svm := models.Svm{ + newSvm := models.Svm{ UUID: &svmUUID, Name: &svmName, State: utils.Ptr("running"), @@ -2970,7 +2971,7 @@ func mockSVMList(hasNextLink bool, w http.ResponseWriter, r *http.Request) { } svmResponse := models.SvmResponse{ - SvmResponseInlineRecords: []*models.Svm{&svm}, + SvmResponseInlineRecords: []*models.Svm{&newSvm}, NumRecords: utils.Ptr(int64(1)), Links: hrefLink, } @@ -2982,7 +2983,7 @@ func mockSVMListInternalError(hasNextLink bool, w http.ResponseWriter, r *http.R svmUUID := "1234" svmName := "svm0" - svm := models.Svm{ + newsvm := models.Svm{ UUID: &svmUUID, Name: &svmName, State: utils.Ptr("running"), @@ -3002,7 +3003,7 @@ func mockSVMListInternalError(hasNextLink bool, w http.ResponseWriter, r *http.R } svmResponse := models.SvmResponse{ - SvmResponseInlineRecords: []*models.Svm{&svm}, + SvmResponseInlineRecords: []*models.Svm{&newsvm}, NumRecords: utils.Ptr(int64(1)), Links: hrefLink, } @@ -3030,10 +3031,10 @@ func TestOntapREST_SvmList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - svm, err := rs.SvmList(ctx, "svm0") + svmres, err := rs.SvmList(ctx, "svm0") if !test.isErrorExpected { assert.NoError(t, err, "could not get svm") - assert.Equal(t, "svm0", *svm.Payload.SvmResponseInlineRecords[0].Name) + assert.Equal(t, "svm0", *svmres.Payload.SvmResponseInlineRecords[0].Name) } else { assert.Error(t, err, "get the svm") } @@ -3058,10 +3059,10 @@ func TestOntapREST_SvmGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - svm, err := rs.SvmGetByName(ctx, "svm0") + svmname, err := rs.SvmGetByName(ctx, "svm0") if !test.isErrorExpected { assert.NoError(t, err, "could not get svm by name") - assert.Equal(t, "svm0", *svm.Name) + assert.Equal(t, "svm0", *svmname.Name) } else { assert.Error(t, err, "get the svm by name") } @@ -3074,7 +3075,7 @@ func mockSVMSvmStateNil(w http.ResponseWriter, r *http.Request) { svmUUID := "1234" svmName := "svm0" - svm := models.Svm{ + newsvm := models.Svm{ UUID: &svmUUID, Name: &svmName, SvmInlineAggregates: []*models.SvmInlineAggregatesInlineArrayItem{ @@ -3083,7 +3084,7 @@ func mockSVMSvmStateNil(w http.ResponseWriter, r *http.Request) { } setHTTPResponseHeader(w, http.StatusOK) - json.NewEncoder(w).Encode(svm) + json.NewEncoder(w).Encode(newsvm) } func TestOntapREST_GetSVMState(t *testing.T) { @@ -3702,7 +3703,7 @@ func TestOntapRest_NVMeNamespaceList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - nvmeResponse, err := rs.NVMeNamespaceList(ctx, "namespace1") + nvmeResponse, err := rs.NVMeNamespaceList(ctx, "namespace1", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get the NVMe namespace list") assert.Equal(t, "namespace1", *nvmeResponse.Payload.NvmeNamespaceResponseInlineRecords[0].Name) @@ -3731,7 +3732,7 @@ func TestOntapRest_NVMeNamespaceGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - nvmeResponse, err := rs.NVMeNamespaceGetByName(ctx, "namespace1") + nvmeResponse, err := rs.NVMeNamespaceGetByName(ctx, "namespace1", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get the NVMe namespace by name") assert.Equal(t, "namespace1", *nvmeResponse.Name) @@ -3868,7 +3869,7 @@ func TestOntapRest_NVMeSubsystemList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - _, err := rs.NVMeSubsystemList(ctx, test.pattern) + _, err := rs.NVMeSubsystemList(ctx, test.pattern, []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "failed to get NVMe subsystem list") } else { @@ -3894,7 +3895,7 @@ func TestOntapRest_NVMeSubsystemGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - nvmeSubsystemList, err := rs.NVMeSubsystemGetByName(ctx, "subsystemUUID") + nvmeSubsystemList, err := rs.NVMeSubsystemGetByName(ctx, "subsystemUUID", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "failed to get NVMe subsystem by name") assert.Equal(t, "subsystemName", *nvmeSubsystemList.Name) @@ -4045,7 +4046,7 @@ func mockSVM(w http.ResponseWriter, r *http.Request) { svmUUID := "1234" svmName := "svm0" - svm := models.Svm{ + mocksvm := models.Svm{ UUID: &svmUUID, Name: &svmName, State: utils.Ptr("running"), @@ -4055,12 +4056,12 @@ func mockSVM(w http.ResponseWriter, r *http.Request) { } if r.URL.Path == "/api/svm/svms/1234" { setHTTPResponseHeader(w, http.StatusOK) - json.NewEncoder(w).Encode(svm) + json.NewEncoder(w).Encode(mocksvm) } if r.URL.Path == "/api/svm/svms" { svmResponse := models.SvmResponse{ - SvmResponseInlineRecords: []*models.Svm{&svm}, + SvmResponseInlineRecords: []*models.Svm{&mocksvm}, NumRecords: utils.Ptr(int64(1)), } setHTTPResponseHeader(w, http.StatusOK) @@ -4069,7 +4070,7 @@ func mockSVM(w http.ResponseWriter, r *http.Request) { } func mockSVMNameNil(w http.ResponseWriter, r *http.Request) { - svm := models.Svm{ + mocksvm := models.Svm{ UUID: utils.Ptr("fake-uuid"), State: utils.Ptr("running"), SvmInlineAggregates: []*models.SvmInlineAggregatesInlineArrayItem{ @@ -4078,7 +4079,7 @@ func mockSVMNameNil(w http.ResponseWriter, r *http.Request) { } svmResponse := models.SvmResponse{ - SvmResponseInlineRecords: []*models.Svm{&svm}, + SvmResponseInlineRecords: []*models.Svm{&mocksvm}, NumRecords: utils.Ptr(int64(1)), } setHTTPResponseHeader(w, http.StatusOK) @@ -4086,14 +4087,14 @@ func mockSVMNameNil(w http.ResponseWriter, r *http.Request) { } func mockSVMNumRecordsNil(w http.ResponseWriter, r *http.Request) { - svm := models.Svm{ + mocksvm := models.Svm{ Name: utils.Ptr("svm0"), SvmInlineAggregates: []*models.SvmInlineAggregatesInlineArrayItem{ {Name: utils.Ptr("aggr1")}, }, } svmResponse := models.SvmResponse{ - SvmResponseInlineRecords: []*models.Svm{&svm}, + SvmResponseInlineRecords: []*models.Svm{&mocksvm}, } setHTTPResponseHeader(w, http.StatusOK) @@ -4482,7 +4483,10 @@ func TestGetAllVolumesByPatternStyleAndState_failure(t *testing.T) { volumeParam := &storage.VolumeCollectionGetParams{} volumeParam.Context = ctx - volume, err := rs.getAllVolumesByPatternStyleAndState(ctx, "trident", test.style, test.state) + + fields := []string{"size", "type", "nas.unix_permissions", "aggregates"} + volume, err := rs.getAllVolumesByPatternStyleAndState(ctx, "trident", test.style, test.state, fields) + if !test.isErrorExpected { assert.NoError(t, err, "could not get the volume info") assert.Equal(t, "fakeVolume", *volume.Payload.VolumeResponseInlineRecords[0].Name) @@ -4520,7 +4524,7 @@ func TestOntapRestGetVolumeByNameAndStyle(t *testing.T) { volumeParam := &storage.VolumeCollectionGetParams{} volumeParam.Context = ctx - _, err := rs.getVolumeByNameAndStyle(ctx, "trident", models.VolumeStyleFlexgroup) + _, err := rs.getVolumeByNameAndStyle(ctx, "trident", models.VolumeStyleFlexgroup, []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get the volume info") } else { @@ -5037,7 +5041,12 @@ func TestOntapRESTVolumeList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - volume, err := rs.VolumeList(ctx, "fakeVolume") + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", + "snapshot_policy", "snapshot_directory_access_enabled", + "space.snapshot.used", "space.snapshot.reserve_percent", + } + volume, err := rs.VolumeList(ctx, "fakeVolume", fields) if !test.isErrorExpected { assert.NoError(t, err, "could not get a volume") assert.Equal(t, "fakeVolume", *volume.Payload.VolumeResponseInlineRecords[0].Name) @@ -5098,7 +5107,9 @@ func TestOntapREST_VolumeGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - volume, err := rs.VolumeGetByName(ctx, "fakeVolume") + fields := []string{"size", "type", "nas.unix_permissions", "aggregates"} + volume, err := rs.VolumeGetByName(ctx, "fakeVolume", fields) + if !test.isErrorExpected { assert.NoError(t, err, "could not get a volume") assert.Equal(t, "fakeVolume", *volume.Name) @@ -5775,7 +5786,11 @@ func TestOntapREST_FlexGroupGetByName(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - volume, err := rs.FlexGroupGetByName(ctx, "fakeVolume") + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", "snapshot_policy", + "snapshot_directory_access_enabled", "space.snapshot.used", "space.snapshot.reserve_percent", + } + volume, err := rs.FlexGroupGetByName(ctx, "fakeVolume", fields) if !test.isErrorExpected { assert.NoError(t, err, "could not get the flexgroup volume") assert.Equal(t, "fakeVolume", *volume.Name) @@ -5807,7 +5822,12 @@ func TestOntapREST_FlexGroupGetAll(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - volume, err := rs.FlexGroupGetAll(ctx, "fakeVolume") + fields := []string{ + "type", "size", "comment", "aggregates", "nas", "guarantee", + "snapshot_policy", "snapshot_directory_access_enabled", + "space.snapshot.used", "space.snapshot.reserve_percent", + } + volume, err := rs.FlexGroupGetAll(ctx, "fakeVolume", fields) if !test.isErrorExpected { assert.NoError(t, err, "could not get the flexgroup volume") assert.Equal(t, "fakeVolume", *volume.Payload.VolumeResponseInlineRecords[0].Name) @@ -5945,11 +5965,11 @@ func TestOntapREST_VolumeListByAttrs(t *testing.T) { volumeParam := &storage.VolumeCollectionGetParams{} volumeParam.Context = ctx - volumes, err := rs.VolumeListByAttrs(ctx, &volume) + volumes, err := rs.VolumeListByAttrs(ctx, &volume, []string{""}) assert.NoError(t, err) - assert.Equal(t, volumeName, volumes[0].Name) + assert.Equal(t, volumeName, *volumes.Payload.VolumeResponseInlineRecords[0].Name) - volumes, err = rs.VolumeListByAttrs(ctx, &Volume{}) + volumes, err = rs.VolumeListByAttrs(ctx, &Volume{}, []string{""}) assert.NoError(t, err) server.Close() } @@ -5962,10 +5982,10 @@ func getQtree() models.Qtree { exportPolicy := "fake-export-policy" volumeName := "vol1" volumeUUID := "vol1UUID" - svm := "svm1" + svmname := "svm1" qtreeExportPolicy := models.QtreeInlineExportPolicy{Name: &exportPolicy} - qtreeSVM := models.QtreeInlineSvm{Name: &svm} + qtreeSVM := models.QtreeInlineSvm{Name: &svmname} qtreeVolume := models.QtreeInlineVolume{Name: &volumeName, UUID: &volumeUUID} return models.Qtree{ @@ -6301,7 +6321,7 @@ func TestOntapREST_QtreeGetByPath(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - qtree, err := rs.QtreeGetByPath(ctx, "/vol1/qtree_vol1") + qtree, err := rs.QtreeGetByPath(ctx, "/vol1/qtree_vol1", []string{""}) if !test.isErrorExpected { assert.NoError(t, err, "could not get qtree by name") assert.Equal(t, "qtree_vol1", *qtree.Name) @@ -6388,7 +6408,8 @@ func TestOntapREST_QtreeList(t *testing.T) { rs := newRestClient(server.Listener.Addr().String(), server.Client()) assert.NotNil(t, rs) - qtree, err := rs.QtreeList(ctx, "qtree_", "volume_") + fields := []string{"name", "volume"} + qtree, err := rs.QtreeList(ctx, "qtree_", "volume_", fields) if !test.isErrorExpected { assert.NoError(t, err, "could not get the qtree list") assert.Equal(t, "qtree_vol1", *qtree.Payload.QtreeResponseInlineRecords[0].Name) diff --git a/storage_drivers/ontap/ontap_common_test.go b/storage_drivers/ontap/ontap_common_test.go index 006dfa819..7cd63b74f 100644 --- a/storage_drivers/ontap/ontap_common_test.go +++ b/storage_drivers/ontap/ontap_common_test.go @@ -360,8 +360,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { return nil, nil }, ).AnyTimes() @@ -378,8 +378,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: nil, } @@ -400,8 +400,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: nil, @@ -420,8 +420,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: []*models.Aggregate{}, @@ -444,8 +444,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: []*models.Aggregate{ @@ -470,8 +470,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: []*models.Aggregate{ @@ -499,8 +499,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: []*models.Aggregate{ @@ -530,8 +530,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: []*models.Aggregate{ @@ -568,8 +568,8 @@ func TestRestGetSVMAggregateSpace(t *testing.T) { assert.Nil(t, err) assert.NotNil(t, d) - mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr).DoAndReturn( - func(ctx context.Context, pattern string) (*ontap_storage.AggregateCollectionGetOK, error) { + mockRestClient.EXPECT().AggregateList(gomock.Any(), aggr, gomock.Any()).DoAndReturn( + func(ctx context.Context, pattern string, fields []string) (*ontap_storage.AggregateCollectionGetOK, error) { result := &ontap_storage.AggregateCollectionGetOK{ Payload: &models.AggregateResponse{ AggregateResponseInlineRecords: []*models.Aggregate{