From 56e9b944e8f8e6384d32600ed81babaf1048cc4d Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Fri, 2 Jun 2023 09:32:07 -0400 Subject: [PATCH] node pools: validate pool exists on job registration (#17386) Add a new job admission hook for node pools that enforces the pool exists on registration. Also provide the skeleton function we need for Enterprise enforcement functions we'll implement later. --- nomad/job_endpoint.go | 2 ++ nomad/job_endpoint_hook_node_pool.go | 34 ++++++++++++++++++++++++ nomad/job_endpoint_hook_node_pool_oss.go | 28 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 nomad/job_endpoint_hook_node_pool.go create mode 100644 nomad/job_endpoint_hook_node_pool_oss.go diff --git a/nomad/job_endpoint.go b/nomad/job_endpoint.go index 031a9df74..a976cd6f1 100644 --- a/nomad/job_endpoint.go +++ b/nomad/job_endpoint.go @@ -72,12 +72,14 @@ func NewJobEndpoints(s *Server, ctx *RPCContext) *Job { jobConnectHook{}, jobExposeCheckHook{}, jobImpliedConstraints{}, + jobNodePoolMutatingHook{srv: s}, }, validators: []jobValidator{ jobConnectHook{}, jobExposeCheckHook{}, jobVaultHook{srv: s}, jobNamespaceConstraintCheckHook{srv: s}, + jobNodePoolValidatingHook{srv: s}, &jobValidate{srv: s}, &memoryOversubscriptionValidate{srv: s}, }, diff --git a/nomad/job_endpoint_hook_node_pool.go b/nomad/job_endpoint_hook_node_pool.go new file mode 100644 index 000000000..a483d090d --- /dev/null +++ b/nomad/job_endpoint_hook_node_pool.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package nomad + +import ( + "fmt" + + "github.com/hashicorp/nomad/nomad/structs" +) + +// jobNodePoolValidatingHook is an admission hook that ensures the job has valid +// node pool configuration. +type jobNodePoolValidatingHook struct { + srv *Server +} + +func (j jobNodePoolValidatingHook) Name() string { + return "node-pool-validation" +} + +func (j jobNodePoolValidatingHook) Validate(job *structs.Job) ([]error, error) { + poolName := job.NodePool + + pool, err := j.srv.State().NodePoolByName(nil, poolName) + if err != nil { + return nil, err + } + if pool == nil { + return nil, fmt.Errorf("job %q is in nonexistent node pool %q", job.ID, poolName) + } + + return j.enterpriseValidation(job, pool) +} diff --git a/nomad/job_endpoint_hook_node_pool_oss.go b/nomad/job_endpoint_hook_node_pool_oss.go new file mode 100644 index 000000000..6a12cce44 --- /dev/null +++ b/nomad/job_endpoint_hook_node_pool_oss.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build !ent +// +build !ent + +package nomad + +import "github.com/hashicorp/nomad/nomad/structs" + +// enterpriseValidation implements any admission hooks for node pools for Nomad +// Enterprise. +func (j jobNodePoolValidatingHook) enterpriseValidation(_ *structs.Job, _ *structs.NodePool) ([]error, error) { + return nil, nil +} + +// jobNodePoolMutatingHook mutates the job on Nomad Enterprise only. +type jobNodePoolMutatingHook struct { + srv *Server +} + +func (c jobNodePoolMutatingHook) Name() string { + return "node-pool-mutation" +} + +func (c jobNodePoolMutatingHook) Mutate(job *structs.Job) (*structs.Job, []error, error) { + return job, nil, nil +}