I'm trying to make EnvoyFilters work in my installation. For test purposes I'm trying to set lua filter that logs dumb message and adds header to the resonse.
Here's my configuration:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: dumb-filter
namespace: istio-system
spec:
# workloadSelector:
# labels:
# istio: ingressgateway
configPatches:
# - applyTo: VIRTUAL_HOST
- applyTo: HTTP_ROUTE
match:
context: GATEWAY
# context: ANY
routeConfiguration:
vhost:
# name: "<domain>:443"
route:
#TODO: Understand name compose logic
name: https.443.https.geth-dedicated.default
patch:
operation: MERGE
value:
name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_response(response_handle)
response_handle:headers():add("dm3ch-test", "dm3ch")
response_handle:logErr("Bye Bye.")
end
For now I see no log message or test header in response. I already tried:
istio: ingressgateway
label)VIRTUAL_HOST
and HTTP_ROUTE
modeshttps.443.https.geth-dedicated.default
using istioctl proxy-config route <gateway_pod>
command.vhost.name
setting and commenting vhost.route.name
Istio version info:
❯ istioctl version
client version: 1.11.4
control plane version: 1.12.0-alpha.1
data plane version: 1.12.0-alpha.1 (1 proxies)
route configuration json:
❯ istioctl proxy-config route istio-ingress-675cb54bc9-5r8cs.istio-system --name https.443.https.geth-dedicated.default -o json
[
{
"name": "https.443.https.geth-dedicated.default",
"virtualHosts": [
{
"name": "<domain>:443",
"domains": [
"<domain>",
"<domain>:*"
],
"routes": [
{
"match": {
"prefix": "/",
"caseSensitive": true
},
"route": {
"cluster": "outbound|8545||geth-dedicated.default.svc.cluster.local",
"timeout": "0s",
"retryPolicy": {
"retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
"numRetries": 2,
"retryHostPredicate": [
{
"name": "envoy.retry_host_predicates.previous_hosts"
}
],
"hostSelectionRetryMaxAttempts": "5",
"retriableStatusCodes": [
503
]
},
"hashPolicy": [
{
"connectionProperties": {
"sourceIp": true
}
}
],
"maxGrpcTimeout": "0s"
},
"metadata": {
"filterMetadata": {
"istio": {
"config": "/apis/networking.istio.io/v1alpha3/namespaces/default/virtual-service/geth-dedicated"
}
}
},
"decorator": {
"operation": "geth-dedicated.default.svc.cluster.local:8545/*"
}
}
],
"includeRequestAttemptCount": true
}
],
"validateClusters": false
I would be glad if anyone could consult me what am I doing wrong or how can I better debug why filter is not applied.
P.S. My goal is to invoke custom logic during request/response handling on ingressgateway istio deployment for specific virtualservice only
Chris answer was very useful, but unfortunately it wasn't not full. :(
Here what I've found:
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
filter on HTTP_ROUTE
(but it's possible to use LuaPerRoute
)type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
itself doesn't allow to define new lua filter, it allows only disable existing Lua filter or override it's source code envoy docsSo to make lua custom logic that is applied to only one http route you need to define "global" Lua
filter and override it's code for specific http route using LuaPerRoute
filter.
Here's my manifests that allowed me to make it work:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: geth-dedicated
namespace: default
spec:
gateways:
- geth-dedicated # I'm ommiting gateway creation in this snippet
hosts:
- <domain>
http:
- match:
- uri:
prefix: /
name: geth-public
route:
- destination:
host: geth-dedicated
port:
number: 8545
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: dumb-filter
namespace: istio-system # Namespace where istio gateway pods are actually running
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
# Patch that creates "global" lua filter that does nothing useful
- applyTo: HTTP_FILTER
match:
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
-- Empty lua function
end
# Filter for http route that overrides "global" filter lua source code
- applyTo: HTTP_ROUTE
match:
context: GATEWAY
routeConfiguration:
vhost:
route:
name: geth-public # Corresponds to http[0].name in VirtualService
patch:
operation: MERGE
value:
name: envoy.lua
typed_per_filter_config:
envoy.filters.http.lua:
'@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.LuaPerRoute
source_code:
inline_string: |
function envoy_on_response(response_handle)
response_handle:logErr("Goodbye my brain.")
response_handle:headers():add("dm3ch-test", "dm3ch wins")
end