diff --git a/command/agent/job_endpoint.go b/command/agent/job_endpoint.go index 396916627..a1015b058 100644 --- a/command/agent/job_endpoint.go +++ b/command/agent/job_endpoint.go @@ -1088,6 +1088,12 @@ func ApiTaskToStructsTask(job *structs.Job, group *structs.TaskGroup, } } } + + // Task services can't have a connect block. We still convert it so that + // we can later return a validation error. + if service.Connect != nil { + structsTask.Services[i].Connect = ApiConsulConnectToStructs(service.Connect) + } } } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index ec905c06e..e8824371d 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -6954,6 +6954,11 @@ func validateServices(t *Task, tgNetworks Networks) error { } } + // connect block is only allowed on group level + if service.Connect != nil { + mErr.Errors = append(mErr.Errors, fmt.Errorf("service %q cannot have \"connect\" block, only services defined in a \"group\" block can", service.Name)) + } + // Ensure that check names are unique and have valid ports knownChecks := make(map[string]struct{}) for _, check := range service.Checks { diff --git a/nomad/structs/structs_test.go b/nomad/structs/structs_test.go index a313a73b3..0ed2bf5c1 100644 --- a/nomad/structs/structs_test.go +++ b/nomad/structs/structs_test.go @@ -1933,6 +1933,13 @@ func TestTask_Validate_Service_Check_AddressMode(t *testing.T) { }, ErrContains: `invalid: check requires a port but neither check nor service`, }, + { + Service: &Service{ + Name: "conect-block-on-task-level", + Connect: &ConsulConnect{SidecarService: &ConsulSidecarService{}}, + }, + ErrContains: `cannot have "connect" block`, + }, } for _, tc := range cases {