diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_test.go index a3b5e394bd4f..3e1a961f3a67 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_builder_test.go @@ -29,6 +29,7 @@ var ( }, Ports: map[string]*pbcatalog.WorkloadPort{ "tcp": {Port: 7070, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, + "tcp2": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, "http": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, @@ -43,6 +44,11 @@ var ( VirtualPort: 7070, Protocol: pbcatalog.Protocol_PROTOCOL_TCP, }, + { + TargetPort: "tcp2", + VirtualPort: 8081, + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }, { TargetPort: "http", VirtualPort: 8080, @@ -205,6 +211,38 @@ func TestBuildExplicitDestinations(t *testing.T) { Build() resourcetest.ValidateAndNormalize(t, registry, api1TCPRoute) + api1TCP2Route := resourcetest.Resource(types.TCPRouteType, "api-1-tcp2-route"). + WithTenancy(resource.DefaultNamespacedTenancy()). + WithData(t, &pbmesh.TCPRoute{ + ParentRefs: []*pbmesh.ParentReference{{ + Ref: resource.Reference(api1Service.Id, ""), + Port: "tcp2", + }}, + Rules: []*pbmesh.TCPRouteRule{{ + BackendRefs: []*pbmesh.TCPBackendRef{ + { + BackendRef: &pbmesh.BackendReference{ + Ref: resource.Reference(api2Service.Id, ""), + }, + Weight: 60, + }, + { + BackendRef: &pbmesh.BackendReference{ + Ref: resource.Reference(api1Service.Id, ""), + }, + Weight: 40, + }, + { + BackendRef: &pbmesh.BackendReference{ + Ref: resource.Reference(api3Service.Id, ""), + }, + Weight: 10, + }, + }, + }}, + }). + Build() + api1ComputedRoutesID := resource.ReplaceType(types.ComputedRoutesType, api1Service.Id) api1ComputedRoutes := routestest.BuildComputedRoutes(t, api1ComputedRoutesID, resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), @@ -214,6 +252,7 @@ func TestBuildExplicitDestinations(t *testing.T) { resourcetest.MustDecode[*pbmesh.HTTPRoute](t, api1HTTPRoute), resourcetest.MustDecode[*pbmesh.TCPRoute](t, api1TCPRoute), resourcetest.MustDecode[*pbcatalog.FailoverPolicy](t, api1FailoverPolicy), + resourcetest.MustDecode[*pbmesh.TCPRoute](t, api1TCP2Route), ) require.NotNil(t, api1ComputedRoutes) @@ -247,6 +286,30 @@ func TestBuildExplicitDestinations(t *testing.T) { }), } + destinationIpPort2 := &intermediate.Destination{ + Explicit: &pbmesh.Upstream{ + DestinationRef: resource.Reference(api1Endpoints.Id, ""), + DestinationPort: "tcp2", + Datacenter: "dc1", + ListenAddr: &pbmesh.Upstream_IpPort{ + IpPort: &pbmesh.IPPortAddress{Ip: "1.1.1.1", Port: 2345}, + }, + }, + Service: resourcetest.MustDecode[*pbcatalog.Service](t, api1Service), + ComputedPortRoutes: routestest.MutateTargets(t, api1ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) { + switch { + case resource.ReferenceOrIDMatch(api1Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": + details.ServiceEndpointsId = api1Endpoints.Id + details.ServiceEndpoints = endpointsData + details.IdentityRefs = []*pbresource.Reference{api1Identity} + case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": + details.ServiceEndpointsId = api2Endpoints.Id + details.ServiceEndpoints = endpointsData + details.IdentityRefs = []*pbresource.Reference{api2Identity} + } + }), + } + destinationUnix := &intermediate.Destination{ Explicit: &pbmesh.Upstream{ DestinationRef: resource.Reference(api2Endpoints.Id, ""), @@ -267,6 +330,25 @@ func TestBuildExplicitDestinations(t *testing.T) { }), } + destinationUnix2 := &intermediate.Destination{ + Explicit: &pbmesh.Upstream{ + DestinationRef: resource.Reference(api2Endpoints.Id, ""), + DestinationPort: "tcp2", + Datacenter: "dc1", + ListenAddr: &pbmesh.Upstream_Unix{ + Unix: &pbmesh.UnixSocketAddress{Path: "/path/to/socket", Mode: "0666"}, + }, + }, + Service: resourcetest.MustDecode[*pbcatalog.Service](t, api2Service), + ComputedPortRoutes: routestest.MutateTargets(t, api2ComputedRoutes.Data, "tcp2", func(t *testing.T, details *pbmesh.BackendTargetDetails) { + switch { + case resource.ReferenceOrIDMatch(api2Service.Id, details.BackendRef.Ref) && details.BackendRef.Port == "tcp2": + details.ServiceEndpointsId = api2Endpoints.Id + details.ServiceEndpoints = endpointsData + details.IdentityRefs = []*pbresource.Reference{api2Identity} + } + }), + } destinationIpPortHTTP := &intermediate.Destination{ Explicit: &pbmesh.Upstream{ DestinationRef: resource.Reference(api1Endpoints.Id, ""), @@ -306,7 +388,7 @@ func TestBuildExplicitDestinations(t *testing.T) { destinations: []*intermediate.Destination{destinationUnix}, }, "destination/l4-multi-destination": { - destinations: []*intermediate.Destination{destinationIpPort, destinationUnix}, + destinations: []*intermediate.Destination{destinationIpPort, destinationUnix, destinationIpPort2, destinationUnix2}, }, "destination/mixed-multi-destination": { destinations: []*intermediate.Destination{destinationIpPort, destinationUnix, destinationIpPortHTTP}, diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden index 30aeb94f66fc..eebeffd99d8a 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden @@ -38,6 +38,33 @@ }, "name": "tcp.api-1.default.dc1.internal.foo.consul" }, + "tcp2.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-1.default.dc1.internal.foo.consul" + }, "tcp.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", "endpointGroup": { @@ -64,6 +91,33 @@ } }, "name": "tcp.api-2.default.dc1.internal.foo.consul" + }, + "tcp2.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-2.default.dc1.internal.foo.consul" } }, "identity": { @@ -123,6 +177,55 @@ "mode": "0666", "path": "/path/to/socket" } + }, + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 2345 + }, + "name": "api-1:tcp2:1.1.1.1:2345", + "routers": [ + { + "l4": { + "statPrefix": "upstream.tcp2.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp2.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp2.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + }, + { + "direction": "DIRECTION_OUTBOUND", + "name": "api-2:tcp2:/path/to/socket", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp2.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-2.default.default.dc1" + } + } + ], + "unixSocket": { + "mode": "0666", + "path": "/path/to/socket" + } } ] }, @@ -143,6 +246,22 @@ }, "port": "mesh" }, + "tcp2.api-1.default.dc1.internal.foo.consul": { + "id": { + "name": "api-1", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v1alpha1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" + }, "tcp.api-2.default.dc1.internal.foo.consul": { "id": { "name": "api-2", @@ -158,6 +277,22 @@ } }, "port": "mesh" + }, + "tcp2.api-2.default.dc1.internal.foo.consul": { + "id": { + "name": "api-2", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v1alpha1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" } }, "requiredLeafCertificates": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden index 0a8976d5e8a1..6a3632769467 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-multiple-implicit-destinations-tproxy.golden @@ -108,6 +108,60 @@ } }, "name": "tcp.api-app2.default.dc1.internal.foo.consul" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "tcp2.api-app2.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app2.default.dc1.internal.foo.consul" } }, "identity": { @@ -168,6 +222,44 @@ ] } }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app2.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + } + }, { "l7": { "name": "outbound_listener", @@ -276,6 +368,22 @@ }, "port": "mesh" }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "id": { + "name": "api-app", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v1alpha1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" + }, "tcp.api-app2.default.dc1.internal.foo.consul": { "id": { "name": "api-app2", @@ -291,6 +399,22 @@ } }, "port": "mesh" + }, + "tcp2.api-app2.default.dc1.internal.foo.consul": { + "id": { + "name": "api-app2", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v1alpha1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" } }, "requiredLeafCertificates": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden index 1802e2f83440..5e756d659ad5 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-tproxy.golden @@ -54,6 +54,33 @@ } }, "name": "tcp.api-app.default.dc1.internal.foo.consul" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app.default.dc1.internal.foo.consul" } }, "identity": { @@ -93,6 +120,23 @@ ] } }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, { "l7": { "name": "outbound_listener", @@ -166,6 +210,22 @@ } }, "port": "mesh" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "id": { + "name": "api-app", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v1alpha1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" } }, "requiredLeafCertificates": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden index 1802e2f83440..5e756d659ad5 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -54,6 +54,33 @@ } }, "name": "tcp.api-app.default.dc1.internal.foo.consul" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app.default.dc1.internal.foo.consul" } }, "identity": { @@ -93,6 +120,23 @@ ] } }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, { "l7": { "name": "outbound_listener", @@ -166,6 +210,22 @@ } }, "port": "mesh" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "id": { + "name": "api-app", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "catalog", + "groupVersion": "v1alpha1", + "kind": "ServiceEndpoints" + } + }, + "port": "mesh" } }, "requiredLeafCertificates": {