nomad: additional constraint validation
This commit is contained in:
parent
4387d3ddb3
commit
369be8e8f4
|
@ -4,11 +4,13 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-msgpack/codec"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -809,6 +811,12 @@ func (j *Job) Validate() error {
|
|||
if len(j.TaskGroups) == 0 {
|
||||
mErr.Errors = append(mErr.Errors, errors.New("Missing job task groups"))
|
||||
}
|
||||
for idx, constr := range j.Constraints {
|
||||
if err := constr.Validate(); err != nil {
|
||||
outer := fmt.Errorf("Constraint %d validation failed: %s", idx+1, err)
|
||||
mErr.Errors = append(mErr.Errors, outer)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for duplicate task groups
|
||||
taskGroups := make(map[string]int)
|
||||
|
@ -918,6 +926,12 @@ func (tg *TaskGroup) Validate() error {
|
|||
if len(tg.Tasks) == 0 {
|
||||
mErr.Errors = append(mErr.Errors, errors.New("Missing tasks for task group"))
|
||||
}
|
||||
for idx, constr := range tg.Constraints {
|
||||
if err := constr.Validate(); err != nil {
|
||||
outer := fmt.Errorf("Constraint %d validation failed: %s", idx+1, err)
|
||||
mErr.Errors = append(mErr.Errors, outer)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for duplicate tasks
|
||||
tasks := make(map[string]int)
|
||||
|
@ -997,6 +1011,12 @@ func (t *Task) Validate() error {
|
|||
if t.Resources == nil {
|
||||
mErr.Errors = append(mErr.Errors, errors.New("Missing task resources"))
|
||||
}
|
||||
for idx, constr := range t.Constraints {
|
||||
if err := constr.Validate(); err != nil {
|
||||
outer := fmt.Errorf("Constraint %d validation failed: %s", idx+1, err)
|
||||
mErr.Errors = append(mErr.Errors, outer)
|
||||
}
|
||||
}
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
|
@ -1015,6 +1035,26 @@ func (c *Constraint) String() string {
|
|||
return fmt.Sprintf("%s %s %s", c.LTarget, c.Operand, c.RTarget)
|
||||
}
|
||||
|
||||
func (c *Constraint) Validate() error {
|
||||
var mErr multierror.Error
|
||||
if c.Operand == "" {
|
||||
mErr.Errors = append(mErr.Errors, errors.New("Missing constraint operand"))
|
||||
}
|
||||
|
||||
// Perform additional validation based on operand
|
||||
switch c.Operand {
|
||||
case "regexp":
|
||||
if _, err := regexp.Compile(c.RTarget); err != nil {
|
||||
mErr.Errors = append(mErr.Errors, fmt.Errorf("Regular expression failed to compile: %v", err))
|
||||
}
|
||||
case "version":
|
||||
if _, err := version.NewConstraint(c.RTarget); err != nil {
|
||||
mErr.Errors = append(mErr.Errors, fmt.Errorf("Version constraint is invalid: %v", err))
|
||||
}
|
||||
}
|
||||
return mErr.ErrorOrNil()
|
||||
}
|
||||
|
||||
const (
|
||||
AllocDesiredStatusRun = "run" // Allocation should run
|
||||
AllocDesiredStatusStop = "stop" // Allocation should stop
|
||||
|
|
|
@ -125,6 +125,43 @@ func TestTask_Validate(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestConstraint_Validate(t *testing.T) {
|
||||
c := &Constraint{}
|
||||
err := c.Validate()
|
||||
mErr := err.(*multierror.Error)
|
||||
if !strings.Contains(mErr.Errors[0].Error(), "Missing constraint operand") {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
c = &Constraint{
|
||||
LTarget: "$attr.kernel.name",
|
||||
RTarget: "linux",
|
||||
Operand: "=",
|
||||
}
|
||||
err = c.Validate()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Perform additional regexp validation
|
||||
c.Operand = "regexp"
|
||||
c.RTarget = "(foo"
|
||||
err = c.Validate()
|
||||
mErr = err.(*multierror.Error)
|
||||
if !strings.Contains(mErr.Errors[0].Error(), "missing closing") {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Perform version validation
|
||||
c.Operand = "version"
|
||||
c.RTarget = "~> foo"
|
||||
err = c.Validate()
|
||||
mErr = err.(*multierror.Error)
|
||||
if !strings.Contains(mErr.Errors[0].Error(), "Malformed constraint") {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResource_NetIndex(t *testing.T) {
|
||||
r := &Resources{
|
||||
Networks: []*NetworkResource{
|
||||
|
|
Loading…
Reference in a new issue