Re-routing host when calling external service (based on header)

Hi all,

I am currently trying to route traffic from a service running in Kubernetes to an external service represented by Wikipedia. The routing should be made based on some header value of wikipedia-country and should route to the respective Wikipedia country host. Thereby, the K8s pod should always use wikipedia.org as its domain.
Some routing examples I imagined based on the docs (Istio / Virtual Service):
wikipedia-country: de → routes to de.wikipedia.org instead of wikipedia.org
wikipedia-country: fr → routes to fr.wikipedia.org instead of wikipedia.org

I tried to set this up using ServiceEntry and VirtualService as defined below:

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: external-svc-wikipedia
  namespace: service-mesh-demo
spec:
  hosts:
    - wikipedia.org
    - "*.wikipedia.org"
  location: MESH_EXTERNAL
  ports:
    - number: 443
      name: https
      protocol: TLS
    - number: 80
      name: http
      protocol: HTTP
  resolution: NONE
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: wikipedia
  namespace: service-mesh-demo
spec:
  hosts:
    - wikipedia.org
  http:
    - match:
      - headers:
          wikipedia-country:
            exact: de
      route:
        - destination:
            host: de.wikipedia.org
    - match:
      - headers:
          wikipedia-country:
            exact: fr
      route:
        - destination:
            host: fr.wikipedia.org

Unfortunately, the VirtualService does either not work (even if replacing the redirect with fault injection or timeouts) or result in 504 Gateway errors.

It would be awesome in case someone can point me in the right direction or could tell me if I am aiming for something impossible to do.

I also added the very simple express.js server running in OpenShift/ K8s:

Service source code executing the call
'use strict';
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;

const express = require('express');
const axios = require('axios');

// Constants
const PORT = 8080;
const HOST = '0.0.0.0';

const WIKIPEDIA_HOST = process.env.WIKIPEDIA_HOST ? process.env.WIKIPEDIA_HOST : "https://wikipedia.org";
console.log("WIKIPEDIA_HOST: " + WIKIPEDIA_HOST);

// App
const app = express();
app.get('/wiki/search', (req, res) => {

  console.log(`Received request with searchString ${req.query.searchString} for wikipedia-country ${req.headers["wikipedia-country"]}`)

  var config = {
      method: 'get',
      url: WIKIPEDIA_HOST + "/w/api.php?action=query&origin=*&format=json&generator=search&gsrnamespace=0&gsrlimit=5&gsrsearch=" + req.query.searchString,
      headers: propagateHeader(req)
  };

  axios(config)
      .then(function (response) {
          console.log(JSON.stringify(response.data));
          res.send(response.data);
      })
      .catch(function (error) {
          console.log(error);
      });
});

app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

function propagateHeader(req) {
  return {
      "wikipedia-country": req.headers["wikipedia-country"]
  }
}

@MarianZoll Did you get this working by any chance?