MMCTL: Add import delete cmd for removing the import files (#29764)

Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Этот коммит содержится в:
Harsh Aulakh
2025-06-10 15:36:38 +05:30
коммит произвёл GitHub
родитель 0cf6361139
Коммит 09a2037b61
17 изменённых файлов: 348 добавлений и 35 удалений

Просмотреть файл

@@ -128,6 +128,7 @@ type Client interface {
GetUploadsForUser(ctx context.Context, userID string) ([]*model.UploadSession, *model.Response, error)
UploadData(ctx context.Context, uploadID string, data io.Reader) (*model.FileInfo, *model.Response, error)
ListImports(ctx context.Context) ([]string, *model.Response, error)
DeleteImport(ctx context.Context, name string) (*model.Response, error)
GetJob(ctx context.Context, id string) (*model.Job, *model.Response, error)
GetJobs(ctx context.Context, jobType string, status string, page int, perPage int) ([]*model.Job, *model.Response, error)
GetJobsByType(ctx context.Context, jobType string, page int, perPage int) ([]*model.Job, *model.Response, error)

Просмотреть файл

@@ -88,7 +88,6 @@ func (s *MmctlUnitTestSuite) TestExportCreateCmdF() {
s.Equal(mockJob, printer.GetLines()[0].(*model.Job))
})
}
func (s *MmctlUnitTestSuite) TestExportDeleteCmdF() {
printer.Clean()

Просмотреть файл

@@ -37,6 +37,14 @@ var ImportUploadCmd = &cobra.Command{
RunE: withClient(importUploadCmdF),
}
var ImportDeleteCmd = &cobra.Command{
Use: "delete [importname]",
Short: "Delete an import file",
Example: " import delete import_file.zip",
Args: cobra.ExactArgs(1),
RunE: withClient(importDeleteCmdF),
}
var ImportListCmd = &cobra.Command{
Use: "list",
Aliases: []string{"ls"},
@@ -130,6 +138,7 @@ func init() {
ImportProcessCmd,
ImportJobCmd,
ImportValidateCmd,
ImportDeleteCmd,
)
RootCmd.AddCommand(ImportCmd)
}
@@ -250,6 +259,17 @@ func importUploadCmdF(c client.Client, command *cobra.Command, args []string) er
return nil
}
func importDeleteCmdF(c client.Client, command *cobra.Command, args []string) error {
importName := args[0]
if _, err := c.DeleteImport(context.TODO(), importName); err != nil {
return fmt.Errorf("failed to delete import: %w", err)
}
printer.Print(fmt.Sprintf("Import file %q has been deleted", importName))
return nil
}
func importProcessCmdF(c client.Client, command *cobra.Command, args []string) error {
importFile := args[0]

Просмотреть файл

@@ -5,6 +5,7 @@ package commands
import (
"context"
"fmt"
"os"
"path/filepath"
"time"
@@ -14,6 +15,7 @@ import (
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/public/utils"
"github.com/spf13/cobra"
)
@@ -430,3 +432,53 @@ func (s *MmctlE2ETestSuite) TestImportValidateCmdF() {
s.Require().Equal("Validation complete\n", printer.GetLines()[2])
})
}
func (s *MmctlE2ETestSuite) TestImportDeleteCmdF() {
s.SetupTestHelper().InitBasic()
s.Run("no permissions", func() {
printer.Clean()
err := importDeleteCmdF(s.th.Client, &cobra.Command{}, []string{"import1.zip"})
s.Require().EqualError(err, "failed to delete import: You do not have the appropriate permissions.")
s.Require().Empty(printer.GetLines())
s.Require().Empty(printer.GetErrorLines())
})
s.RunForSystemAdminAndLocal("delete import", func(c client.Client) {
importName := "import_test.zip"
importFilePath := filepath.Join(server.GetPackagePath(), "tests", importName)
importPath, err := filepath.Abs(filepath.Join(*s.th.App.Config().FileSettings.Directory,
*s.th.App.Config().ImportSettings.Directory))
s.Require().Nil(err)
cmd := &cobra.Command{}
newImportName := "new_import_test.zip"
err = utils.CopyFile(importFilePath, filepath.Join(importPath, newImportName))
s.Require().Nil(err)
printer.Clean()
imports, appErr := s.th.App.ListImports()
s.Require().Nil(appErr)
s.Require().NotEmpty(imports)
s.Require().Equal(newImportName, imports[0])
err = importDeleteCmdF(c, cmd, []string{newImportName})
s.Require().Nil(err)
s.Require().Empty(printer.GetErrorLines())
s.Require().Len(printer.GetLines(), 1)
s.Equal(fmt.Sprintf(`Import file "%s" has been deleted`, newImportName), printer.GetLines()[0])
imports, appErr = s.th.App.ListImports()
s.Require().Nil(appErr)
s.Require().Empty(imports)
//idempotency check
err = importDeleteCmdF(c, cmd, []string{newImportName})
s.Require().Nil(err)
s.Require().Empty(printer.GetErrorLines())
s.Require().Len(printer.GetLines(), 2)
s.Equal(fmt.Sprintf(`Import file "%s" has been deleted`, newImportName), printer.GetLines()[0])
})
}

