From 1f3c3f4cf59875682d15c2352eaecc586e73f381 Mon Sep 17 00:00:00 2001 From: Nikita Volodin Date: Wed, 28 Feb 2024 22:56:14 -0500 Subject: [PATCH] feat: add buffer filter and naive buffer for edge case --- .../bookinfo/envoy-filter/golang-filter.yaml | 44 ++++++++++++++++--- .../pkg/envoyfilter/filter.go | 36 +++++++++++++-- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/evaluation/kubernetes/apps/test-sample-microservices/bookinfo/envoy-filter/golang-filter.yaml b/evaluation/kubernetes/apps/test-sample-microservices/bookinfo/envoy-filter/golang-filter.yaml index 0f26ce1d..4a3609b0 100644 --- a/evaluation/kubernetes/apps/test-sample-microservices/bookinfo/envoy-filter/golang-filter.yaml +++ b/evaluation/kubernetes/apps/test-sample-microservices/bookinfo/envoy-filter/golang-filter.yaml @@ -7,7 +7,7 @@ spec: configPatches: - applyTo: NETWORK_FILTER match: - context: SIDECAR_INBOUND + context: &direction SIDECAR_INBOUND listener: filterChain: filter: @@ -34,7 +34,7 @@ spec: split_spans_for_request: true - applyTo: HTTP_FILTER match: - context: &direction SIDECAR_INBOUND + context: *direction listener: portNumber: 9080 filterChain: @@ -45,7 +45,7 @@ spec: patch: operation: INSERT_BEFORE value: - name: golangfilter-inbound + name: &golang-filter-name golangfilter-inbound typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config library_id: simple @@ -70,6 +70,22 @@ spec: max_delay_seconds: 3600 decision_logs: console: true + - applyTo: HTTP_FILTER + match: + context: *direction + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: *golang-filter-name + patch: + operation: INSERT_BEFORE + value: + name: buffer-filter + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer + max_request_bytes: 5242880 --- apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter @@ -80,7 +96,7 @@ spec: configPatches: - applyTo: NETWORK_FILTER match: - context: SIDECAR_OUTBOUND + context: &direction SIDECAR_OUTBOUND listener: filterChain: filter: @@ -107,7 +123,7 @@ spec: split_spans_for_request: true - applyTo: HTTP_FILTER match: - context: &direction SIDECAR_OUTBOUND + context: *direction listener: filterChain: filter: @@ -117,7 +133,7 @@ spec: patch: operation: INSERT_BEFORE value: - name: golangfilter-outbound + name: &golang-filter-name golangfilter-outbound typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.golang.v3alpha.Config library_id: simple @@ -142,3 +158,19 @@ spec: max_delay_seconds: 3600 decision_logs: console: true + - applyTo: HTTP_FILTER + match: + context: *direction + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: *golang-filter-name + patch: + operation: INSERT_BEFORE + value: + name: buffer-filter + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer + max_request_bytes: 5242880 diff --git a/privacy-profile-composer/pkg/envoyfilter/filter.go b/privacy-profile-composer/pkg/envoyfilter/filter.go index fb07ca67..82034999 100644 --- a/privacy-profile-composer/pkg/envoyfilter/filter.go +++ b/privacy-profile-composer/pkg/envoyfilter/filter.go @@ -51,6 +51,8 @@ type Filter struct { // Runtime state of the filter parentSpanContext model.SpanContext headerMetadata common.HeaderMetadata + decodeDataBuffer string + encodeDataBuffer string } // Callbacks which are called in request path @@ -69,10 +71,24 @@ func (f *Filter) DecodeHeaders(header api.RequestHeaderMap, endStream bool) api. common.LogDecodeHeaderData(header) - return api.Continue + if !endStream { + return api.StopAndBuffer + } else { + return api.Continue + } } func (f *Filter) DecodeData(buffer api.BufferInstance, endStream bool) api.StatusType { + if !endStream { + // TODO: we might need to be careful about collecting the data from all + // of these buffers. Maybe go has some builtin methods to work with it, + // instead of us collecting the entire body using string concat. + // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/buffer_filter + // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/file_system_buffer_filter + f.decodeDataBuffer += buffer.String() + return api.StopAndBuffer + } + span, ctx := f.tracer.StartSpanFromContext( context.Background(), "DecodeData", @@ -81,7 +97,9 @@ func (f *Filter) DecodeData(buffer api.BufferInstance, endStream bool) api.Statu defer span.Finish() log.Println(">>> DECODE DATA") - log.Println(" <>") + log.Println(" <>") + + span.Tag("buffer-value", f.decodeDataBuffer) processBody := false // If it is an inbound sidecar, then do process the body @@ -148,6 +166,16 @@ func (f *Filter) EncodeHeaders(header api.ResponseHeaderMap, endStream bool) api // Callbacks which are called in response path func (f *Filter) EncodeData(buffer api.BufferInstance, endStream bool) api.StatusType { + if !endStream { + // TODO: we might need to be careful about collecting the data from all + // of these buffers. Maybe go has some builtin methods to work with it, + // instead of us collecting the entire body using string concat. + // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/buffer_filter + // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/file_system_buffer_filter + f.encodeDataBuffer += buffer.String() + return api.StopAndBuffer + } + span, ctx := f.tracer.StartSpanFromContext( context.Background(), "EncodeData", @@ -156,7 +184,9 @@ func (f *Filter) EncodeData(buffer api.BufferInstance, endStream bool) api.Statu defer span.Finish() log.Println("<<< ENCODE DATA") - log.Println(" <>") + log.Println(" <>") + + span.Tag("buffer-value", f.encodeDataBuffer) // if outbound then indirect purpose of use violation // TODO: This is usually data obtained from another service