diff --git a/client/fs_endpoint_test.go b/client/fs_endpoint_test.go index b7ccb9f46..0735e9609 100644 --- a/client/fs_endpoint_test.go +++ b/client/fs_endpoint_test.go @@ -905,6 +905,7 @@ func TestFS_Logs_TaskPending(t *testing.T) { args := &structs.JobRegisterRequest{} args.Job = job args.WriteRequest.Region = "global" + args.Namespace = job.Namespace var jobResp structs.JobRegisterResponse require.NoError(s.RPC("Job.Register", args, &jobResp)) diff --git a/nomad/job_endpoint.go b/nomad/job_endpoint.go index 0f5a9c380..6c7c3ad28 100644 --- a/nomad/job_endpoint.go +++ b/nomad/job_endpoint.go @@ -88,6 +88,11 @@ func (j *Job) Register(args *structs.JobRegisterRequest, reply *structs.JobRegis return fmt.Errorf("missing job for registration") } + // defensive check; http layer and RPC requester should ensure namespaces are set consistently + if args.RequestNamespace() != args.Job.Namespace { + return fmt.Errorf("mismatched request namespace in request: %q, %q", args.RequestNamespace(), args.Job.Namespace) + } + // Run admission controllers job, warnings, err := j.admissionControllers(args.Job) if err != nil { @@ -343,6 +348,11 @@ func (j *Job) Summary(args *structs.JobSummaryRequest, func (j *Job) Validate(args *structs.JobValidateRequest, reply *structs.JobValidateResponse) error { defer metrics.MeasureSince([]string{"nomad", "job", "validate"}, time.Now()) + // defensive check; http layer and RPC requester should ensure namespaces are set consistently + if args.RequestNamespace() != args.Job.Namespace { + return fmt.Errorf("mismatched request namespace in request: %q, %q", args.RequestNamespace(), args.Job.Namespace) + } + job, mutateWarnings, err := j.admissionMutators(args.Job) if err != nil { return err diff --git a/nomad/job_endpoint_test.go b/nomad/job_endpoint_test.go index 59296062f..7ba97d940 100644 --- a/nomad/job_endpoint_test.go +++ b/nomad/job_endpoint_test.go @@ -363,8 +363,11 @@ func TestJobEndpoint_Register_ACL(t *testing.T) { t.Run(tt.Name, func(t *testing.T) { codec := rpcClient(t, s1) req := &structs.JobRegisterRequest{ - Job: tt.Job, - WriteRequest: structs.WriteRequest{Region: "global"}, + Job: tt.Job, + WriteRequest: structs.WriteRequest{ + Region: "global", + Namespace: tt.Job.Namespace, + }, } req.AuthToken = tt.Token @@ -407,8 +410,11 @@ func TestJobEndpoint_Register_InvalidNamespace(t *testing.T) { job := mock.Job() job.Namespace = "foo" req := &structs.JobRegisterRequest{ - Job: job, - WriteRequest: structs.WriteRequest{Region: "global"}, + Job: job, + WriteRequest: structs.WriteRequest{ + Region: "global", + Namespace: job.Namespace, + }, } // Try without a token, expect failure