diff --git a/test/envoye2e/basic_flow/basic_flow_test.go b/test/envoye2e/basic_flow/basic_flow_test.go index f2fea806d5..8d983aa335 100644 --- a/test/envoye2e/basic_flow/basic_flow_test.go +++ b/test/envoye2e/basic_flow/basic_flow_test.go @@ -27,19 +27,15 @@ import ( // Stats in Client Envoy proxy. var expectedClientStats = map[string]int{ // http listener stats - "listener.127.0.0.1_{{.Ports.AppToClientProxyPort}}.http.inbound_http.downstream_rq_completed": 10, - "listener.127.0.0.1_{{.Ports.AppToClientProxyPort}}.http.inbound_http.downstream_rq_2xx": 10, - "listener.127.0.0.1_{{.Ports.ClientToServerProxyPort}}.http.outbound_http.downstream_rq_completed": 10, - "listener.127.0.0.1_{{.Ports.ClientToServerProxyPort}}.http.outbound_http.downstream_rq_2xx": 10, + "listener.127.0.0.1_{{.Ports.AppToClientProxyPort}}.http.inbound_http.downstream_rq_completed": 10, + "listener.127.0.0.1_{{.Ports.AppToClientProxyPort}}.http.inbound_http.downstream_rq_2xx": 10, } // Stats in Server Envoy proxy. var expectedServerStats = map[string]int{ // http listener stats - "listener.127.0.0.1_{{.Ports.ProxyToServerProxyPort}}.http.inbound_http.downstream_rq_completed": 10, - "listener.127.0.0.1_{{.Ports.ProxyToServerProxyPort}}.http.inbound_http.downstream_rq_2xx": 10, - "listener.127.0.0.1_{{.Ports.ClientToAppProxyPort}}.http.outbound_http.downstream_rq_completed": 10, - "listener.127.0.0.1_{{.Ports.ClientToAppProxyPort}}.http.outbound_http.downstream_rq_2xx": 10, + "listener.127.0.0.1_{{.Ports.ClientToServerProxyPort}}.http.inbound_http.downstream_rq_completed": 10, + "listener.127.0.0.1_{{.Ports.ClientToServerProxyPort}}.http.inbound_http.downstream_rq_2xx": 10, } func TestBasicFlow(t *testing.T) { diff --git a/test/envoye2e/basic_flow/basic_xds_test.go b/test/envoye2e/basic_flow/basic_xds_test.go index 4ac191d48c..9ea4241d95 100644 --- a/test/envoye2e/basic_flow/basic_xds_test.go +++ b/test/envoye2e/basic_flow/basic_xds_test.go @@ -83,10 +83,10 @@ func TestBasicHTTP(t *testing.T) { params := &driver.Params{ Vars: map[string]string{ "BackendPort": fmt.Sprintf("%d", ports.BackendPort), - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), }, XDS: int(ports.XDSPort), } @@ -98,7 +98,7 @@ func TestBasicHTTP(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, }, }).Run(params); err != nil { t.Fatal(err) @@ -110,10 +110,10 @@ func TestBasicHTTPwithTLS(t *testing.T) { params := &driver.Params{ Vars: map[string]string{ "BackendPort": fmt.Sprintf("%d", ports.BackendPort), - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), }, XDS: int(ports.XDSPort), } @@ -127,7 +127,7 @@ func TestBasicHTTPwithTLS(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, }, }).Run(params); err != nil { t.Fatal(err) @@ -140,10 +140,10 @@ func TestBasicHTTPGateway(t *testing.T) { params := &driver.Params{ Vars: map[string]string{ "BackendPort": fmt.Sprintf("%d", ports.BackendPort), - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), }, XDS: int(ports.XDSPort), } @@ -156,7 +156,7 @@ func TestBasicHTTPGateway(t *testing.T) { }, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, }, }).Run(params); err != nil { t.Fatal(err) diff --git a/test/envoye2e/env/envoy.go b/test/envoye2e/env/envoy.go index fd3830326e..d15f91ae6c 100644 --- a/test/envoye2e/env/envoy.go +++ b/test/envoye2e/env/envoy.go @@ -39,7 +39,7 @@ func (s *TestSetup) NewClientEnvoy() (*Envoy, error) { } baseID := strconv.Itoa(int(s.testName)*2 + 1) - return newEnvoy(s.ports.ClientAdminPort, confTmpl, baseID, s) + return newEnvoy(s.ports.ClientAdminPort, confTmpl, baseID, "client.yaml", s) } // NewServerEnvoy creates a new Server Envoy struct and starts envoy. @@ -50,7 +50,7 @@ func (s *TestSetup) NewServerEnvoy() (*Envoy, error) { } baseID := strconv.Itoa(int(s.testName+1) * 2) - return newEnvoy(s.ports.ServerAdminPort, confTmpl, baseID, s) + return newEnvoy(s.ports.ServerAdminPort, confTmpl, baseID, "server.yaml", s) } // Start starts the envoy process @@ -100,14 +100,29 @@ func (s *Envoy) TearDown() { } } +func copyYamlFiles(src, dst string) { + cpCmd := exec.Command("cp", "-rf", src, dst) + if err := cpCmd.Run(); err != nil { + log.Printf("Error Copying Yaml Files %s\n", err) + } +} + // NewEnvoy creates a new Envoy struct and starts envoy at the specified port. -func newEnvoy(port uint16, confTmpl, baseID string, s *TestSetup) (*Envoy, error) { +func newEnvoy(port uint16, confTmpl, baseID, yamlName string, s *TestSetup) (*Envoy, error) { confPath := filepath.Join(GetDefaultIstioOut(), fmt.Sprintf("config.conf.%v.yaml", port)) log.Printf("Envoy config: in %v\n", confPath) if err := s.CreateEnvoyConf(confPath, confTmpl); err != nil { return nil, err } + if s.copyYamlFiles { + if wd, err := os.Getwd(); err == nil { + if err := os.MkdirAll(filepath.Join(wd, "testoutput"), os.ModePerm); err == nil { + copyYamlFiles(confPath, filepath.Join(wd, "testoutput", yamlName)) + } + } + } + debugLevel, ok := os.LookupEnv("ENVOY_DEBUG") if !ok { debugLevel = "info" diff --git a/test/envoye2e/env/envoy_conf.go b/test/envoye2e/env/envoy_conf.go index efb6bfb446..575a1ed86b 100644 --- a/test/envoye2e/env/envoy_conf.go +++ b/test/envoye2e/env/envoy_conf.go @@ -22,8 +22,7 @@ import ( "text/template" ) -const envoyClientConfTemplYAML = ` -node: +const envoyClientConfTemplYAML = `node: id: test-client metadata: { {{.ClientNodeMetadata | indent 4 }} @@ -49,21 +48,11 @@ static_resources: socket_address: address: 127.0.0.1 port_value: {{.Ports.ClientToServerProxyPort}} - - name: server - connect_timeout: 5s - type: STATIC - load_assignment: - cluster_name: server - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ProxyToServerProxyPort}} +{{.UpstreamFiltersInClient | indent 4 }} +{{.ClusterTLSContext | indent 4 }} listeners: - name: app-to-client - traffic_direction: INBOUND + traffic_direction: OUTBOUND address: socket_address: address: 127.0.0.1 @@ -92,40 +81,9 @@ static_resources: route: cluster: client timeout: 0s - - name: client-to-proxy - traffic_direction: OUTBOUND - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ClientToServerProxyPort}} - filter_chains: - - filters: - - name: envoy.http_connection_manager - config: - codec_type: AUTO - stat_prefix: outbound_http - access_log: - - name: envoy.file_access_log - config: - path: {{.ClientAccessLogPath}} - http_filters: -{{.FiltersBeforeEnvoyRouterInClientToProxy | indent 10 }} - - name: envoy.router - route_config: - name: client-to-proxy-route - virtual_hosts: - - name: client-to-proxy-route - domains: ["*"] - routes: - - match: - prefix: / - route: - cluster: server - timeout: 0s -` +{{.TLSContext | indent 6 }}` -const envoyServerConfTemplYAML = ` -node: +const envoyServerConfTemplYAML = `node: id: test-server metadata: { {{.ServerNodeMetadata | indent 4 }} @@ -139,18 +97,6 @@ admin: port_value: {{.Ports.ServerAdminPort}} static_resources: clusters: - - name: inbound|9080|http|backend.default.svc.cluster.local - connect_timeout: 5s - type: STATIC - load_assignment: - cluster_name: inbound|9080|http|backend.default.svc.cluster.local - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.BackendPort}} - name: inbound|9080|http|server.default.svc.cluster.local connect_timeout: 5s type: STATIC @@ -162,16 +108,18 @@ static_resources: address: socket_address: address: 127.0.0.1 - port_value: {{.Ports.ClientToAppProxyPort}} + port_value: {{.Ports.BackendPort}} +{{.ClusterTLSContext | indent 4 }} listeners: - - name: proxy-to-server + - name: proxy-to-backend traffic_direction: INBOUND address: socket_address: address: 127.0.0.1 - port_value: {{.Ports.ProxyToServerProxyPort}} + port_value: {{.Ports.ClientToServerProxyPort}} filter_chains: - filters: +{{.FiltersBeforeHTTPConnectionManagerInProxyToServer | indent 6 }} - name: envoy.http_connection_manager config: codec_type: AUTO @@ -184,9 +132,9 @@ static_resources: {{.FiltersBeforeEnvoyRouterInProxyToServer | indent 10 }} - name: envoy.router route_config: - name: proxy-to-server-route + name: proxy-to-backend-route virtual_hosts: - - name: proxy-to-server-route + - name: proxy-to-backend-route domains: ["*"] routes: - match: @@ -194,36 +142,7 @@ static_resources: route: cluster: inbound|9080|http|server.default.svc.cluster.local timeout: 0s - - name: client-to-app - address: - socket_address: - address: 127.0.0.1 - port_value: {{.Ports.ClientToAppProxyPort}} - filter_chains: - - filters: - - name: envoy.http_connection_manager - config: - codec_type: AUTO - stat_prefix: outbound_http - access_log: - - name: envoy.file_access_log - config: - path: {{.ServerAccessLogPath}} - http_filters: -{{.FiltersBeforeEnvoyRouterInClientToApp | indent 10 }} - - name: envoy.router - route_config: - name: client-to-app-route - virtual_hosts: - - name: client-to-app-route - domains: ["*"] - routes: - - match: - prefix: / - route: - cluster: inbound|9080|http|backend.default.svc.cluster.local - timeout: 0s -` +{{.TLSContext | indent 6 }}` // CreateEnvoyConf create envoy config. func (s *TestSetup) CreateEnvoyConf(path, confTmpl string) error { diff --git a/test/envoye2e/env/http_client.go b/test/envoye2e/env/http_client.go index e7b8f460f9..377ba8b28d 100644 --- a/test/envoye2e/env/http_client.go +++ b/test/envoye2e/env/http_client.go @@ -15,12 +15,15 @@ package env import ( + "crypto/tls" + "crypto/x509" "fmt" "io/ioutil" "log" "net" "net/http" "net/url" + "path/filepath" "strings" "time" ) @@ -53,6 +56,50 @@ func HTTPGet(url string) (code int, respBody string, err error) { return code, respBody, nil } +// HTTPGet send GET +func HTTPTlsGet(url, rootdir string, port uint16) (code int, respBody string, err error) { + certPool := x509.NewCertPool() + bs, err := ioutil.ReadFile(filepath.Join(rootdir, "testdata/certs/cert-chain.pem")) + if err != nil { + return 0, "", fmt.Errorf("failed to read client ca cert: %s", err) + } + ok := certPool.AppendCertsFromPEM(bs) + if !ok { + return 0, "", fmt.Errorf("failed to append client certs") + } + + certificate, err := tls.LoadX509KeyPair(filepath.Join(rootdir, "testdata/certs/cert-chain.pem"), + filepath.Join(rootdir, "testdata/certs/key.pem")) + if err != nil { + return 0, "", fmt.Errorf("failed to get certificate") + } + tlsConf := &tls.Config{Certificates: []tls.Certificate{certificate}, ServerName: "localhost", RootCAs: certPool} + tr := &http.Transport{ + TLSClientConfig: tlsConf, + //DialTLS: func(network, addr string) (net.Conn, error) { + // return tls.Dial("tcp", fmt.Sprintf("localhost:%d", port), tlsConf) + //return tls.Dial(network, addr, tlsConf) + //}, + } + log.Println("HTTP TLS GET", url) + client := &http.Client{Timeout: httpTimeOut, Transport: tr} + resp, err := client.Get(url) + log.Println("resp ", resp) + if err != nil { + log.Println(err) + return 0, "", err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println(err) + return 0, "", err + } + respBody = string(body) + code = resp.StatusCode + return code, respBody, nil +} + // HTTPPost sends POST func HTTPPost(url string, contentType string, reqBody string) (code int, respBody string, err error) { log.Println("HTTP POST", url) @@ -133,9 +180,20 @@ func HTTPGetWithHeaders(l string, headers map[string]string) (code int, respBody // WaitForHTTPServer waits for a HTTP server func WaitForHTTPServer(url string) error { + return WaitForHTTPServerWithTLS(url, "", false, 0) +} + +// WaitForHTTPServer waits for a HTTP server +func WaitForHTTPServerWithTLS(url, rootDir string, enableTLS bool, port uint16) error { for i := 0; i < maxAttempts; i++ { log.Println("Pinging URL: ", url) - code, _, err := HTTPGet(url) + var err error + var code int + if enableTLS { + code, _, err = HTTPTlsGet(url, rootDir, port) + } else { + code, _, err = HTTPGet(url) + } if err == nil && code == http.StatusOK { log.Println("Server is up and running...") return nil diff --git a/test/envoye2e/env/http_server.go b/test/envoye2e/env/http_server.go index d0b42729f4..c4f5bfc125 100644 --- a/test/envoye2e/env/http_server.go +++ b/test/envoye2e/env/http_server.go @@ -15,11 +15,14 @@ package env import ( + "crypto/tls" + "crypto/x509" "fmt" "io/ioutil" "log" "net" "net/http" + "path/filepath" "strconv" "sync" "time" @@ -69,8 +72,11 @@ const publicKey = ` // HTTPServer stores data for a HTTP server. type HTTPServer struct { - port uint16 - lis net.Listener + enableTLS bool + port uint16 + rootTestDir string + lis net.Listener + TLSConfig *tls.Config reqHeaders http.Header mu sync.Mutex @@ -131,16 +137,45 @@ func (s *HTTPServer) handle(w http.ResponseWriter, r *http.Request) { } // NewHTTPServer creates a new HTTP server. -func NewHTTPServer(port uint16) (*HTTPServer, error) { +func NewHTTPServer(port uint16, enableTLS bool, rootDir string) (*HTTPServer, error) { log.Printf("Http server listening on port %v\n", port) + var config *tls.Config + if enableTLS { + certificate, err := tls.LoadX509KeyPair( + filepath.Join(rootDir, "testdata/certs/cert-chain.pem"), + filepath.Join(rootDir, "testdata/certs/key.pem")) + if err != nil { + return nil, err + } + caCert, err := ioutil.ReadFile(filepath.Join(rootDir, "testdata/certs/root-cert.pem")) + if err != nil { + return nil, err + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + config = &tls.Config{ + Certificates: []tls.Certificate{certificate}, + //NextProtos: []string{"http/1.1","h2","istio2"}, + ClientAuth: tls.RequestClientCert, + ClientCAs: caCertPool, + ServerName: "localhost", + } + + } + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { log.Fatal(err) return nil, err } + return &HTTPServer{ - port: port, - lis: lis, + port: port, + lis: lis, + enableTLS: enableTLS, + rootTestDir: rootDir, + TLSConfig: config, }, nil } @@ -152,13 +187,27 @@ func (s *HTTPServer) Start() <-chan error { m := http.NewServeMux() m.HandleFunc("/", s.handle) m.HandleFunc("/pubkey", pubkeyHandler) - errCh <- http.Serve(s.lis, m) + server := http.Server{ + Addr: fmt.Sprintf(":%d", s.port), + Handler: m, + TLSConfig: s.TLSConfig, + } + if s.enableTLS { + errCh <- server.ServeTLS(s.lis, filepath.Join(s.rootTestDir, "testdata/certs/cert-chain.pem"), + filepath.Join(s.rootTestDir, "testdata/certs/key.pem")) + } else { + errCh <- server.Serve(s.lis) + } }() go func() { - url := fmt.Sprintf("http://localhost:%v/echo", s.port) - errCh <- WaitForHTTPServer(url) + var url string + if s.enableTLS { + url = fmt.Sprintf("https://localhost:%v/echo", s.port) + } else { + url = fmt.Sprintf("http://localhost:%v/echo", s.port) + } + errCh <- WaitForHTTPServerWithTLS(url, s.rootTestDir, s.enableTLS, s.port) }() - return errCh } diff --git a/test/envoye2e/env/ports.go b/test/envoye2e/env/ports.go index d7c6603713..d3651927a1 100644 --- a/test/envoye2e/env/ports.go +++ b/test/envoye2e/env/ports.go @@ -31,6 +31,7 @@ const ( StackdriverPluginTest TCPMetadataExchangeTest + HTTPMetadataExchangeTest // xDS driven tests BasicHTTP @@ -63,10 +64,6 @@ type Ports struct { AppToClientProxyPort uint16 ClientToServerProxyPort uint16 ServerAdminPort uint16 - ProxyToServerProxyPort uint16 - ClientToAppProxyPort uint16 - ClientTCPProxyPort uint16 - ServerTCPProxyPort uint16 XDSPort uint16 SDPort uint16 } @@ -102,11 +99,7 @@ func NewPorts(name uint16) *Ports { AppToClientProxyPort: base + 2, ClientToServerProxyPort: base + 3, ServerAdminPort: base + 4, - ProxyToServerProxyPort: base + 5, - ClientToAppProxyPort: base + 6, - ClientTCPProxyPort: base + 7, - ServerTCPProxyPort: base + 8, - XDSPort: base + 9, - SDPort: base + 10, + XDSPort: base + 5, + SDPort: base + 6, } } diff --git a/test/envoye2e/env/setup.go b/test/envoye2e/env/setup.go index 923e4a604a..723d920d74 100644 --- a/test/envoye2e/env/setup.go +++ b/test/envoye2e/env/setup.go @@ -30,23 +30,25 @@ import ( // TestSetup store data for a test. type TestSetup struct { - t *testing.T - epoch int - ports *Ports - - clientEnvoy *Envoy - serverEnvoy *Envoy - backend *HTTPServer - tcpBackend *TCPServer - testName uint16 stress bool noProxy bool noBackend bool disableHotRestart bool checkDict bool startTCPBackend bool + copyYamlFiles bool + // Whether TLS is Enabled or not. + EnableTLS bool - FiltersBeforeMixer string + t *testing.T + ports *Ports + clientEnvoy *Envoy + serverEnvoy *Envoy + backend *HTTPServer + tcpBackend *TCPServer + + testName uint16 + epoch int // ClientEnvoyTemplate is the bootstrap config used by client envoy. ClientEnvoyTemplate string @@ -54,12 +56,6 @@ type TestSetup struct { // ServerEnvoyTemplate is the bootstrap config used by client envoy. ServerEnvoyTemplate string - // EnvoyParams contain extra envoy parameters to pass in the CLI (cluster, node) - EnvoyParams []string - - // EnvoyConfigOpt allows passing additional parameters to the EnvoyTemplate - EnvoyConfigOpt map[string]interface{} - // IstioSrc is the base directory of istio sources. May be set for finding testdata or // other files in the source tree IstioSrc string @@ -80,18 +76,14 @@ type TestSetup struct { // listener. FiltersBeforeEnvoyRouterInAppToClient string - // FiltersBeforeEnvoyRouterInClientToProxy are the filters that come before envoy.router http filter in - // ClientToProxy listener. - FiltersBeforeEnvoyRouterInClientToProxy string + // FiltersBeforeHTTPConnectionManagerInProxyToServer are the filters that come before http connection manager filter + // ProxyToServer listener. + FiltersBeforeHTTPConnectionManagerInProxyToServer string // FiltersBeforeEnvoyRouterInProxyToServer are the filters that come before envoy.router http filter in // ProxyToServer listener. FiltersBeforeEnvoyRouterInProxyToServer string - // FiltersBeforeEnvoyRouterInClientToApp are the filters that come before envoy.router http filter in ClientToApp - // listener. - FiltersBeforeEnvoyRouterInClientToApp string - // Dir is the working dir for envoy Dir string @@ -101,9 +93,6 @@ type TestSetup struct { // Client side Envoy node metadata. ClientNodeMetadata string - // Whether TLS is Enabled or not. - EnableTLS bool - // Format for client accesslog AccesslogFormat string @@ -121,6 +110,12 @@ type TestSetup struct { // ExtraConfig that needs to be passed to envoy. Ex stats_config. ExtraConfig string + + // EnvoyParams contain extra envoy parameters to pass in the CLI (cluster, node) + EnvoyParams []string + + // EnvoyConfigOpt allows passing additional parameters to the EnvoyTemplate + EnvoyConfigOpt map[string]interface{} } // Stat represents a prometheus stat with labels. @@ -176,6 +171,11 @@ func (s *TestSetup) SetStartTCPBackend(yes bool) { s.startTCPBackend = yes } +// SetCopyYamlFiles set copyYamlFiles flag +func (s *TestSetup) SetCopyYamlFiles(yes bool) { + s.copyYamlFiles = yes +} + // SetFiltersBeforeEnvoyRouterInAppToClient sets the configurations of the filters that come before envoy.router http // filter in AppToClient listener. func (s *TestSetup) SetFiltersBeforeEnvoyRouterInAppToClient(filters string) { @@ -197,22 +197,16 @@ func (s *TestSetup) SetClusterTLSContext(clusterTLSContext string) { s.ClusterTLSContext = clusterTLSContext } -// SetFiltersBeforeEnvoyRouterInClientToProxy sets the configurations of the filters that come before envoy.router http -// filter in ClientToProxy listener. -func (s *TestSetup) SetFiltersBeforeEnvoyRouterInClientToProxy(filters string) { - s.FiltersBeforeEnvoyRouterInClientToProxy = filters -} - // SetFiltersBeforeEnvoyRouterInProxyToServer sets the configurations of the filters tthat come before envoy.router http // filter in ProxyToServer listener. func (s *TestSetup) SetFiltersBeforeEnvoyRouterInProxyToServer(filters string) { s.FiltersBeforeEnvoyRouterInProxyToServer = filters } -// SetFiltersBeforeEnvoyRouterInClientToApp sets the configurations of the filters that come before envoy.router http -// filter in ClientToApp listener. -func (s *TestSetup) SetFiltersBeforeEnvoyRouterInClientToApp(filters string) { - s.FiltersBeforeEnvoyRouterInClientToApp = filters +// SetFiltersBeforeHTTPConnectionManagerInProxyToServer sets the configurations of the filters that come before http +// connection manager filter in ProxyToServer listener. +func (s *TestSetup) SeFiltersBeforeHTTPConnectionManagerInProxyToServer(filters string) { + s.FiltersBeforeHTTPConnectionManagerInProxyToServer = filters } // SetServerNodeMetadata sets envoy's node metadata. @@ -275,7 +269,7 @@ func (s *TestSetup) SetUpClientServerEnvoy() error { } if !s.noBackend { - s.backend, err = NewHTTPServer(s.ports.BackendPort) + s.backend, err = NewHTTPServer(s.ports.BackendPort, s.EnableTLS, s.Dir) if err != nil { log.Printf("unable to create HTTP server %v", err) } else { diff --git a/test/envoye2e/env/tcp_envoy_conf.go b/test/envoye2e/env/tcp_envoy_conf.go index d40438ce2c..1ad5c0c3d7 100644 --- a/test/envoye2e/env/tcp_envoy_conf.go +++ b/test/envoye2e/env/tcp_envoy_conf.go @@ -110,7 +110,7 @@ static_resources: typed_config: {} filter_chains: - filters: -{{.FiltersBeforeEnvoyRouterInClientToApp | indent 6 }} +{{.FiltersBeforeEnvoyRouterInProxyToServer | indent 6 }} - name: envoy.tcp_proxy config: stat_prefix: outbound_tcp diff --git a/test/envoye2e/http_metadata_exchange/doc.go b/test/envoye2e/http_metadata_exchange/doc.go new file mode 100644 index 0000000000..5aaa414ef8 --- /dev/null +++ b/test/envoye2e/http_metadata_exchange/doc.go @@ -0,0 +1,16 @@ +// Copyright 2019 Istio 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 client contains an integration test for envoy proxy. +package client diff --git a/test/envoye2e/http_metadata_exchange/http_metadata_exchange_test.go b/test/envoye2e/http_metadata_exchange/http_metadata_exchange_test.go new file mode 100644 index 0000000000..e8a8b2d98f --- /dev/null +++ b/test/envoye2e/http_metadata_exchange/http_metadata_exchange_test.go @@ -0,0 +1,274 @@ +// Copyright 2019 Istio 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 client_test + +import ( + "bytes" + "fmt" + "testing" + + "text/template" + + "istio.io/proxy/test/envoye2e/driver" + "istio.io/proxy/test/envoye2e/env" +) + +const metadataExchangeIstioDownstreamConfigFilter = `- name: envoy.filters.network.metadata_exchange + config: + protocol: istio2` + +const metadataExchangeIstioStatsServerFilter = `- name: envoy.filters.http.wasm + config: + config: + root_id: "stats_inbound" + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.stats" } + configuration: | + { "debug": "false", max_peer_cache_size: 20, field_separator: ";.;" }` +const metadataExchangeIstioUpstreamConfigFilterChain = `filters: +- name: envoy.filters.network.upstream.metadata_exchange + typed_config: + "@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange + protocol: istio2` + +const metadataExchangeIstioStatsClientFilter = `- name: envoy.filters.http.wasm + config: + config: + root_id: "stats_outbound" + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.stats" } + configuration: | + { "debug": "false", max_peer_cache_size: 20, field_separator: ";.;" }` + +const tlsContext = `tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: { filename: "testdata/certs/cert-chain.pem" } + private_key: { filename: "testdata/certs/key.pem" } + validation_context: + trusted_ca: { filename: "testdata/certs/root-cert.pem" } + require_client_certificate: true` + +const clusterTLSContext = `tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: { filename: "testdata/certs/cert-chain.pem" } + private_key: { filename: "testdata/certs/key.pem" } + validation_context: + trusted_ca: { filename: "testdata/certs/root-cert.pem" }` + +const outboundNodeMetadata = `"NAMESPACE": "default", +"INCLUDE_INBOUND_PORTS": "9080", +"app": "productpage", +"EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,CANONICAL_TELEMETRY_SERVICE,MESH_ID,SERVICE_ACCOUNT", +"INSTANCE_IPS": "10.52.0.34,fe80::a075:11ff:fe5e:f1cd", +"pod-template-hash": "84975bc778", +"INTERCEPTION_MODE": "REDIRECT", +"SERVICE_ACCOUNT": "bookinfo-productpage", +"CONFIG_NAMESPACE": "default", +"version": "v1", +"OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/productpage-v1", +"WORKLOAD_NAME": "productpage-v1", +"ISTIO_VERSION": "1.3-dev", +"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container productpage", +"POD_NAME": "productpage-v1-84975bc778-pxz2w", +"istio": "sidecar", +"PLATFORM_METADATA": { + "gcp_cluster_name": "test-cluster", + "gcp_project": "test-project", + "gcp_cluster_location": "us-east4-b" +}, +"LABELS": { + "app": "productpage", + "version": "v1", + "pod-template-hash": "84975bc778" +}, +"ISTIO_PROXY_SHA": "istio-proxy:47e4559b8e4f0d516c0d17b233d127a3deb3d7ce", +"NAME": "productpage-v1-84975bc778-pxz2w",` + +const inboundNodeMetadata = `"NAMESPACE": "default", +"INCLUDE_INBOUND_PORTS": "9080", +"app": "ratings", +"EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,CANONICAL_TELEMETRY_SERVICE,MESH_ID,SERVICE_ACCOUNT", +"INSTANCE_IPS": "10.52.0.34,fe80::a075:11ff:fe5e:f1cd", +"pod-template-hash": "84975bc778", +"INTERCEPTION_MODE": "REDIRECT", +"SERVICE_ACCOUNT": "bookinfo-ratings", +"CONFIG_NAMESPACE": "default", +"version": "v1", +"OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/ratings-v1", +"WORKLOAD_NAME": "ratings-v1", +"ISTIO_VERSION": "1.3-dev", +"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container ratings", +"POD_NAME": "ratings-v1-84975bc778-pxz2w", +"istio": "sidecar", +"PLATFORM_METADATA": { + "gcp_cluster_name": "test-cluster", + "gcp_project": "test-project", + "gcp_cluster_location": "us-east4-b" +}, +"LABELS": { + "app": "ratings", + "version": "v1", + "pod-template-hash": "84975bc778" +}, +"ISTIO_PROXY_SHA": "istio-proxy:47e4559b8e4f0d516c0d17b233d127a3deb3d7ce", +"NAME": "ratings-v1-84975bc778-pxz2w",` + +const statsConfig = `stats_config: + use_all_default_tags: true + stats_tags: + - tag_name: "reporter" + regex: "(reporter=\\.=(.+?);\\.;)" + - tag_name: "source_namespace" + regex: "(source_namespace=\\.=(.+?);\\.;)" + - tag_name: "source_workload" + regex: "(source_workload=\\.=(.+?);\\.;)" + - tag_name: "source_workload_namespace" + regex: "(source_workload_namespace=\\.=(.+?);\\.;)" + - tag_name: "source_principal" + regex: "(source_principal=\\.=(.+?);\\.;)" + - tag_name: "source_app" + regex: "(source_app=\\.=(.+?);\\.;)" + - tag_name: "source_version" + regex: "(source_version=\\.=(.+?);\\.;)" + - tag_name: "destination_namespace" + regex: "(destination_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_workload" + regex: "(destination_workload=\\.=(.+?);\\.;)" + - tag_name: "destination_workload_namespace" + regex: "(destination_workload_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_principal" + regex: "(destination_principal=\\.=(.+?);\\.;)" + - tag_name: "destination_app" + regex: "(destination_app=\\.=(.+?);\\.;)" + - tag_name: "destination_version" + regex: "(destination_version=\\.=(.+?);\\.;)" + - tag_name: "destination_service" + regex: "(destination_service=\\.=(.+?);\\.;)" + - tag_name: "destination_service_name" + regex: "(destination_service_name=\\.=(.+?);\\.;)" + - tag_name: "destination_service_namespace" + regex: "(destination_service_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_port" + regex: "(destination_port=\\.=(.+?);\\.;)" + - tag_name: "request_protocol" + regex: "(request_protocol=\\.=(.+?);\\.;)" + - tag_name: "response_code" + regex: "(response_code=\\.=(.+?);\\.;)|_rq(_(\\.d{3}))$" + - tag_name: "response_flags" + regex: "(response_flags=\\.=(.+?);\\.;)" + - tag_name: "connection_security_policy" + regex: "(connection_security_policy=\\.=(.+?);\\.;)" + - tag_name: "permissive_response_code" + regex: "(permissive_response_code=\\.=(.+?);\\.;)" + - tag_name: "permissive_response_policyid" + regex: "(permissive_response_policyid=\\.=(.+?);\\.;)" + - tag_name: "cache" + regex: "(cache\\.(.+?)\\.)" + - tag_name: "component" + regex: "(component\\.(.+?)\\.)" + - tag_name: "tag" + regex: "(tag\\.(.+?);\\.)"` + +// Stats in Client Envoy proxy. +var expectedClientStats = map[string]int{ + "cluster.client.metadata_exchange.alpn_protocol_found": 1, + "cluster.client.metadata_exchange.alpn_protocol_not_found": 0, + "cluster.client.metadata_exchange.initial_header_not_found": 0, + "cluster.client.metadata_exchange.header_not_found": 0, + "cluster.client.metadata_exchange.metadata_added": 1, +} + +// Stats in Server Envoy proxy. +var expectedServerStats = map[string]int{ + "metadata_exchange.alpn_protocol_found": 1, + "metadata_exchange.alpn_protocol_not_found": 0, + "metadata_exchange.initial_header_not_found": 0, + "metadata_exchange.header_not_found": 0, + "metadata_exchange.metadata_added": 1, +} + +func TestHttpMetadataExchange(t *testing.T) { + testPlugins(t, func(s *env.TestSetup) { + serverStats := map[string]env.Stat{ + "istio_requests_total": {Value: 10, Labels: map[string]string{"destination_service": "server.default.svc.cluster.local", + "source_app": "productpage", "destination_app": "ratings"}}, + } + s.VerifyPrometheusStats(serverStats, s.Ports().ServerAdminPort) + s.VerifyEnvoyStats(getParsedExpectedStats(expectedClientStats, t, s), s.Ports().ClientAdminPort) + s.VerifyEnvoyStats(getParsedExpectedStats(expectedServerStats, t, s), s.Ports().ServerAdminPort) + }) +} + +type verifyFn func(s *env.TestSetup) + +func testPlugins(t *testing.T, fn verifyFn) { + s := env.NewClientServerEnvoyTestSetup(env.HTTPMetadataExchangeTest, t) + s.Dir = driver.BazelWorkspace() + s.SetTLSContext(tlsContext) + s.SetClusterTLSContext(clusterTLSContext) + s.SetUpstreamFiltersInClient(metadataExchangeIstioUpstreamConfigFilterChain) + s.SeFiltersBeforeHTTPConnectionManagerInProxyToServer(metadataExchangeIstioDownstreamConfigFilter) + s.SetFiltersBeforeEnvoyRouterInAppToClient(metadataExchangeIstioStatsClientFilter) + s.SetFiltersBeforeEnvoyRouterInProxyToServer(metadataExchangeIstioStatsServerFilter) + s.SetServerNodeMetadata(inboundNodeMetadata) + s.SetClientNodeMetadata(outboundNodeMetadata) + s.SetExtraConfig(statsConfig) + s.SetEnableTLS(true) + s.SetCopyYamlFiles(true) + if err := s.SetUpClientServerEnvoy(); err != nil { + t.Fatalf("Failed to setup test: %v", err) + } + defer s.TearDownClientServerEnvoy() + + url := fmt.Sprintf("https://127.0.0.1:%d/echo", s.Ports().AppToClientProxyPort) + + // Issues a GET echo request with 0 size body + tag := "OKGet" + for i := 0; i < 10; i++ { + if _, _, err := env.HTTPTlsGet(url, s.Dir, s.Ports().AppToClientProxyPort); err != nil { + t.Errorf("Failed in request %s: %v", tag, err) + } + } + fn(s) +} + +func getParsedExpectedStats(expectedStats map[string]int, t *testing.T, s *env.TestSetup) map[string]int { + parsedExpectedStats := make(map[string]int) + for key, value := range expectedStats { + tmpl, err := template.New("parse_state").Parse(key) + if err != nil { + t.Errorf("failed to parse config template: %v", err) + } + + var tpl bytes.Buffer + err = tmpl.Execute(&tpl, s) + if err != nil { + t.Errorf("failed to execute config template: %v", err) + } + parsedExpectedStats[tpl.String()] = value + } + + return parsedExpectedStats +} diff --git a/test/envoye2e/http_metadata_exchange/testoutput/client.yaml b/test/envoye2e/http_metadata_exchange/testoutput/client.yaml new file mode 100644 index 0000000000..2e4b44a2c5 --- /dev/null +++ b/test/envoye2e/http_metadata_exchange/testoutput/client.yaml @@ -0,0 +1,171 @@ +node: + id: test-client + metadata: { + "NAMESPACE": "default", + "INCLUDE_INBOUND_PORTS": "9080", + "app": "productpage", + "EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,CANONICAL_TELEMETRY_SERVICE,MESH_ID,SERVICE_ACCOUNT", + "INSTANCE_IPS": "10.52.0.34,fe80::a075:11ff:fe5e:f1cd", + "pod-template-hash": "84975bc778", + "INTERCEPTION_MODE": "REDIRECT", + "SERVICE_ACCOUNT": "bookinfo-productpage", + "CONFIG_NAMESPACE": "default", + "version": "v1", + "OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/productpage-v1", + "WORKLOAD_NAME": "productpage-v1", + "ISTIO_VERSION": "1.3-dev", + "kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container productpage", + "POD_NAME": "productpage-v1-84975bc778-pxz2w", + "istio": "sidecar", + "PLATFORM_METADATA": { + "gcp_cluster_name": "test-cluster", + "gcp_project": "test-project", + "gcp_cluster_location": "us-east4-b" + }, + "LABELS": { + "app": "productpage", + "version": "v1", + "pod-template-hash": "84975bc778" + }, + "ISTIO_PROXY_SHA": "istio-proxy:47e4559b8e4f0d516c0d17b233d127a3deb3d7ce", + "NAME": "productpage-v1-84975bc778-pxz2w", + } +stats_config: + use_all_default_tags: true + stats_tags: + - tag_name: "reporter" + regex: "(reporter=\\.=(.+?);\\.;)" + - tag_name: "source_namespace" + regex: "(source_namespace=\\.=(.+?);\\.;)" + - tag_name: "source_workload" + regex: "(source_workload=\\.=(.+?);\\.;)" + - tag_name: "source_workload_namespace" + regex: "(source_workload_namespace=\\.=(.+?);\\.;)" + - tag_name: "source_principal" + regex: "(source_principal=\\.=(.+?);\\.;)" + - tag_name: "source_app" + regex: "(source_app=\\.=(.+?);\\.;)" + - tag_name: "source_version" + regex: "(source_version=\\.=(.+?);\\.;)" + - tag_name: "destination_namespace" + regex: "(destination_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_workload" + regex: "(destination_workload=\\.=(.+?);\\.;)" + - tag_name: "destination_workload_namespace" + regex: "(destination_workload_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_principal" + regex: "(destination_principal=\\.=(.+?);\\.;)" + - tag_name: "destination_app" + regex: "(destination_app=\\.=(.+?);\\.;)" + - tag_name: "destination_version" + regex: "(destination_version=\\.=(.+?);\\.;)" + - tag_name: "destination_service" + regex: "(destination_service=\\.=(.+?);\\.;)" + - tag_name: "destination_service_name" + regex: "(destination_service_name=\\.=(.+?);\\.;)" + - tag_name: "destination_service_namespace" + regex: "(destination_service_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_port" + regex: "(destination_port=\\.=(.+?);\\.;)" + - tag_name: "request_protocol" + regex: "(request_protocol=\\.=(.+?);\\.;)" + - tag_name: "response_code" + regex: "(response_code=\\.=(.+?);\\.;)|_rq(_(\\.d{3}))$" + - tag_name: "response_flags" + regex: "(response_flags=\\.=(.+?);\\.;)" + - tag_name: "connection_security_policy" + regex: "(connection_security_policy=\\.=(.+?);\\.;)" + - tag_name: "permissive_response_code" + regex: "(permissive_response_code=\\.=(.+?);\\.;)" + - tag_name: "permissive_response_policyid" + regex: "(permissive_response_policyid=\\.=(.+?);\\.;)" + - tag_name: "cache" + regex: "(cache\\.(.+?)\\.)" + - tag_name: "component" + regex: "(component\\.(.+?)\\.)" + - tag_name: "tag" + regex: "(tag\\.(.+?);\\.)" +admin: + access_log_path: /tmp/envoy-client-access.log + address: + socket_address: + address: 127.0.0.1 + port_value: 20081 +static_resources: + clusters: + - name: client + connect_timeout: 5s + type: STATIC + load_assignment: + cluster_name: client + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 20083 + filters: + - name: envoy.filters.network.upstream.metadata_exchange + typed_config: + "@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange + protocol: istio2 + tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: { filename: "testdata/certs/cert-chain.pem" } + private_key: { filename: "testdata/certs/key.pem" } + validation_context: + trusted_ca: { filename: "testdata/certs/root-cert.pem" } + listeners: + - name: app-to-client + traffic_direction: OUTBOUND + address: + socket_address: + address: 127.0.0.1 + port_value: 20082 + filter_chains: + - filters: + - name: envoy.http_connection_manager + config: + codec_type: AUTO + stat_prefix: inbound_http + access_log: + - name: envoy.file_access_log + config: + path: /tmp/envoy-client-access.log + http_filters: + - name: envoy.filters.http.wasm + config: + config: + root_id: "stats_outbound" + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.stats" } + configuration: | + { "debug": "false", max_peer_cache_size: 20, field_separator: ";.;" } + - name: envoy.router + route_config: + name: app-to-client-route + virtual_hosts: + - name: app-to-client-route + domains: ["*"] + routes: + - match: + prefix: / + route: + cluster: client + timeout: 0s + tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: { filename: "testdata/certs/cert-chain.pem" } + private_key: { filename: "testdata/certs/key.pem" } + validation_context: + trusted_ca: { filename: "testdata/certs/root-cert.pem" } + require_client_certificate: true \ No newline at end of file diff --git a/test/envoye2e/http_metadata_exchange/testoutput/server.yaml b/test/envoye2e/http_metadata_exchange/testoutput/server.yaml new file mode 100644 index 0000000000..a751e7385b --- /dev/null +++ b/test/envoye2e/http_metadata_exchange/testoutput/server.yaml @@ -0,0 +1,169 @@ +node: + id: test-server + metadata: { + "NAMESPACE": "default", + "INCLUDE_INBOUND_PORTS": "9080", + "app": "ratings", + "EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,CANONICAL_TELEMETRY_SERVICE,MESH_ID,SERVICE_ACCOUNT", + "INSTANCE_IPS": "10.52.0.34,fe80::a075:11ff:fe5e:f1cd", + "pod-template-hash": "84975bc778", + "INTERCEPTION_MODE": "REDIRECT", + "SERVICE_ACCOUNT": "bookinfo-ratings", + "CONFIG_NAMESPACE": "default", + "version": "v1", + "OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/ratings-v1", + "WORKLOAD_NAME": "ratings-v1", + "ISTIO_VERSION": "1.3-dev", + "kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container ratings", + "POD_NAME": "ratings-v1-84975bc778-pxz2w", + "istio": "sidecar", + "PLATFORM_METADATA": { + "gcp_cluster_name": "test-cluster", + "gcp_project": "test-project", + "gcp_cluster_location": "us-east4-b" + }, + "LABELS": { + "app": "ratings", + "version": "v1", + "pod-template-hash": "84975bc778" + }, + "ISTIO_PROXY_SHA": "istio-proxy:47e4559b8e4f0d516c0d17b233d127a3deb3d7ce", + "NAME": "ratings-v1-84975bc778-pxz2w", + } +stats_config: + use_all_default_tags: true + stats_tags: + - tag_name: "reporter" + regex: "(reporter=\\.=(.+?);\\.;)" + - tag_name: "source_namespace" + regex: "(source_namespace=\\.=(.+?);\\.;)" + - tag_name: "source_workload" + regex: "(source_workload=\\.=(.+?);\\.;)" + - tag_name: "source_workload_namespace" + regex: "(source_workload_namespace=\\.=(.+?);\\.;)" + - tag_name: "source_principal" + regex: "(source_principal=\\.=(.+?);\\.;)" + - tag_name: "source_app" + regex: "(source_app=\\.=(.+?);\\.;)" + - tag_name: "source_version" + regex: "(source_version=\\.=(.+?);\\.;)" + - tag_name: "destination_namespace" + regex: "(destination_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_workload" + regex: "(destination_workload=\\.=(.+?);\\.;)" + - tag_name: "destination_workload_namespace" + regex: "(destination_workload_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_principal" + regex: "(destination_principal=\\.=(.+?);\\.;)" + - tag_name: "destination_app" + regex: "(destination_app=\\.=(.+?);\\.;)" + - tag_name: "destination_version" + regex: "(destination_version=\\.=(.+?);\\.;)" + - tag_name: "destination_service" + regex: "(destination_service=\\.=(.+?);\\.;)" + - tag_name: "destination_service_name" + regex: "(destination_service_name=\\.=(.+?);\\.;)" + - tag_name: "destination_service_namespace" + regex: "(destination_service_namespace=\\.=(.+?);\\.;)" + - tag_name: "destination_port" + regex: "(destination_port=\\.=(.+?);\\.;)" + - tag_name: "request_protocol" + regex: "(request_protocol=\\.=(.+?);\\.;)" + - tag_name: "response_code" + regex: "(response_code=\\.=(.+?);\\.;)|_rq(_(\\.d{3}))$" + - tag_name: "response_flags" + regex: "(response_flags=\\.=(.+?);\\.;)" + - tag_name: "connection_security_policy" + regex: "(connection_security_policy=\\.=(.+?);\\.;)" + - tag_name: "permissive_response_code" + regex: "(permissive_response_code=\\.=(.+?);\\.;)" + - tag_name: "permissive_response_policyid" + regex: "(permissive_response_policyid=\\.=(.+?);\\.;)" + - tag_name: "cache" + regex: "(cache\\.(.+?)\\.)" + - tag_name: "component" + regex: "(component\\.(.+?)\\.)" + - tag_name: "tag" + regex: "(tag\\.(.+?);\\.)" +admin: + access_log_path: /tmp/envoy-server-access.log + address: + socket_address: + address: 127.0.0.1 + port_value: 20084 +static_resources: + clusters: + - name: inbound|9080|http|server.default.svc.cluster.local + connect_timeout: 5s + type: STATIC + load_assignment: + cluster_name: inbound|9080|http|server.default.svc.cluster.local + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 20080 + tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: { filename: "testdata/certs/cert-chain.pem" } + private_key: { filename: "testdata/certs/key.pem" } + validation_context: + trusted_ca: { filename: "testdata/certs/root-cert.pem" } + listeners: + - name: proxy-to-backend + traffic_direction: INBOUND + address: + socket_address: + address: 127.0.0.1 + port_value: 20083 + filter_chains: + - filters: + - name: envoy.filters.network.metadata_exchange + config: + protocol: istio2 + - name: envoy.http_connection_manager + config: + codec_type: AUTO + stat_prefix: inbound_http + access_log: + - name: envoy.file_access_log + config: + path: /tmp/envoy-server-access.log + http_filters: + - name: envoy.filters.http.wasm + config: + config: + root_id: "stats_inbound" + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.stats" } + configuration: | + { "debug": "false", max_peer_cache_size: 20, field_separator: ";.;" } + - name: envoy.router + route_config: + name: proxy-to-backend-route + virtual_hosts: + - name: proxy-to-backend-route + domains: ["*"] + routes: + - match: + prefix: / + route: + cluster: inbound|9080|http|server.default.svc.cluster.local + timeout: 0s + tls_context: + common_tls_context: + alpn_protocols: + - istio2 + tls_certificates: + - certificate_chain: { filename: "testdata/certs/cert-chain.pem" } + private_key: { filename: "testdata/certs/key.pem" } + validation_context: + trusted_ca: { filename: "testdata/certs/root-cert.pem" } + require_client_certificate: true \ No newline at end of file diff --git a/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go b/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go index b4add0774a..674a0fca28 100644 --- a/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go +++ b/test/envoye2e/stackdriver_plugin/stackdriver_plugin_test.go @@ -99,7 +99,7 @@ func verifyCreateTimeSeriesReq(got *monitoringpb.CreateTimeSeriesRequest) (bool, var srvReqCount, cltReqCount monitoringpb.TimeSeries p := &driver.Params{ Vars: map[string]string{ - "ServerPort": "20045", + "ServerPort": "20043", "ClientPort": "20042", "ServiceAuthenticationPolicy": "NONE", }, @@ -169,7 +169,7 @@ func verifyTrafficAssertionsReq(got *edgespb.ReportTrafficAssertionsRequest) err func TestStackdriverPlugin(t *testing.T) { s := env.NewClientServerEnvoyTestSetup(env.StackdriverPluginTest, t) fsdm, fsdl, edgesSvc := fs.NewFakeStackdriver(12312, 0) - s.SetFiltersBeforeEnvoyRouterInClientToProxy(outboundStackdriverFilter) + s.SetFiltersBeforeEnvoyRouterInAppToClient(outboundStackdriverFilter) s.SetFiltersBeforeEnvoyRouterInProxyToServer(inboundStackdriverFilter) params := driver.Params{Vars: map[string]string{"SDPort": "12312"}} s.SetClientNodeMetadata(params.LoadTestData("testdata/client_node_metadata.json.tmpl")) diff --git a/test/envoye2e/stackdriver_plugin/stackdriver_xds_test.go b/test/envoye2e/stackdriver_plugin/stackdriver_xds_test.go index c84c9ed422..bcc85a0979 100644 --- a/test/envoye2e/stackdriver_plugin/stackdriver_xds_test.go +++ b/test/envoye2e/stackdriver_plugin/stackdriver_xds_test.go @@ -120,12 +120,12 @@ func TestStackdriverPayload(t *testing.T) { ports := env.NewPorts(env.StackDriverPayload) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "SDPort": fmt.Sprintf("%d", ports.SDPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), "ServiceAuthenticationPolicy": "NONE", }, XDS: int(ports.XDSPort), @@ -144,7 +144,7 @@ func TestStackdriverPayload(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Repeat{N: 10, Step: &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}}, + &driver.Repeat{N: 10, Step: &driver.Get{ports.AppToClientProxyPort, "hello, world!"}}, sd.Check(params, []string{"testdata/stackdriver/client_request_count.yaml.tmpl", "testdata/stackdriver/server_request_count.yaml.tmpl"}, []string{"testdata/stackdriver/server_access_log.yaml.tmpl"}, @@ -159,12 +159,12 @@ func TestStackdriverPayloadGateway(t *testing.T) { ports := env.NewPorts(env.StackDriverPayloadGateway) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "SDPort": fmt.Sprintf("%d", ports.SDPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), }, XDS: int(ports.XDSPort), } @@ -181,7 +181,7 @@ func TestStackdriverPayloadGateway(t *testing.T) { Listeners: []string{StackdriverClientHTTPListener, StackdriverServerHTTPListener}}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Repeat{N: 1, Step: &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}}, + &driver.Repeat{N: 1, Step: &driver.Get{ports.AppToClientProxyPort, "hello, world!"}}, sd.Check(params, nil, []string{"testdata/stackdriver/gateway_access_log.yaml.tmpl"}, @@ -196,12 +196,12 @@ func TestStackdriverPayloadWithTLS(t *testing.T) { ports := env.NewPorts(env.StackDriverPayloadWithTLS) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "SDPort": fmt.Sprintf("%d", ports.SDPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), "ServiceAuthenticationPolicy": "MUTUAL_TLS", "SourcePrincipal": "spiffe://cluster.local/ns/default/sa/client", "DestinationPrincipal": "spiffe://cluster.local/ns/default/sa/server", @@ -224,7 +224,7 @@ func TestStackdriverPayloadWithTLS(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Repeat{N: 10, Step: &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}}, + &driver.Repeat{N: 10, Step: &driver.Get{ports.AppToClientProxyPort, "hello, world!"}}, sd.Check(params, []string{"testdata/stackdriver/client_request_count.yaml.tmpl", "testdata/stackdriver/server_request_count.yaml.tmpl"}, []string{"testdata/stackdriver/server_access_log.yaml.tmpl"}, @@ -240,12 +240,12 @@ func TestStackdriverReload(t *testing.T) { ports := env.NewPorts(env.StackDriverReload) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "SDPort": fmt.Sprintf("%d", ports.SDPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), }, XDS: int(ports.XDSPort), } @@ -262,7 +262,7 @@ func TestStackdriverReload(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, // should drain all listeners &driver.Update{Node: "client", Version: "1"}, &driver.Update{Node: "server", Version: "1"}, @@ -274,7 +274,7 @@ func TestStackdriverReload(t *testing.T) { &driver.Update{Node: "client", Version: "i{{ .N }}", Listeners: []string{StackdriverClientHTTPListener}}, &driver.Update{Node: "server", Version: "i{{ .N }}", Listeners: []string{StackdriverServerHTTPListener}}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, }, }, }, @@ -289,12 +289,12 @@ func TestStackdriverParallel(t *testing.T) { ports := env.NewPorts(env.StackDriverParallel) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "SDPort": fmt.Sprintf("%d", ports.SDPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), }, XDS: int(ports.XDSPort), } @@ -310,14 +310,14 @@ func TestStackdriverParallel(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, &driver.Fork{ Fore: &driver.Scenario{ []driver.Step{ &driver.Sleep{1 * time.Second}, &driver.Repeat{ Duration: 19 * time.Second, - Step: &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + Step: &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, }, }, }, diff --git a/test/envoye2e/stats/stats_xds_test.go b/test/envoye2e/stats/stats_xds_test.go index 33c66e65fe..282d0af8b2 100644 --- a/test/envoye2e/stats/stats_xds_test.go +++ b/test/envoye2e/stats/stats_xds_test.go @@ -135,11 +135,11 @@ func TestStatsPayload(t *testing.T) { ports := env.NewPorts(env.StatsPayload) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), "RequestCount": "10", }, XDS: int(ports.XDSPort), @@ -156,7 +156,7 @@ func TestStatsPayload(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Repeat{N: 10, Step: &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}}, + &driver.Repeat{N: 10, Step: &driver.Get{ports.AppToClientProxyPort, "hello, world!"}}, &driver.Stats{ports.ClientAdminPort, map[string]driver.StatMatcher{ "istio_requests_total": &driver.ExactStat{"testdata/metric/client_request_total.yaml.tmpl"}, }}, @@ -173,11 +173,11 @@ func TestStatsParallel(t *testing.T) { ports := env.NewPorts(env.StatsParallel) params := &driver.Params{ Vars: map[string]string{ - "ClientPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), + "ClientPort": fmt.Sprintf("%d", ports.AppToClientProxyPort), "BackendPort": fmt.Sprintf("%d", ports.BackendPort), "ClientAdmin": fmt.Sprintf("%d", ports.ClientAdminPort), "ServerAdmin": fmt.Sprintf("%d", ports.ServerAdminPort), - "ServerPort": fmt.Sprintf("%d", ports.ProxyToServerProxyPort), + "ServerPort": fmt.Sprintf("%d", ports.ClientToServerProxyPort), "RequestCount": "1", }, XDS: int(ports.XDSPort), @@ -198,14 +198,14 @@ func TestStatsParallel(t *testing.T) { &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/server.yaml.tmpl")}, &driver.Envoy{Bootstrap: params.LoadTestData("testdata/bootstrap/client.yaml.tmpl")}, &driver.Sleep{1 * time.Second}, - &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, &driver.Fork{ Fore: &driver.Scenario{ []driver.Step{ &driver.Sleep{1 * time.Second}, &driver.Repeat{ Duration: 9 * time.Second, - Step: &driver.Get{ports.ClientToServerProxyPort, "hello, world!"}, + Step: &driver.Get{ports.AppToClientProxyPort, "hello, world!"}, }, capture{}, }, diff --git a/test/envoye2e/stats_plugin/stats_plugin_test.go b/test/envoye2e/stats_plugin/stats_plugin_test.go index 675ff2dd4b..649aef87f1 100644 --- a/test/envoye2e/stats_plugin/stats_plugin_test.go +++ b/test/envoye2e/stats_plugin/stats_plugin_test.go @@ -202,7 +202,7 @@ type verifyFn func(s *env.TestSetup) func testStatsPlugin(t *testing.T, disableHostHeaderFallback bool, fn verifyFn) { s := env.NewClientServerEnvoyTestSetup(env.StatsPluginTest, t) - s.SetFiltersBeforeEnvoyRouterInClientToProxy(fmt.Sprintf(outboundStatsFilter, disableHostHeaderFallback)) + s.SetFiltersBeforeEnvoyRouterInAppToClient(fmt.Sprintf(outboundStatsFilter, disableHostHeaderFallback)) s.SetFiltersBeforeEnvoyRouterInProxyToServer(inboundStatsFilter) s.SetServerNodeMetadata(inboundNodeMetadata) s.SetClientNodeMetadata(outboundNodeMetadata) diff --git a/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go b/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go index 26c8668ec8..e82e7a2977 100644 --- a/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go +++ b/test/envoye2e/tcp_metadata_exchange/tcp_metadata_exchange_test.go @@ -150,7 +150,7 @@ func TestTCPMetadataExchange(t *testing.T) { s.SetStartTCPBackend(true) s.SetTLSContext(tlsContext) s.SetClusterTLSContext(clusterTLSContext) - s.SetFiltersBeforeEnvoyRouterInClientToApp(metadataExchangeIstioConfigFilter) + s.SetFiltersBeforeEnvoyRouterInProxyToServer(metadataExchangeIstioConfigFilter) s.SetUpstreamFiltersInClient(metadataExchangeIstioUpstreamConfigFilterChain) s.SetEnableTLS(true) s.SetClientNodeMetadata(clientNodeMetadata)