Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kuma-cp) add simple HTTP connection configurers #2593

Merged
merged 1 commit into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions pkg/xds/envoy/listeners/configurers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package listeners

import (
envoy_listener "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
"google.golang.org/protobuf/types/known/wrapperspb"
envoy_hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"

mesh_proto "github.com/kumahq/kuma/api/mesh/v1alpha1"
core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
core_xds "github.com/kumahq/kuma/pkg/core/xds"
"github.com/kumahq/kuma/pkg/tls"
util_proto "github.com/kumahq/kuma/pkg/util/proto"
xds_context "github.com/kumahq/kuma/pkg/xds/context"
envoy_common "github.com/kumahq/kuma/pkg/xds/envoy"
v3 "github.com/kumahq/kuma/pkg/xds/envoy/listeners/v3"
Expand Down Expand Up @@ -273,7 +274,7 @@ func DNS(vips map[string]string, emptyDnsPort uint32) ListenerBuilderOpt {
func ConnectionBufferLimit(bytes uint32) ListenerBuilderOpt {
return AddListenerConfigurer(
v3.ListenerMustConfigureFunc(func(l *envoy_listener.Listener) {
l.PerConnectionBufferLimitBytes = wrapperspb.UInt32(bytes)
l.PerConnectionBufferLimitBytes = util_proto.UInt32(bytes)
}))
}

Expand All @@ -288,6 +289,40 @@ func EnableReusePort(enable bool) ListenerBuilderOpt {
func EnableFreebind(enable bool) ListenerBuilderOpt {
return AddListenerConfigurer(
v3.ListenerMustConfigureFunc(func(l *envoy_listener.Listener) {
l.Freebind = wrapperspb.Bool(enable)
l.Freebind = util_proto.Bool(enable)
}))
}

// ServerHeader sets the value that the HttpConnectionManager will write
// to the "Server" header in HTTP responses.
func ServerHeader(name string) FilterChainBuilderOpt {
return AddFilterChainConfigurer(
v3.HttpConnectionManagerMustConfigureFunc(func(hcm *envoy_hcm.HttpConnectionManager) {
hcm.ServerName = name
}),
)
}

// EnablePathNormalization enables HTTP request path normalization.
func EnablePathNormalization() FilterChainBuilderOpt {
return AddFilterChainConfigurer(
v3.HttpConnectionManagerMustConfigureFunc(func(hcm *envoy_hcm.HttpConnectionManager) {
hcm.NormalizePath = util_proto.Bool(true)
hcm.MergeSlashes = true

// TODO(jpeach) set path_with_escaped_slashes_action when we upgrade to Envoy v1.19.
}),
)
}

// StripHostPort strips the port component before matching the HTTP host
// header (authority) to the available virtual hosts.
func StripHostPort() FilterChainBuilderOpt {
return AddFilterChainConfigurer(
v3.HttpConnectionManagerMustConfigureFunc(func(hcm *envoy_hcm.HttpConnectionManager) {
hcm.StripPortMode = &envoy_hcm.HttpConnectionManager_StripAnyHostPort{
StripAnyHostPort: true,
}
}),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package listeners_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"

util_proto "github.com/kumahq/kuma/pkg/util/proto"
"github.com/kumahq/kuma/pkg/xds/envoy"
. "github.com/kumahq/kuma/pkg/xds/envoy/listeners"
)

var _ = Describe("HttpConnectionManager Configurers", func() {
type Opt = FilterChainBuilderOpt

type testCase struct {
opts []Opt
expected string
}

Context("V3", func() {
DescribeTable("should generate proper Envoy config",
func(given testCase) {
opts := append([]Opt{
HttpConnectionManager("test", false),
}, given.opts...)

// when
chain, err := NewFilterChainBuilder(envoy.APIV3).
Configure(opts...).
Build()
// then
Expect(err).ToNot(HaveOccurred())

// when
actual, err := util_proto.ToYAML(chain)
// then
Expect(err).ToNot(HaveOccurred())
// and
Expect(actual).To(MatchYAML(given.expected))
},
Entry("set the server header", testCase{
opts: []Opt{ServerHeader("test-server")},
expected: `
filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
httpFilters:
- name: envoy.filters.http.router
serverName: test-server
statPrefix: test`,
}),

Entry("set path normalization", testCase{
opts: []Opt{EnablePathNormalization()},
expected: `
filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
httpFilters:
- name: envoy.filters.http.router
mergeSlashes: true
normalizePath: true
statPrefix: test`,
}),

Entry("strip host port", testCase{
opts: []Opt{StripHostPort()},
expected: `
filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
httpFilters:
- name: envoy.filters.http.router
statPrefix: test
stripAnyHostPort: true`,
}),
)
})
})