фильтр посланника для перехвата ответа восходящего потока

Я написал фильтр ext_authz для envoy и имею базовое представление о том, как работают фильтры envoy. Но теперь я хочу отфильтровать ответ от восходящего потока. В частности, я хочу разобраться с двумя вещами:

  1. Перехватить данные / jsonBody, поступающие из восходящего потока, и отфильтровать / изменить responseJsonBody на основе некоторого бизнес-правила, прежде чем посланник отправит обратно в нисходящий поток.

  2. Если восходящий поток не работает (когда HTTP-код ответа 408-Timeout), я хочу сохранить пост-запрос в async-msg-que и отправить обратно 202-Accepted обратно в нисходящий поток. Таким образом, когда восходящий поток вернется, он обработает ожидающий пост-запрос от него async-msg-que.

Есть ли существующий фильтр, который я могу использовать для этих целей, или как это сделать с помощью сопроводительного файла envoy-proxy.

Спасибо.


person sriba    schedule 01.05.2021    source источник


Ответы (1)


Вам нужно написать фильтр самостоятельно, используя 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

Обратите внимание, что вам нужно как-то обрабатывать тайм-ауты очереди.

Envoy с Lua

https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/lua_filter#httpcall

Документы Lua

person Chris    schedule 01.05.2021
comment
Спасибо, Крис, я понимаю, как подойти к решению. Логика фильтрации данных и логика очередей в моем случае велики, и их использование непосредственно в lua не оптимально. Но с lua + httpCall () я могу передать тяжелую работу другой коляске, написанной на golang. Такой подход должен работать. Но было бы более оптимальным, если бы можно было избежать lua и перейти к сопроводительному файлу golang непосредственно из envoy (например, фильтр ext_auth). Я заметил, что другой фильтр envoy.filters.http.ext_proc выглядит очень похожим, но документ говорит, что он в процессе. Есть ли альтернатива подходу lua? - person sriba; 04.05.2021
comment
Почему бы не попробовать с веб-сборкой? - person Peter Claes; 04.05.2021
comment
У меня такое впечатление, что envoy + webassembly все еще готовится ... пока нет встроенных фильтров ... или я ошибаюсь? - person sriba; 05.05.2021
comment
Если ваша бизнес-логика настолько важна / сложна, я бы предпочел создать другую службу, которая вызывает вашу службу, обрабатывает время простоя и манипулирование ответами, вместо того, чтобы пытаться вытащить эту логику в istio sidecar / другой sidecar. Гораздо проще разрабатывать, отлаживать и поддерживать. - person Chris; 05.05.2021
comment
@ChristophRaab, Да Крис, я планирую нечто подобное. Напишите эту сложную манипуляцию с ответами в golang rest-service и разверните эту службу в качестве сопутствующего компонента в том же модуле и вызовите ее сверху функцией lua filter on_reponse. У меня есть аналогичная коляска, которая подходит как ext_authz непосредственно к посланнику. Я искал что-то похожее на прямой фильтр, чем на обход через lua. Вызов внешней службы из lua на данный момент не так уж и плох, интересно, доступны ли какие-либо другие варианты. - person sriba; 07.05.2021
comment
@sriba, solo.io проделал отличную работу по упрощению веб-сборки в Istio: docs.solo. io / web-assembly-hub / последняя версия - person Peter Claes; 14.05.2021