diff --git a/internal/mesh/internal/controllers/routes/generate.go b/internal/mesh/internal/controllers/routes/generate.go index 42ecc56ff7..afd66e2e4a 100644 --- a/internal/mesh/internal/controllers/routes/generate.go +++ b/internal/mesh/internal/controllers/routes/generate.go @@ -314,6 +314,14 @@ func compile( computedRoutes.PortedConfigs[port] = mc } + if len(computedRoutes.PortedConfigs) == 0 { + // This service only exposes a "mesh" port, so it cannot be another service's upstream. + return &ComputedRoutesResult{ + ID: computedRoutesID, + Data: nil, // returning nil signals a delete is requested + } + } + return &ComputedRoutesResult{ ID: computedRoutesID, OwnerID: parentServiceID, diff --git a/internal/mesh/internal/controllers/routes/generate_test.go b/internal/mesh/internal/controllers/routes/generate_test.go index e46bc57f01..ed9b565f6f 100644 --- a/internal/mesh/internal/controllers/routes/generate_test.go +++ b/internal/mesh/internal/controllers/routes/generate_test.go @@ -160,6 +160,24 @@ func TestGenerateComputedRoutes(t *testing.T) { run(t, related, expect, nil) }) + t.Run("aligned service in mesh but no actual ports", func(t *testing.T) { + related := loader.NewRelatedResources(). + AddComputedRoutesIDs(apiComputedRoutesID). + AddResources(newService("api", &pbcatalog.Service{ + Workloads: &pbcatalog.WorkloadSelector{ + Prefixes: []string{"api-"}, + }, + Ports: []*pbcatalog.ServicePort{ + {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + }, + })) + expect := []*ComputedRoutesResult{{ + ID: apiComputedRoutesID, + Data: nil, + }} + run(t, related, expect, nil) + }) + t.Run("tcp service with default route", func(t *testing.T) { apiServiceData := &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{