From a8154ddae01e66c1d2a4cd90401227957f09d96f Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 15 Sep 2022 08:46:43 +0530 Subject: [PATCH] MM-38698: Add limit to the CLI compliance export command (#20997) ```release-note A batchSize option has been added to the mattermost export CLI command to limit the number of items exported. By default, if it is not included, it exports all the posts. ``` https://mattermost.atlassian.net/browse/MM-38698 Co-authored-by: Mattermod --- cmd/mattermost/commands/export.go | 11 ++++++++++- einterfaces/message_export.go | 2 +- einterfaces/mocks/MessageExportInterface.go | 14 +++++++------- store/storetest/compliance_store.go | 5 +++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/cmd/mattermost/commands/export.go b/cmd/mattermost/commands/export.go index 2fa5295986..fa0f251e1b 100644 --- a/cmd/mattermost/commands/export.go +++ b/cmd/mattermost/commands/export.go @@ -71,9 +71,13 @@ func init() { ScheduleExportCmd.Flags().Int("timeoutSeconds", -1, "The maximum number of seconds to wait for the job to complete before timing out.") CsvExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + CsvExportCmd.Flags().Int("limit", -1, "The number of posts to export. The default of -1 means no limit.") ActianceExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + ActianceExportCmd.Flags().Int("limit", -1, "The number of posts to export. The default of -1 means no limit.") + GlobalRelayZipExportCmd.Flags().Int64("exportFrom", -1, "The timestamp of the earliest post to export, expressed in seconds since the unix epoch.") + GlobalRelayZipExportCmd.Flags().Int("limit", -1, "The number of posts to export. The default of -1 means no limit.") BulkExportCmd.Flags().Bool("all-teams", true, "Export all teams from the server.") BulkExportCmd.Flags().Bool("attachments", false, "Also export file attachments.") @@ -164,11 +168,16 @@ func buildExportCmdF(format string) func(command *cobra.Command, args []string) return errors.New("exportFrom must be a positive integer") } + limit, err := command.Flags().GetInt("limit") + if err != nil { + return errors.New("limit flag error") + } + if a.MessageExport() == nil || license == nil || !*license.Features.MessageExport { return errors.New("message export feature not available") } - warningsCount, appErr := a.MessageExport().RunExport(format, startTime) + warningsCount, appErr := a.MessageExport().RunExport(format, startTime, limit) if appErr != nil { return appErr } diff --git a/einterfaces/message_export.go b/einterfaces/message_export.go index 6411327a34..27cc753a9d 100644 --- a/einterfaces/message_export.go +++ b/einterfaces/message_export.go @@ -11,5 +11,5 @@ import ( type MessageExportInterface interface { StartSynchronizeJob(ctx context.Context, exportFromTimestamp int64) (*model.Job, *model.AppError) - RunExport(format string, since int64) (int64, *model.AppError) + RunExport(format string, since int64, limit int) (int64, *model.AppError) } diff --git a/einterfaces/mocks/MessageExportInterface.go b/einterfaces/mocks/MessageExportInterface.go index 635d371dfc..a3767eb93a 100644 --- a/einterfaces/mocks/MessageExportInterface.go +++ b/einterfaces/mocks/MessageExportInterface.go @@ -17,20 +17,20 @@ type MessageExportInterface struct { mock.Mock } -// RunExport provides a mock function with given fields: format, since -func (_m *MessageExportInterface) RunExport(format string, since int64) (int64, *model.AppError) { - ret := _m.Called(format, since) +// RunExport provides a mock function with given fields: format, since, limit +func (_m *MessageExportInterface) RunExport(format string, since int64, limit int) (int64, *model.AppError) { + ret := _m.Called(format, since, limit) var r0 int64 - if rf, ok := ret.Get(0).(func(string, int64) int64); ok { - r0 = rf(format, since) + if rf, ok := ret.Get(0).(func(string, int64, int) int64); ok { + r0 = rf(format, since, limit) } else { r0 = ret.Get(0).(int64) } var r1 *model.AppError - if rf, ok := ret.Get(1).(func(string, int64) *model.AppError); ok { - r1 = rf(format, since) + if rf, ok := ret.Get(1).(func(string, int64, int) *model.AppError); ok { + r1 = rf(format, since, limit) } else { if ret.Get(1) != nil { r1 = ret.Get(1).(*model.AppError) diff --git a/store/storetest/compliance_store.go b/store/storetest/compliance_store.go index b45bf3742d..b052332b1d 100644 --- a/store/storetest/compliance_store.go +++ b/store/storetest/compliance_store.go @@ -175,6 +175,11 @@ func testComplianceExport(t *testing.T, ss store.Store) { assert.Equal(t, cposts[0].PostId, o1.Id) assert.Equal(t, cposts[3].PostId, o2a.Id) + // Test limit + cposts, _, nErr = ss.Compliance().ComplianceExport(cr1, model.ComplianceExportCursor{}, 2) + require.NoError(t, nErr) + assert.Len(t, cposts, 2) + cr2 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1, Emails: u2.Email} cposts, _, nErr = ss.Compliance().ComplianceExport(cr2, model.ComplianceExportCursor{}, limit) require.NoError(t, nErr)