diff --git a/acl/policy.go b/acl/policy.go index 757fe2fde..d1a13e55e 100644 --- a/acl/policy.go +++ b/acl/policy.go @@ -25,6 +25,7 @@ const ( NamespaceCapabilityListJobs = "list-jobs" NamespaceCapabilityReadJob = "read-job" NamespaceCapabilitySubmitJob = "submit-job" + NamespaceCapabilityDispatchJob = "dispatch-job" NamespaceCapabilityReadLogs = "read-logs" NamespaceCapabilityReadFS = "read-fs" NamespaceCapabilitySentinelOverride = "sentinel-override" @@ -76,7 +77,8 @@ func isPolicyValid(policy string) bool { func isNamespaceCapabilityValid(cap string) bool { switch cap { case NamespaceCapabilityDeny, NamespaceCapabilityListJobs, NamespaceCapabilityReadJob, - NamespaceCapabilitySubmitJob, NamespaceCapabilityReadLogs, NamespaceCapabilityReadFS: + NamespaceCapabilitySubmitJob, NamespaceCapabilityDispatchJob, NamespaceCapabilityReadLogs, + NamespaceCapabilityReadFS: return true // Seperate the enterprise-only capabilities case NamespaceCapabilitySentinelOverride: @@ -102,6 +104,7 @@ func expandNamespacePolicy(policy string) []string { NamespaceCapabilityListJobs, NamespaceCapabilityReadJob, NamespaceCapabilitySubmitJob, + NamespaceCapabilityDispatchJob, NamespaceCapabilityReadLogs, NamespaceCapabilityReadFS, } diff --git a/nomad/job_endpoint.go b/nomad/job_endpoint.go index c4bbd9812..7ebbf2eba 100644 --- a/nomad/job_endpoint.go +++ b/nomad/job_endpoint.go @@ -1176,7 +1176,7 @@ func (j *Job) Dispatch(args *structs.JobDispatchRequest, reply *structs.JobDispa // Check for submit-job permissions if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil { return err - } else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilitySubmitJob) { + } else if aclObj != nil && !aclObj.AllowNsOp(args.RequestNamespace(), acl.NamespaceCapabilityDispatchJob) { return structs.ErrPermissionDenied } diff --git a/nomad/job_endpoint_test.go b/nomad/job_endpoint_test.go index 7061a6c76..df1427ec2 100644 --- a/nomad/job_endpoint_test.go +++ b/nomad/job_endpoint_test.go @@ -3275,7 +3275,7 @@ func TestJobEndpoint_Dispatch_ACL(t *testing.T) { // Dispatch with a valid token should succeed validToken := CreatePolicyAndToken(t, state, 1003, "test-valid", - NamespacePolicy(structs.DefaultNamespace, "", []string{acl.NamespaceCapabilitySubmitJob})) + NamespacePolicy(structs.DefaultNamespace, "", []string{acl.NamespaceCapabilityDispatchJob})) req.SecretID = validToken.SecretID var validResp2 structs.JobDispatchResponse diff --git a/website/source/api/jobs.html.md b/website/source/api/jobs.html.md index 755d415f5..16d6ed272 100644 --- a/website/source/api/jobs.html.md +++ b/website/source/api/jobs.html.md @@ -1103,9 +1103,9 @@ The table below shows this endpoint's support for [blocking queries](/api/index.html#blocking-queries) and [required ACLs](/api/index.html#acls). -| Blocking Queries | ACL Required | -| ---------------- | ---------------------------- | -| `NO` | `namespace:submit-job` | +| Blocking Queries | ACL Required | +| ---------------- | ------------------------------ | +| `NO` | `namespace:dispatch-job` | ### Parameters