How to use OR logic in istio virtual service header exact match?

Viewed 1149

I have two services running and 4 different headers. I want to direct requests with headers a and c to one service and b and d to another service. What is the best way to achieve that in a virtual service manifests?

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sample_virtualservice
  namespace: sample_namespace
spec:
  hosts:
    - sample_service.sample_namespace.svc.cluster.local
  http:
  - match:
    - headers:
        x-test:
          exact: "a" OR "c" //This doesn't work but I want to achieve.
    route:
      - destination:
          host: service_1.sample_namespace.svc.cluster.local
          port:
            number: 80
  - route:
    - destination:
        host: service_2.sample_namespace.svc.cluster.local
        port:
          number: 80

I believe there must be a better way instead of mentioning the same route destination multiple times in a manifest file.

2 Answers

I found a clean solution of using regex instead of exact which allows us to send requests to the same destination for different headers without mentioning the same route destination multiple times in a manifest file.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sample_virtualservice
  namespace: sample_namespace
spec:
  hosts:
    - sample_service.sample_namespace.svc.cluster.local
  http:
  - match:
    - headers:
        x-test:
          regex: "a|c"
    route:
      - destination:
          host: service_1.sample_namespace.svc.cluster.local
          port:
            number: 80
  - route:
    - destination:
        host: service_2.sample_namespace.svc.cluster.local
        port:
          number: 80

As far as I know there are not logical operators in istio virtual service.

They are only available in rules and mixer expression language.


As you mentioned for now the only option is to use the same route multiple times.

So virtual service would look like this.

http:
- name: "a"
  match:
  - headers:
      x-test:
        exact: "a" 
  route:
  - destination:
    host: service_1.sample_namespace.svc.cluster.local
      port:
        number: 80
- name: "b"
  match:
  - headers:
      x-test:
        exact: "b" 
  route:
  - destination:
    host: service_1.sample_namespace.svc.cluster.local
      port:
        number: 80  
- name: "c"
  match:
  - headers:
      x-test:
        exact: "c" 
  route:
  - destination:
    host: service_2.sample_namespace.svc.cluster.local
      port:
        number: 80
- name: "d"
  match:
  - headers:
      x-test:
        exact: "d" 
  route:
  - destination:
    host: service_2.sample_namespace.svc.cluster.local
      port:
        number: 80 

Additional info, I see you have virtual service deployed in sample_namespace, remember that gateway should be deployed in the same namespace. If it´s not, you should add it like in below example.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: my-gateway
  namespace: some-config-namespace

Check the spec.gateways section

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo-Mongo
  namespace: sample_namespace
spec:
  gateways:
  - some-config-namespace/my-gateway 
Related