diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 380bdeaef..c3ab3a056 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -1527,6 +1527,10 @@ func (s *Service) Validate() error { } for _, c := range s.Checks { + if s.PortLabel == "" && (c.Type == ServiceCheckTCP || c.Type == ServiceCheckHTTP) { + mErr.Errors = append(mErr.Errors, fmt.Errorf("check %q is not valid since service %q doesn't have port", c.Name, s.Name)) + continue + } if err := c.Validate(); err != nil { mErr.Errors = append(mErr.Errors, err) } diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index 04f96635d..72e7145ce 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -551,6 +551,44 @@ func TestInvalidServiceCheck(t *testing.T) { if err := s.Validate(); err == nil { t.Fatalf("Service should be invalid (too long): %v", err) } + + s = Service{ + Name: "service-name", + Checks: []*ServiceCheck{ + { + Name: "check-tcp", + Type: ServiceCheckTCP, + Interval: 5 * time.Second, + Timeout: 2 * time.Second, + }, + { + Name: "check-http", + Type: ServiceCheckHTTP, + Path: "/foo", + Interval: 5 * time.Second, + Timeout: 2 * time.Second, + }, + }, + } + if err := s.Validate(); err == nil { + t.Fatalf("service should be invalid (tcp/http checks with no port): %v", err) + } + + s = Service{ + Name: "service-name", + Checks: []*ServiceCheck{ + { + Name: "check-script", + Type: ServiceCheckScript, + Command: "/bin/date", + Interval: 5 * time.Second, + Timeout: 2 * time.Second, + }, + }, + } + if err := s.Validate(); err != nil { + t.Fatalf("un-expected error: %v", err) + } } func TestDistinctCheckID(t *testing.T) {