Istio Ingress Regex Negation

11/26/2019

I'm using Kubernetes with Istio which comes with traffic management. All backend api endpoints starts with /api/** followed by specific uri except frontend service. Frontend service has no any general uri prefix.

What i want to achieve is in the istio VirtualService use a regular expression that basically says, if a requested uri does not start with /api/, let it be served by frontend-service.

This is my VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: {{ .Release.Name }}-frontend-ingress
  namespace: default
spec:
  hosts:
  {{ include "application.domain" . }}
  gateways:
  - iprocure-gateway
  http:
  - match:
    - uri:
        regex: '^(?!\/api\/).*'
    route:
    - destination:  
        host: {{ printf "%s.%s.svc.cluster.local" .Values.frontendService.serviceName .Release.Name }}
        port:
          number: {{ .Values.frontendService.service.port }}

What is the regex value that I can use to make all request that does not start with /api/ be served with frontend-service

-- Yunus Einsteinium
istio
kubernetes
kubernetes-ingress

2 Answers

4/7/2020

See Istio 1.4.x upgrade notes under the heading "Regex engine changes". Envoy has moved to the Google Re2 "safe" regex engine which doesn't support negative look-ahead. An opt-out via an environment variable to Pilot is possible but will be removed in future versions. I've yet to find a long-term solution to this other than writing long regexs.

For your particular case try

regex: "^/((a$)|(ap$)|(api$)|([^a].*)|(a[^p].*)|(ap[^i].*)|(api[^/].*))"
-- acarroll
Source: StackOverflow

11/27/2019

Please try removing the single quotes from the regex: field , from other github posts they are not being used.

Virtual Service uses ECMAscript style so when you add the single quotes it searches literally for the string between them

-- Ernesto U
Source: StackOverflow