diff --git a/pkg/envoy/lds/inmesh.go b/pkg/envoy/lds/inmesh.go index e399a663c9..00d1b1ec81 100644 --- a/pkg/envoy/lds/inmesh.go +++ b/pkg/envoy/lds/inmesh.go @@ -128,3 +128,25 @@ func (lb *listenerBuilder) getOutboundHTTPFilterChainMatchForService(dstSvc serv return filterMatch, nil } + +func (lb *listenerBuilder) getOutboundHTTPFilterChainForService(upstream service.MeshService) (*xds_listener.FilterChain, error) { + // Get HTTP filter for service + filter, err := lb.getOutboundHTTPFilter() + if err != nil { + log.Error().Err(err).Msgf("Error getting HTTP filter for upstream service %s", upstream) + return nil, err + } + + // Get filter match criteria for destination service + filterChainMatch, err := lb.getOutboundHTTPFilterChainMatchForService(upstream) + if err != nil { + log.Error().Err(err).Msgf("Error getting HTTP filter chain match for upstream service %s", upstream) + return nil, err + } + + return &xds_listener.FilterChain{ + Name: upstream.String(), + Filters: []*xds_listener.Filter{filter}, + FilterChainMatch: filterChainMatch, + }, nil +} diff --git a/pkg/envoy/lds/inmesh_test.go b/pkg/envoy/lds/inmesh_test.go new file mode 100644 index 0000000000..7ec0b97edd --- /dev/null +++ b/pkg/envoy/lds/inmesh_test.go @@ -0,0 +1,70 @@ +package lds + +import ( + "fmt" + "net" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + "github.com/openservicemesh/osm/pkg/catalog" + "github.com/openservicemesh/osm/pkg/configurator" + "github.com/openservicemesh/osm/pkg/endpoint" + "github.com/openservicemesh/osm/pkg/tests" +) + +func TestGetOutboundHTTPFilterChainForService(t *testing.T) { + assert := assert.New(t) + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockCatalog := catalog.NewMockMeshCataloger(mockCtrl) + mockConfigurator := configurator.NewMockConfigurator(mockCtrl) + + // Mock calls used to build the HTTP connection manager + mockConfigurator.EXPECT().IsTracingEnabled().Return(false).AnyTimes() + mockConfigurator.EXPECT().GetTracingEndpoint().Return("test-api").AnyTimes() + + lb := &listenerBuilder{ + meshCatalog: mockCatalog, + cfg: mockConfigurator, + svcAccount: tests.BookbuyerServiceAccount, + } + + testCases := []struct { + name string + expectedEndpoints []endpoint.Endpoint + expectError bool + }{ + { + name: "service with multiple endpoints", + expectedEndpoints: []endpoint.Endpoint{ + {IP: net.ParseIP("1.1.1.1"), Port: 80}, + {IP: net.ParseIP("2.2.2.2"), Port: 80}, + }, + expectError: false, + }, + { + name: "service with no endpoints", + expectedEndpoints: []endpoint.Endpoint{}, + expectError: true, + }, + } + + for i, tc := range testCases { + t.Run(fmt.Sprintf("Testing test case %d: %s", i, tc.name), func(t *testing.T) { + mockCatalog.EXPECT().GetResolvableServiceEndpoints(tests.BookstoreApexService).Return(tc.expectedEndpoints, nil) + httpFilterChain, err := lb.getOutboundHTTPFilterChainForService(tests.BookstoreApexService) + + assert.Equal(err != nil, tc.expectError) + + if err != nil { + assert.Nil(httpFilterChain) + } else { + assert.NotNil(httpFilterChain) + assert.Len(httpFilterChain.FilterChainMatch.PrefixRanges, len(tc.expectedEndpoints)) + } + }) + } +} diff --git a/pkg/envoy/lds/listener.go b/pkg/envoy/lds/listener.go index 7c4f490f3a..3c93c33581 100644 --- a/pkg/envoy/lds/listener.go +++ b/pkg/envoy/lds/listener.go @@ -149,26 +149,13 @@ func (lb *listenerBuilder) getOutboundFilterChains(downstreamSvc []service.MeshS } // Iterate all destination services - for keyService := range dstServicesSet { - // Get HTTP filter for service - filter, err := lb.getOutboundHTTPFilter() - if err != nil { - log.Error().Err(err).Msgf("Error getting filter for dst service %s", keyService.String()) - continue + for upstream := range dstServicesSet { + // Construct HTTP filter chain + if httpFilterChain, err := lb.getOutboundHTTPFilterChainForService(upstream); err != nil { + log.Error().Err(err).Msgf("Error constructing outbount HTTP filter chain for upstream service %q", upstream) + } else { + filterChains = append(filterChains, httpFilterChain) } - - // Get filter match criteria for destination service - filterChainMatch, err := lb.getOutboundHTTPFilterChainMatchForService(keyService) - if err != nil { - log.Error().Err(err).Msgf("Error getting Chain Match for service %s", keyService.String()) - continue - } - - filterChains = append(filterChains, &xds_listener.FilterChain{ - Name: keyService.String(), - Filters: []*xds_listener.Filter{filter}, - FilterChainMatch: filterChainMatch, - }) } // This filterchain matches any traffic not filtered by allow rules, it will be treated as egress