72 lines
1.6 KiB
Go
72 lines
1.6 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package nomad
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
)
|
|
|
|
type jobNamespaceConstraintCheckHook struct {
|
|
srv *Server
|
|
}
|
|
|
|
func (jobNamespaceConstraintCheckHook) Name() string {
|
|
return "namespace-constraint-check"
|
|
}
|
|
|
|
func (c jobNamespaceConstraintCheckHook) Validate(job *structs.Job) (warnings []error, err error) {
|
|
// This was validated before and matches the WriteRequest namespace
|
|
ns, err := c.srv.State().NamespaceByName(nil, job.Namespace)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if ns == nil {
|
|
return nil, fmt.Errorf("job %q is in nonexistent namespace %q", job.ID, job.Namespace)
|
|
}
|
|
|
|
var disallowedDrivers []string
|
|
for _, tg := range job.TaskGroups {
|
|
for _, t := range tg.Tasks {
|
|
if !taskValidateDriver(t, ns) {
|
|
disallowedDrivers = append(disallowedDrivers, t.Driver)
|
|
}
|
|
}
|
|
}
|
|
if len(disallowedDrivers) > 0 {
|
|
if len(disallowedDrivers) == 1 {
|
|
return nil, fmt.Errorf(
|
|
"used task driver %q is not allowed in namespace %q", disallowedDrivers[0], ns.Name,
|
|
)
|
|
|
|
} else {
|
|
return nil, fmt.Errorf(
|
|
"used task drivers %q are not allowed in namespace %q", disallowedDrivers, ns.Name,
|
|
)
|
|
}
|
|
}
|
|
return nil, nil
|
|
}
|
|
|
|
func taskValidateDriver(task *structs.Task, ns *structs.Namespace) bool {
|
|
if ns.Capabilities == nil {
|
|
return true
|
|
}
|
|
allow := len(ns.Capabilities.EnabledTaskDrivers) == 0
|
|
for _, d := range ns.Capabilities.EnabledTaskDrivers {
|
|
if task.Driver == d {
|
|
allow = true
|
|
break
|
|
}
|
|
}
|
|
for _, d := range ns.Capabilities.DisabledTaskDrivers {
|
|
if task.Driver == d {
|
|
allow = false
|
|
break
|
|
}
|
|
}
|
|
return allow
|
|
}
|