Add headers using virtual service

Hello,

I tried hard searching for a solution or doc for this but there is nothing out there which will be straight forward explaining this.

There is some information here: https://istio.io/docs/reference/config/networking/v1alpha3/virtual-service/#Headers

but how to use it is not there. Someone asked in THIS github issue to make a doc but that is not done yet too.

Here is my VS:

spec:
  gateways:
  - my-gateway
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /api/browse
    rewrite:
      uri: /
    route:
    - destination:
        host: browse.browse-relqa.svc.cluster.local
        port:
          number: 80
        subset: v1
      weight: 100
    - destination:
        host: browse.browse-relqa.svc.cluster.local
        port:
          number: 80
        subset: v2
      weight: 0

What should I do to add one header with following key value – “name: test”

If you want to add the header to the request, add something like this:

headers:
  request:
    add:
      name: test

If you want to add the header for all routes, put it just before the route: field.
If you only want it to be added to one of the routes, put it after the weight field of the corresponding route.

@frankbu you da man

Thanks a lot for this, I was doing such a silly indentation mistake.You are amazing. :slight_smile:

@frankbu If we want to extend this header addition to match a condition such as:

if one header “test-2” has value “name-2” then only I want to add or set a header “name” with value “test”:

I dont think I am doing right thing in following config:

spec:
  gateways:
  - my-gateway
  hosts:
  - '*'
  http:
  - headers:
      request:
        set:
          name: test
    match:
    - headers:
        name-2:
          exact: test-2
    - uri:
        prefix: /api/checkout
    rewrite:
      uri: /
    route:
    - destination:
        host: checkout.checkout-relqa.svc.cluster.local
        port:
          number: 80
        subset: v1
      weight: 100
    - destination:
        host: checkout.checkout-relqa.svc.cluster.local
        port:
          number: 80
        subset: v2
      weight: 0
    timeout: 10s

to reiterate I want a “if” condition here …

If name-2=test-2
then set
name=test

Your VirtualService is configuring the route for requests that have the name2=test-2 header. Your rule is also saying, btw, add the name=test header for requests taking this route.

So that will do what you want, but what’s missing in your VirtualService is what route to take when the name2=test-2 header is not present in the request. If you want it to take the same route just without adding your header, you need to add a complete copy of the rule (minus the header and match) and add it as a second rule. That’s not the nicest way to achieve your goal.

If you really want to add custom logic in the request path, it may be better to do it in the application code, or maybe using a policy adapter or an EnvoyFilter to do it.

@frankbu We are using EnvoyFilters to do all the header manipulation. It is becoming really complicated to solve some of the problems using that.

but I agree its better to use envoyFilters for such tasks.

Thank You