-
Notifications
You must be signed in to change notification settings - Fork 339
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactoring: introduce FilterChainBuilder in addition to ListenerBuilder
- Loading branch information
Showing
29 changed files
with
365 additions
and
310 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package listeners | ||
|
||
import ( | ||
envoy_listener "github.com/envoyproxy/go-control-plane/envoy/api/v2/listener" | ||
) | ||
|
||
// FilterChainConfigurer is responsible for configuring a single aspect of the entire Envoy filter chain, | ||
// such as TcpProxy filter, RBAC filter, access log, etc. | ||
type FilterChainConfigurer interface { | ||
// Configure configures a single aspect on a given Envoy filter chain. | ||
Configure(filterChain *envoy_listener.FilterChain) error | ||
} | ||
|
||
// FilterChainBuilderOpt is a configuration option for FilterChainBuilder. | ||
// | ||
// The goal of FilterChainBuilderOpt is to facilitate fluent FilterChainBuilder API. | ||
type FilterChainBuilderOpt interface { | ||
// ApplyTo adds FilterChainConfigurer(s) to the FilterChainBuilder. | ||
ApplyTo(config *FilterChainBuilderConfig) | ||
} | ||
|
||
func NewFilterChainBuilder() *FilterChainBuilder { | ||
return &FilterChainBuilder{} | ||
} | ||
|
||
// FilterChainBuilder is responsible for generating an Envoy filter chain | ||
// by applying a series of FilterChainConfigurers. | ||
type FilterChainBuilder struct { | ||
config FilterChainBuilderConfig | ||
} | ||
|
||
// Configure configures FilterChainBuilder by adding individual FilterChainConfigurers. | ||
func (b *FilterChainBuilder) Configure(opts ...FilterChainBuilderOpt) *FilterChainBuilder { | ||
for _, opt := range opts { | ||
opt.ApplyTo(&b.config) | ||
} | ||
return b | ||
} | ||
|
||
// Build generates an Envoy filter chain by applying a series of FilterChainConfigurers. | ||
func (b *FilterChainBuilder) Build() (*envoy_listener.FilterChain, error) { | ||
filterChain := envoy_listener.FilterChain{} | ||
for _, configurer := range b.config.Configurers { | ||
if err := configurer.Configure(&filterChain); err != nil { | ||
return nil, err | ||
} | ||
} | ||
return &filterChain, nil | ||
} | ||
|
||
// FilterChainBuilderConfig holds configuration of a FilterChainBuilder. | ||
type FilterChainBuilderConfig struct { | ||
// A series of FilterChainConfigurers to apply to Envoy filter chain. | ||
Configurers []FilterChainConfigurer | ||
} | ||
|
||
// Add appends a given FilterChainConfigurer to the end of the chain. | ||
func (c *FilterChainBuilderConfig) Add(configurer FilterChainConfigurer) { | ||
c.Configurers = append(c.Configurers, configurer) | ||
} | ||
|
||
// FilterChainBuilderOptFunc is a convenience type adapter. | ||
type FilterChainBuilderOptFunc func(config *FilterChainBuilderConfig) | ||
|
||
func (f FilterChainBuilderOptFunc) ApplyTo(config *FilterChainBuilderConfig) { | ||
f(config) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package listeners | ||
|
||
import ( | ||
v2 "github.com/envoyproxy/go-control-plane/envoy/api/v2" | ||
) | ||
|
||
func FilterChain(builder *FilterChainBuilder) ListenerBuilderOpt { | ||
return ListenerBuilderOptFunc(func(config *ListenerBuilderConfig) { | ||
config.Add(&ListenerFilterChainConfigurer{ | ||
builder: builder, | ||
}) | ||
}) | ||
} | ||
|
||
type ListenerFilterChainConfigurer struct { | ||
builder *FilterChainBuilder | ||
} | ||
|
||
func (c ListenerFilterChainConfigurer) Configure(listener *v2.Listener) error { | ||
filterChain, err := c.builder.Build() | ||
if err != nil { | ||
return err | ||
} | ||
listener.FilterChains = append(listener.FilterChains, filterChain) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package listeners_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/ginkgo/extensions/table" | ||
. "github.com/onsi/gomega" | ||
|
||
. "github.com/Kong/kuma/pkg/xds/envoy/listeners" | ||
|
||
util_proto "github.com/Kong/kuma/pkg/util/proto" | ||
) | ||
|
||
var _ = Describe("ListenerFilterChainConfigurer", func() { | ||
|
||
type testCase struct { | ||
listenerName string | ||
listenerAddress string | ||
listenerPort uint32 | ||
expected string | ||
} | ||
|
||
DescribeTable("should generate proper Envoy config", | ||
func(given testCase) { | ||
// when | ||
listener, err := NewListenerBuilder(). | ||
Configure(InboundListener(given.listenerName, given.listenerAddress, given.listenerPort)). | ||
Configure(FilterChain(NewFilterChainBuilder())). | ||
Build() | ||
// then | ||
Expect(err).ToNot(HaveOccurred()) | ||
|
||
// when | ||
actual, err := util_proto.ToYAML(listener) | ||
// then | ||
Expect(err).ToNot(HaveOccurred()) | ||
// and | ||
Expect(actual).To(MatchYAML(given.expected)) | ||
}, | ||
Entry("basic listener with an empty filter chain", testCase{ | ||
listenerName: "inbound:192.168.0.1:8080", | ||
listenerAddress: "192.168.0.1", | ||
listenerPort: 8080, | ||
expected: ` | ||
name: inbound:192.168.0.1:8080 | ||
address: | ||
socketAddress: | ||
address: 192.168.0.1 | ||
portValue: 8080 | ||
filterChains: | ||
- {} | ||
`, | ||
}), | ||
) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.