0e09b120e4
PR #11956 implemented a new mTLS RPC check to validate the role of the certificate used in the request, but further testing revealed two flaws: 1. client-only endpoints did not accept server certificates so the request would fail when forwarded from one server to another. 2. the certificate was being checked after the request was forwarded, so the check would happen over the server certificate, not the actual source. This commit checks for the desired mTLS level, where the client level accepts both, a server or a client certificate. It also validates the cercertificate before the request is forwarded.
67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
package nomad
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
metrics "github.com/armon/go-metrics"
|
|
log "github.com/hashicorp/go-hclog"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
// Plan endpoint is used for plan interactions
|
|
type Plan struct {
|
|
srv *Server
|
|
logger log.Logger
|
|
|
|
// ctx provides context regarding the underlying connection
|
|
ctx *RPCContext
|
|
}
|
|
|
|
// Submit is used to submit a plan to the leader
|
|
func (p *Plan) Submit(args *structs.PlanRequest, reply *structs.PlanResponse) error {
|
|
// Ensure the connection was initiated by another server if TLS is used.
|
|
err := validateTLSCertificateLevel(p.srv, p.ctx, tlsCertificateLevelServer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if done, err := p.srv.forward("Plan.Submit", args, args, reply); done {
|
|
return err
|
|
}
|
|
defer metrics.MeasureSince([]string{"nomad", "plan", "submit"}, time.Now())
|
|
|
|
if args.Plan == nil {
|
|
return fmt.Errorf("cannot submit nil plan")
|
|
}
|
|
|
|
// Pause the Nack timer for the eval as it is making progress as long as it
|
|
// is in the plan queue. We resume immediately after we get a result to
|
|
// handle the case that the receiving worker dies.
|
|
plan := args.Plan
|
|
id := plan.EvalID
|
|
token := plan.EvalToken
|
|
if err := p.srv.evalBroker.PauseNackTimeout(id, token); err != nil {
|
|
return err
|
|
}
|
|
defer p.srv.evalBroker.ResumeNackTimeout(id, token)
|
|
|
|
// Submit the plan to the queue
|
|
future, err := p.srv.planQueue.Enqueue(plan)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Wait for the results
|
|
result, err := future.Wait()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Package the result
|
|
reply.Result = result
|
|
reply.Index = result.AllocIndex
|
|
return nil
|
|
}
|