diff --git a/cmd/contour/contour.go b/cmd/contour/contour.go index 16f01005dea..9ca896860c2 100644 --- a/cmd/contour/contour.go +++ b/cmd/contour/contour.go @@ -104,7 +104,8 @@ func main() { if err := envoy.ValidAdminAddress(bootstrapCtx.AdminAddress); err != nil { log.WithField("flag", "--admin-address").WithError(err).Fatal("failed to parse bootstrap args") } - if err := envoy_v3.WriteBootstrap(bootstrapCtx); err != nil { + cg := envoy_v3.NewConfigGenerator() + if err := cg.WriteBootstrap(bootstrapCtx); err != nil { log.WithError(err).Fatal("failed to write bootstrap configuration") } case certgenApp.FullCommand(): diff --git a/cmd/contour/serve.go b/cmd/contour/serve.go index 41831018506..85da37ffd2f 100644 --- a/cmd/contour/serve.go +++ b/cmd/contour/serve.go @@ -441,11 +441,12 @@ func (s *Server) doServe() error { // due to their high update rate and their orthogonal nature. endpointHandler := xdscache_v3.NewEndpointsTranslator(s.log.WithField("context", "endpointstranslator")) + configGen := envoy_v3.NewConfigGenerator() resources := []xdscache.ResourceCache{ - xdscache_v3.NewListenerCache(listenerConfig, *contourConfiguration.Envoy.Metrics, *contourConfiguration.Envoy.Health, *contourConfiguration.Envoy.Network.EnvoyAdminPort), + xdscache_v3.NewListenerCache(listenerConfig, *contourConfiguration.Envoy.Metrics, *contourConfiguration.Envoy.Health, *contourConfiguration.Envoy.Network.EnvoyAdminPort, configGen), xdscache_v3.NewSecretsCache(envoy_v3.StatsSecrets(contourConfiguration.Envoy.Metrics.TLS)), &xdscache_v3.RouteCache{}, - &xdscache_v3.ClusterCache{}, + xdscache_v3.NewClusterCache(configGen), endpointHandler, &xdscache_v3.RuntimeCache{}, } diff --git a/internal/envoy/v3/auth.go b/internal/envoy/v3/auth.go index c452b81f1f3..716d68d276f 100644 --- a/internal/envoy/v3/auth.go +++ b/internal/envoy/v3/auth.go @@ -25,13 +25,12 @@ import ( // UpstreamTLSContext creates an envoy_v3_tls.UpstreamTlsContext. By default // UpstreamTLSContext returns a HTTP/1.1 TLS enabled context. A list of // additional ALPN protocols can be provided. -func UpstreamTLSContext(peerValidationContext *dag.PeerValidationContext, sni string, clientSecret *dag.Secret, alpnProtocols ...string) *envoy_v3_tls.UpstreamTlsContext { +func (g *ConfigGenerator) UpstreamTLSContext(peerValidationContext *dag.PeerValidationContext, sni string, clientSecret *dag.Secret, alpnProtocols ...string) *envoy_v3_tls.UpstreamTlsContext { var clientSecretConfigs []*envoy_v3_tls.SdsSecretConfig if clientSecret != nil { - clientSecretConfigs = []*envoy_v3_tls.SdsSecretConfig{{ - Name: envoy.Secretname(clientSecret), - SdsConfig: ConfigSource("contour"), - }} + clientSecretConfigs = []*envoy_v3_tls.SdsSecretConfig{ + g.sdsSecretConfig(envoy.Secretname(clientSecret)), + } } context := &envoy_v3_tls.UpstreamTlsContext{ @@ -105,7 +104,7 @@ func validationContext(ca []byte, subjectName string, skipVerifyPeerCert bool, c } // DownstreamTLSContext creates a new DownstreamTlsContext. -func DownstreamTLSContext(serverSecret *dag.Secret, tlsMinProtoVersion envoy_v3_tls.TlsParameters_TlsProtocol, cipherSuites []string, peerValidationContext *dag.PeerValidationContext, alpnProtos ...string) *envoy_v3_tls.DownstreamTlsContext { +func (g *ConfigGenerator) DownstreamTLSContext(serverSecret *dag.Secret, tlsMinProtoVersion envoy_v3_tls.TlsParameters_TlsProtocol, cipherSuites []string, peerValidationContext *dag.PeerValidationContext, alpnProtos ...string) *envoy_v3_tls.DownstreamTlsContext { context := &envoy_v3_tls.DownstreamTlsContext{ CommonTlsContext: &envoy_v3_tls.CommonTlsContext{ TlsParams: &envoy_v3_tls.TlsParameters{ @@ -113,10 +112,9 @@ func DownstreamTLSContext(serverSecret *dag.Secret, tlsMinProtoVersion envoy_v3_ TlsMaximumProtocolVersion: envoy_v3_tls.TlsParameters_TLSv1_3, CipherSuites: cipherSuites, }, - TlsCertificateSdsSecretConfigs: []*envoy_v3_tls.SdsSecretConfig{{ - Name: envoy.Secretname(serverSecret), - SdsConfig: ConfigSource("contour"), - }}, + TlsCertificateSdsSecretConfigs: []*envoy_v3_tls.SdsSecretConfig{ + g.sdsSecretConfig(envoy.Secretname(serverSecret)), + }, AlpnProtocols: alpnProtos, }, } diff --git a/internal/envoy/v3/auth_test.go b/internal/envoy/v3/auth_test.go index 96df9c2a919..ed46f41a1ee 100644 --- a/internal/envoy/v3/auth_test.go +++ b/internal/envoy/v3/auth_test.go @@ -112,7 +112,8 @@ func TestUpstreamTLSContext(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - got := UpstreamTLSContext(tc.validation, tc.externalName, nil, tc.alpnProtocols...) + cg := NewConfigGenerator() + got := cg.UpstreamTLSContext(tc.validation, tc.externalName, nil, tc.alpnProtocols...) protobuf.ExpectEqual(t, tc.want, got) }) } diff --git a/internal/envoy/v3/bootstrap.go b/internal/envoy/v3/bootstrap.go index 904c5288f26..ed17d678a66 100644 --- a/internal/envoy/v3/bootstrap.go +++ b/internal/envoy/v3/bootstrap.go @@ -46,9 +46,9 @@ import ( ) // WriteBootstrap writes bootstrap configuration to files. -func WriteBootstrap(c *envoy.BootstrapConfig) error { +func (g *ConfigGenerator) WriteBootstrap(c *envoy.BootstrapConfig) error { // Create Envoy bootstrap config and associated resource files. - steps, err := bootstrap(c) + steps, err := g.bootstrap(c) if err != nil { return err } @@ -76,13 +76,13 @@ func WriteBootstrap(c *envoy.BootstrapConfig) error { type bootstrapf func(*envoy.BootstrapConfig) (string, proto.Message) // bootstrap creates a new v3 bootstrap configuration and associated resource files. -func bootstrap(c *envoy.BootstrapConfig) ([]bootstrapf, error) { +func (g *ConfigGenerator) bootstrap(c *envoy.BootstrapConfig) ([]bootstrapf, error) { var steps []bootstrapf if c.GrpcClientCert == "" && c.GrpcClientKey == "" && c.GrpcCABundle == "" { steps = append(steps, func(*envoy.BootstrapConfig) (string, proto.Message) { - return c.Path, bootstrapConfig(c) + return c.Path, g.bootstrapConfig(c) }) return steps, nil @@ -121,7 +121,7 @@ func bootstrap(c *envoy.BootstrapConfig) ([]bootstrapf, error) { steps = append(steps, func(*envoy.BootstrapConfig) (string, proto.Message) { - b := bootstrapConfig(c) + b := g.bootstrapConfig(c) b.StaticResources.Clusters[0].TransportSocket = UpstreamTLSTransportSocket( upstreamFileTLSContext(c)) return c.Path, b @@ -149,7 +149,7 @@ func bootstrap(c *envoy.BootstrapConfig) ([]bootstrapf, error) { return sdsValidationContextPath, validationContextSdsSecretConfig(c) }, func(*envoy.BootstrapConfig) (string, proto.Message) { - b := bootstrapConfig(c) + b := g.bootstrapConfig(c) b.StaticResources.Clusters[0].TransportSocket = UpstreamTLSTransportSocket( upstreamSdsTLSContext(sdsTLSCertificatePath, sdsValidationContextPath)) return c.Path, b @@ -159,7 +159,7 @@ func bootstrap(c *envoy.BootstrapConfig) ([]bootstrapf, error) { return steps, nil } -func bootstrapConfig(c *envoy.BootstrapConfig) *envoy_bootstrap_v3.Bootstrap { +func (g *ConfigGenerator) bootstrapConfig(c *envoy.BootstrapConfig) *envoy_bootstrap_v3.Bootstrap { bootstrap := &envoy_bootstrap_v3.Bootstrap{ LayeredRuntime: &envoy_bootstrap_v3.LayeredRuntime{ Layers: []*envoy_bootstrap_v3.RuntimeLayer{ @@ -174,7 +174,7 @@ func bootstrapConfig(c *envoy.BootstrapConfig) *envoy_bootstrap_v3.Bootstrap { LayerSpecifier: &envoy_bootstrap_v3.RuntimeLayer_RtdsLayer_{ RtdsLayer: &envoy_bootstrap_v3.RuntimeLayer_RtdsLayer{ Name: DynamicRuntimeLayerName, - RtdsConfig: ConfigSource("contour"), + RtdsConfig: g.ConfigSource(), }, }, }, @@ -192,8 +192,8 @@ func bootstrapConfig(c *envoy.BootstrapConfig) *envoy_bootstrap_v3.Bootstrap { }, }, DynamicResources: &envoy_bootstrap_v3.Bootstrap_DynamicResources{ - LdsConfig: ConfigSource("contour"), - CdsConfig: ConfigSource("contour"), + LdsConfig: g.ConfigSource(), + CdsConfig: g.ConfigSource(), }, StaticResources: &envoy_bootstrap_v3.Bootstrap_StaticResources{ Clusters: []*envoy_cluster_v3.Cluster{{ diff --git a/internal/envoy/v3/bootstrap_test.go b/internal/envoy/v3/bootstrap_test.go index fa01f916342..358471cbf37 100644 --- a/internal/envoy/v3/bootstrap_test.go +++ b/internal/envoy/v3/bootstrap_test.go @@ -2056,7 +2056,8 @@ func TestBootstrap(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - steps, gotError := bootstrap(&tc.config) + cg := NewConfigGenerator() + steps, gotError := cg.bootstrap(&tc.config) assert.Equal(t, gotError != nil, tc.wantedError) gotConfigs := map[string]proto.Message{} diff --git a/internal/envoy/v3/cluster.go b/internal/envoy/v3/cluster.go index e39beedadee..bfcc1813fd1 100644 --- a/internal/envoy/v3/cluster.go +++ b/internal/envoy/v3/cluster.go @@ -36,13 +36,13 @@ import ( func clusterDefaults() *envoy_cluster_v3.Cluster { return &envoy_cluster_v3.Cluster{ ConnectTimeout: durationpb.New(2 * time.Second), - CommonLbConfig: ClusterCommonLBConfig(), + CommonLbConfig: clusterCommonLBConfig(), LbPolicy: lbPolicy(dag.LoadBalancerPolicyRoundRobin), } } // Cluster creates new envoy_cluster_v3.Cluster from dag.Cluster. -func Cluster(c *dag.Cluster) *envoy_cluster_v3.Cluster { +func (g *ConfigGenerator) Cluster(c *dag.Cluster) *envoy_cluster_v3.Cluster { service := c.Upstream cluster := clusterDefaults() @@ -60,7 +60,7 @@ func Cluster(c *dag.Cluster) *envoy_cluster_v3.Cluster { case 0: // external name not set, cluster will be discovered via EDS cluster.ClusterDiscoveryType = ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS) - cluster.EdsClusterConfig = edsconfig("contour", service) + cluster.EdsClusterConfig = g.edsconfig(service) default: // external name set, use hard coded DNS name // external name set to LOGICAL_DNS when user selects the ALL loookup family @@ -93,7 +93,7 @@ func Cluster(c *dag.Cluster) *envoy_cluster_v3.Cluster { switch c.Protocol { case "tls": cluster.TransportSocket = UpstreamTLSTransportSocket( - UpstreamTLSContext( + g.UpstreamTLSContext( c.UpstreamValidation, c.SNI, c.ClientCertificate, @@ -102,7 +102,7 @@ func Cluster(c *dag.Cluster) *envoy_cluster_v3.Cluster { case "h2": httpVersion = HTTPVersion2 cluster.TransportSocket = UpstreamTLSTransportSocket( - UpstreamTLSContext( + g.UpstreamTLSContext( c.UpstreamValidation, c.SNI, c.ClientCertificate, @@ -142,7 +142,7 @@ func Cluster(c *dag.Cluster) *envoy_cluster_v3.Cluster { } // ExtensionCluster builds a envoy_cluster_v3.Cluster struct for the given extension service. -func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_cluster_v3.Cluster { +func (g *ConfigGenerator) ExtensionCluster(ext *dag.ExtensionCluster) *envoy_cluster_v3.Cluster { cluster := clusterDefaults() // The Envoy cluster name has already been set. @@ -162,7 +162,7 @@ func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_cluster_v3.Cluster { // Cluster will be discovered via EDS. cluster.ClusterDiscoveryType = ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS) cluster.EdsClusterConfig = &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: g.ConfigSource(), ServiceName: ext.Upstream.ClusterName, } @@ -173,7 +173,7 @@ func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_cluster_v3.Cluster { case "h2": http2Version = HTTPVersion2 cluster.TransportSocket = UpstreamTLSTransportSocket( - UpstreamTLSContext( + g.UpstreamTLSContext( ext.UpstreamValidation, ext.SNI, ext.ClientCertificate, @@ -193,7 +193,7 @@ func ExtensionCluster(ext *dag.ExtensionCluster) *envoy_cluster_v3.Cluster { } // DNSNameCluster builds a envoy_cluster_v3.Cluster for the given *dag.DNSNameCluster. -func DNSNameCluster(c *dag.DNSNameCluster) *envoy_cluster_v3.Cluster { +func (g *ConfigGenerator) DNSNameCluster(c *dag.DNSNameCluster) *envoy_cluster_v3.Cluster { cluster := clusterDefaults() cluster.Name = envoy.DNSNameClusterName(c) @@ -207,7 +207,7 @@ func DNSNameCluster(c *dag.DNSNameCluster) *envoy_cluster_v3.Cluster { var transportSocket *envoy_core_v3.TransportSocket if c.Scheme == "https" { - transportSocket = UpstreamTLSTransportSocket(UpstreamTLSContext(c.UpstreamValidation, c.Address, nil)) + transportSocket = UpstreamTLSTransportSocket(g.UpstreamTLSContext(c.UpstreamValidation, c.Address, nil)) } cluster.LoadAssignment = ClusterLoadAssignment(envoy.DNSNameClusterName(c), SocketAddress(c.Address, c.Port)) @@ -216,9 +216,9 @@ func DNSNameCluster(c *dag.DNSNameCluster) *envoy_cluster_v3.Cluster { return cluster } -func edsconfig(cluster string, service *dag.Service) *envoy_cluster_v3.Cluster_EdsClusterConfig { +func (g *ConfigGenerator) edsconfig(service *dag.Service) *envoy_cluster_v3.Cluster_EdsClusterConfig { return &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource(cluster), + EdsConfig: g.ConfigSource(), ServiceName: xds.ClusterLoadAssignmentName( types.NamespacedName{Name: service.Weighted.ServiceName, Namespace: service.Weighted.ServiceNamespace}, service.Weighted.ServicePort.Name, @@ -255,8 +255,8 @@ func edshealthcheck(c *dag.Cluster) []*envoy_core_v3.HealthCheck { } } -// ClusterCommonLBConfig creates a *envoy_cluster_v3.Cluster_CommonLbConfig with HealthyPanicThreshold disabled. -func ClusterCommonLBConfig() *envoy_cluster_v3.Cluster_CommonLbConfig { +// clusterCommonLBConfig creates a *envoy_cluster_v3.Cluster_CommonLbConfig with HealthyPanicThreshold disabled. +func clusterCommonLBConfig() *envoy_cluster_v3.Cluster_CommonLbConfig { return &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type.Percent{ // Disable HealthyPanicThreshold Value: 0, @@ -264,22 +264,6 @@ func ClusterCommonLBConfig() *envoy_cluster_v3.Cluster_CommonLbConfig { } } -// ConfigSource returns a *envoy_core_v3.ConfigSource for cluster. -func ConfigSource(cluster string) *envoy_core_v3.ConfigSource { - return &envoy_core_v3.ConfigSource{ - ResourceApiVersion: envoy_core_v3.ApiVersion_V3, - ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{ - ApiConfigSource: &envoy_core_v3.ApiConfigSource{ - ApiType: envoy_core_v3.ApiConfigSource_GRPC, - TransportApiVersion: envoy_core_v3.ApiVersion_V3, - GrpcServices: []*envoy_core_v3.GrpcService{ - GrpcService(cluster, "", timeout.DefaultSetting()), - }, - }, - }, - } -} - // ClusterDiscoveryType returns the type of a ClusterDiscovery as a Cluster_type. func ClusterDiscoveryType(t envoy_cluster_v3.Cluster_DiscoveryType) *envoy_cluster_v3.Cluster_Type { return &envoy_cluster_v3.Cluster_Type{Type: t} @@ -293,7 +277,7 @@ func ClusterDiscoveryTypeForAddress(address string, t envoy_cluster_v3.Cluster_D if net.ParseIP(address) != nil { clusterType = envoy_cluster_v3.Cluster_STATIC } - return &envoy_cluster_v3.Cluster_Type{Type: clusterType} + return ClusterDiscoveryType(clusterType) } // parseDNSLookupFamily parses the dnsLookupFamily string into a envoy_cluster_v3.Cluster_DnsLookupFamily diff --git a/internal/envoy/v3/cluster_test.go b/internal/envoy/v3/cluster_test.go index 42ebd5b108e..be34ec5760b 100644 --- a/internal/envoy/v3/cluster_test.go +++ b/internal/envoy/v3/cluster_test.go @@ -40,6 +40,8 @@ import ( ) func TestCluster(t *testing.T) { + cg := NewConfigGenerator() + s1 := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "kuard", @@ -126,7 +128,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, }, @@ -141,7 +143,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TypedExtensionProtocolOptions: map[string]*anypb.Any{ @@ -166,11 +168,11 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TransportSocket: UpstreamTLSTransportSocket( - UpstreamTLSContext(nil, "", nil, "h2"), + cg.UpstreamTLSContext(nil, "", nil, "h2"), ), TypedExtensionProtocolOptions: map[string]*anypb.Any{ "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": protobuf.MustMarshalAny( @@ -270,11 +272,11 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TransportSocket: UpstreamTLSTransportSocket( - UpstreamTLSContext(nil, "", nil), + cg.UpstreamTLSContext(nil, "", nil), ), }, }, @@ -290,7 +292,7 @@ func TestCluster(t *testing.T) { ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), LoadAssignment: ExternalNameClusterLoadAssignment(service(svcExternal, "tls")), TransportSocket: UpstreamTLSTransportSocket( - UpstreamTLSContext(nil, "projectcontour.local", nil), + cg.UpstreamTLSContext(nil, "projectcontour.local", nil), ), }, }, @@ -308,11 +310,11 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TransportSocket: UpstreamTLSTransportSocket( - UpstreamTLSContext( + cg.UpstreamTLSContext( &dag.PeerValidationContext{ CACertificate: secret, SubjectName: "foo.bar.io", @@ -340,7 +342,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -368,7 +370,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -396,7 +398,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -424,7 +426,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -444,7 +446,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, LbPolicy: envoy_cluster_v3.Cluster_RANDOM, @@ -460,7 +462,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -476,7 +478,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, }, @@ -496,7 +498,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, IgnoreHealthOnHostRemoval: true, @@ -522,11 +524,11 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TransportSocket: UpstreamTLSTransportSocket( - UpstreamTLSContext(nil, "", clientSecret), + cg.UpstreamTLSContext(nil, "", clientSecret), ), }, }, @@ -540,7 +542,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, ConnectTimeout: durationpb.New(10 * time.Second), @@ -556,7 +558,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TypedExtensionProtocolOptions: map[string]*anypb.Any{ @@ -589,7 +591,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, LbConfig: &envoy_cluster_v3.Cluster_RoundRobinLbConfig_{ @@ -623,7 +625,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, LbPolicy: envoy_cluster_v3.Cluster_LEAST_REQUEST, @@ -653,7 +655,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, PerConnectionBufferLimitBytes: wrapperspb.UInt32(32768), @@ -669,7 +671,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TypedExtensionProtocolOptions: map[string]*anypb.Any{ @@ -701,7 +703,7 @@ func TestCluster(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TypedExtensionProtocolOptions: map[string]*anypb.Any{ @@ -725,7 +727,8 @@ func TestCluster(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - got := Cluster(tc.cluster) + cg := NewConfigGenerator() + got := cg.Cluster(tc.cluster) want := clusterDefaults() proto.Merge(want, tc.want) @@ -736,6 +739,7 @@ func TestCluster(t *testing.T) { } func TestDNSNameCluster(t *testing.T) { + cg := NewConfigGenerator() tests := map[string]struct { cluster *dag.DNSNameCluster want *envoy_cluster_v3.Cluster @@ -854,7 +858,7 @@ func TestDNSNameCluster(t *testing.T) { }, }, }, - TransportSocket: UpstreamTLSTransportSocket(UpstreamTLSContext(nil, "foo.projectcontour.io", nil)), + TransportSocket: UpstreamTLSTransportSocket(cg.UpstreamTLSContext(nil, "foo.projectcontour.io", nil)), }, }, "HTTPS cluster with upstream validation": { @@ -894,7 +898,7 @@ func TestDNSNameCluster(t *testing.T) { }, }, }, - TransportSocket: UpstreamTLSTransportSocket(UpstreamTLSContext(&dag.PeerValidationContext{ + TransportSocket: UpstreamTLSTransportSocket(cg.UpstreamTLSContext(&dag.PeerValidationContext{ CACertificate: &dag.Secret{ Object: &v1.Secret{ Data: map[string][]byte{ @@ -910,7 +914,8 @@ func TestDNSNameCluster(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - got := DNSNameCluster(tc.cluster) + cg := NewConfigGenerator() + got := cg.DNSNameCluster(tc.cluster) want := clusterDefaults() proto.Merge(want, tc.want) @@ -1081,7 +1086,7 @@ func TestLBPolicy(t *testing.T) { } func TestClusterCommonLBConfig(t *testing.T) { - got := ClusterCommonLBConfig() + got := clusterCommonLBConfig() want := &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type.Percent{ // Disable HealthyPanicThreshold Value: 0, diff --git a/internal/envoy/v3/config_generator.go b/internal/envoy/v3/config_generator.go new file mode 100644 index 00000000000..68d1b499651 --- /dev/null +++ b/internal/envoy/v3/config_generator.go @@ -0,0 +1,53 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v3 + +import ( + envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + "github.com/projectcontour/contour/internal/timeout" +) + +const defaultXDSServerClusterName = "contour" + +// ConfigGenerator holds common configuration that can be applied across +// various Envoy xDS resource types to reduce duplication. It should +// typically be instantiated once and shared between various consumers +// that need to generate Envoy config. +type ConfigGenerator struct { + // Name of xDS server Cluster. Referenced in ConfigSources across + // various resources. + xdsServerClusterName string +} + +func NewConfigGenerator() *ConfigGenerator { + return &ConfigGenerator{ + xdsServerClusterName: defaultXDSServerClusterName, + } +} + +// ConfigSource returns a *envoy_core_v3.ConfigSource for cluster. +func (g *ConfigGenerator) ConfigSource() *envoy_core_v3.ConfigSource { + return &envoy_core_v3.ConfigSource{ + ResourceApiVersion: envoy_core_v3.ApiVersion_V3, + ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{ + ApiConfigSource: &envoy_core_v3.ApiConfigSource{ + ApiType: envoy_core_v3.ApiConfigSource_GRPC, + TransportApiVersion: envoy_core_v3.ApiVersion_V3, + GrpcServices: []*envoy_core_v3.GrpcService{ + grpcService(g.xdsServerClusterName, "", timeout.DefaultSetting()), + }, + }, + }, + } +} diff --git a/internal/envoy/v3/fixture_test.go b/internal/envoy/v3/fixture_test.go new file mode 100644 index 00000000000..91b4a57faf6 --- /dev/null +++ b/internal/envoy/v3/fixture_test.go @@ -0,0 +1,49 @@ +// Copyright Project Contour Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v3 + +import envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + +var defaultConfigSource = &envoy_core_v3.ConfigSource{ + ResourceApiVersion: envoy_core_v3.ApiVersion_V3, + ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{ + ApiConfigSource: &envoy_core_v3.ApiConfigSource{ + ApiType: envoy_core_v3.ApiConfigSource_GRPC, + TransportApiVersion: envoy_core_v3.ApiVersion_V3, + GrpcServices: []*envoy_core_v3.GrpcService{ + { + TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{ + EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{ + ClusterName: "contour", + Authority: "contour", + }, + }, + }, + }, + }, + }, +} + +// // httpConnectionManager creates a new HTTP Connection Manager filter +// // for the supplied route, access log, and client request timeout. +// func httpConnectionManager(routename string, accesslogger []*accesslog_v3.AccessLog, requestTimeout time.Duration) *envoy_listener_v3.Filter { +// cg := NewConfigGenerator() +// return cg.HTTPConnectionManagerBuilder(). +// RouteConfigName(routename). +// MetricsPrefix(routename). +// AccessLoggers(accesslogger). +// RequestTimeout(timeout.DurationSetting(requestTimeout)). +// DefaultFilters(). +// Get() +// } diff --git a/internal/envoy/v3/listener.go b/internal/envoy/v3/listener.go index e794ed39d18..d928b56e2ed 100644 --- a/internal/envoy/v3/listener.go +++ b/internal/envoy/v3/listener.go @@ -149,6 +149,7 @@ func Listener(name, address string, port int, lf []*envoy_listener_v3.ListenerFi } type httpConnectionManagerBuilder struct { + cg *ConfigGenerator routeConfigName string metricsPrefix string accessLoggers []*accesslog.AccessLog @@ -467,7 +468,7 @@ func (b *httpConnectionManagerBuilder) Get() *envoy_listener_v3.Filter { RouteSpecifier: &http.HttpConnectionManager_Rds{ Rds: &http.Rds{ RouteConfigName: b.routeConfigName, - ConfigSource: ConfigSource("contour"), + ConfigSource: b.cg.ConfigSource(), }, }, Tracing: b.tracingConfig, @@ -549,22 +550,12 @@ func (b *httpConnectionManagerBuilder) Get() *envoy_listener_v3.Filter { } } -// HTTPConnectionManager creates a new HTTP Connection Manager filter -// for the supplied route, access log, and client request timeout. -func HTTPConnectionManager(routename string, accesslogger []*accesslog.AccessLog, requestTimeout time.Duration) *envoy_listener_v3.Filter { - return HTTPConnectionManagerBuilder(). - RouteConfigName(routename). - MetricsPrefix(routename). - AccessLoggers(accesslogger). - RequestTimeout(timeout.DurationSetting(requestTimeout)). - DefaultFilters(). - Get() -} - // HTTPConnectionManagerBuilder creates a new HTTP connection manager builder. // nolint:revive -func HTTPConnectionManagerBuilder() *httpConnectionManagerBuilder { - return &httpConnectionManagerBuilder{} +func (g *ConfigGenerator) HTTPConnectionManagerBuilder() *httpConnectionManagerBuilder { + return &httpConnectionManagerBuilder{ + cg: g, + } } // TCPProxy creates a new TCPProxy filter. @@ -764,7 +755,7 @@ end func FilterExternalAuthz(externalAuthorization *dag.ExternalAuthorization) *http.HttpFilter { authConfig := envoy_config_filter_http_ext_authz_v3.ExtAuthz{ Services: &envoy_config_filter_http_ext_authz_v3.ExtAuthz_GrpcService{ - GrpcService: GrpcService(externalAuthorization.AuthorizationService.Name, externalAuthorization.AuthorizationService.SNI, externalAuthorization.AuthorizationResponseTimeout), + GrpcService: grpcService(externalAuthorization.AuthorizationService.Name, externalAuthorization.AuthorizationService.SNI, externalAuthorization.AuthorizationResponseTimeout), }, // Pretty sure we always want this. Why have an // external auth service if it is not going to affect @@ -898,8 +889,8 @@ func FilterChainTLSFallback(downstream *envoy_tls_v3.DownstreamTlsContext, filte return fc } -// GRPCService returns a envoy_core_v3.GrpcService for the given parameters. -func GrpcService(clusterName, sni string, timeout timeout.Setting) *envoy_core_v3.GrpcService { +// GRPCService returns a envoy_core_v3.grpcService for the given parameters. +func grpcService(clusterName, sni string, timeout timeout.Setting) *envoy_core_v3.GrpcService { authority := strings.ReplaceAll(clusterName, "/", ".") if sni != "" { authority = sni diff --git a/internal/envoy/v3/listener_test.go b/internal/envoy/v3/listener_test.go index faf728f763d..95ae10e3d55 100644 --- a/internal/envoy/v3/listener_test.go +++ b/internal/envoy/v3/listener_test.go @@ -79,6 +79,12 @@ func TestProtoNamesForVersions(t *testing.T) { } func TestListener(t *testing.T) { + filter := &envoy_listener_v3.Filter{ + Name: wellknown.HTTPConnectionManager, + ConfigType: &envoy_listener_v3.Filter_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(&http.HttpConnectionManager{}), + }, + } tests := map[string]struct { name, address string port int @@ -91,13 +97,13 @@ func TestListener(t *testing.T) { address: "0.0.0.0", port: 9000, f: []*envoy_listener_v3.Filter{ - HTTPConnectionManager("http", FileAccessLogEnvoy("/dev/null", "", nil, v1alpha1.LogLevelInfo), 0), + filter, }, want: &envoy_listener_v3.Listener{ Name: "http", Address: SocketAddress("0.0.0.0", 9000), FilterChains: FilterChains( - HTTPConnectionManager("http", FileAccessLogEnvoy("/dev/null", "", nil, v1alpha1.LogLevelInfo), 0), + filter, ), SocketOptions: TCPKeepaliveSocketOptions(), }, @@ -110,7 +116,7 @@ func TestListener(t *testing.T) { ProxyProtocol(), }, f: []*envoy_listener_v3.Filter{ - HTTPConnectionManager("http-proxy", FileAccessLogEnvoy("/dev/null", "", nil, v1alpha1.LogLevelInfo), 0), + filter, }, want: &envoy_listener_v3.Listener{ Name: "http-proxy", @@ -119,7 +125,7 @@ func TestListener(t *testing.T) { ProxyProtocol(), ), FilterChains: FilterChains( - HTTPConnectionManager("http-proxy", FileAccessLogEnvoy("/dev/null", "", nil, v1alpha1.LogLevelInfo), 0), + filter, ), SocketOptions: TCPKeepaliveSocketOptions(), }, @@ -421,12 +427,14 @@ func TestDownstreamTLSContext(t *testing.T) { }, } + cg := NewConfigGenerator() + tests := map[string]struct { got *envoy_tls_v3.DownstreamTlsContext want *envoy_tls_v3.DownstreamTlsContext }{ "TLS context without client authentication": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, nil, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, nil, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -436,7 +444,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "TLS context with client authentication": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContext, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContext, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -448,7 +456,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "Downstream validation shall not support subjectName validation": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextWithSubjectName, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextWithSubjectName, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -460,7 +468,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "skip client cert validation": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextSkipClientCertValidation, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextSkipClientCertValidation, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -472,7 +480,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "skip client cert validation with ca": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextSkipClientCertValidationWithCA, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextSkipClientCertValidationWithCA, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -484,7 +492,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "optional client cert validation with ca": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextOptionalClientCertValidationWithCA, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextOptionalClientCertValidationWithCA, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -496,7 +504,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "Downstream validation with CRL check": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextWithCRLCheck, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextWithCRLCheck, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -508,7 +516,7 @@ func TestDownstreamTLSContext(t *testing.T) { }, }, "Downstream validation with CRL check but only for leaf-certificate": { - DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextWithCRLCheckOnlyLeaf, "h2", "http/1.1"), + cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, cipherSuites, peerValidationContextWithCRLCheckOnlyLeaf, "h2", "http/1.1"), &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: tlsParams, @@ -1362,7 +1370,8 @@ func TestHTTPConnectionManager(t *testing.T) { } for name, tc := range tests { t.Run(name, func(t *testing.T) { - got := HTTPConnectionManagerBuilder(). + cg := NewConfigGenerator() + got := cg.HTTPConnectionManagerBuilder(). RouteConfigName(tc.routename). MetricsPrefix(tc.routename). AccessLoggers(tc.accesslogger). @@ -1621,11 +1630,12 @@ func TestFilterChainTLS_Match(t *testing.T) { // TestBuilderValidation tests that validation checks that // DefaultFilters adds the required HTTP connection manager filters. func TestBuilderValidation(t *testing.T) { + cg := NewConfigGenerator() - assert.Error(t, HTTPConnectionManagerBuilder().Validate(), + assert.Error(t, cg.HTTPConnectionManagerBuilder().Validate(), "ConnectionManager with no filters should not pass validation") - assert.Error(t, HTTPConnectionManagerBuilder().AddFilter(&http.HttpFilter{ + assert.Error(t, cg.HTTPConnectionManagerBuilder().AddFilter(&http.HttpFilter{ Name: "foo", ConfigType: &http.HttpFilter_TypedConfig{ TypedConfig: &anypb.Any{ @@ -1635,10 +1645,10 @@ func TestBuilderValidation(t *testing.T) { }).Validate(), "ConnectionManager with only non-router filter should not pass validation") - assert.NoError(t, HTTPConnectionManagerBuilder().DefaultFilters().Validate(), + assert.NoError(t, cg.HTTPConnectionManagerBuilder().DefaultFilters().Validate(), "ConnectionManager with default filters failed validation") - badBuilder := HTTPConnectionManagerBuilder().DefaultFilters() + badBuilder := cg.HTTPConnectionManagerBuilder().DefaultFilters() badBuilder.filters = append(badBuilder.filters, &http.HttpFilter{ Name: "foo", ConfigType: &http.HttpFilter_TypedConfig{ @@ -1651,6 +1661,7 @@ func TestBuilderValidation(t *testing.T) { } func TestAddFilter(t *testing.T) { + cg := NewConfigGenerator() tests := map[string]struct { builder *httpConnectionManagerBuilder @@ -1658,12 +1669,12 @@ func TestAddFilter(t *testing.T) { want []*http.HttpFilter }{ "Nil add to empty builder": { - builder: HTTPConnectionManagerBuilder(), + builder: cg.HTTPConnectionManagerBuilder(), add: nil, want: nil, }, "Add a single router filter to empty builder": { - builder: HTTPConnectionManagerBuilder(), + builder: cg.HTTPConnectionManagerBuilder(), add: &http.HttpFilter{ Name: "router", ConfigType: &http.HttpFilter_TypedConfig{ @@ -1680,7 +1691,7 @@ func TestAddFilter(t *testing.T) { }, }, "Add a single non-router filter to empty builder": { - builder: HTTPConnectionManagerBuilder(), + builder: cg.HTTPConnectionManagerBuilder(), add: &http.HttpFilter{ Name: "grpcweb", ConfigType: &http.HttpFilter_TypedConfig{ @@ -1697,7 +1708,7 @@ func TestAddFilter(t *testing.T) { }, }, "Add a filter to a builder with a router": { - builder: HTTPConnectionManagerBuilder().AddFilter(&http.HttpFilter{ + builder: cg.HTTPConnectionManagerBuilder().AddFilter(&http.HttpFilter{ Name: "router", ConfigType: &http.HttpFilter_TypedConfig{ TypedConfig: protobuf.MustMarshalAny(&envoy_router_v3.Router{}), @@ -1725,7 +1736,7 @@ func TestAddFilter(t *testing.T) { }, }, "Add to the default filters": { - builder: HTTPConnectionManagerBuilder().DefaultFilters(), + builder: cg.HTTPConnectionManagerBuilder().DefaultFilters(), add: FilterExternalAuthz(&dag.ExternalAuthorization{ AuthorizationService: &dag.ExtensionCluster{ Name: "test", @@ -1823,7 +1834,7 @@ func TestAddFilter(t *testing.T) { }, }, "Add to the default filters with AuthorizationServerBufferSettings": { - builder: HTTPConnectionManagerBuilder().DefaultFilters(), + builder: cg.HTTPConnectionManagerBuilder().DefaultFilters(), add: FilterExternalAuthz(&dag.ExternalAuthorization{ AuthorizationService: &dag.ExtensionCluster{ Name: "test", @@ -1959,7 +1970,7 @@ func TestAddFilter(t *testing.T) { } assert.Panics(t, func() { - HTTPConnectionManagerBuilder().DefaultFilters().AddFilter(&http.HttpFilter{ + cg.HTTPConnectionManagerBuilder().DefaultFilters().AddFilter(&http.HttpFilter{ Name: "router", ConfigType: &http.HttpFilter_TypedConfig{ TypedConfig: protobuf.MustMarshalAny(&envoy_router_v3.Router{}), diff --git a/internal/envoy/v3/ratelimit.go b/internal/envoy/v3/ratelimit.go index 1aebd499570..25b848618b8 100644 --- a/internal/envoy/v3/ratelimit.go +++ b/internal/envoy/v3/ratelimit.go @@ -147,7 +147,7 @@ func GlobalRateLimitFilter(config *GlobalRateLimitConfig) *http.HttpFilter { Timeout: envoy.Timeout(config.Timeout), FailureModeDeny: !config.FailOpen, RateLimitService: &ratelimit_config_v3.RateLimitServiceConfig{ - GrpcService: GrpcService(dag.ExtensionClusterName(config.ExtensionService), config.SNI, timeout.DefaultSetting()), + GrpcService: grpcService(dag.ExtensionClusterName(config.ExtensionService), config.SNI, timeout.DefaultSetting()), TransportApiVersion: envoy_core_v3.ApiVersion_V3, }, EnableXRatelimitHeaders: enableXRateLimitHeaders(config.EnableXRateLimitHeaders), diff --git a/internal/envoy/v3/secret.go b/internal/envoy/v3/secret.go index 5670e6fe2f8..2712f6eedf6 100644 --- a/internal/envoy/v3/secret.go +++ b/internal/envoy/v3/secret.go @@ -40,3 +40,10 @@ func Secret(s *dag.Secret) *envoy_tls_v3.Secret { }, } } + +func (g *ConfigGenerator) sdsSecretConfig(secretName string) *envoy_tls_v3.SdsSecretConfig { + return &envoy_tls_v3.SdsSecretConfig{ + Name: secretName, + SdsConfig: g.ConfigSource(), + } +} diff --git a/internal/envoy/v3/socket_test.go b/internal/envoy/v3/socket_test.go index 68dd8e44ed6..3fa62c1b8ab 100644 --- a/internal/envoy/v3/socket_test.go +++ b/internal/envoy/v3/socket_test.go @@ -25,27 +25,16 @@ import ( ) func TestUpstreamTLSTransportSocket(t *testing.T) { - tests := map[string]struct { - ctxt *envoy_tls_v3.UpstreamTlsContext - want *envoy_core_v3.TransportSocket - }{ - "h2": { - ctxt: UpstreamTLSContext(nil, "", nil, "h2"), - want: &envoy_core_v3.TransportSocket{ - Name: "envoy.transport_sockets.tls", - ConfigType: &envoy_core_v3.TransportSocket_TypedConfig{ - TypedConfig: protobuf.MustMarshalAny(UpstreamTLSContext(nil, "", nil, "h2")), - }, - }, + cg := NewConfigGenerator() + context := cg.UpstreamTLSContext(nil, "", nil, "h2") + want := &envoy_core_v3.TransportSocket{ + Name: "envoy.transport_sockets.tls", + ConfigType: &envoy_core_v3.TransportSocket_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(context), }, } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - got := UpstreamTLSTransportSocket(tc.ctxt) - protobuf.ExpectEqual(t, tc.want, got) - }) - } + got := UpstreamTLSTransportSocket(context) + protobuf.ExpectEqual(t, want, got) } func TestDownstreamTLSTransportSocket(t *testing.T) { @@ -61,25 +50,14 @@ func TestDownstreamTLSTransportSocket(t *testing.T) { }, }, } - tests := map[string]struct { - ctxt *envoy_tls_v3.DownstreamTlsContext - want *envoy_core_v3.TransportSocket - }{ - "default/tls": { - ctxt: DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, nil, nil, "client-subject-name", "h2", "http/1.1"), - want: &envoy_core_v3.TransportSocket{ - Name: "envoy.transport_sockets.tls", - ConfigType: &envoy_core_v3.TransportSocket_TypedConfig{ - TypedConfig: protobuf.MustMarshalAny(DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, nil, nil, "client-subject-name", "h2", "http/1.1")), - }, - }, + cg := NewConfigGenerator() + context := cg.DownstreamTLSContext(serverSecret, envoy_tls_v3.TlsParameters_TLSv1_2, nil, nil, "client-subject-name", "h2", "http/1.1") + want := &envoy_core_v3.TransportSocket{ + Name: "envoy.transport_sockets.tls", + ConfigType: &envoy_core_v3.TransportSocket_TypedConfig{ + TypedConfig: protobuf.MustMarshalAny(context), }, } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - got := DownstreamTLSTransportSocket(tc.ctxt) - protobuf.ExpectEqual(t, tc.want, got) - }) - } + got := DownstreamTLSTransportSocket(context) + protobuf.ExpectEqual(t, want, got) } diff --git a/internal/envoy/v3/stats.go b/internal/envoy/v3/stats.go index 179500e9c1d..9cd6fa6257f 100644 --- a/internal/envoy/v3/stats.go +++ b/internal/envoy/v3/stats.go @@ -34,7 +34,7 @@ const metricsCaBundleSDSName = "metrics-ca-certificate" // The listeners are configured to serve: // - prometheus metrics on /stats (either over HTTP or HTTPS) // - readiness probe on /ready (always over HTTP) -func StatsListeners(metrics contour_api_v1alpha1.MetricsConfig, health contour_api_v1alpha1.HealthConfig) []*envoy_listener_v3.Listener { +func (g *ConfigGenerator) StatsListeners(metrics contour_api_v1alpha1.MetricsConfig, health contour_api_v1alpha1.HealthConfig) []*envoy_listener_v3.Listener { var listeners []*envoy_listener_v3.Listener switch { @@ -46,7 +46,7 @@ func StatsListeners(metrics contour_api_v1alpha1.MetricsConfig, health contour_a SocketOptions: TCPKeepaliveSocketOptions(), FilterChains: filterChain("stats", DownstreamTLSTransportSocket( - downstreamTLSContext(metrics.TLS.CAFile != "")), routeForAdminInterface("/stats")), + g.statsDownstreamTLSContext(metrics.TLS.CAFile != "")), routeForAdminInterface("/stats")), }, { Name: "health", Address: SocketAddress(health.Address, health.Port), @@ -162,28 +162,24 @@ func routeForAdminInterface(prefixes ...string) *http.HttpConnectionManager_Rout return config } -// downstreamTLSContext creates TLS context when HTTPS is used to protect Envoy stats endpoint. +// statsDownstreamTLSContext creates TLS context when HTTPS is used to protect Envoy stats endpoint. // Certificates and key are hardcoded to the SDS secrets which are returned by StatsSecrets. -func downstreamTLSContext(clientValidation bool) *envoy_tls_v3.DownstreamTlsContext { +func (g *ConfigGenerator) statsDownstreamTLSContext(clientValidation bool) *envoy_tls_v3.DownstreamTlsContext { context := &envoy_tls_v3.DownstreamTlsContext{ CommonTlsContext: &envoy_tls_v3.CommonTlsContext{ TlsParams: &envoy_tls_v3.TlsParameters{ TlsMinimumProtocolVersion: envoy_tls_v3.TlsParameters_TLSv1_3, TlsMaximumProtocolVersion: envoy_tls_v3.TlsParameters_TLSv1_3, }, - TlsCertificateSdsSecretConfigs: []*envoy_tls_v3.SdsSecretConfig{{ - Name: metricsServerCertSDSName, - SdsConfig: ConfigSource("contour"), - }}, + TlsCertificateSdsSecretConfigs: []*envoy_tls_v3.SdsSecretConfig{ + g.sdsSecretConfig(metricsServerCertSDSName), + }, }, } if clientValidation { context.CommonTlsContext.ValidationContextType = &envoy_tls_v3.CommonTlsContext_ValidationContextSdsSecretConfig{ - ValidationContextSdsSecretConfig: &envoy_tls_v3.SdsSecretConfig{ - Name: metricsCaBundleSDSName, - SdsConfig: ConfigSource("contour"), - }, + ValidationContextSdsSecretConfig: g.sdsSecretConfig(metricsCaBundleSDSName), } context.RequireClientCertificate = wrapperspb.Bool(true) } diff --git a/internal/envoy/v3/stats_test.go b/internal/envoy/v3/stats_test.go index 2ab95c1e42d..2b138d170f1 100644 --- a/internal/envoy/v3/stats_test.go +++ b/internal/envoy/v3/stats_test.go @@ -69,7 +69,8 @@ func TestStatsListeners(t *testing.T) { t.Helper() t.Run(name, func(t *testing.T) { t.Helper() - got := StatsListeners(tc.metrics, tc.health) + cg := NewConfigGenerator() + got := cg.StatsListeners(tc.metrics, tc.health) protobuf.ExpectEqual(t, tc.want, got) }) } @@ -158,7 +159,7 @@ func TestStatsListeners(t *testing.T) { }, TlsCertificateSdsSecretConfigs: []*envoy_tls_v3.SdsSecretConfig{{ Name: "metrics-tls-certificate", - SdsConfig: ConfigSource("contour"), + SdsConfig: defaultConfigSource, }}, }, }, @@ -247,12 +248,12 @@ func TestStatsListeners(t *testing.T) { }, TlsCertificateSdsSecretConfigs: []*envoy_tls_v3.SdsSecretConfig{{ Name: "metrics-tls-certificate", - SdsConfig: ConfigSource("contour"), + SdsConfig: defaultConfigSource, }}, ValidationContextType: &envoy_tls_v3.CommonTlsContext_ValidationContextSdsSecretConfig{ ValidationContextSdsSecretConfig: &envoy_tls_v3.SdsSecretConfig{ Name: "metrics-ca-certificate", - SdsConfig: ConfigSource("contour"), + SdsConfig: defaultConfigSource, }, }, }, diff --git a/internal/envoy/v3/tracing.go b/internal/envoy/v3/tracing.go index ffd44084968..15effaf267c 100644 --- a/internal/envoy/v3/tracing.go +++ b/internal/envoy/v3/tracing.go @@ -49,7 +49,7 @@ func TracingConfig(tracing *EnvoyTracingConfig) *http.HttpConnectionManager_Trac Name: "envoy.tracers.opentelemetry", ConfigType: &envoy_config_trace_v3.Tracing_Http_TypedConfig{ TypedConfig: protobuf.MustMarshalAny(&envoy_config_trace_v3.OpenTelemetryConfig{ - GrpcService: GrpcService(dag.ExtensionClusterName(tracing.ExtensionService), tracing.SNI, tracing.Timeout), + GrpcService: grpcService(dag.ExtensionClusterName(tracing.ExtensionService), tracing.SNI, tracing.Timeout), ServiceName: tracing.ServiceName, }), }, diff --git a/internal/featuretests/v3/backendclientauth_test.go b/internal/featuretests/v3/backendclientauth_test.go index d3b32cc4382..f008aa3b6d5 100644 --- a/internal/featuretests/v3/backendclientauth_test.go +++ b/internal/featuretests/v3/backendclientauth_test.go @@ -201,7 +201,7 @@ func TestBackendClientAuthenticationWithExtensionService(t *testing.T) { rh.OnAdd(ext) tlsSocket := envoy_v3.UpstreamTLSTransportSocket( - envoy_v3.UpstreamTLSContext( + envoy_v3.NewConfigGenerator().UpstreamTLSContext( &dag.PeerValidationContext{ CACertificate: &dag.Secret{Object: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ diff --git a/internal/featuretests/v3/cluster_test.go b/internal/featuretests/v3/cluster_test.go index 0c9c3dd0ae5..9f43b147e77 100644 --- a/internal/featuretests/v3/cluster_test.go +++ b/internal/featuretests/v3/cluster_test.go @@ -415,7 +415,7 @@ func TestClusterCircuitbreakerAnnotations(t *testing.T) { AltStatName: "default_kuard_8080", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: "default/kuard", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -448,7 +448,7 @@ func TestClusterCircuitbreakerAnnotations(t *testing.T) { AltStatName: "default_kuard_8080", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: "default/kuard", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -560,7 +560,7 @@ func TestClusterLoadBalancerStrategyPerRoute(t *testing.T) { AltStatName: "default_kuard_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: "default/kuard", }, LbPolicy: envoy_cluster_v3.Cluster_RANDOM, @@ -570,7 +570,7 @@ func TestClusterLoadBalancerStrategyPerRoute(t *testing.T) { AltStatName: "default_kuard_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: "default/kuard", }, LbPolicy: envoy_cluster_v3.Cluster_LEAST_REQUEST, diff --git a/internal/featuretests/v3/envoy.go b/internal/featuretests/v3/envoy.go index b14cbe7e48e..83c8c9dcca2 100644 --- a/internal/featuretests/v3/envoy.go +++ b/internal/featuretests/v3/envoy.go @@ -32,6 +32,7 @@ import ( envoy_tcp_proxy_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" envoy_extensions_upstream_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" + envoy_type "github.com/envoyproxy/go-control-plane/envoy/type/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" contour_api_v1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" "github.com/projectcontour/contour/internal/dag" @@ -54,7 +55,11 @@ func DefaultCluster(clusters ...*envoy_cluster_v3.Cluster) *envoy_cluster_v3.Clu defaults := &envoy_cluster_v3.Cluster{ ConnectTimeout: durationpb.New(2 * time.Second), LbPolicy: envoy_cluster_v3.Cluster_ROUND_ROBIN, - CommonLbConfig: envoy_v3.ClusterCommonLBConfig(), + CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ + HealthyPanicThreshold: &envoy_type.Percent{ // Disable HealthyPanicThreshold + Value: 0, + }, + }, } for _, c := range clusters { @@ -169,7 +174,7 @@ func cluster(name, servicename, statName string) *envoy_cluster_v3.Cluster { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: statName, EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: envoy_v3.NewConfigGenerator().ConfigSource(), ServiceName: servicename, }, }) @@ -182,7 +187,7 @@ func tlsCluster(c *envoy_cluster_v3.Cluster, ca []byte, subjectName string, sni } c.TransportSocket = envoy_v3.UpstreamTLSTransportSocket( - envoy_v3.UpstreamTLSContext( + envoy_v3.NewConfigGenerator().UpstreamTLSContext( &dag.PeerValidationContext{ CACertificate: &dag.Secret{Object: &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -208,7 +213,7 @@ func tlsClusterWithoutValidation(c *envoy_cluster_v3.Cluster, sni string, client } c.TransportSocket = envoy_v3.UpstreamTLSTransportSocket( - envoy_v3.UpstreamTLSContext( + envoy_v3.NewConfigGenerator().UpstreamTLSContext( nil, sni, secret, @@ -417,7 +422,7 @@ func appendFilterChains(chains ...*envoy_listener_v3.FilterChain) []*envoy_liste func filterchaintls(domain string, secret *v1.Secret, filter *envoy_listener_v3.Filter, peerValidationContext *dag.PeerValidationContext, alpn ...string) *envoy_listener_v3.FilterChain { return envoy_v3.FilterChainTLS( domain, - envoy_v3.DownstreamTLSContext( + envoy_v3.NewConfigGenerator().DownstreamTLSContext( &dag.Secret{Object: secret}, envoy_tls_v3.TlsParameters_TLSv1_2, nil, @@ -429,15 +434,16 @@ func filterchaintls(domain string, secret *v1.Secret, filter *envoy_listener_v3. // filterchaintlsfallback returns a FilterChain for the given TLS fallback certificate. func filterchaintlsfallback(fallbackSecret *v1.Secret, peerValidationContext *dag.PeerValidationContext, alpn ...string) *envoy_listener_v3.FilterChain { + cg := envoy_v3.NewConfigGenerator() return envoy_v3.FilterChainTLSFallback( - envoy_v3.DownstreamTLSContext( + cg.DownstreamTLSContext( &dag.Secret{Object: fallbackSecret}, envoy_tls_v3.TlsParameters_TLSv1_2, nil, peerValidationContext, alpn...), envoy_v3.Filters( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). DefaultFilters(). RouteConfigName(xdscache_v3.ENVOY_FALLBACK_ROUTECONFIG). MetricsPrefix(xdscache_v3.ENVOY_HTTPS_LISTENER). @@ -448,7 +454,7 @@ func filterchaintlsfallback(fallbackSecret *v1.Secret, peerValidationContext *da } func httpsFilterFor(vhost string) *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). DefaultFilters(). RouteConfigName(path.Join("https", vhost)). @@ -458,7 +464,7 @@ func httpsFilterFor(vhost string) *envoy_listener_v3.Filter { } func httpFilterForGateway() *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). DefaultFilters(). RouteConfigName("http-80"). AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)). @@ -467,7 +473,7 @@ func httpFilterForGateway() *envoy_listener_v3.Filter { } func httpsFilterForGateway(listener, vhost string) *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). DefaultFilters(). RouteConfigName(path.Join(listener, vhost)). @@ -480,7 +486,7 @@ func httpsFilterForGateway(listener, vhost string) *envoy_listener_v3.Filter { // httpsFilterWithXfccFor does the same as httpsFilterFor but enable // client certs details forwarding func httpsFilterWithXfccFor(vhost string, d *dag.ClientCertificateDetails) *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). DefaultFilters(). RouteConfigName(path.Join("https", vhost)). @@ -497,7 +503,7 @@ func authzFilterFor( vhost string, authz *envoy_config_filter_http_ext_authz_v3.ExtAuthz, ) *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). DefaultFilters(). AddFilter(&http.HttpFilter{ @@ -516,7 +522,7 @@ func jwtAuthnFilterFor( vhost string, jwt *envoy_jwt_v3.JwtAuthentication, ) *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). DefaultFilters(). AddFilter(&http.HttpFilter{ @@ -578,7 +584,7 @@ func tcpproxyWeighted(statPrefix string, clusters ...clusterWeight) *envoy_liste func statsListener() *envoy_listener_v3.Listener { // Single listener with metrics and health endpoints. - listeners := envoy_v3.StatsListeners( + listeners := envoy_v3.NewConfigGenerator().StatsListeners( contour_api_v1alpha1.MetricsConfig{Address: "0.0.0.0", Port: 8002}, contour_api_v1alpha1.HealthConfig{Address: "0.0.0.0", Port: 8002}) return listeners[0] @@ -593,7 +599,12 @@ func defaultHTTPListener() *envoy_listener_v3.Listener { Name: "ingress_http", Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManager("ingress_http", envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo), 0), + envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). + RouteConfigName("ingress_http"). + MetricsPrefix("ingress_http"). + AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)). + DefaultFilters(). + Get(), ), SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), } diff --git a/internal/featuretests/v3/externalname_test.go b/internal/featuretests/v3/externalname_test.go index 1d3b1c2b872..a0b33ee2727 100644 --- a/internal/featuretests/v3/externalname_test.go +++ b/internal/featuretests/v3/externalname_test.go @@ -42,6 +42,8 @@ func TestExternalNameService(t *testing.T) { rh, c, done := setup(t, enableExternalNameService(t)) defer done() + cg := envoy_v3.NewConfigGenerator() + s1 := fixture.NewService("kuard"). WithSpec(v1.ServiceSpec{ Ports: []v1.ServicePort{{ @@ -219,7 +221,7 @@ func TestExternalNameService(t *testing.T) { }, &envoy_cluster_v3.Cluster{ TransportSocket: envoy_v3.UpstreamTLSTransportSocket( - envoy_v3.UpstreamTLSContext(nil, "external.address", nil, "h2"), + cg.UpstreamTLSContext(nil, "external.address", nil, "h2"), ), }, ), @@ -271,7 +273,7 @@ func TestExternalNameService(t *testing.T) { externalNameCluster("default/kuard/80/f9439c1de8", "default/kuard", "default_kuard_80", "foo.io", 80), &envoy_cluster_v3.Cluster{ TransportSocket: envoy_v3.UpstreamTLSTransportSocket( - envoy_v3.UpstreamTLSContext(nil, "external.address", nil), + cg.UpstreamTLSContext(nil, "external.address", nil), ), }, ), @@ -312,7 +314,7 @@ func TestExternalNameService(t *testing.T) { externalNameCluster("default/kuard/80/7d449598f5", "default/kuard", "default_kuard_80", "foo.io", 80), &envoy_cluster_v3.Cluster{ TransportSocket: envoy_v3.UpstreamTLSTransportSocket( - envoy_v3.UpstreamTLSContext(nil, "foo.io", nil), + cg.UpstreamTLSContext(nil, "foo.io", nil), ), }, ), diff --git a/internal/featuretests/v3/featuretests.go b/internal/featuretests/v3/featuretests.go index 8cd2fbc8f95..a676c6c499e 100644 --- a/internal/featuretests/v3/featuretests.go +++ b/internal/featuretests/v3/featuretests.go @@ -36,6 +36,7 @@ import ( "github.com/projectcontour/contour/apis/projectcontour/v1alpha1" "github.com/projectcontour/contour/internal/contour" "github.com/projectcontour/contour/internal/dag" + envoy_v3 "github.com/projectcontour/contour/internal/envoy/v3" "github.com/projectcontour/contour/internal/fixture" "github.com/projectcontour/contour/internal/k8s" "github.com/projectcontour/contour/internal/metrics" @@ -89,16 +90,18 @@ func setup(t *testing.T, opts ...any) (ResourceEventHandlerWrapper, *Contour, fu } } + cg := envoy_v3.NewConfigGenerator() resources := []xdscache.ResourceCache{ xdscache_v3.NewListenerCache( conf, v1alpha1.MetricsConfig{Address: "0.0.0.0", Port: 8002}, v1alpha1.HealthConfig{Address: "0.0.0.0", Port: 8002}, 0, + cg, ), &xdscache_v3.SecretCache{}, &xdscache_v3.RouteCache{}, - &xdscache_v3.ClusterCache{}, + xdscache_v3.NewClusterCache(cg), et, } @@ -197,6 +200,7 @@ func setup(t *testing.T, opts ...any) (ResourceEventHandlerWrapper, *Contour, fu T: t, ClientConn: cc, statusUpdateCache: statusUpdateCacher, + cg: cg, }, func() { // close client connection cc.Close() @@ -392,6 +396,7 @@ type Contour struct { *testing.T statusUpdateCache *k8s.StatusUpdateCacher + cg *envoy_v3.ConfigGenerator } // Status returns a StatusResult object that can be used to assert diff --git a/internal/featuretests/v3/global_authorization_test.go b/internal/featuretests/v3/global_authorization_test.go index c600464a8de..083725a9e6c 100644 --- a/internal/featuretests/v3/global_authorization_test.go +++ b/internal/featuretests/v3/global_authorization_test.go @@ -67,7 +67,7 @@ func globalExternalAuthorizationFilterExists(t *testing.T, rh ResourceEventHandl // replace the default filter chains with an HCM that includes the global // extAuthz filter. - httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM(c)) c.Request(listenerType).Equals(&envoy_discovery_v3.DiscoveryResponse{ TypeUrl: listenerType, @@ -105,7 +105,7 @@ func globalExternalAuthorizationFilterExistsTLS(t *testing.T, rh ResourceEventHa // replace the default filter chains with an HCM that includes the global // extAuthz filter. - httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM(c)) httpsListener := &envoy_listener_v3.Listener{ Name: "ingress_https", @@ -179,7 +179,7 @@ func globalExternalAuthorizationWithTLSGlobalAuthDisabled(t *testing.T, rh Resou // replace the default filter chains with an HCM that includes the global // extAuthz filter. - httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM(c)) httpsListener := &envoy_listener_v3.Listener{ Name: "ingress_https", @@ -243,7 +243,7 @@ func globalExternalAuthorizationWithMergedAuthPolicy(t *testing.T, rh ResourceEv // replace the default filter chains with an HCM that includes the global // extAuthz filter. - httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM(c)) c.Request(listenerType).Equals(&envoy_discovery_v3.DiscoveryResponse{ TypeUrl: listenerType, @@ -317,7 +317,7 @@ func globalExternalAuthorizationWithMergedAuthPolicyTLS(t *testing.T, rh Resourc // replace the default filter chains with an HCM that includes the global // extAuthz filter. - httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM(c)) httpsListener := &envoy_listener_v3.Listener{ Name: "ingress_https", @@ -438,7 +438,7 @@ func globalExternalAuthorizationWithTLSAuthOverride(t *testing.T, rh ResourceEve // replace the default filter chains with an HCM that includes the global // extAuthz filter. - httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM()) + httpListener.FilterChains = envoy_v3.FilterChains(getGlobalExtAuthHCM(c)) httpsListener := &envoy_listener_v3.Listener{ Name: "ingress_https", @@ -582,8 +582,8 @@ func TestGlobalAuthorization(t *testing.T) { } // getGlobalExtAuthHCM returns a HTTP Connection Manager with Global External Authorization configured. -func getGlobalExtAuthHCM() *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). +func getGlobalExtAuthHCM(c *Contour) *envoy_listener_v3.Filter { + return c.cg.HTTPConnectionManagerBuilder(). RouteConfigName("ingress_http"). MetricsPrefix("ingress_http"). AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)). diff --git a/internal/featuretests/v3/globalratelimit_test.go b/internal/featuretests/v3/globalratelimit_test.go index 7be0de28dd6..45437e5cf5d 100644 --- a/internal/featuretests/v3/globalratelimit_test.go +++ b/internal/featuretests/v3/globalratelimit_test.go @@ -65,7 +65,7 @@ func globalRateLimitFilterExists(t *testing.T, rh ResourceEventHandlerWrapper, c // replace the default filter chains with an HCM that includes the global // rate limit filter. - hcm := envoy_v3.HTTPConnectionManagerBuilder(). + hcm := c.cg.HTTPConnectionManagerBuilder(). RouteConfigName("ingress_http"). MetricsPrefix("ingress_http"). AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)). diff --git a/internal/featuretests/v3/jwtverification_test.go b/internal/featuretests/v3/jwtverification_test.go index bc6ee7a0814..04fcd562724 100644 --- a/internal/featuretests/v3/jwtverification_test.go +++ b/internal/featuretests/v3/jwtverification_test.go @@ -175,10 +175,8 @@ func TestJWTVerification(t *testing.T) { TypeUrl: clusterType, Resources: resources(t, &envoy_cluster_v3.Cluster{ - Name: "dnsname/https/jwt.example.com", - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ - Type: envoy_cluster_v3.Cluster_STRICT_DNS, - }, + Name: "dnsname/https/jwt.example.com", + ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type_v3.Percent{Value: 0}, }, @@ -660,10 +658,8 @@ func TestJWTVerification(t *testing.T) { TypeUrl: clusterType, Resources: resources(t, &envoy_cluster_v3.Cluster{ - Name: "dnsname/https/jwt.example.com", - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ - Type: envoy_cluster_v3.Cluster_STRICT_DNS, - }, + Name: "dnsname/https/jwt.example.com", + ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type_v3.Percent{Value: 0}, }, @@ -814,10 +810,8 @@ func TestJWTVerification(t *testing.T) { TypeUrl: clusterType, Resources: resources(t, &envoy_cluster_v3.Cluster{ - Name: "dnsname/https/jwt.example.com", - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ - Type: envoy_cluster_v3.Cluster_STRICT_DNS, - }, + Name: "dnsname/https/jwt.example.com", + ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type_v3.Percent{Value: 0}, }, @@ -978,10 +972,8 @@ func TestJWTVerification(t *testing.T) { TypeUrl: clusterType, Resources: resources(t, &envoy_cluster_v3.Cluster{ - Name: "dnsname/https/jwt.example.com", - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ - Type: envoy_cluster_v3.Cluster_STRICT_DNS, - }, + Name: "dnsname/https/jwt.example.com", + ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type_v3.Percent{Value: 0}, }, @@ -1124,10 +1116,8 @@ func TestJWTVerification(t *testing.T) { TypeUrl: clusterType, Resources: resources(t, &envoy_cluster_v3.Cluster{ - Name: "dnsname/https/jwt.example.com", - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ - Type: envoy_cluster_v3.Cluster_STRICT_DNS, - }, + Name: "dnsname/https/jwt.example.com", + ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type_v3.Percent{Value: 0}, }, @@ -1345,10 +1335,8 @@ func TestJWTVerification_Inclusion(t *testing.T) { TypeUrl: clusterType, Resources: resources(t, &envoy_cluster_v3.Cluster{ - Name: "dnsname/https/jwt.example.com", - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{ - Type: envoy_cluster_v3.Cluster_STRICT_DNS, - }, + Name: "dnsname/https/jwt.example.com", + ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_STRICT_DNS), CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ HealthyPanicThreshold: &envoy_type_v3.Percent{Value: 0}, }, diff --git a/internal/featuretests/v3/listeners_test.go b/internal/featuretests/v3/listeners_test.go index 25515b1006d..a58a4333bc1 100644 --- a/internal/featuretests/v3/listeners_test.go +++ b/internal/featuretests/v3/listeners_test.go @@ -48,6 +48,7 @@ func customAdminPort(t *testing.T, port int) []xdscache.ResourceCache { contour_api_v1alpha1.MetricsConfig{Address: "0.0.0.0", Port: 8002}, contour_api_v1alpha1.HealthConfig{Address: "0.0.0.0", Port: 8002}, port, + envoy_v3.NewConfigGenerator(), ), &xdscache_v3.SecretCache{}, &xdscache_v3.RouteCache{}, @@ -405,7 +406,7 @@ func TestHTTPProxyTLSListener(t *testing.T) { FilterChains: []*envoy_listener_v3.FilterChain{ envoy_v3.FilterChainTLS( "kuard.example.com", - envoy_v3.DownstreamTLSContext( + envoy_v3.NewConfigGenerator().DownstreamTLSContext( &dag.Secret{Object: secret1}, envoy_tls_v3.TlsParameters_TLSv1_3, nil, @@ -486,7 +487,7 @@ func TestTLSListenerCipherSuites(t *testing.T) { FilterChains: []*envoy_listener_v3.FilterChain{ envoy_v3.FilterChainTLS( "kuard.example.com", - envoy_v3.DownstreamTLSContext( + envoy_v3.NewConfigGenerator().DownstreamTLSContext( &dag.Secret{Object: secret1}, envoy_tls_v3.TlsParameters_TLSv1_2, []string{"ECDHE-ECDSA-AES256-GCM-SHA384"}, @@ -902,7 +903,12 @@ func TestLDSCustomAccessLogPaths(t *testing.T) { httpListener := defaultHTTPListener() httpListener.FilterChains = envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManager("ingress_http", envoy_v3.FileAccessLogEnvoy("/tmp/http_access.log", "", nil, contour_api_v1alpha1.LogLevelInfo), 0), + envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). + RouteConfigName("ingress_http"). + MetricsPrefix("ingress_http"). + AccessLoggers(envoy_v3.FileAccessLogEnvoy("/tmp/http_access.log", "", nil, contour_api_v1alpha1.LogLevelInfo)). + DefaultFilters(). + Get(), ) httpsListener := &envoy_listener_v3.Listener{ @@ -913,7 +919,7 @@ func TestLDSCustomAccessLogPaths(t *testing.T) { ), FilterChains: []*envoy_listener_v3.FilterChain{ filterchaintls("kuard.example.com", s1, - envoy_v3.HTTPConnectionManagerBuilder(). + envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("kuard.example.com")). DefaultFilters(). RouteConfigName("https/kuard.example.com"). @@ -1076,7 +1082,7 @@ func TestHTTPProxyMinimumTLSVersion(t *testing.T) { FilterChains: []*envoy_listener_v3.FilterChain{ envoy_v3.FilterChainTLS( "kuard.example.com", - envoy_v3.DownstreamTLSContext( + c.cg.DownstreamTLSContext( &dag.Secret{Object: secret1}, envoy_tls_v3.TlsParameters_TLSv1_2, nil, @@ -1132,7 +1138,7 @@ func TestHTTPProxyMinimumTLSVersion(t *testing.T) { FilterChains: []*envoy_listener_v3.FilterChain{ envoy_v3.FilterChainTLS( "kuard.example.com", - envoy_v3.DownstreamTLSContext( + c.cg.DownstreamTLSContext( &dag.Secret{Object: secret1}, envoy_tls_v3.TlsParameters_TLSv1_3, nil, @@ -1251,7 +1257,7 @@ func TestHTTPProxyXffNumTrustedHops(t *testing.T) { // verify that the xff-num-trusted-hops have been set to 1. httpListener := defaultHTTPListener() - httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + httpListener.FilterChains = envoy_v3.FilterChains(c.cg.HTTPConnectionManagerBuilder(). RouteConfigName("ingress_http"). MetricsPrefix("ingress_http"). AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)). @@ -1305,7 +1311,7 @@ func TestHTTPProxyServerHeaderTransformation(t *testing.T) { // verify that the server-header-transformation has been set to append_if_absent. httpListener := defaultHTTPListener() - httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + httpListener.FilterChains = envoy_v3.FilterChains(c.cg.HTTPConnectionManagerBuilder(). RouteConfigName("ingress_http"). MetricsPrefix("ingress_http"). AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, contour_api_v1alpha1.LogLevelInfo)). diff --git a/internal/featuretests/v3/loadbalancerpolicy_test.go b/internal/featuretests/v3/loadbalancerpolicy_test.go index c4758a16b9c..420239dce04 100644 --- a/internal/featuretests/v3/loadbalancerpolicy_test.go +++ b/internal/featuretests/v3/loadbalancerpolicy_test.go @@ -60,7 +60,7 @@ func TestLoadBalancerPolicySessionAffinity(t *testing.T) { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: s1.Namespace + "_" + s1.Name + "_80", EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: s1.Namespace + "/" + s1.Name, }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -112,7 +112,7 @@ func TestLoadBalancerPolicySessionAffinity(t *testing.T) { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: s1.Namespace + "_" + s1.Name + "_80", EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: s1.Namespace + "/" + s1.Name, }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -122,7 +122,7 @@ func TestLoadBalancerPolicySessionAffinity(t *testing.T) { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: s1.Namespace + "_" + s1.Name + "_8080", EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: s1.Namespace + "/" + s1.Name, }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -197,7 +197,7 @@ func TestLoadBalancerPolicyRequestHashHeader(t *testing.T) { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: s1.Namespace + "_" + s1.Name + "_80", EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: s1.Namespace + "/" + s1.Name, }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -267,7 +267,7 @@ func TestLoadBalancerPolicyRequestHashSourceIP(t *testing.T) { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: s1.Namespace + "_" + s1.Name + "_80", EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: s1.Namespace + "/" + s1.Name, }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -340,7 +340,7 @@ func TestLoadBalancerPolicyRequestHashQueryParameter(t *testing.T) { ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), AltStatName: s1.Namespace + "_" + s1.Name + "_80", EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: c.cg.ConfigSource(), ServiceName: s1.Namespace + "/" + s1.Name, }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, diff --git a/internal/featuretests/v3/timeouts_test.go b/internal/featuretests/v3/timeouts_test.go index f342c4c3ec4..d1d2e56354b 100644 --- a/internal/featuretests/v3/timeouts_test.go +++ b/internal/featuretests/v3/timeouts_test.go @@ -60,7 +60,7 @@ func TestTimeoutsNotSpecified(t *testing.T) { httpListener := defaultHTTPListener() httpListener.FilterChains = envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER). MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -114,7 +114,7 @@ func TestNonZeroTimeoutsSpecified(t *testing.T) { rh.OnAdd(hp1) httpListener := defaultHTTPListener() - httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER). MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). diff --git a/internal/featuretests/v3/tlsprotocolversion_test.go b/internal/featuretests/v3/tlsprotocolversion_test.go index bbc328f6efc..603c433268b 100644 --- a/internal/featuretests/v3/tlsprotocolversion_test.go +++ b/internal/featuretests/v3/tlsprotocolversion_test.go @@ -119,7 +119,7 @@ func TestTLSMinimumProtocolVersion(t *testing.T) { FilterChains: []*envoy_listener_v3.FilterChain{ envoy_v3.FilterChainTLS( "kuard.example.com", - envoy_v3.DownstreamTLSContext( + envoy_v3.NewConfigGenerator().DownstreamTLSContext( &dag.Secret{Object: sec1}, envoy_tls_v3.TlsParameters_TLSv1_3, nil, diff --git a/internal/featuretests/v3/tracing_test.go b/internal/featuretests/v3/tracing_test.go index 3af7b807ad3..5d097560174 100644 --- a/internal/featuretests/v3/tracing_test.go +++ b/internal/featuretests/v3/tracing_test.go @@ -113,7 +113,7 @@ func TestTracing(t *testing.T) { rh.OnAdd(p) httpListener := defaultHTTPListener() - httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + httpListener.FilterChains = envoy_v3.FilterChains(envoy_v3.NewConfigGenerator().HTTPConnectionManagerBuilder(). RouteConfigName(xdscache_v3.ENVOY_HTTP_LISTENER). MetricsPrefix(xdscache_v3.ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(xdscache_v3.DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). diff --git a/internal/xdscache/v3/cluster.go b/internal/xdscache/v3/cluster.go index 134efedbb12..443c4b7c55b 100644 --- a/internal/xdscache/v3/cluster.go +++ b/internal/xdscache/v3/cluster.go @@ -33,6 +33,13 @@ type ClusterCache struct { mu sync.Mutex values map[string]*envoy_cluster_v3.Cluster contour.Cond + cg *envoy_v3.ConfigGenerator +} + +func NewClusterCache(cg *envoy_v3.ConfigGenerator) *ClusterCache { + return &ClusterCache{ + cg: cg, + } } // Update replaces the contents of the cache with the supplied map. @@ -82,20 +89,20 @@ func (c *ClusterCache) OnChange(root *dag.DAG) { for _, cluster := range root.GetClusters() { name := envoy.Clustername(cluster) if _, ok := clusters[name]; !ok { - clusters[name] = envoy_v3.Cluster(cluster) + clusters[name] = c.cg.Cluster(cluster) } } for name, ec := range root.GetExtensionClusters() { if _, ok := clusters[name]; !ok { - clusters[name] = envoy_v3.ExtensionCluster(ec) + clusters[name] = c.cg.ExtensionCluster(ec) } } for _, cluster := range root.GetDNSNameClusters() { name := envoy.DNSNameClusterName(cluster) if _, ok := clusters[name]; !ok { - clusters[name] = envoy_v3.DNSNameCluster(cluster) + clusters[name] = c.cg.DNSNameCluster(cluster) } } diff --git a/internal/xdscache/v3/cluster_test.go b/internal/xdscache/v3/cluster_test.go index 6cf891fe73f..38f1ef7abd1 100644 --- a/internal/xdscache/v3/cluster_test.go +++ b/internal/xdscache/v3/cluster_test.go @@ -20,6 +20,7 @@ import ( envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_extensions_upstream_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/upstreams/http/v3" + envoy_type "github.com/envoyproxy/go-control-plane/envoy/type/v3" contour_api_v1 "github.com/projectcontour/contour/apis/projectcontour/v1" envoy_v3 "github.com/projectcontour/contour/internal/envoy/v3" "github.com/projectcontour/contour/internal/protobuf" @@ -45,23 +46,13 @@ func TestClusterCacheContents(t *testing.T) { "simple": { contents: clustermap( &envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), want: []proto.Message{ cluster(&envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), }, }, @@ -86,61 +77,36 @@ func TestClusterCacheQuery(t *testing.T) { "exact match": { contents: clustermap( &envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), query: []string{"default/kuard/443/da39a3ee5e"}, want: []proto.Message{ cluster(&envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), }, }, "partial match": { contents: clustermap( &envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), query: []string{"default/kuard/443/da39a3ee5e", "foo/bar/baz"}, want: []proto.Message{ cluster(&envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), }, }, "no match": { contents: clustermap( &envoy_cluster_v3.Cluster{ - Name: "default/kuard/443/da39a3ee5e", - AltStatName: "default_kuard_443", - ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), - EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), - ServiceName: "default/kuard", - }, + Name: "default/kuard/443/da39a3ee5e", + AltStatName: "default_kuard_443", }), query: []string{"foo/bar/baz"}, want: nil, @@ -191,7 +157,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard", }, }), @@ -227,7 +193,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/https", }, }), @@ -267,7 +233,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_kuard_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, TypedExtensionProtocolOptions: map[string]*anypb.Any{ @@ -309,7 +275,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "beurocratic-company-test-domain-1_tiny-cog-department-test-instance_443", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "beurocratic-company-test-domain-1/tiny-cog-department-test-instance/svc-0", }, }), @@ -357,7 +323,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, }, @@ -366,7 +332,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_8080", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/alt", }, }, @@ -410,7 +376,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, HealthChecks: []*envoy_core_v3.HealthCheck{{ @@ -472,7 +438,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, HealthChecks: []*envoy_core_v3.HealthCheck{{ @@ -529,7 +495,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, }, @@ -573,7 +539,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, LbPolicy: envoy_cluster_v3.Cluster_LEAST_REQUEST, @@ -618,7 +584,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, LbPolicy: envoy_cluster_v3.Cluster_RANDOM, @@ -670,7 +636,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, LbPolicy: envoy_cluster_v3.Cluster_RING_HASH, @@ -717,7 +683,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_backend_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/backend/http", }, }, @@ -761,7 +727,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_kuard_80", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/http", }, CircuitBreakers: &envoy_cluster_v3.CircuitBreakers{ @@ -810,7 +776,7 @@ func TestClusterVisit(t *testing.T) { AltStatName: "default_kuard_443", ClusterDiscoveryType: envoy_v3.ClusterDiscoveryType(envoy_cluster_v3.Cluster_EDS), EdsClusterConfig: &envoy_cluster_v3.Cluster_EdsClusterConfig{ - EdsConfig: envoy_v3.ConfigSource("contour"), + EdsConfig: defaultConfigSource, ServiceName: "default/kuard/https", }, }), @@ -819,7 +785,7 @@ func TestClusterVisit(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { - var cc ClusterCache + cc := NewClusterCache(envoy_v3.NewConfigGenerator()) cc.OnChange(buildDAG(t, tc.objs...)) protobuf.ExpectEqual(t, tc.want, cc.values) }) @@ -847,8 +813,12 @@ func cluster(c *envoy_cluster_v3.Cluster) *envoy_cluster_v3.Cluster { // NOTE: Keep this in sync with envoy.defaultCluster(). defaults := &envoy_cluster_v3.Cluster{ ConnectTimeout: durationpb.New(2 * time.Second), - CommonLbConfig: envoy_v3.ClusterCommonLBConfig(), - LbPolicy: envoy_cluster_v3.Cluster_ROUND_ROBIN, + CommonLbConfig: &envoy_cluster_v3.Cluster_CommonLbConfig{ + HealthyPanicThreshold: &envoy_type.Percent{ // Disable HealthyPanicThreshold + Value: 0, + }, + }, + LbPolicy: envoy_cluster_v3.Cluster_ROUND_ROBIN, } proto.Merge(defaults, c) @@ -862,3 +832,23 @@ func clustermap(clusters ...*envoy_cluster_v3.Cluster) map[string]*envoy_cluster } return m } + +var defaultConfigSource = &envoy_core_v3.ConfigSource{ + ResourceApiVersion: envoy_core_v3.ApiVersion_V3, + ConfigSourceSpecifier: &envoy_core_v3.ConfigSource_ApiConfigSource{ + ApiConfigSource: &envoy_core_v3.ApiConfigSource{ + ApiType: envoy_core_v3.ApiConfigSource_GRPC, + TransportApiVersion: envoy_core_v3.ApiVersion_V3, + GrpcServices: []*envoy_core_v3.GrpcService{ + { + TargetSpecifier: &envoy_core_v3.GrpcService_EnvoyGrpc_{ + EnvoyGrpc: &envoy_core_v3.GrpcService_EnvoyGrpc{ + ClusterName: "contour", + Authority: "contour", + }, + }, + }, + }, + }, + }, +} diff --git a/internal/xdscache/v3/listener.go b/internal/xdscache/v3/listener.go index b850ac56889..b822cceefc8 100644 --- a/internal/xdscache/v3/listener.go +++ b/internal/xdscache/v3/listener.go @@ -257,6 +257,7 @@ type ListenerCache struct { mu sync.Mutex values map[string]*envoy_listener_v3.Listener staticValues map[string]*envoy_listener_v3.Listener + cg *envoy_v3.ConfigGenerator Config ListenerConfig contour.Cond @@ -268,13 +269,15 @@ func NewListenerCache( metricsConfig contour_api_v1alpha1.MetricsConfig, healthConfig contour_api_v1alpha1.HealthConfig, adminPort int, + cg *envoy_v3.ConfigGenerator, ) *ListenerCache { listenerCache := &ListenerCache{ Config: listenerConfig, + cg: cg, staticValues: map[string]*envoy_listener_v3.Listener{}, } - for _, l := range envoy_v3.StatsListeners(metricsConfig, healthConfig) { + for _, l := range listenerCache.cg.StatsListeners(metricsConfig, healthConfig) { listenerCache.staticValues[l.Name] = l } @@ -366,7 +369,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { // If there are non-TLS vhosts bound to the listener, // add a listener with a single filter chain. if len(listener.VirtualHosts) > 0 { - cm := envoy_v3.HTTPConnectionManagerBuilder(). + cm := c.cg.HTTPConnectionManagerBuilder(). Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)). DefaultFilters(). RouteConfigName(httpRouteConfigName(listener)). @@ -433,7 +436,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { // metrics prefix to keep compatibility with previous // Contour versions since the metrics prefix will be // coded into monitoring dashboards. - cm := envoy_v3.HTTPConnectionManagerBuilder(). + cm := c.cg.HTTPConnectionManagerBuilder(). Codec(envoy_v3.CodecForVersions(cfg.DefaultHTTPVersions...)). AddFilter(envoy_v3.FilterMisdirectedRequests(vh.VirtualHost.Name)). DefaultFilters(). @@ -477,7 +480,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { // Choose the higher of the configured or requested TLS version. vers := max(cfg.minTLSVersion(), envoy_v3.ParseTLSVersion(vh.MinTLSVersion)) - downstreamTLS = envoy_v3.DownstreamTLSContext( + downstreamTLS = c.cg.DownstreamTLSContext( vh.Secret, vers, cfg.CipherSuites, @@ -495,7 +498,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { if vh.FallbackCertificate != nil && !envoy_v3.ContainsFallbackFilterChain(listeners[listener.Name].FilterChains) { // Construct the downstreamTLSContext passing the configured fallbackCertificate. The TLS minProtocolVersion will use // the value defined in the Contour Configuration file if defined. - downstreamTLS = envoy_v3.DownstreamTLSContext( + downstreamTLS = c.cg.DownstreamTLSContext( vh.FallbackCertificate, cfg.minTLSVersion(), cfg.CipherSuites, @@ -503,7 +506,7 @@ func (c *ListenerCache) OnChange(root *dag.DAG) { alpnProtos..., ) - cm := envoy_v3.HTTPConnectionManagerBuilder(). + cm := c.cg.HTTPConnectionManagerBuilder(). DefaultFilters(). RouteConfigName(fallbackCertRouteConfigName(listener)). MetricsPrefix(listener.Name). diff --git a/internal/xdscache/v3/listener_test.go b/internal/xdscache/v3/listener_test.go index 499ab4d0dd4..948e7008434 100644 --- a/internal/xdscache/v3/listener_test.go +++ b/internal/xdscache/v3/listener_test.go @@ -53,17 +53,13 @@ func TestListenerCacheContents(t *testing.T) { }, "simple": { contents: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }), want: []proto.Message{ &envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }, }, }, @@ -87,44 +83,34 @@ func TestListenerCacheQuery(t *testing.T) { }{ "exact match": { contents: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }), query: []string{ENVOY_HTTP_LISTENER}, want: []proto.Message{ &envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }, }, }, "partial match": { contents: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }), query: []string{ENVOY_HTTP_LISTENER, "stats-listener"}, want: []proto.Message{ &envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }, }, }, "no match": { contents: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), }), query: []string{"stats-listener"}, want: nil, @@ -142,8 +128,9 @@ func TestListenerCacheQuery(t *testing.T) { } func TestListenerVisit(t *testing.T) { + cg := envoy_v3.NewConfigGenerator() httpsFilterFor := func(vhost string) *envoy_listener_v3.Filter { - return envoy_v3.HTTPConnectionManagerBuilder(). + return cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests(vhost)). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -152,7 +139,7 @@ func TestListenerVisit(t *testing.T) { Get() } - fallbackCertFilter := envoy_v3.HTTPConnectionManagerBuilder(). + fallbackCertFilter := cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -194,12 +181,7 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap(defaultHTTPListener()), }, "one http only httpproxy": { objs: []any{ @@ -237,12 +219,7 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap(defaultHTTPListener()), }, "simple ingress with secret": { objs: []any{ @@ -290,26 +267,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"whatever.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("whatever.example.com")), - }}, - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"whatever.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("whatever.example.com")), + }}, + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "multiple tls ingress with secrets should be sorted": { objs: []any{ @@ -379,32 +354,30 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"sortedfirst.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("sortedfirst.example.com")), - }, { - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"sortedsecond.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("sortedsecond.example.com")), - }}, - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"sortedfirst.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("sortedfirst.example.com")), + }, { + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"sortedsecond.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("sortedsecond.example.com")), + }}, + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "simple ingress with missing secret": { objs: []any{ @@ -452,12 +425,7 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap(defaultHTTPListener()), }, "simple httpproxy with secret": { objs: []any{ @@ -503,26 +471,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "ingress with allow-http: false": { objs: []any{ @@ -661,7 +627,7 @@ func TestListenerVisit(t *testing.T) { ListenerFilters: envoy_v3.ListenerFilters( envoy_v3.ProxyProtocol(), ), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), + FilterChains: defaultFilterChains, SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), }, &envoy_listener_v3.Listener{ Name: ENVOY_HTTPS_LISTENER, @@ -731,9 +697,15 @@ func TestListenerVisit(t *testing.T) { }, }, want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy("/tmp/http_access.log", "", nil, v1alpha1.LogLevelInfo), 0)), + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), + FilterChains: envoy_v3.FilterChains(envoy_v3.NewConfigGenerator(). + HTTPConnectionManagerBuilder(). + RouteConfigName(ENVOY_HTTP_LISTENER). + MetricsPrefix(ENVOY_HTTP_LISTENER). + AccessLoggers(envoy_v3.FileAccessLogEnvoy("/tmp/http_access.log", "", nil, v1alpha1.LogLevelInfo)). + DefaultFilters(). + Get()), SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), }, &envoy_listener_v3.Listener{ Name: ENVOY_HTTPS_LISTENER, @@ -746,7 +718,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"whatever.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("whatever.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -806,26 +778,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"whatever.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("whatever.example.com")), - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"whatever.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("whatever.example.com")), + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "tls-min-protocol-version from config overridden by annotation": { ListenerConfig: ListenerConfig{ @@ -879,26 +849,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"whatever.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), // note, cannot downgrade from the configured version - Filters: envoy_v3.Filters(httpsFilterFor("whatever.example.com")), - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"whatever.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), // note, cannot downgrade from the configured version + Filters: envoy_v3.Filters(httpsFilterFor("whatever.example.com")), + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "tls-min-protocol-version from config overridden by httpproxy": { ListenerConfig: ListenerConfig{ @@ -948,26 +916,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), // note, cannot downgrade from the configured version - Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_3, nil, "h2", "http/1.1"), // note, cannot downgrade from the configured version + Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "tls-cipher-suites from config": { ListenerConfig: ListenerConfig{ @@ -1019,26 +985,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, []string{"ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384"}, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, []string{"ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384"}, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "httpproxy with fallback certificate and with request timeout set": { fallbackCertificate: &types.NamespacedName{ @@ -1110,7 +1074,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -1126,7 +1090,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -1140,7 +1104,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -1226,7 +1190,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -1242,7 +1206,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -1256,7 +1220,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -1342,7 +1306,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -1358,7 +1322,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -1372,7 +1336,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -1458,7 +1422,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -1474,7 +1438,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -1488,7 +1452,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -1574,7 +1538,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -1590,7 +1554,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -1604,7 +1568,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -1690,7 +1654,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -1706,7 +1670,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -1720,7 +1684,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -1797,33 +1761,31 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), - }, { - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - TransportProtocol: "tls", - }, - TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(fallbackCertFilter), - Name: "fallback-certificate", - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), + }, { + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + TransportProtocol: "tls", + }, + TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(fallbackCertFilter), + Name: "fallback-certificate", + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "multiple httpproxies with fallback certificate": { fallbackCertificate: &types.NamespacedName{ @@ -1911,42 +1873,40 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{ - { - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.another.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("www.another.com")), - }, - { - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.example.com"}, + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{ + { + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.another.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("www.another.com")), }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), - }, - { - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - TransportProtocol: "tls", + { + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), }, - TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(fallbackCertFilter), - Name: "fallback-certificate", - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + { + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + TransportProtocol: "tls", + }, + TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(fallbackCertFilter), + Name: "fallback-certificate", + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "httpproxy with fallback certificate - no cert passed": { fallbackCertificate: &types.NamespacedName{ @@ -2056,26 +2016,24 @@ func TestListenerVisit(t *testing.T) { }, }, }, - want: listenermap(&envoy_listener_v3.Listener{ - Name: ENVOY_HTTP_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManager(ENVOY_HTTP_LISTENER, envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo), 0)), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }, &envoy_listener_v3.Listener{ - Name: ENVOY_HTTPS_LISTENER, - Address: envoy_v3.SocketAddress("0.0.0.0", 8443), - FilterChains: []*envoy_listener_v3.FilterChain{{ - FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ - ServerNames: []string{"www.example.com"}, - }, - TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), - }}, - ListenerFilters: envoy_v3.ListenerFilters( - envoy_v3.TLSInspector(), - ), - SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), - }), + want: listenermap( + defaultHTTPListener(), + &envoy_listener_v3.Listener{ + Name: ENVOY_HTTPS_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8443), + FilterChains: []*envoy_listener_v3.FilterChain{{ + FilterChainMatch: &envoy_listener_v3.FilterChainMatch{ + ServerNames: []string{"www.example.com"}, + }, + TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), + Filters: envoy_v3.Filters(httpsFilterFor("www.example.com")), + }}, + ListenerFilters: envoy_v3.ListenerFilters( + envoy_v3.TLSInspector(), + ), + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + }, + ), }, "httpproxy with connection idle timeout set in listener config": { ListenerConfig: ListenerConfig{ @@ -2122,7 +2080,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2178,7 +2136,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2234,7 +2192,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2290,7 +2248,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2346,7 +2304,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2409,7 +2367,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2426,7 +2384,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -2484,7 +2442,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2539,7 +2497,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2594,7 +2552,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2648,7 +2606,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2711,7 +2669,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2728,7 +2686,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -2795,7 +2753,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2812,7 +2770,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -2879,7 +2837,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2896,7 +2854,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -2963,7 +2921,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -2980,7 +2938,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -3046,7 +3004,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName("ingress_http"). MetricsPrefix("ingress_http"). AccessLoggers(envoy_v3.FileAccessLogEnvoy("/dev/stdout", "", nil, v1alpha1.LogLevelInfo)). @@ -3137,7 +3095,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -3176,7 +3134,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -3290,7 +3248,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). DefaultFilters(). @@ -3328,7 +3286,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -3364,7 +3322,7 @@ func TestListenerVisit(t *testing.T) { TransportProtocol: "tls", }, TransportSocket: transportSocket("fallbacksecret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). RouteConfigName(ENVOY_FALLBACK_ROUTECONFIG). @@ -3445,7 +3403,7 @@ func TestListenerVisit(t *testing.T) { Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), FilterChains: envoy_v3.FilterChains( - envoy_v3.HTTPConnectionManagerBuilder(). + cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -3506,7 +3464,7 @@ func TestListenerVisit(t *testing.T) { want: listenermap(&envoy_listener_v3.Listener{ Name: ENVOY_HTTP_LISTENER, Address: envoy_v3.SocketAddress("0.0.0.0", 8080), - FilterChains: envoy_v3.FilterChains(envoy_v3.HTTPConnectionManagerBuilder(). + FilterChains: envoy_v3.FilterChains(cg.HTTPConnectionManagerBuilder(). RouteConfigName(ENVOY_HTTP_LISTENER). MetricsPrefix(ENVOY_HTTP_LISTENER). AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). @@ -3523,7 +3481,7 @@ func TestListenerVisit(t *testing.T) { ServerNames: []string{"www.example.com"}, }, TransportSocket: transportSocket("secret", envoy_tls_v3.TlsParameters_TLSv1_2, nil, "h2", "http/1.1"), - Filters: envoy_v3.Filters(envoy_v3.HTTPConnectionManagerBuilder(). + Filters: envoy_v3.Filters(cg.HTTPConnectionManagerBuilder(). AddFilter(envoy_v3.FilterMisdirectedRequests("www.example.com")). DefaultFilters(). MetricsPrefix(ENVOY_HTTPS_LISTENER). @@ -3544,6 +3502,7 @@ func TestListenerVisit(t *testing.T) { t.Run(name, func(t *testing.T) { lc := ListenerCache{ Config: tc.ListenerConfig, + cg: envoy_v3.NewConfigGenerator(), } lc.OnChange(buildDAGFallback(t, tc.fallbackCertificate, tc.objs...)) protobuf.ExpectEqual(t, tc.want, lc.values) @@ -3563,7 +3522,7 @@ func transportSocket(secretname string, tlsMinProtoVersion envoy_tls_v3.TlsParam }, } return envoy_v3.DownstreamTLSTransportSocket( - envoy_v3.DownstreamTLSContext(secret, tlsMinProtoVersion, cipherSuites, nil, alpnprotos...), + envoy_v3.NewConfigGenerator().DownstreamTLSContext(secret, tlsMinProtoVersion, cipherSuites, nil, alpnprotos...), ) } @@ -3574,3 +3533,22 @@ func listenermap(listeners ...*envoy_listener_v3.Listener) map[string]*envoy_lis } return m } + +var defaultFilterChains = envoy_v3.FilterChains( + envoy_v3.NewConfigGenerator(). + HTTPConnectionManagerBuilder(). + RouteConfigName(ENVOY_HTTP_LISTENER). + MetricsPrefix(ENVOY_HTTP_LISTENER). + AccessLoggers(envoy_v3.FileAccessLogEnvoy(DEFAULT_HTTP_ACCESS_LOG, "", nil, v1alpha1.LogLevelInfo)). + DefaultFilters(). + Get(), +) + +func defaultHTTPListener() *envoy_listener_v3.Listener { + return &envoy_listener_v3.Listener{ + Name: ENVOY_HTTP_LISTENER, + Address: envoy_v3.SocketAddress("0.0.0.0", 8080), + FilterChains: defaultFilterChains, + SocketOptions: envoy_v3.TCPKeepaliveSocketOptions(), + } +}