nomad: enforce ACLs on job submit
This commit is contained in:
parent
6f5150a227
commit
ac6283c31f
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/hashicorp/consul/lib"
|
"github.com/hashicorp/consul/lib"
|
||||||
"github.com/hashicorp/go-memdb"
|
"github.com/hashicorp/go-memdb"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/hashicorp/nomad/acl"
|
||||||
"github.com/hashicorp/nomad/client/driver"
|
"github.com/hashicorp/nomad/client/driver"
|
||||||
"github.com/hashicorp/nomad/helper"
|
"github.com/hashicorp/nomad/helper"
|
||||||
"github.com/hashicorp/nomad/nomad/state"
|
"github.com/hashicorp/nomad/nomad/state"
|
||||||
|
@ -71,6 +72,13 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis
|
||||||
// Set the warning message
|
// Set the warning message
|
||||||
reply.Warnings = structs.MergeMultierrorWarnings(warnings, canonicalizeWarnings)
|
reply.Warnings = structs.MergeMultierrorWarnings(warnings, canonicalizeWarnings)
|
||||||
|
|
||||||
|
// Check job submission permissions
|
||||||
|
if aclObj, err := j.srv.resolveToken(args.SecretID); err != nil {
|
||||||
|
return err
|
||||||
|
} else if aclObj != nil && !aclObj.AllowNamespaceOperation(structs.DefaultNamespace, acl.NamespaceCapabilitySubmitJob) {
|
||||||
|
return structs.ErrPermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup the job
|
// Lookup the job
|
||||||
snap, err := j.srv.fsm.State().Snapshot()
|
snap, err := j.srv.fsm.State().Snapshot()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -93,6 +93,49 @@ func TestJobEndpoint_Register(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestJobEndpoint_Register_ACL(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
s1, root := testACLServer(t, func(c *Config) {
|
||||||
|
c.NumSchedulers = 0 // Prevent automatic dequeue
|
||||||
|
})
|
||||||
|
defer s1.Shutdown()
|
||||||
|
codec := rpcClient(t, s1)
|
||||||
|
testutil.WaitForLeader(t, s1.RPC)
|
||||||
|
|
||||||
|
// Create the register request
|
||||||
|
job := mock.Job()
|
||||||
|
req := &structs.JobRegisterRequest{
|
||||||
|
Job: job,
|
||||||
|
WriteRequest: structs.WriteRequest{Region: "global"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try without a token, expect failure
|
||||||
|
var resp structs.JobRegisterResponse
|
||||||
|
if err := msgpackrpc.CallWithCodec(codec, "Job.Register", req, &resp); err == nil {
|
||||||
|
t.Fatalf("expected error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try with a token
|
||||||
|
req.SecretID = root.SecretID
|
||||||
|
if err := msgpackrpc.CallWithCodec(codec, "Job.Register", req, &resp); err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if resp.Index == 0 {
|
||||||
|
t.Fatalf("bad index: %d", resp.Index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for the node in the FSM
|
||||||
|
state := s1.fsm.State()
|
||||||
|
ws := memdb.NewWatchSet()
|
||||||
|
out, err := state.JobByID(ws, job.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
if out == nil {
|
||||||
|
t.Fatalf("expected job")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestJobEndpoint_Register_InvalidDriverConfig(t *testing.T) {
|
func TestJobEndpoint_Register_InvalidDriverConfig(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
s1 := testServer(t, func(c *Config) {
|
s1 := testServer(t, func(c *Config) {
|
||||||
|
|
|
@ -108,6 +108,9 @@ const (
|
||||||
// ACLClientToken and ACLManagementToken are the only types of tokens
|
// ACLClientToken and ACLManagementToken are the only types of tokens
|
||||||
ACLClientToken = "client"
|
ACLClientToken = "client"
|
||||||
ACLManagementToken = "management"
|
ACLManagementToken = "management"
|
||||||
|
|
||||||
|
// DefaultNamespace is the default namespace.
|
||||||
|
DefaultNamespace = "default"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context defines the scope in which a search for Nomad object operates, and
|
// Context defines the scope in which a search for Nomad object operates, and
|
||||||
|
|
Loading…
Reference in New Issue