Просмотреть файл

@@ -536,3 +536,25 @@ func (s *MmctlUnitTestSuite) TestImportValidateCmdF() {
s.Equal("Validation complete\n", printer.GetLines()[2])
})
}
func (s *MmctlUnitTestSuite) TestDeleteImportCmdF() {
s.Run("delete command succeeds", func() {
printer.Clean()
s.client.
EXPECT().
DeleteImport(context.TODO(), "import.zip").
Return(&model.Response{}, nil).
Times(2)
err := importDeleteCmdF(s.client, &cobra.Command{}, []string{"import.zip"})
s.Require().Nil(err)
s.Len(printer.GetLines(), 1)
s.Equal("Import file \"import.zip\" has been deleted", printer.GetLines()[0])
//idempotency check
err = importDeleteCmdF(s.client, &cobra.Command{}, []string{"import.zip"})
s.Require().Nil(err)
s.Len(printer.GetLines(), 2)
s.Equal("Import file \"import.zip\" has been deleted", printer.GetLines()[1])
})
}

Просмотреть файл

@@ -37,6 +37,7 @@ SEE ALSO
~~~~~~~~
* `mmctl <mmctl.rst>`_ - Remote client for the Open Source, self-hosted Slack-alternative
* `mmctl import delete <mmctl_import_delete.rst>`_ - Delete an import file
* `mmctl import job <mmctl_import_job.rst>`_ - List and show import jobs
* `mmctl import list <mmctl_import_list.rst>`_ - List import files
* `mmctl import process <mmctl_import_process.rst>`_ - Start an import job

Просмотреть файл

@@ -0,0 +1,51 @@
.. _mmctl_import_delete:
mmctl import delete
-------------------
Delete an import file
Synopsis
~~~~~~~~
Delete an import file
::
mmctl import delete [importname] [flags]
Examples
~~~~~~~~
::
import delete import_file.zip
Options
~~~~~~~
::
-h, --help help for delete
Options inherited from parent commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
--config string path to the configuration file (default "$XDG_CONFIG_HOME/mmctl/config")
--disable-pager disables paged output
--insecure-sha1-intermediate allows to use insecure TLS protocols, such as SHA-1
--insecure-tls-version allows to use TLS versions 1.0 and 1.1
--json the output format will be in json format
--local allows communicating with the server through a unix socket
--quiet prevent mmctl to generate output for the commands
--strict will only run commands if the mmctl version matches the server one
--suppress-warnings disables printing warning messages
SEE ALSO
~~~~~~~~
* `mmctl import <mmctl_import.rst>`_ - Management of imports

Просмотреть файл

@@ -387,6 +387,21 @@ func (mr *MockClientMockRecorder) DeleteExport(arg0, arg1 interface{}) *gomock.C
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExport", reflect.TypeOf((*MockClient)(nil).DeleteExport), arg0, arg1)
}
// DeleteImport mocks base method.
func (m *MockClient) DeleteImport(arg0 context.Context, arg1 string) (*model.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteImport", arg0, arg1)
ret0, _ := ret[0].(*model.Response)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DeleteImport indicates an expected call of DeleteImport.
func (mr *MockClientMockRecorder) DeleteImport(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteImport", reflect.TypeOf((*MockClient)(nil).DeleteImport), arg0, arg1)
}
// DeleteIncomingWebhook mocks base method.
func (m *MockClient) DeleteIncomingWebhook(arg0 context.Context, arg1 string) (*model.Response, error) {
m.ctrl.T.Helper()