mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
* Add create, show, and cancel subcommands to mmctl job The `mmctl job` command previously only supported `list` and `update`. This adds three subcommands backed by existing client methods: - `job create [type] [--data k=v]` triggers a new job (CreateJob) - `job show [job]` displays a single job (GetJob) - `job cancel [job]` requests cancellation via the dedicated cancel endpoint (CancelJob), which uses the create-job permission and emits its own audit event, unlike `update [job] cancel_requested` Also fixes the leftover "import jobs" wording in the `list` flag help and regenerates the mmctl docs. * Exercise --data flag parsing in mmctl job create test The create-job test passed the Data map as the flag's default value, so GetStringToString returned the default without ever exercising pflag's stringToString parser. Declare the flag empty and Set the value explicitly so the test validates the real parse path. * Don't gate mmctl job create on model.AllJobTypes model.AllJobTypes (which IsValidJobType checks against) is a curated subset that omits creatable job types such as access_control_sync, so validating the type client-side wrongly rejected jobs the server can schedule. Drop the client-side check and let the server validate the type per its create-job permissions; it returns a clear error for anything unschedulable. Tab-completion still suggests AllJobTypes as an advisory hint. * Remove explanatory AllJobTypes comments from mmctl job * Add e2e tests for mmctl job create, show, and cancel Cover the no-permission, not-found, and success paths for the new generic job subcommands against a running server, mirroring the existing export job e2e tests. --------- Co-authored-by: Hanzo Dev <[email protected]>
143 lines
4.4 KiB
Go
143 lines
4.4 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package commands
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/client"
|
|
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func (s *MmctlE2ETestSuite) TestCreateJobCmdF() {
|
|
s.SetupTestHelper().InitBasic(s.T())
|
|
|
|
newCmd := func() *cobra.Command {
|
|
cmd := &cobra.Command{}
|
|
cmd.Flags().StringToString("data", nil, "")
|
|
return cmd
|
|
}
|
|
|
|
s.Run("create a job without permissions", func() {
|
|
printer.Clean()
|
|
|
|
err := createJobCmdF(s.th.Client, newCmd(), []string{model.JobTypeExportProcess})
|
|
s.Require().EqualError(err, "failed to create job: You do not have the appropriate permissions.")
|
|
s.Require().Empty(printer.GetLines())
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("create a job", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
err := createJobCmdF(c, newCmd(), []string{model.JobTypeExportProcess})
|
|
s.Require().Nil(err)
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Equal(model.JobTypeExportProcess, printer.GetLines()[0].(*model.Job).Type)
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("create a job with data", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
cmd := newCmd()
|
|
err := cmd.Flags().Set("data", "include_attachments=true")
|
|
s.Require().NoError(err)
|
|
|
|
err = createJobCmdF(c, cmd, []string{model.JobTypeExportProcess})
|
|
s.Require().Nil(err)
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Equal("true", printer.GetLines()[0].(*model.Job).Data["include_attachments"])
|
|
})
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestShowJobCmdF() {
|
|
s.SetupTestHelper().InitBasic(s.T())
|
|
|
|
job, appErr := s.th.App.CreateJob(s.th.Context, &model.Job{
|
|
Type: model.JobTypeExportProcess,
|
|
})
|
|
s.Require().Nil(appErr)
|
|
|
|
s.Run("show a job without permissions", func() {
|
|
printer.Clean()
|
|
|
|
err := showJobCmdF(s.th.Client, &cobra.Command{}, []string{job.Id})
|
|
s.Require().EqualError(err, "failed to get job: You do not have the appropriate permissions.")
|
|
s.Require().Empty(printer.GetLines())
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("show a job that does not exist", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
err := showJobCmdF(c, &cobra.Command{}, []string{model.NewId()})
|
|
s.Require().ErrorContains(err, "failed to get job: Unable to get the job.")
|
|
s.Require().Empty(printer.GetLines())
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("show a job", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
err := showJobCmdF(c, &cobra.Command{}, []string{job.Id})
|
|
s.Require().Nil(err)
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
s.Require().Len(printer.GetLines(), 1)
|
|
s.Require().Equal(job, printer.GetLines()[0].(*model.Job))
|
|
})
|
|
}
|
|
|
|
func (s *MmctlE2ETestSuite) TestCancelJobCmdF() {
|
|
s.SetupTestHelper().InitBasic(s.T())
|
|
|
|
s.Run("cancel a job without permissions", func() {
|
|
printer.Clean()
|
|
|
|
job, appErr := s.th.App.CreateJob(s.th.Context, &model.Job{
|
|
Type: model.JobTypeExportProcess,
|
|
})
|
|
s.Require().Nil(appErr)
|
|
|
|
err := cancelJobCmdF(s.th.Client, &cobra.Command{}, []string{job.Id})
|
|
s.Require().EqualError(err, "failed to cancel job: You do not have the appropriate permissions.")
|
|
s.Require().Empty(printer.GetLines())
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("cancel a job that does not exist", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
err := cancelJobCmdF(c, &cobra.Command{}, []string{model.NewId()})
|
|
s.Require().ErrorContains(err, "failed to cancel job: Unable to get the job.")
|
|
s.Require().Empty(printer.GetLines())
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
})
|
|
|
|
s.RunForSystemAdminAndLocal("cancel a job", func(c client.Client) {
|
|
printer.Clean()
|
|
|
|
job, appErr := s.th.App.CreateJob(s.th.Context, &model.Job{
|
|
Type: model.JobTypeExportProcess,
|
|
})
|
|
s.Require().Nil(appErr)
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
err := cancelJobCmdF(c, &cobra.Command{}, []string{job.Id})
|
|
s.Require().Nil(err)
|
|
s.Require().Empty(printer.GetLines())
|
|
s.Require().Empty(printer.GetErrorLines())
|
|
|
|
// Refresh the job to confirm it was canceled.
|
|
job, appErr = s.th.App.GetJob(s.th.Context, job.Id)
|
|
s.Require().Nil(appErr)
|
|
s.Require().Equal(model.JobStatusCanceled, job.Status)
|
|
})
|
|
}
|