[MM-56074] mmctl job commands (#26855)
* add job list and update job status command to mmctl
Этот коммит содержится в:
@@ -7018,8 +7018,8 @@ func (c *Client4) GetJob(ctx context.Context, id string) (*Job, *Response, error
|
||||
}
|
||||
|
||||
// GetJobs gets all jobs, sorted with the job that was created most recently first.
|
||||
func (c *Client4) GetJobs(ctx context.Context, page int, perPage int) ([]*Job, *Response, error) {
|
||||
r, err := c.DoAPIGet(ctx, c.jobsRoute()+fmt.Sprintf("?page=%v&per_page=%v", page, perPage), "")
|
||||
func (c *Client4) GetJobs(ctx context.Context, jobType string, status string, page int, perPage int) ([]*Job, *Response, error) {
|
||||
r, err := c.DoAPIGet(ctx, c.jobsRoute()+fmt.Sprintf("?page=%v&per_page=%v&job_type=%v&status=%v", page, perPage, jobType, status), "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
@@ -7088,6 +7088,23 @@ func (c *Client4) DownloadJob(ctx context.Context, jobId string) ([]byte, *Respo
|
||||
return data, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// UpdateJobStatus updates the status of a job
|
||||
func (c *Client4) UpdateJobStatus(ctx context.Context, jobId string, status string, force bool) (*Response, error) {
|
||||
buf, err := json.Marshal(map[string]any{
|
||||
"status": status,
|
||||
"force": force,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, NewAppError("UpdateJobStatus", "api.marshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
r, err := c.DoAPIPatchBytes(ctx, c.jobsRoute()+fmt.Sprintf("/%v/status", jobId), buf)
|
||||
if err != nil {
|
||||
return BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
return BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// Roles Section
|
||||
|
||||
// GetAllRoles returns a list of all the roles.
|
||||
|
||||
@@ -108,7 +108,31 @@ func (j *Job) IsValid() *AppError {
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.create_at.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
switch j.Status {
|
||||
validStatus := IsValidJobStatus(j.Status)
|
||||
if !validStatus {
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.status.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j *Job) IsValidStatusChange(newStatus string) bool {
|
||||
currentStatus := j.Status
|
||||
|
||||
switch currentStatus {
|
||||
case JobStatusInProgress:
|
||||
return newStatus == JobStatusPending || newStatus == JobStatusCancelRequested
|
||||
case JobStatusPending:
|
||||
return newStatus == JobStatusCancelRequested
|
||||
case JobStatusCancelRequested:
|
||||
return newStatus == JobStatusCanceled
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func IsValidJobStatus(status string) bool {
|
||||
switch status {
|
||||
case JobStatusPending,
|
||||
JobStatusInProgress,
|
||||
JobStatusSuccess,
|
||||
@@ -117,10 +141,20 @@ func (j *Job) IsValid() *AppError {
|
||||
JobStatusCancelRequested,
|
||||
JobStatusCanceled:
|
||||
default:
|
||||
return NewAppError("Job.IsValid", "model.job.is_valid.status.app_error", nil, "id="+j.Id, http.StatusBadRequest)
|
||||
return false
|
||||
}
|
||||
|
||||
return nil
|
||||
return true
|
||||
}
|
||||
|
||||
func IsValidJobType(jobType string) bool {
|
||||
for _, t := range AllJobTypes {
|
||||
if t == jobType {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (j *Job) LogClone() any {
|
||||
|
||||
@@ -121,3 +121,113 @@ func TestJobIsValid(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestJobIsValidStatusChange(t *testing.T) {
|
||||
t.Run("invalid status change", func(t *testing.T) {
|
||||
job := &Job{
|
||||
Id: "arandomstring0123456789012",
|
||||
Type: JobTypeExportProcess,
|
||||
Priority: 42,
|
||||
CreateAt: 1336,
|
||||
StartAt: 1337,
|
||||
LastActivityAt: 1666609360813,
|
||||
Status: JobStatusInProgress,
|
||||
Progress: 32,
|
||||
Data: StringMap{"Hello": "World"},
|
||||
}
|
||||
|
||||
require.False(t, job.IsValidStatusChange("invalid!"))
|
||||
})
|
||||
|
||||
t.Run("valid status change from in_progress", func(t *testing.T) {
|
||||
job := &Job{
|
||||
Id: "arandomstring0123456789012",
|
||||
Type: JobTypeExportProcess,
|
||||
Priority: 42,
|
||||
CreateAt: 1336,
|
||||
StartAt: 1337,
|
||||
LastActivityAt: 1666609360813,
|
||||
Status: JobStatusInProgress,
|
||||
Progress: 32,
|
||||
Data: StringMap{"Hello": "World"},
|
||||
}
|
||||
|
||||
require.True(t, job.IsValidStatusChange(JobStatusPending))
|
||||
require.True(t, job.IsValidStatusChange(JobStatusCancelRequested))
|
||||
require.False(t, job.IsValidStatusChange(JobStatusCanceled))
|
||||
})
|
||||
|
||||
t.Run("valid status change from pending", func(t *testing.T) {
|
||||
job := &Job{
|
||||
Id: "arandomstring0123456789012",
|
||||
Type: JobTypeExportProcess,
|
||||
Priority: 42,
|
||||
CreateAt: 1336,
|
||||
StartAt: 1337,
|
||||
LastActivityAt: 1666609360813,
|
||||
Status: JobStatusPending,
|
||||
Progress: 32,
|
||||
Data: StringMap{"Hello": "World"},
|
||||
}
|
||||
|
||||
require.True(t, job.IsValidStatusChange(JobStatusCancelRequested))
|
||||
require.False(t, job.IsValidStatusChange(JobStatusInProgress))
|
||||
})
|
||||
|
||||
t.Run("valid status change from cancel_requested", func(t *testing.T) {
|
||||
job := &Job{
|
||||
Id: "arandomstring0123456789012",
|
||||
Type: JobTypeExportProcess,
|
||||
Priority: 42,
|
||||
CreateAt: 1336,
|
||||
StartAt: 1337,
|
||||
LastActivityAt: 1666609360813,
|
||||
Status: JobStatusCancelRequested,
|
||||
Progress: 32,
|
||||
Data: StringMap{"Hello": "World"},
|
||||
}
|
||||
|
||||
require.True(t, job.IsValidStatusChange(JobStatusCanceled))
|
||||
require.False(t, job.IsValidStatusChange(JobStatusPending))
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsValidJobType(t *testing.T) {
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
validTypes := []string{JobTypeExportProcess, JobTypeImportProcess}
|
||||
for _, jobType := range validTypes {
|
||||
t.Run(jobType, func(t *testing.T) {
|
||||
require.True(t, IsValidJobType(jobType))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
invalidTypes := []string{"invalid!", ""}
|
||||
for _, jobType := range invalidTypes {
|
||||
t.Run(jobType, func(t *testing.T) {
|
||||
require.False(t, IsValidJobType(jobType))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsValidJobStatus(t *testing.T) {
|
||||
t.Run("valid", func(t *testing.T) {
|
||||
validStatuses := []string{JobStatusCancelRequested, JobStatusCanceled, JobStatusError, JobStatusInProgress, JobStatusPending, JobStatusSuccess, JobStatusWarning}
|
||||
for _, status := range validStatuses {
|
||||
t.Run(status, func(t *testing.T) {
|
||||
require.True(t, IsValidJobStatus(status))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
invalidStatuses := []string{"invalid!", ""}
|
||||
for _, status := range invalidStatuses {
|
||||
t.Run(status, func(t *testing.T) {
|
||||
require.False(t, IsValidJobStatus(status))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -47,4 +47,5 @@ const (
|
||||
MigrationKeyAddIPFilteringPermissions = "add_ip_filtering_permissions"
|
||||
MigrationKeyAddOutgoingOAuthConnectionsPermissions = "add_outgoing_oauth_connections_permissions"
|
||||
MigrationKeyAddChannelBookmarksPermissions = "add_channel_bookmarks_permissions"
|
||||
MigrationKeyAddManageJobAncillaryPermissions = "add_manage_jobs_ancillary_permissions"
|
||||
)
|
||||
|
||||
@@ -123,8 +123,10 @@ var PermissionManageSharedChannels *Permission
|
||||
var PermissionManageSecureConnections *Permission
|
||||
var PermissionDownloadComplianceExportResult *Permission
|
||||
var PermissionCreateDataRetentionJob *Permission
|
||||
var PermissionManageDataRetentionJob *Permission
|
||||
var PermissionReadDataRetentionJob *Permission
|
||||
var PermissionCreateComplianceExportJob *Permission
|
||||
var PermissionManageComplianceExportJob *Permission
|
||||
var PermissionReadComplianceExportJob *Permission
|
||||
var PermissionReadAudits *Permission
|
||||
var PermissionTestElasticsearch *Permission
|
||||
@@ -136,12 +138,16 @@ var PermissionRecycleDatabaseConnections *Permission
|
||||
var PermissionPurgeElasticsearchIndexes *Permission
|
||||
var PermissionTestEmail *Permission
|
||||
var PermissionCreateElasticsearchPostIndexingJob *Permission
|
||||
var PermissionManageElasticsearchPostIndexingJob *Permission
|
||||
var PermissionCreateElasticsearchPostAggregationJob *Permission
|
||||
var PermissionManageElasticsearchPostAggregationJob *Permission
|
||||
var PermissionReadElasticsearchPostIndexingJob *Permission
|
||||
var PermissionReadElasticsearchPostAggregationJob *Permission
|
||||
var PermissionPurgeBleveIndexes *Permission
|
||||
var PermissionCreatePostBleveIndexesJob *Permission
|
||||
var PermissionManagePostBleveIndexesJob *Permission
|
||||
var PermissionCreateLdapSyncJob *Permission
|
||||
var PermissionManageLdapSyncJob *Permission
|
||||
var PermissionReadLdapSyncJob *Permission
|
||||
var PermissionTestLdap *Permission
|
||||
var PermissionInvalidateEmailInvite *Permission
|
||||
@@ -790,6 +796,12 @@ func initializePermissions() {
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionManageDataRetentionJob = &Permission{
|
||||
"manage_data_retention_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionReadDataRetentionJob = &Permission{
|
||||
"read_data_retention_job",
|
||||
"",
|
||||
@@ -803,6 +815,12 @@ func initializePermissions() {
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionManageComplianceExportJob = &Permission{
|
||||
"manage_compliance_export_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionReadComplianceExportJob = &Permission{
|
||||
"read_compliance_export_job",
|
||||
"",
|
||||
@@ -831,12 +849,25 @@ func initializePermissions() {
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
|
||||
PermissionManagePostBleveIndexesJob = &Permission{
|
||||
"manage_post_bleve_indexes_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
|
||||
PermissionCreateLdapSyncJob = &Permission{
|
||||
"create_ldap_sync_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionManageLdapSyncJob = &Permission{
|
||||
"manage_ldap_sync_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionReadLdapSyncJob = &Permission{
|
||||
"read_ldap_sync_job",
|
||||
"",
|
||||
@@ -1029,12 +1060,24 @@ func initializePermissions() {
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionManageElasticsearchPostIndexingJob = &Permission{
|
||||
"manage_elasticsearch_post_indexing_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionCreateElasticsearchPostAggregationJob = &Permission{
|
||||
"create_elasticsearch_post_aggregation_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionManageElasticsearchPostAggregationJob = &Permission{
|
||||
"manage_elasticsearch_post_aggregation_job",
|
||||
"",
|
||||
"",
|
||||
PermissionScopeSystem,
|
||||
}
|
||||
PermissionReadElasticsearchPostIndexingJob = &Permission{
|
||||
"read_elasticsearch_post_indexing_job",
|
||||
"",
|
||||
@@ -2347,8 +2390,10 @@ func initializePermissions() {
|
||||
PermissionManageSecureConnections,
|
||||
PermissionDownloadComplianceExportResult,
|
||||
PermissionCreateDataRetentionJob,
|
||||
PermissionManageDataRetentionJob,
|
||||
PermissionReadDataRetentionJob,
|
||||
PermissionCreateComplianceExportJob,
|
||||
PermissionManageComplianceExportJob,
|
||||
PermissionReadComplianceExportJob,
|
||||
PermissionReadAudits,
|
||||
PermissionTestSiteURL,
|
||||
@@ -2360,12 +2405,16 @@ func initializePermissions() {
|
||||
PermissionPurgeElasticsearchIndexes,
|
||||
PermissionTestEmail,
|
||||
PermissionCreateElasticsearchPostIndexingJob,
|
||||
PermissionManageElasticsearchPostIndexingJob,
|
||||
PermissionCreateElasticsearchPostAggregationJob,
|
||||
PermissionManageElasticsearchPostAggregationJob,
|
||||
PermissionReadElasticsearchPostIndexingJob,
|
||||
PermissionReadElasticsearchPostAggregationJob,
|
||||
PermissionPurgeBleveIndexes,
|
||||
PermissionCreatePostBleveIndexesJob,
|
||||
PermissionManagePostBleveIndexesJob,
|
||||
PermissionCreateLdapSyncJob,
|
||||
PermissionManageLdapSyncJob,
|
||||
PermissionReadLdapSyncJob,
|
||||
PermissionTestLdap,
|
||||
PermissionInvalidateEmailInvite,
|
||||
|
||||
@@ -90,7 +90,9 @@ func init() {
|
||||
PermissionSysconsoleWriteEnvironmentElasticsearch.Id: {
|
||||
PermissionTestElasticsearch,
|
||||
PermissionCreateElasticsearchPostIndexingJob,
|
||||
PermissionManageElasticsearchPostIndexingJob,
|
||||
PermissionCreateElasticsearchPostAggregationJob,
|
||||
PermissionManageElasticsearchPostAggregationJob,
|
||||
PermissionPurgeElasticsearchIndexes,
|
||||
},
|
||||
PermissionSysconsoleWriteEnvironmentFileStorage.Id: {
|
||||
@@ -145,12 +147,14 @@ func init() {
|
||||
},
|
||||
PermissionSysconsoleWriteComplianceDataRetentionPolicy.Id: {
|
||||
PermissionCreateDataRetentionJob,
|
||||
PermissionManageDataRetentionJob,
|
||||
},
|
||||
PermissionSysconsoleReadComplianceDataRetentionPolicy.Id: {
|
||||
PermissionReadDataRetentionJob,
|
||||
},
|
||||
PermissionSysconsoleWriteComplianceComplianceExport.Id: {
|
||||
PermissionCreateComplianceExportJob,
|
||||
PermissionManageComplianceExportJob,
|
||||
PermissionDownloadComplianceExportResult,
|
||||
},
|
||||
PermissionSysconsoleReadComplianceComplianceExport.Id: {
|
||||
@@ -163,9 +167,11 @@ func init() {
|
||||
PermissionSysconsoleWriteExperimentalBleve.Id: {
|
||||
PermissionCreatePostBleveIndexesJob,
|
||||
PermissionPurgeBleveIndexes,
|
||||
PermissionManagePostBleveIndexesJob,
|
||||
},
|
||||
PermissionSysconsoleWriteAuthenticationLdap.Id: {
|
||||
PermissionCreateLdapSyncJob,
|
||||
PermissionManageLdapSyncJob,
|
||||
PermissionAddLdapPublicCert,
|
||||
PermissionRemoveLdapPublicCert,
|
||||
PermissionAddLdapPrivateCert,
|
||||
|
||||
Ссылка в новой задаче
Block a user