From e4a099727cb58f126631eb59500b22021051532c Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Thu, 8 Jul 2021 09:43:38 -0400 Subject: [PATCH] service: remove duplicate name check during validation (#10868) When a task group with `service` block(s) is validated, we validate that there are no duplicates, but this validation doesn't have access to the task environment because it hasn't been created yet. Services and checks with interpolation can be flagged incorrectly as conflicting. Name conflicts in services are not actually an error in Consul and users have reported wanting to use the same service name for task groups differentiated by tags. --- .changelog/10868.txt | 3 +++ nomad/structs/structs.go | 13 ++----------- 2 files changed, 5 insertions(+), 11 deletions(-) create mode 100644 .changelog/10868.txt diff --git a/.changelog/10868.txt b/.changelog/10868.txt new file mode 100644 index 000000000000..eaff667f55ec --- /dev/null +++ b/.changelog/10868.txt @@ -0,0 +1,3 @@ +```release-note:bug +consul: Fixed a bug where services may incorrectly fail conflicting name validation +``` diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index 6761ca87ad81..4204a6d3e27a 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -6240,13 +6240,11 @@ func (tg *TaskGroup) validateNetworks() error { return mErr.ErrorOrNil() } -// validateServices runs Service.Validate() on group-level services, -// checks that group services do not conflict with task services and that +// validateServices runs Service.Validate() on group-level services, checks // group service checks that refer to tasks only refer to tasks that exist. func (tg *TaskGroup) validateServices() error { var mErr multierror.Error knownTasks := make(map[string]struct{}) - knownServices := make(map[string]struct{}) // Create a map of known tasks and their services so we can compare // vs the group-level services and checks @@ -6256,15 +6254,11 @@ func (tg *TaskGroup) validateServices() error { continue } for _, service := range task.Services { - if _, ok := knownServices[service.Name+service.PortLabel]; ok { - mErr.Errors = append(mErr.Errors, fmt.Errorf("Service %s is duplicate", service.Name)) - } for _, check := range service.Checks { if check.TaskName != "" { mErr.Errors = append(mErr.Errors, fmt.Errorf("Check %s is invalid: only task group service checks can be assigned tasks", check.Name)) } } - knownServices[service.Name+service.PortLabel] = struct{}{} } } for i, service := range tg.Services { @@ -6279,10 +6273,7 @@ func (tg *TaskGroup) validateServices() error { if service.AddressMode == AddressModeDriver { mErr.Errors = append(mErr.Errors, fmt.Errorf("service %q cannot use address_mode=\"driver\", only services defined in a \"task\" block can use this mode", service.Name)) } - if _, ok := knownServices[service.Name+service.PortLabel]; ok { - mErr.Errors = append(mErr.Errors, fmt.Errorf("Service %s is duplicate", service.Name)) - } - knownServices[service.Name+service.PortLabel] = struct{}{} + for _, check := range service.Checks { if check.TaskName != "" { if check.Type != ServiceCheckScript && check.Type != ServiceCheckGRPC {