diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 8fe568d0d..6e851b3a3 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -995,6 +995,13 @@ func (tg *TaskGroup) GoString() string { return fmt.Sprintf("*%#v", *tg) } +const ( + ServiceCheckHTTP = "http" + ServiceCheckTCP = "tcp" + ServiceCheckDocker = "docker" + ServiceCheckScript = "script" +) + // The ServiceCheck data model represents the consul health check that // Nomad registers for a Task type ServiceCheck struct { @@ -1007,6 +1014,14 @@ type ServiceCheck struct { Timeout time.Duration } +func (sc *ServiceCheck) Validate() error { + t := strings.ToLower(sc.Type) + if t != ServiceCheckTCP && t != ServiceCheckHTTP && t != ServiceCheckDocker && t != ServiceCheckScript { + return fmt.Errorf("Check with name %v has invalid check type: %s ", sc.Name, sc.Type) + } + return nil +} + // The Service model represents a Consul service defintion type Service struct { Id string @@ -1016,6 +1031,16 @@ type Service struct { Checks []ServiceCheck } +func (s *Service) Validate() error { + var mErr multierror.Error + for _, c := range s.Checks { + if err := c.Validate(); err != nil { + mErr.Errors = append(mErr.Errors, err) + } + } + return mErr.ErrorOrNil() +} + // Task is a single process typically that is executed as part of a task group. type Task struct { // Name of the task @@ -1156,6 +1181,12 @@ func (t *Task) Validate() error { mErr.Errors = append(mErr.Errors, outer) } } + + for _, service := range t.Services { + if err := service.Validate(); err != nil { + mErr.Errors = append(mErr.Errors, err) + } + } return mErr.ErrorOrNil() } diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 8221c40fd..84af2a198 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -357,9 +357,21 @@ func TestEncodeDecode(t *testing.T) { } } -func TestBatchRestartPolicyValidate(t *testing.T) { - rp := RestartPolicy{Attempts: 10, Delay: 25 * time.Second} - if err := rp.Validate(); err != nil { - t.Fatalf("err: %v", err) +func TestInvalidServiceCheck(t *testing.T) { + s := Service{ + Id: "service-id", + Name: "service-name", + PortLabel: "bar", + Checks: []ServiceCheck{ + { + + Id: "check-id", + Name: "check-name", + Type: "lol", + }, + }, + } + if err := s.Validate(); err == nil { + t.Fatalf("Service should be invalid") } }