From 2c789b49c234e5e0ad61163a47e68958fa43119d Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 3 Aug 2020 10:02:36 -0700 Subject: [PATCH 01/12] initial tool Signed-off-by: Kuat Yessenov --- test/envoye2e/driver/xds.go | 8 +++- tools/extension_server/main/main.go | 60 ++++++++++++++++++++++++++++ tools/extension_server/server.go | 61 +++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 tools/extension_server/main/main.go create mode 100644 tools/extension_server/server.go diff --git a/test/envoye2e/driver/xds.go b/test/envoye2e/driver/xds.go index dc3b1e4c2bc..99bbc73934e 100644 --- a/test/envoye2e/driver/xds.go +++ b/test/envoye2e/driver/xds.go @@ -20,9 +20,12 @@ import ( "log" "net" + "istio.io/proxy/tools/extension_server" + cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" + extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" "github.com/envoyproxy/go-control-plane/pkg/cache/types" "github.com/envoyproxy/go-control-plane/pkg/cache/v3" "github.com/envoyproxy/go-control-plane/pkg/server/v3" @@ -31,7 +34,8 @@ import ( // XDS creates an xDS server type XDS struct { - grpc *grpc.Server + grpc *grpc.Server + extensionserver *extension_server.ExtensionServer } var _ Step = &XDS{} @@ -39,6 +43,7 @@ var _ Step = &XDS{} func (x *XDS) Run(p *Params) error { log.Printf("XDS server starting on %d\n", p.XDS) x.grpc = grpc.NewServer() + x.extensionserver = extension_server.New(context.Background()) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", p.XDS)) if err != nil { return err @@ -47,6 +52,7 @@ func (x *XDS) Run(p *Params) error { p.Config = cache.NewSnapshotCache(false, cache.IDHash{}, x) xdsServer := server.NewServer(context.Background(), p.Config, nil) discovery.RegisterAggregatedDiscoveryServiceServer(x.grpc, xdsServer) + extensionservice.RegisterExtensionConfigDiscoveryServiceServer(x.grpc, x.extensionserver) go func() { _ = x.grpc.Serve(lis) diff --git a/tools/extension_server/main/main.go b/tools/extension_server/main/main.go new file mode 100644 index 00000000000..29cca7444d7 --- /dev/null +++ b/tools/extension_server/main/main.go @@ -0,0 +1,60 @@ +// Copyright 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 main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + + "google.golang.org/grpc" + + discoveryservice "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" + extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" + "istio.io/proxy/tools/extension_server" +) + +const ( + grpcMaxConcurrentStreams = 100000 +) + +var ( + port uint + server *extension_server.ExtensionServer +) + +func init() { + flag.UintVar(&port, "port", 8080, "xDS management server port") +} + +func main() { + flag.Parse() + + grpcServer := grpc.NewServer(grpc.MaxConcurrentStreams(grpcMaxConcurrentStreams)) + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + log.Fatal(err) + } + server := extension_server.New(context.Background()) + discoveryservice.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) + extensionservice.RegisterExtensionConfigDiscoveryServiceServer(grpcServer, server) + + log.Printf("management server listening on %d\n", port) + if err = grpcServer.Serve(lis); err != nil { + log.Println(err) + } +} diff --git a/tools/extension_server/server.go b/tools/extension_server/server.go new file mode 100644 index 00000000000..6095f5c6b20 --- /dev/null +++ b/tools/extension_server/server.go @@ -0,0 +1,61 @@ +// Copyright 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 extension_server + +import ( + "context" + + discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" + extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" + "github.com/envoyproxy/go-control-plane/pkg/cache/v3" + "github.com/envoyproxy/go-control-plane/pkg/server/v3" + "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +const ( + // ApiType for extension configs. + ApiType = "type.googleapis.com/envoy.config.core.v3.TypedExtensionConfig" +) + +// ExtensionServer is the main server instance. +type ExtensionServer struct { + server.Server + server.CallbackFuncs + cache *cache.LinearCache +} + +var _ extensionservice.ExtensionConfigDiscoveryServiceServer = &ExtensionServer{} + +func New(ctx context.Context) *ExtensionServer { + out := &ExtensionServer{} + out.cache = cache.NewLinearCache(ApiType, nil) + out.Server = server.NewServer(ctx, out.cache, out) + return out +} + +func (es *ExtensionServer) StreamExtensionConfigs(stream extensionservice.ExtensionConfigDiscoveryService_StreamExtensionConfigsServer) error { + return status.Errorf(codes.Unimplemented, "not implemented") +} +func (es *ExtensionServer) DeltaExtensionConfigs(_ extensionservice.ExtensionConfigDiscoveryService_DeltaExtensionConfigsServer) error { + return status.Errorf(codes.Unimplemented, "not implemented") +} +func (es *ExtensionServer) FetchExtensionConfigs(ctx context.Context, req *discovery.DiscoveryRequest) (*discovery.DiscoveryResponse, error) { + if req == nil { + return nil, status.Errorf(codes.Unavailable, "empty request") + } + req.TypeUrl = ApiType + return es.Server.Fetch(ctx, req) +} From 171e87f272531d0fb3c785d8fa4e3bfd78485653 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 3 Aug 2020 11:26:00 -0700 Subject: [PATCH 02/12] pullout mx filter config Signed-off-by: Kuat Yessenov --- testdata/filters/mx_inbound.yaml.tmpl | 23 +++++++++++++++++++++ testdata/filters/mx_outbound.yaml.tmpl | 23 +++++++++++++++++++++ testdata/filters/stats_inbound.yaml.tmpl | 2 +- testdata/filters/stats_outbound.yaml.tmpl | 2 +- testdata/listener/client.yaml.tmpl | 25 ----------------------- testdata/listener/server.yaml.tmpl | 25 ----------------------- 6 files changed, 48 insertions(+), 52 deletions(-) create mode 100644 testdata/filters/mx_inbound.yaml.tmpl create mode 100644 testdata/filters/mx_outbound.yaml.tmpl diff --git a/testdata/filters/mx_inbound.yaml.tmpl b/testdata/filters/mx_inbound.yaml.tmpl new file mode 100644 index 00000000000..1c778242b19 --- /dev/null +++ b/testdata/filters/mx_inbound.yaml.tmpl @@ -0,0 +1,23 @@ +- name: mx_inbound + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + vm_config: + {{- if .Vars.WasmRuntime }} + runtime: {{ .Vars.WasmRuntime }} + {{- else }} + runtime: envoy.wasm.runtime.null + {{- end }} + code: + {{- if .Vars.MetadataExchangeFilterCode }} + local: { {{ .Vars.MetadataExchangeFilterCode }} } + {{- else }} + local: { inline_string: "envoy.wasm.metadata_exchange" } + {{- end }} + allow_precompiled: true + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + { "max_peer_cache_size": 20 } diff --git a/testdata/filters/mx_outbound.yaml.tmpl b/testdata/filters/mx_outbound.yaml.tmpl new file mode 100644 index 00000000000..41f101aebee --- /dev/null +++ b/testdata/filters/mx_outbound.yaml.tmpl @@ -0,0 +1,23 @@ +- name: mx_outbound + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + vm_config: + {{- if .Vars.WasmRuntime }} + runtime: {{ .Vars.WasmRuntime }} + {{- else }} + runtime: envoy.wasm.runtime.null + {{- end }} + code: + {{- if .Vars.MetadataExchangeFilterCode }} + local: { {{ .Vars.MetadataExchangeFilterCode }} } + {{- else }} + local: { inline_string: "envoy.wasm.metadata_exchange" } + {{- end }} + allow_precompiled: true + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + { "max_peer_cache_size": 20 } diff --git a/testdata/filters/stats_inbound.yaml.tmpl b/testdata/filters/stats_inbound.yaml.tmpl index 773fff98f79..9a2ce8e442d 100644 --- a/testdata/filters/stats_inbound.yaml.tmpl +++ b/testdata/filters/stats_inbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: envoy.filters.http.wasm +- name: stats_inbound typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: envoy.extensions.filters.http.wasm.v3.Wasm diff --git a/testdata/filters/stats_outbound.yaml.tmpl b/testdata/filters/stats_outbound.yaml.tmpl index 7e227c51bb9..f84046c3568 100644 --- a/testdata/filters/stats_outbound.yaml.tmpl +++ b/testdata/filters/stats_outbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: envoy.filters.http.wasm +- name: stats_outbound typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: envoy.extensions.filters.http.wasm.v3.Wasm diff --git a/testdata/listener/client.yaml.tmpl b/testdata/listener/client.yaml.tmpl index 24db65a587c..92ac86ac4b0 100644 --- a/testdata/listener/client.yaml.tmpl +++ b/testdata/listener/client.yaml.tmpl @@ -15,31 +15,6 @@ filter_chains: codec_type: AUTO stat_prefix: client http_filters: -{{- if eq .Vars.EnableMetadataExchange "true" }} - - name: envoy.filters.http.wasm - typed_config: - "@type": type.googleapis.com/udpa.type.v1.TypedStruct - type_url: envoy.extensions.filters.http.wasm.v3.Wasm - value: - config: - vm_config: - {{- if .Vars.WasmRuntime }} - runtime: {{ .Vars.WasmRuntime }} - {{- else }} - runtime: envoy.wasm.runtime.null - {{- end }} - code: - {{- if .Vars.MetadataExchangeFilterCode }} - local: { {{ .Vars.MetadataExchangeFilterCode }} } - {{- else }} - local: { inline_string: "envoy.wasm.metadata_exchange" } - {{- end }} - allow_precompiled: true - configuration: - "@type": "type.googleapis.com/google.protobuf.StringValue" - value: | - { "max_peer_cache_size": 20 } -{{- end }} {{- if ne .Vars.ClientHTTPFilters "" }} {{ .Vars.ClientHTTPFilters | indent 6 }} {{- end }} diff --git a/testdata/listener/server.yaml.tmpl b/testdata/listener/server.yaml.tmpl index a8f431c4f87..63e79c9039a 100644 --- a/testdata/listener/server.yaml.tmpl +++ b/testdata/listener/server.yaml.tmpl @@ -15,31 +15,6 @@ filter_chains: codec_type: AUTO stat_prefix: server http_filters: -{{- if eq .Vars.EnableMetadataExchange "true" }} - - name: envoy.filters.http.wasm - typed_config: - "@type": type.googleapis.com/udpa.type.v1.TypedStruct - type_url: envoy.extensions.filters.http.wasm.v3.Wasm - value: - config: - vm_config: - {{- if .Vars.WasmRuntime }} - runtime: {{ .Vars.WasmRuntime }} - {{- else }} - runtime: envoy.wasm.runtime.null - {{- end }} - code: - {{- if .Vars.MetadataExchangeFilterCode }} - local: { {{ .Vars.MetadataExchangeFilterCode }} } - {{- else }} - local: { inline_string: "envoy.wasm.metadata_exchange" } - {{- end }} - allow_precompiled: true - configuration: - "@type": "type.googleapis.com/google.protobuf.StringValue" - value: | - { "max_peer_cache_size": 20 } -{{- end }} {{- if ne .Vars.ServerHTTPFilters "" }} {{ .Vars.ServerHTTPFilters | indent 6 }} {{- end }} From a77d0f34208193824447a8528006acf707e309aa Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 3 Aug 2020 14:55:05 -0700 Subject: [PATCH 03/12] initial version Signed-off-by: Kuat Yessenov --- go.mod | 9 +- go.sum | 22 ++--- test/envoye2e/driver/scenario.go | 25 ++++- test/envoye2e/driver/xds.go | 45 +++++++-- test/envoye2e/env/utils.go | 10 +- .../http_metadata_exchange/exchange_test.go | 6 +- .../stackdriver_plugin/stackdriver_test.go | 73 +++++++------- test/envoye2e/stats_plugin/README.md | 1 - test/envoye2e/stats_plugin/stats_test.go | 97 +++++++++++++++---- .../filters/extension_config_inbound.yaml | 20 ++++ .../filters/extension_config_outbound.yaml | 20 ++++ tools/extension_server/server.go | 12 ++- 12 files changed, 247 insertions(+), 93 deletions(-) create mode 100644 testdata/filters/extension_config_inbound.yaml create mode 100644 testdata/filters/extension_config_outbound.yaml diff --git a/go.mod b/go.mod index 99d19b06c83..3fda23505de 100644 --- a/go.mod +++ b/go.mod @@ -6,20 +6,19 @@ replace cloud.google.com/go/meshtelemetry/v1alpha1 v0.0.0 => ./test/envoye2e/sta require ( cloud.google.com/go/meshtelemetry/v1alpha1 v0.0.0 - github.com/cncf/udpa/go v0.0.0-20200327203949-e8cd3a4bb307 + github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 github.com/d4l3k/messagediff v1.2.2-0.20180726183240-b9e99b2f9263 - github.com/envoyproxy/go-control-plane v0.9.5 + github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1 github.com/ghodss/yaml v1.0.0 - github.com/golang/protobuf v1.4.1 + github.com/golang/protobuf v1.4.2 github.com/kr/pretty v0.1.0 // indirect github.com/prometheus/client_model v0.2.0 github.com/prometheus/common v0.9.1 golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect golang.org/x/sys v0.0.0-20200331124033-c3d80250170d // indirect - golang.org/x/text v0.3.2 // indirect google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 google.golang.org/grpc v1.28.0 google.golang.org/protobuf v1.25.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect - gopkg.in/yaml.v2 v2.2.8 // indirect + gopkg.in/yaml.v2 v2.2.8 ) diff --git a/go.sum b/go.sum index 9c58540a3b8..140baa84989 100644 --- a/go.sum +++ b/go.sum @@ -12,21 +12,19 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533 h1:8wZizuKuZVu5COB7EsBYxBQz8nRcXXn5d4Gt91eJLvU= -github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20200327203949-e8cd3a4bb307 h1:wP75JfNoHgEnmT+77wAUNQ2shW0sK83RPDQIvYIz47E= -github.com/cncf/udpa/go v0.0.0-20200327203949-e8cd3a4bb307/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 h1:9kRtNpqLHbZVO/NNxhHp2ymxFxsHOe3x2efJGn//Tas= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/d4l3k/messagediff v1.2.2-0.20180726183240-b9e99b2f9263 h1:Ot817IZ8L+/ZlkfVJ0ZnngYA6GnmcvcxR7lrIz/iZDc= github.com/d4l3k/messagediff v1.2.2-0.20180726183240-b9e99b2f9263/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0 h1:67WMNTvGrl7V1dWdKCeTwxDr7nio9clKoTlLhwIPnT4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.5 h1:lRJIqDD8yjV1YyPRqecMdytjDLs2fTXq363aCib5xPU= -github.com/envoyproxy/go-control-plane v0.9.5/go.mod h1:OXl5to++W0ctG+EHWTFUjiypVxC/Y4VLc/KFU+al13s= +github.com/envoyproxy/go-control-plane v0.9.7-0.20200731221939-3f4998b1fa63/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1 h1:jbSSXMArWufIwLI3keHepe+rVOwLExhWWirrdadSHL4= +github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -54,6 +52,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -105,6 +105,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -141,9 +143,6 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ix golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -159,7 +158,6 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -172,6 +170,7 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= @@ -181,6 +180,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= diff --git a/test/envoye2e/driver/scenario.go b/test/envoye2e/driver/scenario.go index df87d68b400..bceab40f188 100644 --- a/test/envoye2e/driver/scenario.go +++ b/test/envoye2e/driver/scenario.go @@ -18,15 +18,16 @@ import ( "bytes" "fmt" "log" + "reflect" "strings" "testing" "text/template" "time" - "github.com/envoyproxy/go-control-plane/pkg/cache/v3" "github.com/ghodss/yaml" "github.com/golang/protobuf/jsonpb" "github.com/golang/protobuf/proto" + yamlv2 "gopkg.in/yaml.v2" "istio.io/proxy/test/envoye2e/env" ) @@ -34,7 +35,7 @@ import ( type ( Params struct { XDS int - Config cache.SnapshotCache + Config XDSServer Ports *env.Ports Vars map[string]string N int @@ -165,7 +166,25 @@ func (s *Scenario) Run(p *Params) error { func (s *Scenario) Cleanup() {} func ReadYAML(input string, pb proto.Message) error { - js, err := yaml.YAMLToJSON([]byte(input)) + var jsonObj interface{} + err := yamlv2.Unmarshal([]byte(input), &jsonObj) + if err != nil { + return err + } + // As a special case, convert [x] to x. + // This is needed because jsonpb is unable to parse arrays. + in := reflect.ValueOf(jsonObj) + switch in.Kind() { + case reflect.Slice, reflect.Array: + if in.Len() == 1 { + jsonObj = in.Index(0).Interface() + } + } + yml, err := yamlv2.Marshal(jsonObj) + if err != nil { + return err + } + js, err := yaml.YAMLToJSON(yml) if err != nil { return err } diff --git a/test/envoye2e/driver/xds.go b/test/envoye2e/driver/xds.go index 99bbc73934e..5ca0e57a8f8 100644 --- a/test/envoye2e/driver/xds.go +++ b/test/envoye2e/driver/xds.go @@ -23,6 +23,7 @@ import ( "istio.io/proxy/tools/extension_server" cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" + core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" @@ -34,8 +35,13 @@ import ( // XDS creates an xDS server type XDS struct { - grpc *grpc.Server - extensionserver *extension_server.ExtensionServer + grpc *grpc.Server +} + +// XDSServer is a struct holding xDS state. +type XDSServer struct { + Extensions *extension_server.ExtensionServer + Cache cache.SnapshotCache } var _ Step = &XDS{} @@ -43,17 +49,16 @@ var _ Step = &XDS{} func (x *XDS) Run(p *Params) error { log.Printf("XDS server starting on %d\n", p.XDS) x.grpc = grpc.NewServer() - x.extensionserver = extension_server.New(context.Background()) + p.Config.Extensions = extension_server.New(context.Background()) + extensionservice.RegisterExtensionConfigDiscoveryServiceServer(x.grpc, p.Config.Extensions) + p.Config.Cache = cache.NewSnapshotCache(false, cache.IDHash{}, x) + xdsServer := server.NewServer(context.Background(), p.Config.Cache, nil) + discovery.RegisterAggregatedDiscoveryServiceServer(x.grpc, xdsServer) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", p.XDS)) if err != nil { return err } - p.Config = cache.NewSnapshotCache(false, cache.IDHash{}, x) - xdsServer := server.NewServer(context.Background(), p.Config, nil) - discovery.RegisterAggregatedDiscoveryServiceServer(x.grpc, xdsServer) - extensionservice.RegisterExtensionConfigDiscoveryServiceServer(x.grpc, x.extensionserver) - go func() { _ = x.grpc.Serve(lis) }() @@ -115,7 +120,29 @@ func (u *Update) Run(p *Params) error { snap := cache.Snapshot{} snap.Resources[types.Cluster] = cache.NewResources(version, clusters) snap.Resources[types.Listener] = cache.NewResources(version, listeners) - return p.Config.SetSnapshot(u.Node, snap) + return p.Config.Cache.SetSnapshot(u.Node, snap) } func (u *Update) Cleanup() {} + +type UpdateExtensions struct { + Extensions []string +} + +var _ Step = &UpdateExtensions{} + +func (u *UpdateExtensions) Run(p *Params) error { + for _, extension := range u.Extensions { + out := &core.TypedExtensionConfig{} + if err := p.FillYAML(extension, out); err != nil { + return err + } + log.Printf("updating extension config %q", out.Name) + if err := p.Config.Extensions.Update(out); err != nil { + return err + } + } + return nil +} + +func (u *UpdateExtensions) Cleanup() {} diff --git a/test/envoye2e/env/utils.go b/test/envoye2e/env/utils.go index d75e32cc41e..421a64fb7ba 100644 --- a/test/envoye2e/env/utils.go +++ b/test/envoye2e/env/utils.go @@ -22,17 +22,15 @@ import ( "testing" ) -func GetDefaultEnvoyBin() string { +func GetBazelBin() string { // Note: `bazel info bazel-bin` returns incorrect path to a binary (always fastbuild, not opt or dbg) // Instead we rely on symbolic link src/envoy/envoy in the workspace workspace, _ := exec.Command("bazel", "info", "workspace").Output() - return filepath.Join(strings.TrimSuffix(string(workspace), "\n"), "bazel-bin/src/envoy/") + return filepath.Join(strings.TrimSuffix(string(workspace), "\n"), "bazel-bin/") } -func GetBazelOptOut() string { - // `make build_wasm` puts generated wasm modules into k8-opt. - bazelOutput, _ := exec.Command("bazel", "info", "output_path").Output() - return filepath.Join(strings.TrimSuffix(string(bazelOutput), "\n"), "k8-opt/bin/") +func GetDefaultEnvoyBin() string { + return filepath.Join(GetBazelBin(), "src/envoy/") } func SkipTSanASan(t *testing.T) { diff --git a/test/envoye2e/http_metadata_exchange/exchange_test.go b/test/envoye2e/http_metadata_exchange/exchange_test.go index 4ed67e3b1ad..0d1b4cedf68 100644 --- a/test/envoye2e/http_metadata_exchange/exchange_test.go +++ b/test/envoye2e/http_metadata_exchange/exchange_test.go @@ -40,11 +40,11 @@ func EncodeMetadata(t *testing.T, p *driver.Params) string { } func TestHTTPExchange(t *testing.T) { - params := driver.NewTestParams(t, map[string]string{ - "EnableMetadataExchange": "true", - }, envoye2e.ProxyE2ETests) + params := driver.NewTestParams(t, map[string]string{}, envoye2e.ProxyE2ETests) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") if err := (&driver.Scenario{ []driver.Step{ &driver.XDS{}, diff --git a/test/envoye2e/stackdriver_plugin/stackdriver_test.go b/test/envoye2e/stackdriver_plugin/stackdriver_test.go index 3a7a02969a0..c7c6384a088 100644 --- a/test/envoye2e/stackdriver_plugin/stackdriver_test.go +++ b/test/envoye2e/stackdriver_plugin/stackdriver_test.go @@ -29,7 +29,6 @@ func TestStackdriverPayload(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "ServiceAuthenticationPolicy": "NONE", "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), @@ -41,8 +40,10 @@ func TestStackdriverPayload(t *testing.T) { params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} @@ -80,20 +81,21 @@ func TestStackdriverPayload(t *testing.T) { func TestStackdriverPayloadGateway(t *testing.T) { t.Parallel() params := driver.NewTestParams(t, map[string]string{ - "RequestPath": "echo", - "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", - "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), - "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), - "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), + "RequestPath": "echo", + "SDLogStatusCode": "200", + "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), + "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), + "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), }, envoye2e.ProxyE2ETests) sdPort := params.Ports.Max + 1 stsPort := params.Ports.Max + 2 params.Vars["SDPort"] = strconv.Itoa(int(sdPort)) params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} @@ -136,7 +138,6 @@ func TestStackdriverPayloadWithTLS(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "ServiceAuthenticationPolicy": "MUTUAL_TLS", "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", "SourcePrincipal": "spiffe://cluster.local/ns/default/sa/client", "DestinationPrincipal": "spiffe://cluster.local/ns/default/sa/server", "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), @@ -151,8 +152,10 @@ func TestStackdriverPayloadWithTLS(t *testing.T) { params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") params.Vars["ClientTLSContext"] = params.LoadTestData("testdata/transport_socket/client.yaml.tmpl") params.Vars["ServerTLSContext"] = params.LoadTestData("testdata/transport_socket/server.yaml.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} @@ -194,7 +197,6 @@ func TestStackdriverReload(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "ServiceAuthenticationPolicy": "NONE", "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), }, envoye2e.ProxyE2ETests) @@ -204,8 +206,10 @@ func TestStackdriverReload(t *testing.T) { params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} if err := (&driver.Scenario{ @@ -246,7 +250,6 @@ func TestStackdriverVMReload(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "ServiceAuthenticationPolicy": "NONE", "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), "ReloadVM": "true", @@ -257,8 +260,10 @@ func TestStackdriverVMReload(t *testing.T) { params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} @@ -306,7 +311,6 @@ func TestStackdriverGCEInstances(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "ServiceAuthenticationPolicy": "NONE", "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), }, envoye2e.ProxyE2ETests) @@ -316,8 +320,10 @@ func TestStackdriverGCEInstances(t *testing.T) { params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/gce_client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/gce_server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} if err := (&driver.Scenario{ @@ -351,10 +357,9 @@ func TestStackdriverGCEInstances(t *testing.T) { func TestStackdriverParallel(t *testing.T) { t.Parallel() params := driver.NewTestParams(t, map[string]string{ - "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", - "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), - "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), + "SDLogStatusCode": "200", + "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), + "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), }, envoye2e.ProxyE2ETests) sdPort := params.Ports.Max + 1 stsPort := params.Ports.Max + 2 @@ -362,8 +367,10 @@ func TestStackdriverParallel(t *testing.T) { params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort, Delay: 100 * time.Millisecond} @@ -430,7 +437,6 @@ func TestStackdriverAccessLog(t *testing.T) { t.Run(tt.name, func(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "LogWindowDuration": tt.logWindowDuration, - "EnableMetadataExchange": "true", "ServiceAuthenticationPolicy": "NONE", "DirectResponseCode": tt.respCode, "SDLogStatusCode": tt.respCode, @@ -444,9 +450,11 @@ func TestStackdriverAccessLog(t *testing.T) { params.Vars["STSPort"] = strconv.Itoa(int(stsPort)) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/access_log_policy.yaml.tmpl") + "\n" + + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/access_log_policy.yaml.tmpl") + "\n" + params.LoadTestData("testdata/filters/stackdriver_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stackdriver_outbound.yaml.tmpl") sd := &Stackdriver{Port: sdPort} respCode, _ := strconv.Atoi(tt.respCode) @@ -515,7 +523,6 @@ func TestStackdriverTCPMetadataExchange(t *testing.T) { params := driver.NewTestParams(t, map[string]string{ "ServiceAuthenticationPolicy": "MUTUAL_TLS", "SDLogStatusCode": "200", - "EnableMetadataExchange": "true", "StackdriverRootCAFile": driver.TestPath("testdata/certs/stackdriver.pem"), "StackdriverTokenFile": driver.TestPath("testdata/certs/access-token"), "SourcePrincipal": "spiffe://cluster.local/ns/default/sa/client", diff --git a/test/envoye2e/stats_plugin/README.md b/test/envoye2e/stats_plugin/README.md index ae194650df6..c5f48b07c9c 100644 --- a/test/envoye2e/stats_plugin/README.md +++ b/test/envoye2e/stats_plugin/README.md @@ -98,7 +98,6 @@ params := driver.NewTestParams(t, map[string]string{ "StatsFilterCode": "inline_string: \"envoy.wasm.stats\"", "AttributeGenFilterConfig": runtime.AttributeGenFilterCode, "AttributeGenWasmRuntime": runtime.WasmRuntime, - "EnableMetadataExchange": "true", "WasmRuntime": "envoy.wasm.runtime.null", "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), "StatsFilterClientConfig": driver.LoadTestJSON("testdata/stats/client_config.yaml"), diff --git a/test/envoye2e/stats_plugin/stats_test.go b/test/envoye2e/stats_plugin/stats_test.go index d9299d81770..92b84dbecd7 100644 --- a/test/envoye2e/stats_plugin/stats_test.go +++ b/test/envoye2e/stats_plugin/stats_test.go @@ -64,13 +64,13 @@ var Runtimes = []struct { WasmRuntime: "envoy.wasm.runtime.null", }, { - MetadataExchangeFilterCode: "filename: " + filepath.Join(env.GetBazelOptOut(), "extensions/metadata_exchange.wasm"), - StatsFilterCode: "filename: " + filepath.Join(env.GetBazelOptOut(), "extensions/stats.wasm"), + MetadataExchangeFilterCode: "filename: " + filepath.Join(env.GetBazelBin(), "extensions/metadata_exchange.wasm"), + StatsFilterCode: "filename: " + filepath.Join(env.GetBazelBin(), "extensions/stats.wasm"), WasmRuntime: "envoy.wasm.runtime.v8", }, { - MetadataExchangeFilterCode: "filename: " + filepath.Join(env.GetBazelOptOut(), "extensions/metadata_exchange.compiled.wasm"), - StatsFilterCode: "filename: " + filepath.Join(env.GetBazelOptOut(), "extensions/stats.compiled.wasm"), + MetadataExchangeFilterCode: "filename: " + filepath.Join(env.GetBazelBin(), "extensions/metadata_exchange.compiled.wasm"), + StatsFilterCode: "filename: " + filepath.Join(env.GetBazelBin(), "extensions/stats.compiled.wasm"), WasmRuntime: "envoy.wasm.runtime.v8", }, } @@ -137,7 +137,7 @@ var AttributeGenRuntimes = []struct { WasmRuntime: "envoy.wasm.runtime.null", }, { - AttributeGenFilterCode: "filename: " + filepath.Join(env.GetBazelOptOut(), "extensions/attributegen.wasm"), + AttributeGenFilterCode: "filename: " + filepath.Join(env.GetBazelBin(), "extensions/attributegen.wasm"), WasmRuntime: "envoy.wasm.runtime.v8", }, } @@ -150,7 +150,6 @@ func TestStatsPayload(t *testing.T) { skipWasm(t, runtime.WasmRuntime) params := driver.NewTestParams(t, map[string]string{ "RequestCount": "10", - "EnableMetadataExchange": "true", "MetadataExchangeFilterCode": runtime.MetadataExchangeFilterCode, "StatsFilterCode": runtime.StatsFilterCode, "WasmRuntime": runtime.WasmRuntime, @@ -161,8 +160,10 @@ func TestStatsPayload(t *testing.T) { }, envoye2e.ProxyE2ETests) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") if err := (&driver.Scenario{ []driver.Step{ &driver.XDS{}, @@ -204,7 +205,6 @@ func TestStatsParallel(t *testing.T) { "MetadataExchangeFilterCode": "inline_string: \"envoy.wasm.metadata_exchange\"", "StatsFilterCode": "inline_string: \"envoy.wasm.stats\"", "WasmRuntime": "envoy.wasm.runtime.null", - "EnableMetadataExchange": "true", "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), "StatsFilterClientConfig": driver.LoadTestJSON(testCase.ClientConfig), "StatsFilterServerConfig": driver.LoadTestJSON("testdata/stats/server_config.yaml"), @@ -215,8 +215,10 @@ func TestStatsParallel(t *testing.T) { serverRequestTotal := &dto.MetricFamily{} params.LoadTestProto("testdata/metric/client_request_total.yaml.tmpl", clientRequestTotal) params.LoadTestProto("testdata/metric/server_request_total.yaml.tmpl", serverRequestTotal) - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") if err := (&driver.Scenario{ []driver.Step{ @@ -277,15 +279,16 @@ func TestStatsGrpc(t *testing.T) { "DisableDirectResponse": "true", "UsingGrpcBackend": "true", "GrpcResponseStatus": "7", - "EnableMetadataExchange": "true", "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), "StatsFilterClientConfig": driver.LoadTestJSON("testdata/stats/client_config.yaml"), "StatsFilterServerConfig": driver.LoadTestJSON("testdata/stats/server_config.yaml"), }, envoye2e.ProxyE2ETests) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") if err := (&driver.Scenario{ Steps: []driver.Step{ &driver.XDS{}, @@ -315,7 +318,7 @@ func TestStatsGrpc(t *testing.T) { } } -func TestAttributeGen(t *testing.T) { +func TestAttributeGenIntegration(t *testing.T) { for _, runtime := range AttributeGenRuntimes { t.Run(runtime.WasmRuntime, func(t *testing.T) { skipWasm(t, runtime.WasmRuntime) @@ -325,7 +328,6 @@ func TestAttributeGen(t *testing.T) { "StatsFilterCode": "inline_string: \"envoy.wasm.stats\"", "AttributeGenFilterConfig": runtime.AttributeGenFilterCode, "AttributeGenWasmRuntime": runtime.WasmRuntime, - "EnableMetadataExchange": "true", "WasmRuntime": "envoy.wasm.runtime.null", "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), "StatsFilterClientConfig": driver.LoadTestJSON("testdata/stats/client_config.yaml"), @@ -334,9 +336,11 @@ func TestAttributeGen(t *testing.T) { }, envoye2e.ProxyE2ETests) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/attributegen.yaml.tmpl") + "\n" + + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/attributegen.yaml.tmpl") + "\n" + params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl") + "\n" + + params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl") if err := (&driver.Scenario{ []driver.Step{ &driver.XDS{}, @@ -361,3 +365,60 @@ func TestAttributeGen(t *testing.T) { }) } } + +func TestStatsECDS(t *testing.T) { + env.SkipTSanASan(t) + for _, runtime := range Runtimes { + t.Run(runtime.WasmRuntime, func(t *testing.T) { + skipWasm(t, runtime.WasmRuntime) + params := driver.NewTestParams(t, map[string]string{ + "RequestCount": "10", + "MetadataExchangeFilterCode": runtime.MetadataExchangeFilterCode, + "StatsFilterCode": runtime.StatsFilterCode, + "WasmRuntime": runtime.WasmRuntime, + "StatsConfig": driver.LoadTestData("testdata/bootstrap/stats.yaml.tmpl"), + "StatsFilterClientConfig": driver.LoadTestJSON("testdata/stats/client_config.yaml"), + "StatsFilterServerConfig": driver.LoadTestJSON("testdata/stats/server_config.yaml"), + }, envoye2e.ProxyE2ETests) + params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") + params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_inbound.yaml") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_outbound.yaml") + if err := (&driver.Scenario{ + []driver.Step{ + &driver.XDS{}, + &driver.Update{ + Node: "client", + Version: "0", + Clusters: []string{params.LoadTestData("testdata/cluster/server.yaml.tmpl")}, + Listeners: []string{params.LoadTestData("testdata/listener/client.yaml.tmpl")}}, + &driver.Update{Node: "server", Version: "0", Listeners: []string{params.LoadTestData("testdata/listener/server.yaml.tmpl")}}, + &driver.UpdateExtensions{Extensions: []string{ + params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl"), + params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl"), + params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl"), + params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl"), + }, + }, + &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.HTTPCall{ + Port: params.Ports.ClientPort, + Body: "hello, world!", + }, + }, + &driver.Stats{params.Ports.ClientAdmin, map[string]driver.StatMatcher{ + "istio_requests_total": &driver.ExactStat{"testdata/metric/client_request_total.yaml.tmpl"}, + }}, + &driver.Stats{params.Ports.ServerAdmin, map[string]driver.StatMatcher{ + "istio_requests_total": &driver.ExactStat{"testdata/metric/server_request_total.yaml.tmpl"}, + }}, + }, + }).Run(params); err != nil { + t.Fatal(err) + } + }) + } +} diff --git a/testdata/filters/extension_config_inbound.yaml b/testdata/filters/extension_config_inbound.yaml new file mode 100644 index 00000000000..29e94529d9f --- /dev/null +++ b/testdata/filters/extension_config_inbound.yaml @@ -0,0 +1,20 @@ +- name: mx_inbound + config_discovery: + config_source: + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] +- name: stats_inbound + config_discovery: + config_source: + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] diff --git a/testdata/filters/extension_config_outbound.yaml b/testdata/filters/extension_config_outbound.yaml new file mode 100644 index 00000000000..bb22732ff53 --- /dev/null +++ b/testdata/filters/extension_config_outbound.yaml @@ -0,0 +1,20 @@ +- name: mx_outbound + config_discovery: + config_source: + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] +- name: stats_outbound + config_discovery: + config_source: + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] diff --git a/tools/extension_server/server.go b/tools/extension_server/server.go index 6095f5c6b20..f6248c3ec81 100644 --- a/tools/extension_server/server.go +++ b/tools/extension_server/server.go @@ -17,6 +17,7 @@ package extension_server import ( "context" + core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" discovery "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" "github.com/envoyproxy/go-control-plane/pkg/cache/v3" @@ -47,15 +48,18 @@ func New(ctx context.Context) *ExtensionServer { } func (es *ExtensionServer) StreamExtensionConfigs(stream extensionservice.ExtensionConfigDiscoveryService_StreamExtensionConfigsServer) error { - return status.Errorf(codes.Unimplemented, "not implemented") + return es.Server.StreamHandler(stream, ApiType) } func (es *ExtensionServer) DeltaExtensionConfigs(_ extensionservice.ExtensionConfigDiscoveryService_DeltaExtensionConfigsServer) error { return status.Errorf(codes.Unimplemented, "not implemented") } func (es *ExtensionServer) FetchExtensionConfigs(ctx context.Context, req *discovery.DiscoveryRequest) (*discovery.DiscoveryResponse, error) { - if req == nil { - return nil, status.Errorf(codes.Unavailable, "empty request") - } req.TypeUrl = ApiType return es.Server.Fetch(ctx, req) } +func (es *ExtensionServer) Update(config *core.TypedExtensionConfig) error { + return es.cache.UpdateResource(config.Name, config) +} +func (es *ExtensionServer) Delete(name string) error { + return es.cache.DeleteResource(name) +} From a06e5471947495afdffa39aa6320be0f77cdcf46 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 3 Aug 2020 15:03:43 -0700 Subject: [PATCH 04/12] iteration Signed-off-by: Kuat Yessenov --- test/envoye2e/stats_plugin/stats_test.go | 4 ++-- ...config_inbound.yaml => extension_config_inbound.yaml.tmpl} | 4 ++-- ...nfig_outbound.yaml => extension_config_outbound.yaml.tmpl} | 4 ++-- testdata/filters/mx_inbound.yaml.tmpl | 2 +- testdata/filters/mx_outbound.yaml.tmpl | 2 +- testdata/filters/stats_inbound.yaml.tmpl | 2 +- testdata/filters/stats_outbound.yaml.tmpl | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) rename testdata/filters/{extension_config_inbound.yaml => extension_config_inbound.yaml.tmpl} (90%) rename testdata/filters/{extension_config_outbound.yaml => extension_config_outbound.yaml.tmpl} (90%) diff --git a/test/envoye2e/stats_plugin/stats_test.go b/test/envoye2e/stats_plugin/stats_test.go index 92b84dbecd7..9ae55c64627 100644 --- a/test/envoye2e/stats_plugin/stats_test.go +++ b/test/envoye2e/stats_plugin/stats_test.go @@ -382,8 +382,8 @@ func TestStatsECDS(t *testing.T) { }, envoye2e.ProxyE2ETests) params.Vars["ClientMetadata"] = params.LoadTestData("testdata/client_node_metadata.json.tmpl") params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") - params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_inbound.yaml") - params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_outbound.yaml") + params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_inbound.yaml.tmpl") + params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_outbound.yaml.tmpl") if err := (&driver.Scenario{ []driver.Step{ &driver.XDS{}, diff --git a/testdata/filters/extension_config_inbound.yaml b/testdata/filters/extension_config_inbound.yaml.tmpl similarity index 90% rename from testdata/filters/extension_config_inbound.yaml rename to testdata/filters/extension_config_inbound.yaml.tmpl index 29e94529d9f..80893f06c9d 100644 --- a/testdata/filters/extension_config_inbound.yaml +++ b/testdata/filters/extension_config_inbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: mx_inbound +- name: mx_inbound{{.N}} config_discovery: config_source: api_config_source: @@ -8,7 +8,7 @@ - envoy_grpc: cluster_name: xds_cluster type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] -- name: stats_inbound +- name: stats_inbound{{.N}} config_discovery: config_source: api_config_source: diff --git a/testdata/filters/extension_config_outbound.yaml b/testdata/filters/extension_config_outbound.yaml.tmpl similarity index 90% rename from testdata/filters/extension_config_outbound.yaml rename to testdata/filters/extension_config_outbound.yaml.tmpl index bb22732ff53..1f534997e49 100644 --- a/testdata/filters/extension_config_outbound.yaml +++ b/testdata/filters/extension_config_outbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: mx_outbound +- name: mx_outbound{{.N}} config_discovery: config_source: api_config_source: @@ -8,7 +8,7 @@ - envoy_grpc: cluster_name: xds_cluster type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] -- name: stats_outbound +- name: stats_outbound{{.N}} config_discovery: config_source: api_config_source: diff --git a/testdata/filters/mx_inbound.yaml.tmpl b/testdata/filters/mx_inbound.yaml.tmpl index 1c778242b19..65623bfeac9 100644 --- a/testdata/filters/mx_inbound.yaml.tmpl +++ b/testdata/filters/mx_inbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: mx_inbound +- name: mx_inbound{{.N}} typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: envoy.extensions.filters.http.wasm.v3.Wasm diff --git a/testdata/filters/mx_outbound.yaml.tmpl b/testdata/filters/mx_outbound.yaml.tmpl index 41f101aebee..9ce71775372 100644 --- a/testdata/filters/mx_outbound.yaml.tmpl +++ b/testdata/filters/mx_outbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: mx_outbound +- name: mx_outbound{{.N}} typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: envoy.extensions.filters.http.wasm.v3.Wasm diff --git a/testdata/filters/stats_inbound.yaml.tmpl b/testdata/filters/stats_inbound.yaml.tmpl index 9a2ce8e442d..19a63bef1ae 100644 --- a/testdata/filters/stats_inbound.yaml.tmpl +++ b/testdata/filters/stats_inbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: stats_inbound +- name: stats_inbound{{.N}} typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: envoy.extensions.filters.http.wasm.v3.Wasm diff --git a/testdata/filters/stats_outbound.yaml.tmpl b/testdata/filters/stats_outbound.yaml.tmpl index f84046c3568..15540d2ebed 100644 --- a/testdata/filters/stats_outbound.yaml.tmpl +++ b/testdata/filters/stats_outbound.yaml.tmpl @@ -1,4 +1,4 @@ -- name: stats_outbound +- name: stats_outbound{{.N}} typed_config: "@type": type.googleapis.com/udpa.type.v1.TypedStruct type_url: envoy.extensions.filters.http.wasm.v3.Wasm From a79352dab1bcf35a78dadefe9b7cc0198a435d2b Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 3 Aug 2020 15:20:40 -0700 Subject: [PATCH 05/12] lint Signed-off-by: Kuat Yessenov --- test/envoye2e/driver/xds.go | 6 +++--- .../main/main.go | 7 ++++--- .../{extension_server => extensionserver}/server.go | 12 ++++++------ 3 files changed, 13 insertions(+), 12 deletions(-) rename tools/{extension_server => extensionserver}/main/main.go (91%) rename tools/{extension_server => extensionserver}/server.go (89%) diff --git a/test/envoye2e/driver/xds.go b/test/envoye2e/driver/xds.go index 5ca0e57a8f8..8b26a63e11a 100644 --- a/test/envoye2e/driver/xds.go +++ b/test/envoye2e/driver/xds.go @@ -20,7 +20,7 @@ import ( "log" "net" - "istio.io/proxy/tools/extension_server" + "istio.io/proxy/tools/extensionserver" cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" @@ -40,7 +40,7 @@ type XDS struct { // XDSServer is a struct holding xDS state. type XDSServer struct { - Extensions *extension_server.ExtensionServer + Extensions *extensionserver.ExtensionServer Cache cache.SnapshotCache } @@ -49,7 +49,7 @@ var _ Step = &XDS{} func (x *XDS) Run(p *Params) error { log.Printf("XDS server starting on %d\n", p.XDS) x.grpc = grpc.NewServer() - p.Config.Extensions = extension_server.New(context.Background()) + p.Config.Extensions = extensionserver.New(context.Background()) extensionservice.RegisterExtensionConfigDiscoveryServiceServer(x.grpc, p.Config.Extensions) p.Config.Cache = cache.NewSnapshotCache(false, cache.IDHash{}, x) xdsServer := server.NewServer(context.Background(), p.Config.Cache, nil) diff --git a/tools/extension_server/main/main.go b/tools/extensionserver/main/main.go similarity index 91% rename from tools/extension_server/main/main.go rename to tools/extensionserver/main/main.go index 29cca7444d7..83baaf74d1d 100644 --- a/tools/extension_server/main/main.go +++ b/tools/extensionserver/main/main.go @@ -25,7 +25,7 @@ import ( discoveryservice "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" - "istio.io/proxy/tools/extension_server" + "istio.io/proxy/tools/extensionserver" ) const ( @@ -34,7 +34,7 @@ const ( var ( port uint - server *extension_server.ExtensionServer + server *extensionserver.ExtensionServer ) func init() { @@ -49,7 +49,7 @@ func main() { if err != nil { log.Fatal(err) } - server := extension_server.New(context.Background()) + server := extensionserver.New(context.Background()) discoveryservice.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) extensionservice.RegisterExtensionConfigDiscoveryServiceServer(grpcServer, server) @@ -57,4 +57,5 @@ func main() { if err = grpcServer.Serve(lis); err != nil { log.Println(err) } + _ = server } diff --git a/tools/extension_server/server.go b/tools/extensionserver/server.go similarity index 89% rename from tools/extension_server/server.go rename to tools/extensionserver/server.go index f6248c3ec81..89f4e674049 100644 --- a/tools/extension_server/server.go +++ b/tools/extensionserver/server.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package extension_server +package extensionserver import ( "context" @@ -27,8 +27,8 @@ import ( ) const ( - // ApiType for extension configs. - ApiType = "type.googleapis.com/envoy.config.core.v3.TypedExtensionConfig" + // APIType for extension configs. + APIType = "type.googleapis.com/envoy.config.core.v3.TypedExtensionConfig" ) // ExtensionServer is the main server instance. @@ -42,19 +42,19 @@ var _ extensionservice.ExtensionConfigDiscoveryServiceServer = &ExtensionServer{ func New(ctx context.Context) *ExtensionServer { out := &ExtensionServer{} - out.cache = cache.NewLinearCache(ApiType, nil) + out.cache = cache.NewLinearCache(APIType, nil) out.Server = server.NewServer(ctx, out.cache, out) return out } func (es *ExtensionServer) StreamExtensionConfigs(stream extensionservice.ExtensionConfigDiscoveryService_StreamExtensionConfigsServer) error { - return es.Server.StreamHandler(stream, ApiType) + return es.Server.StreamHandler(stream, APIType) } func (es *ExtensionServer) DeltaExtensionConfigs(_ extensionservice.ExtensionConfigDiscoveryService_DeltaExtensionConfigsServer) error { return status.Errorf(codes.Unimplemented, "not implemented") } func (es *ExtensionServer) FetchExtensionConfigs(ctx context.Context, req *discovery.DiscoveryRequest) (*discovery.DiscoveryResponse, error) { - req.TypeUrl = ApiType + req.TypeUrl = APIType return es.Server.Fetch(ctx, req) } func (es *ExtensionServer) Update(config *core.TypedExtensionConfig) error { From 89caa3732ef4a685f98cfa30f0119dab9bcba8f6 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Mon, 3 Aug 2020 15:27:00 -0700 Subject: [PATCH 06/12] silly linter Signed-off-by: Kuat Yessenov --- tools/extensionserver/main/main.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/extensionserver/main/main.go b/tools/extensionserver/main/main.go index 83baaf74d1d..929432cb9a0 100644 --- a/tools/extensionserver/main/main.go +++ b/tools/extensionserver/main/main.go @@ -23,6 +23,7 @@ import ( "google.golang.org/grpc" + core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" discoveryservice "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" "istio.io/proxy/tools/extensionserver" @@ -53,9 +54,13 @@ func main() { discoveryservice.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) extensionservice.RegisterExtensionConfigDiscoveryServiceServer(grpcServer, server) + // load some config + server.Update(&core.TypedExtensionConfig{ + Name: "test", + }) + log.Printf("management server listening on %d\n", port) if err = grpcServer.Serve(lis); err != nil { log.Println(err) } - _ = server } From 833f720abe247d46e749defed45782375d2d1258 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 4 Aug 2020 13:03:12 -0700 Subject: [PATCH 07/12] update Signed-off-by: Kuat Yessenov --- go.mod | 1 + go.sum | 4 +- tools/extensionserver/config.go | 118 +++++++++++++++++++++ tools/extensionserver/config_test.go | 39 +++++++ tools/extensionserver/convert.go | 87 +++++++++++++++ tools/extensionserver/envoy.yaml | 63 +++++++++++ tools/extensionserver/main/main.go | 37 +++++-- tools/extensionserver/testdata/config.yaml | 5 + 8 files changed, 347 insertions(+), 7 deletions(-) create mode 100644 tools/extensionserver/config.go create mode 100644 tools/extensionserver/config_test.go create mode 100644 tools/extensionserver/convert.go create mode 100644 tools/extensionserver/envoy.yaml create mode 100644 tools/extensionserver/testdata/config.yaml diff --git a/go.mod b/go.mod index 3fda23505de..32d032a1f50 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 github.com/d4l3k/messagediff v1.2.2-0.20180726183240-b9e99b2f9263 github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1 + github.com/fsnotify/fsnotify v1.4.9 github.com/ghodss/yaml v1.0.0 github.com/golang/protobuf v1.4.2 github.com/kr/pretty v0.1.0 // indirect diff --git a/go.sum b/go.sum index 140baa84989..93bf10bf36a 100644 --- a/go.sum +++ b/go.sum @@ -22,11 +22,12 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7-0.20200731221939-3f4998b1fa63/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1 h1:jbSSXMArWufIwLI3keHepe+rVOwLExhWWirrdadSHL4= github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -138,6 +139,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d h1:nc5K6ox/4lTFbMVSL9WRR81ixkcwXThoiF6yf+R9scA= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/tools/extensionserver/config.go b/tools/extensionserver/config.go new file mode 100644 index 00000000000..911c11a07ad --- /dev/null +++ b/tools/extensionserver/config.go @@ -0,0 +1,118 @@ +// Copyright 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 extensionserver + +import ( + "encoding/json" + "io/ioutil" + "log" + "os" + "path/filepath" + "reflect" + + "github.com/fsnotify/fsnotify" + "github.com/ghodss/yaml" +) + +// Extension configuration +type Extension struct { + // Name of the extension + Name string `json:"name"` + // Configuration passed as JSON string + Configuration json.RawMessage `json:"configuration"` + // Path to the extension code + Path string `json:"path,omitempty"` + // VMID (optional) + VMID string `json:"id,omitempty"` + // RootID (optional) + RootID string `json:"root_id,omitempty"` +} + +// Config for the extension server +type Config struct { + // Extensions list + Extensions []*Extension `json:"extensions"` +} + +func (c *Config) merge(that *Config) { + c.Extensions = append(c.Extensions, that.Extensions...) +} + +// Read loads a configuration +func Read(data []byte) (*Config, error) { + config := &Config{} + return config, yaml.Unmarshal(data, config) +} + +// Load configuration files from a directory +func Load(dir string) *Config { + out := &Config{} + _ = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if info != nil && info.IsDir() { + return nil + } + ext := filepath.Ext(path) + if ext != ".json" && ext != ".yaml" && ext != ".yml" { + return nil + } + data, err := ioutil.ReadFile(path) + if err != nil { + log.Printf("error loading file %q: %v\n", path, err) + return nil + } + config, err := Read(data) + if err != nil { + log.Printf("error parsing file %q: %v\n", path, err) + return nil + } + out.merge(config) + return nil + }) + return out +} + +// Watch configuration files for changes (blocking call) +func Watch(dir string, apply func(*Config)) error { + watcher, err := fsnotify.NewWatcher() + if err != nil { + return err + } + err = watcher.Add(dir) + if err != nil { + return err + } + defer watcher.Close() + current := Load(dir) + apply(current) + for { + select { + case _, ok := <-watcher.Events: + if !ok { + return nil + } + next := Load(dir) + if reflect.DeepEqual(next, current) { + continue + } + current = next + apply(current) + case err, ok := <-watcher.Errors: + if !ok { + return nil + } + log.Printf("watch error: %v\n", err) + } + } +} diff --git a/tools/extensionserver/config_test.go b/tools/extensionserver/config_test.go new file mode 100644 index 00000000000..2410e6365ca --- /dev/null +++ b/tools/extensionserver/config_test.go @@ -0,0 +1,39 @@ +// Copyright 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 extensionserver_test + +import ( + "encoding/json" + "io/ioutil" + "testing" + + "istio.io/proxy/tools/extensionserver" +) + +func TestRead(t *testing.T) { + data, err := ioutil.ReadFile("testdata/config.yaml") + if err != nil { + t.Fatal(err) + } + out, err := extensionserver.Read(data) + if err != nil { + t.Fatal(err) + } + js, err := json.Marshal(out) + if err != nil { + t.Fatal(err) + } + t.Log(string(js)) +} diff --git a/tools/extensionserver/convert.go b/tools/extensionserver/convert.go new file mode 100644 index 00000000000..438143982bf --- /dev/null +++ b/tools/extensionserver/convert.go @@ -0,0 +1,87 @@ +// Copyright 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 extensionserver + +import ( + "io/ioutil" + + // udpa "github.com/cncf/udpa/go/udpa/type/v1" + core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + wasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" + v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" + ptypes "github.com/golang/protobuf/ptypes" + structpb "github.com/golang/protobuf/ptypes/struct" + "github.com/golang/protobuf/ptypes/wrappers" +) + +func pstring(value string) *structpb.Value { + return &structpb.Value{ + Kind: &structpb.Value_StringValue{ + StringValue: value, + }, + } +} + +// Convert to an envoy config. +func Convert(ext *Extension) (*core.TypedExtensionConfig, error) { + // wrap configuration into StringValue + json, err := ext.Configuration.MarshalJSON() + if err != nil { + return nil, err + } + configuration, err := ptypes.MarshalAny(&wrappers.StringValue{Value: string(json)}) + if err != nil { + return nil, err + } + + // load code as bytes + code, err := ioutil.ReadFile(ext.Path) + if err != nil { + return nil, err + } + + // create plugin config + plugin := &wasm.Wasm{ + Config: &v3.PluginConfig{ + RootId: ext.RootID, + VmConfig: &v3.PluginConfig_InlineVmConfig{ + InlineVmConfig: &v3.VmConfig{ + VmId: ext.VMID, + Runtime: "envoy.wasm.runtime.v8", + Code: &core.AsyncDataSource{ + Specifier: &core.AsyncDataSource_Local{ + Local: &core.DataSource{ + Specifier: &core.DataSource_InlineBytes{ + InlineBytes: code, + }, + }, + }, + }, + AllowPrecompiled: true, + }, + }, + Configuration: configuration, + }, + } + + typed, err := ptypes.MarshalAny(plugin) + if err != nil { + return nil, err + } + return &core.TypedExtensionConfig{ + Name: ext.Name, + TypedConfig: typed, + }, nil +} diff --git a/tools/extensionserver/envoy.yaml b/tools/extensionserver/envoy.yaml new file mode 100644 index 00000000000..6f4afd3c5c2 --- /dev/null +++ b/tools/extensionserver/envoy.yaml @@ -0,0 +1,63 @@ +static_resources: + listeners: + - address: + socket_address: + address: 0.0.0.0 + port_value: 8081 + traffic_direction: INBOUND + filter_chains: + - filters: + - name: inbound-http-proxy + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + codec_type: auto + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: backend + domains: + - "*" + routes: + - match: + prefix: "/" + direct_response: + status: 200 + body: + inline_string: "hello, world!\n" + http_filters: + - name: metadata_exchange + config_discovery: + config_source: + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] + - name: front-router + typed_config: + "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router + clusters: + - connect_timeout: 1s + http2_protocol_options: {} + name: xds_cluster + load_assignment: + cluster_name: xds_cluster + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 8080 +admin: + access_log_path: "/dev/null" + address: + socket_address: + address: 0.0.0.0 + port_value: 8001 +node: + id: test + cluster: test diff --git a/tools/extensionserver/main/main.go b/tools/extensionserver/main/main.go index 929432cb9a0..fce7e2fca9f 100644 --- a/tools/extensionserver/main/main.go +++ b/tools/extensionserver/main/main.go @@ -20,10 +20,10 @@ import ( "fmt" "log" "net" + "reflect" "google.golang.org/grpc" - core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" discoveryservice "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3" extensionservice "github.com/envoyproxy/go-control-plane/envoy/service/extension/v3" "istio.io/proxy/tools/extensionserver" @@ -35,11 +35,33 @@ const ( var ( port uint + dir string server *extensionserver.ExtensionServer + names = make(map[string]struct{}) ) func init() { flag.UintVar(&port, "port", 8080, "xDS management server port") + flag.StringVar(&dir, "c", "", "Configuration file directory") +} + +func apply(config *extensionserver.Config) { + next := make(map[string]struct{}) + for _, ext := range config.Extensions { + config, err := extensionserver.Convert(ext) + if err != nil { + log.Printf("error loading extension %q: %v\n", ext.Name, err) + continue + } + server.Update(config) + next[ext.Name] = struct{}{} + delete(names, ext.Name) + } + for name := range names { + server.Delete(name) + } + names = next + log.Printf("loaded extensions %v\n", reflect.ValueOf(names).MapKeys()) } func main() { @@ -50,14 +72,17 @@ func main() { if err != nil { log.Fatal(err) } - server := extensionserver.New(context.Background()) + server = extensionserver.New(context.Background()) discoveryservice.RegisterAggregatedDiscoveryServiceServer(grpcServer, server) extensionservice.RegisterExtensionConfigDiscoveryServiceServer(grpcServer, server) - // load some config - server.Update(&core.TypedExtensionConfig{ - Name: "test", - }) + log.Printf("watching directory %q\n", dir) + go func() { + err := extensionserver.Watch(dir, apply) + if err != nil { + log.Println(err) + } + }() log.Printf("management server listening on %d\n", port) if err = grpcServer.Serve(lis); err != nil { diff --git a/tools/extensionserver/testdata/config.yaml b/tools/extensionserver/testdata/config.yaml new file mode 100644 index 00000000000..448c314fa83 --- /dev/null +++ b/tools/extensionserver/testdata/config.yaml @@ -0,0 +1,5 @@ +extensions: +- name: metadata_exchange + path: bazel-bin/extensions/metadata_exchange.compiled.wasm + configuration: + max_peer_cache_size: 30 From 9390d0f3bd84839be038da8ebd8293f58f3f4aad Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 4 Aug 2020 13:58:37 -0700 Subject: [PATCH 08/12] lint Signed-off-by: Kuat Yessenov --- tools/extensionserver/config.go | 2 +- tools/extensionserver/convert.go | 10 +--------- tools/extensionserver/main/main.go | 8 ++++++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/tools/extensionserver/config.go b/tools/extensionserver/config.go index 911c11a07ad..e24385348aa 100644 --- a/tools/extensionserver/config.go +++ b/tools/extensionserver/config.go @@ -59,7 +59,7 @@ func Read(data []byte) (*Config, error) { // Load configuration files from a directory func Load(dir string) *Config { out := &Config{} - _ = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + _ = filepath.Walk(dir, func(path string, info os.FileInfo, _ error) error { if info != nil && info.IsDir() { return nil } diff --git a/tools/extensionserver/convert.go b/tools/extensionserver/convert.go index 438143982bf..1302198c67a 100644 --- a/tools/extensionserver/convert.go +++ b/tools/extensionserver/convert.go @@ -17,7 +17,6 @@ package extensionserver import ( "io/ioutil" - // udpa "github.com/cncf/udpa/go/udpa/type/v1" core "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" wasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" @@ -26,15 +25,8 @@ import ( "github.com/golang/protobuf/ptypes/wrappers" ) -func pstring(value string) *structpb.Value { - return &structpb.Value{ - Kind: &structpb.Value_StringValue{ - StringValue: value, - }, - } -} - // Convert to an envoy config. +// It so happens that 1.7 and 1.8 match in terms protobuf bytes, but not JSON. func Convert(ext *Extension) (*core.TypedExtensionConfig, error) { // wrap configuration into StringValue json, err := ext.Configuration.MarshalJSON() diff --git a/tools/extensionserver/main/main.go b/tools/extensionserver/main/main.go index fce7e2fca9f..b7ab879e625 100644 --- a/tools/extensionserver/main/main.go +++ b/tools/extensionserver/main/main.go @@ -53,12 +53,16 @@ func apply(config *extensionserver.Config) { log.Printf("error loading extension %q: %v\n", ext.Name, err) continue } - server.Update(config) + if err = server.Update(config); err != nil { + log.Printf("error updating extension %q: %v\n", ext.Name, err) + } next[ext.Name] = struct{}{} delete(names, ext.Name) } for name := range names { - server.Delete(name) + if err := server.Delete(name); err != nil { + log.Printlf("error deleting extension %q: %v\n", ext.Name, err) + } } names = next log.Printf("loaded extensions %v\n", reflect.ValueOf(names).MapKeys()) From 657f5b82fcdfa537a38d8149a3df1213e7225e5f Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 4 Aug 2020 14:10:04 -0700 Subject: [PATCH 09/12] fix import Signed-off-by: Kuat Yessenov --- tools/extensionserver/convert.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/extensionserver/convert.go b/tools/extensionserver/convert.go index 1302198c67a..653564a219d 100644 --- a/tools/extensionserver/convert.go +++ b/tools/extensionserver/convert.go @@ -21,7 +21,6 @@ import ( wasm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/wasm/v3" v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/wasm/v3" ptypes "github.com/golang/protobuf/ptypes" - structpb "github.com/golang/protobuf/ptypes/struct" "github.com/golang/protobuf/ptypes/wrappers" ) From 8d6a14a5fec2015b2556a85ab86fe3a28f812975 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 4 Aug 2020 14:11:09 -0700 Subject: [PATCH 10/12] fix import Signed-off-by: Kuat Yessenov --- tools/extensionserver/main/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/extensionserver/main/main.go b/tools/extensionserver/main/main.go index b7ab879e625..917cbb9ccff 100644 --- a/tools/extensionserver/main/main.go +++ b/tools/extensionserver/main/main.go @@ -61,7 +61,7 @@ func apply(config *extensionserver.Config) { } for name := range names { if err := server.Delete(name); err != nil { - log.Printlf("error deleting extension %q: %v\n", ext.Name, err) + log.Printf("error deleting extension %q: %v\n", name, err) } } names = next From 4182fbd338422cff592982a3108a6475f9344ec9 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Tue, 11 Aug 2020 08:54:59 -0700 Subject: [PATCH 11/12] testing Signed-off-by: Kuat Yessenov --- test/envoye2e/inventory.go | 3 +++ test/envoye2e/stats_plugin/stats_test.go | 17 +++++++++------- tools/extensionserver/envoy.yaml | 23 ++++++++++++++++++++++ tools/extensionserver/testdata/config.yaml | 4 ++-- 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/test/envoye2e/inventory.go b/test/envoye2e/inventory.go index d819c5c29b8..ea760a4b590 100644 --- a/test/envoye2e/inventory.go +++ b/test/envoye2e/inventory.go @@ -54,6 +54,9 @@ func init() { "TestTCPMetadataExchange", "TestTCPMetadataExchangeNoAlpn", "TestAttributeGen", + "TestStatsECDS/envoy.wasm.runtime.null", + "TestStatsECDS/envoy.wasm.runtime.v8", + "TestStatsECDS/envoy.wasm.runtime.v8#01", }, } } diff --git a/test/envoye2e/stats_plugin/stats_test.go b/test/envoye2e/stats_plugin/stats_test.go index 9ae55c64627..98dc1d0f6c6 100644 --- a/test/envoye2e/stats_plugin/stats_test.go +++ b/test/envoye2e/stats_plugin/stats_test.go @@ -384,6 +384,15 @@ func TestStatsECDS(t *testing.T) { params.Vars["ServerMetadata"] = params.LoadTestData("testdata/server_node_metadata.json.tmpl") params.Vars["ServerHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_inbound.yaml.tmpl") params.Vars["ClientHTTPFilters"] = params.LoadTestData("testdata/filters/extension_config_outbound.yaml.tmpl") + + updateExtensions := + &driver.UpdateExtensions{Extensions: []string{ + driver.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl"), + driver.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl"), + driver.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl"), + driver.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl"), + }, + } if err := (&driver.Scenario{ []driver.Step{ &driver.XDS{}, @@ -393,13 +402,7 @@ func TestStatsECDS(t *testing.T) { Clusters: []string{params.LoadTestData("testdata/cluster/server.yaml.tmpl")}, Listeners: []string{params.LoadTestData("testdata/listener/client.yaml.tmpl")}}, &driver.Update{Node: "server", Version: "0", Listeners: []string{params.LoadTestData("testdata/listener/server.yaml.tmpl")}}, - &driver.UpdateExtensions{Extensions: []string{ - params.LoadTestData("testdata/filters/mx_inbound.yaml.tmpl"), - params.LoadTestData("testdata/filters/stats_inbound.yaml.tmpl"), - params.LoadTestData("testdata/filters/mx_outbound.yaml.tmpl"), - params.LoadTestData("testdata/filters/stats_outbound.yaml.tmpl"), - }, - }, + updateExtensions, &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}, diff --git a/tools/extensionserver/envoy.yaml b/tools/extensionserver/envoy.yaml index 6f4afd3c5c2..c6585b0a577 100644 --- a/tools/extensionserver/envoy.yaml +++ b/tools/extensionserver/envoy.yaml @@ -61,3 +61,26 @@ admin: node: id: test cluster: test + metadata: { + "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", + "LABELS": { + "app": "ratings", + "pod-template-hash": "84975bc778", + "version": "v1", + "service.istio.io/canonical-name": "ratings", + "service.istio.io/canonical-revision": "version-1" + }, + "MESH_ID": "mesh", + "NAME": "ratings-v1-84975bc778-pxz2w", + "NAMESPACE": "default", + "OWNER": "kubernetes://apis/apps/v1/namespaces/default/deployments/ratings-v1", + "PLATFORM_METADATA": { + "gcp_gke_cluster_name": "test-cluster", + "gcp_location": "us-east4-b", + "gcp_project": "test-project" + }, + "POD_NAME": "ratings-v1-84975bc778-pxz2w", + "SERVICE_ACCOUNT": "bookinfo-ratings", + "WORKLOAD_NAME": "ratings-v1", + } diff --git a/tools/extensionserver/testdata/config.yaml b/tools/extensionserver/testdata/config.yaml index 448c314fa83..ba4432277be 100644 --- a/tools/extensionserver/testdata/config.yaml +++ b/tools/extensionserver/testdata/config.yaml @@ -1,5 +1,5 @@ extensions: - name: metadata_exchange - path: bazel-bin/extensions/metadata_exchange.compiled.wasm + path: bazel-bin/extensions/metadata_exchange.wasm configuration: - max_peer_cache_size: 30 + max_peer_cache_size: 60 From e0cfec812e8a767b15d68fa8defaac03eb5aaae3 Mon Sep 17 00:00:00 2001 From: Kuat Yessenov Date: Thu, 13 Aug 2020 14:01:27 -0700 Subject: [PATCH 12/12] update Signed-off-by: Kuat Yessenov --- go.mod | 2 +- go.sum | 4 +-- tools/extensionserver/config.go | 2 +- tools/extensionserver/config_test.go | 26 ++++++++++--------- tools/extensionserver/envoy.yaml | 10 +++++++ .../{config.yaml => metadata_exchange.yaml} | 1 + tools/extensionserver/testdata/stats.yaml | 8 ++++++ 7 files changed, 37 insertions(+), 16 deletions(-) rename tools/extensionserver/testdata/{config.yaml => metadata_exchange.yaml} (81%) create mode 100644 tools/extensionserver/testdata/stats.yaml diff --git a/go.mod b/go.mod index 32d032a1f50..9b899fc23ae 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( cloud.google.com/go/meshtelemetry/v1alpha1 v0.0.0 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 github.com/d4l3k/messagediff v1.2.2-0.20180726183240-b9e99b2f9263 - github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1 + github.com/envoyproxy/go-control-plane v0.9.7-0.20200813173324-b603f568eca7 github.com/fsnotify/fsnotify v1.4.9 github.com/ghodss/yaml v1.0.0 github.com/golang/protobuf v1.4.2 diff --git a/go.sum b/go.sum index 93bf10bf36a..ba489904016 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1 h1:jbSSXMArWufIwLI3keHepe+rVOwLExhWWirrdadSHL4= -github.com/envoyproxy/go-control-plane v0.9.7-0.20200803203158-9877870102f1/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.7-0.20200813173324-b603f568eca7 h1:o1sRFwWsIgDAy8NnjYMyskkiFSJnt/S3ex7zkOunHao= +github.com/envoyproxy/go-control-plane v0.9.7-0.20200813173324-b603f568eca7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= diff --git a/tools/extensionserver/config.go b/tools/extensionserver/config.go index e24385348aa..58a8b8f33bf 100644 --- a/tools/extensionserver/config.go +++ b/tools/extensionserver/config.go @@ -35,7 +35,7 @@ type Extension struct { // Path to the extension code Path string `json:"path,omitempty"` // VMID (optional) - VMID string `json:"id,omitempty"` + VMID string `json:"vm_id,omitempty"` // RootID (optional) RootID string `json:"root_id,omitempty"` } diff --git a/tools/extensionserver/config_test.go b/tools/extensionserver/config_test.go index 2410e6365ca..5482f4fee1f 100644 --- a/tools/extensionserver/config_test.go +++ b/tools/extensionserver/config_test.go @@ -23,17 +23,19 @@ import ( ) func TestRead(t *testing.T) { - data, err := ioutil.ReadFile("testdata/config.yaml") - if err != nil { - t.Fatal(err) + for _, file := range []string{"metadata_exchange", "stats"} { + data, err := ioutil.ReadFile("testdata/" + file + ".yaml") + if err != nil { + t.Fatal(err) + } + out, err := extensionserver.Read(data) + if err != nil { + t.Fatal(err) + } + js, err := json.Marshal(out) + if err != nil { + t.Fatal(err) + } + t.Log(string(js)) } - out, err := extensionserver.Read(data) - if err != nil { - t.Fatal(err) - } - js, err := json.Marshal(out) - if err != nil { - t.Fatal(err) - } - t.Log(string(js)) } diff --git a/tools/extensionserver/envoy.yaml b/tools/extensionserver/envoy.yaml index c6585b0a577..c0e7a8154dc 100644 --- a/tools/extensionserver/envoy.yaml +++ b/tools/extensionserver/envoy.yaml @@ -36,6 +36,16 @@ static_resources: - envoy_grpc: cluster_name: xds_cluster type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] + - name: stats + config_discovery: + config_source: + api_config_source: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + type_urls: ["envoy.extensions.filters.http.wasm.v3.Wasm"] - name: front-router typed_config: "@type": type.googleapis.com/envoy.config.filter.http.router.v2.Router diff --git a/tools/extensionserver/testdata/config.yaml b/tools/extensionserver/testdata/metadata_exchange.yaml similarity index 81% rename from tools/extensionserver/testdata/config.yaml rename to tools/extensionserver/testdata/metadata_exchange.yaml index ba4432277be..4d0ce2cf1bd 100644 --- a/tools/extensionserver/testdata/config.yaml +++ b/tools/extensionserver/testdata/metadata_exchange.yaml @@ -1,5 +1,6 @@ extensions: - name: metadata_exchange path: bazel-bin/extensions/metadata_exchange.wasm + vm_id: id1597352232945182978 configuration: max_peer_cache_size: 60 diff --git a/tools/extensionserver/testdata/stats.yaml b/tools/extensionserver/testdata/stats.yaml new file mode 100644 index 00000000000..521efecfa20 --- /dev/null +++ b/tools/extensionserver/testdata/stats.yaml @@ -0,0 +1,8 @@ +extensions: +- name: stats + path: bazel-bin/extensions/stats.wasm + vm_id: stats_inbound + root_id: stats_inbound + configuration: + debug: false + field_separator: ";.;"