1

I have written the ext_authz filter for envoy and have basic understanding of how envoy filters done. But now I want to filter the response coming back from the upstream. Specifically, I want to handle two things:

  1. Intercept data/jsonBody coming from upstream and Filter/Modify the responseJsonBody based on some business rule before envoy sends back to downstream.

  2. If upstream is down(when http response code 408-Timeout), I want to save the post-request to async-msg-que and send back a 202-Accepted back to downstream. This way, when the upstream comes back it will process pending post-request from it's async-msg-que.

Is there a existing filter I can use for these purpose or what is the right way to do this using envoy-proxy sidecar.

Thanks.

sriba
  • 745
  • 1
  • 6
  • 13

1 Answers1

5

You need to write the filter yourself using lua:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-filter
  namespace: some-namespace
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
            subFilter:
              name: "envoy.extAuthz" # name of your ext_authz filter
    patch:
      operation: INSERT_AFTER
      value: 
       name: envoy.custom-resp
       typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
          inlineCode: |
            function envoy_on_response(response_handle) 
              if response_handle:headers():get(":status") == "408" then
                -- send message depending on your queue, eg via httpCall()
                -- Overwrite status and body
                response_handle:headers():replace(":status", "202")
              else 
                -- get response body as jsonString
                local body = response_handle:body()
                local jsonString = tostring(body:getBytes(0, body:length()))
                -- do something, eg replace secret by regex 
                jsonString = jsonString:gsub("(foo|bar)", "")
                response_handle:body():set(jsonString)
              end
            end

Note that you need to handle timeouts of the queue somehow.

Envoy With Lua

httpCall

Lua Docs

Chris
  • 5,109
  • 3
  • 19
  • 40
  • Thanks Chris, I get the idea how to approach the solution. The data filtering logic and queuing logic in my case is big and having them directly in lua is not optimal. But with lua + httpCall(), I can outsource the heavy lifting to another sidecar written in golang. This approach should work. But it would be more optimal if lua can be avoided and go to golang sidecar directly from envoy(like ext_auth filter). I noticed another filter "envoy.filters.http.ext_proc" looks very similar, but doc says it's work in progress. Is there any alternate to lua approach?. – sriba May 04 '21 at 00:08
  • Why not trying with a webassembly ? – Peter Claes May 04 '21 at 18:44
  • My impression is envoy+webassembly is still upcoming...not yet there as native filters...or am i mistaken? – sriba May 05 '21 at 14:37
  • If you're business logic is that important/complex, I would rather create another service that calls your service, handles downtime and response manipulation instead of trying to pull that logic into the istio sidecar/another sidecar. It's much easier to develop, to debug and to maintain. – Chris May 05 '21 at 14:55
  • 1
    @ChristophRaab, Yes Chris, I'm planning to something similar. Write that complex response manipulation in a golang rest-service and deploy that service as a sidecar in same pod and call it from above lua filter on_reponse function. I have a similar sidecar that fits in as ext_authz directly to envoy. I was looking something similar direct filter than taking a round about thru lua. Calling external service from lua is not that bad for now, wonder if any other choices available. – sriba May 07 '21 at 00:20
  • @sriba , solo.io has done some nice work facilitating webassembly in Istio : https://docs.solo.io/web-assembly-hub/latest – Peter Claes May 14 '21 at 19:38