diff --git a/depot/containerstore/proxy_config_handler.go b/depot/containerstore/proxy_config_handler.go index 6f530a79..2531c15f 100644 --- a/depot/containerstore/proxy_config_handler.go +++ b/depot/containerstore/proxy_config_handler.go @@ -83,6 +83,8 @@ type ProxyConfigHandler struct { reloadClock clock.Clock adsServers []string + + http2Enabled bool } type NoopProxyConfigHandler struct{} @@ -126,6 +128,7 @@ func NewProxyConfigHandler( reloadDuration time.Duration, reloadClock clock.Clock, adsServers []string, + http2Enabled bool, ) *ProxyConfigHandler { return &ProxyConfigHandler{ logger: logger.Session("proxy-manager"), @@ -137,6 +140,7 @@ func NewProxyConfigHandler( reloadDuration: reloadDuration, reloadClock: reloadClock, adsServers: adsServers, + http2Enabled: http2Enabled, } } @@ -254,6 +258,7 @@ func (p *ProxyConfigHandler) writeConfig(credentials Credential, container execu adminPort, p.containerProxyRequireClientCerts, p.adsServers, + p.http2Enabled, ) if err != nil { return err @@ -305,6 +310,7 @@ func generateProxyConfig( adminPort uint16, requireClientCerts bool, adsServers []string, + http2Enabled bool, ) (*envoy_bootstrap.Bootstrap, error) { clusters := []*envoy_cluster.Cluster{} for index, portMap := range container.Ports { @@ -332,7 +338,7 @@ func generateProxyConfig( }) } - listeners, err := generateListeners(container, requireClientCerts) + listeners, err := generateListeners(container, requireClientCerts, http2Enabled) if err != nil { return nil, fmt.Errorf("generating listeners: %s", err) } @@ -443,7 +449,7 @@ func writeProxyConfig(proxyConfig *envoy_bootstrap.Bootstrap, path string) error return ioutil.WriteFile(path, yamlStr, 0666) } -func generateListeners(container executor.Container, requireClientCerts bool) ([]*envoy_listener.Listener, error) { +func generateListeners(container executor.Container, requireClientCerts, http2Enabled bool) ([]*envoy_listener.Listener, error) { listeners := []*envoy_listener.Listener{} for index, portMap := range container.Ports { @@ -463,7 +469,6 @@ func generateListeners(container executor.Container, requireClientCerts bool) ([ tlsContext := &envoy_tls.DownstreamTlsContext{ RequireClientCertificate: &wrappers.BoolValue{Value: requireClientCerts}, CommonTlsContext: &envoy_tls.CommonTlsContext{ - AlpnProtocols: AlpnProtocols, TlsCertificateSdsSecretConfigs: []*envoy_tls.SdsSecretConfig{ { Name: "server-cert-and-key", @@ -480,6 +485,10 @@ func generateListeners(container executor.Container, requireClientCerts bool) ([ }, } + if http2Enabled { + tlsContext.CommonTlsContext.AlpnProtocols = AlpnProtocols + } + if requireClientCerts { tlsContext.CommonTlsContext.ValidationContextType = &envoy_tls.CommonTlsContext_ValidationContextSdsSecretConfig{ ValidationContextSdsSecretConfig: &envoy_tls.SdsSecretConfig{ diff --git a/depot/containerstore/proxy_config_handler_test.go b/depot/containerstore/proxy_config_handler_test.go index 1e9e569d..918e9958 100644 --- a/depot/containerstore/proxy_config_handler_test.go +++ b/depot/containerstore/proxy_config_handler_test.go @@ -60,6 +60,7 @@ var _ = Describe("ProxyConfigHandler", func() { containerProxyVerifySubjectAltName []string containerProxyRequireClientCerts bool adsServers []string + http2Enabled bool ) BeforeEach(func() { @@ -101,6 +102,7 @@ var _ = Describe("ProxyConfigHandler", func() { "10.255.217.2:15010", "10.255.217.3:15010", } + http2Enabled = true }) JustBeforeEach(func() { @@ -114,6 +116,7 @@ var _ = Describe("ProxyConfigHandler", func() { reloadDuration, reloadClock, adsServers, + http2Enabled, ) Eventually(rotatingCredChan).Should(BeSent(containerstore.Credential{ Cert: "some-cert", @@ -394,6 +397,7 @@ var _ = Describe("ProxyConfigHandler", func() { statPrefix: "0-stats", clusterName: "0-service-cluster", requireClientCertificate: false, + alpnProtocols: []string{"h2,http/1.1"}, }.check(proxyConfig.StaticResources.Listeners[0]) }) }) @@ -548,6 +552,7 @@ var _ = Describe("ProxyConfigHandler", func() { statPrefix: "0-stats", clusterName: "0-service-cluster", requireClientCertificate: true, + alpnProtocols: []string{"h2,http/1.1"}, }.check(proxyConfig.StaticResources.Listeners[0]) adsConfigSource := &envoy_core.ConfigSource{ @@ -621,6 +626,31 @@ var _ = Describe("ProxyConfigHandler", func() { }) }) + Context("when HTTP/2 is disabled", func() { + BeforeEach(func() { + http2Enabled = false + }) + + It("creates a proxy config without ALPN for listeners", func() { + err := proxyConfigHandler.Update(containerstore.Credential{Cert: "cert", Key: "key"}, container) + Expect(err).NotTo(HaveOccurred()) + Eventually(proxyConfigFile).Should(BeAnExistingFile()) + + var proxyConfig envoy_bootstrap.Bootstrap + Expect(yamlFileToProto(proxyConfigFile, &proxyConfig)).To(Succeed()) + + Expect(proxyConfig.StaticResources.Listeners).To(HaveLen(1)) + expectedListener{ + name: "listener-8080", + listenPort: 61001, + statPrefix: "0-stats", + clusterName: "0-service-cluster", + requireClientCertificate: true, + alpnProtocols: nil, + }.check(proxyConfig.StaticResources.Listeners[0]) + }) + }) + Context("with multiple port mappings", func() { BeforeEach(func() { container.Ports = []executor.PortMapping{ @@ -683,6 +713,7 @@ var _ = Describe("ProxyConfigHandler", func() { statPrefix: "0-stats", clusterName: "0-service-cluster", requireClientCertificate: true, + alpnProtocols: []string{"h2,http/1.1"}, }.check(proxyConfig.StaticResources.Listeners[0]) expectedListener{ @@ -691,6 +722,7 @@ var _ = Describe("ProxyConfigHandler", func() { statPrefix: "1-stats", clusterName: "1-service-cluster", requireClientCertificate: true, + alpnProtocols: []string{"h2,http/1.1"}, }.check(proxyConfig.StaticResources.Listeners[1]) }) @@ -846,6 +878,7 @@ type expectedListener struct { statPrefix string clusterName string requireClientCertificate bool + alpnProtocols []string } func (l expectedListener) check(listener *envoy_listener.Listener) { @@ -869,7 +902,7 @@ func (l expectedListener) check(listener *envoy_listener.Listener) { Expect(filterChain.TransportSocket.Name).To(Equal(l.name)) Expect(downstreamTlsContext.RequireClientCertificate.Value).To(Equal(l.requireClientCertificate)) - Expect(downstreamTlsContext.CommonTlsContext.AlpnProtocols).To(Equal([]string{"h2,http/1.1"})) + Expect(downstreamTlsContext.CommonTlsContext.AlpnProtocols).To(Equal(l.alpnProtocols)) Expect(downstreamTlsContext.CommonTlsContext.TlsCertificateSdsSecretConfigs).To(ConsistOf( &envoy_tls.SdsSecretConfig{ Name: "server-cert-and-key", diff --git a/initializer/initializer.go b/initializer/initializer.go index 0f3d5ba5..61841469 100644 --- a/initializer/initializer.go +++ b/initializer/initializer.go @@ -139,6 +139,7 @@ type ExecutorConfig struct { PathToTLSKey string `json:"path_to_tls_key"` PostSetupHook string `json:"post_setup_hook"` PostSetupUser string `json:"post_setup_user"` + ProxyEnableHttp2 bool `json:"proxy_enable_http2"` ProxyMemoryAllocationMB int `json:"proxy_memory_allocation_mb,omitempty"` ReadWorkPoolSize int `json:"read_work_pool_size,omitempty"` ReservedExpirationTime durationjson.Duration `json:"reserved_expiration_time,omitempty"` @@ -290,6 +291,7 @@ func Initialize(logger lager.Logger, config ExecutorConfig, cellID, zone string, time.Duration(config.EnvoyConfigReloadDuration), clock, config.ContainerProxyADSServers, + config.ProxyEnableHttp2, ) } else { proxyConfigHandler = containerstore.NewNoopProxyConfigHandler()