Hi-
I’m trying find a way to forward an inbound header value to a service
that is, an inbound request for an istio service svc1
contains header “foo=bar”, i’d like to automatically forward that header to an upstream service like svc2
At the moment, i have to read that key/value in code and then reemit that to the outbound call.
Is it possible to do this automatically using something like EnvoyFilter
and LUA?
I made some progress below by using both a filter that reads the header using SIDECAR_INBOUND
and then emits some other header to upstream using SIDECAR_OUTBOUND
:
What i can’t figure out is how to use the inbound_header
variable in one filter in another one in the chain later on (i.,e read it in SIDECAR_INBOUND
and use that in SIDECAR_OUTBOUND
both of whih are envoy.lua
Here’s the yaml i’ve setup so far:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin-virtualservice
spec:
hosts:
- "httpbin.example.com"
gateways:
- my-gateway
http:
- route:
- destination:
host: httpbin
headers:
request:
add:
added: "header"
set:
test: "true"
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin-destination
spec:
host: httpbin
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
loadBalancer:
simple: ROUND_ROBIN
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: httpbin-lua-inbound
spec:
workloadLabels:
app: httpbin
filters:
- listenerMatch:
listenerType: ANY
insertPosition:
index: FIRST
filterName: envoy.lua
filterType: HTTP
filterConfig:
inlineCode: |
local inbound_header
function envoy_on_request(request_handle)
request_handle:logInfo(">>>> SIDECAR_INBOUND envoy_on_request called ")
inbound_header = request_handle:headers():get("foo")
end
- listenerMatch:
listenerType: SIDECAR_OUTBOUND
insertPosition:
index: BEFORE
relativeTo: envoy.router
filterName: envoy.lua
filterType: HTTP
filterConfig:
inlineCode: |
function envoy_on_request(request_handle)
request_handle:logInfo(">>>> SIDECAR_OUTBOUND envoy_on_request called ")
-- somehow read inbound_header and add that to the request header here
request_handle:headers():add("foo", inbound_header)
end
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
serviceAccountName: httpbin
containers:
- image: salrashid123/httpbin-remote:1
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 8080
note, the image salrashid123/httpbin-remote:1
just makes an http GET call to httpbin (which means if you tail the logs on that cotnainer while testing, it’ll print out the headers svc1
sent out (externally outside of istio)
Is there any easier way to do this (i tried using dynamic metadata in LUA but didn’t make any progress)