Q:

Istio Virtual Service - can I route traffic based on the calling service

Say I've got three services, ServiceA, ServiceB, and ServiceC. ServiceA and ServiceB both call ServiceC. I want to deploy a new version of ServiceC, but only want to send it traffic from ServiceB for testing. Is there a Route configuration that takes "calling service" into account?

A:

Based on istio documentation
You can do it with virtual service, or virtual service and destination rule.

With labels, example here

Deployments with app and version labels: We recommend adding an explicit app label and version label to deployments. Add the labels to the deployment specification of pods deployed using the Kubernetes Deployment. The app and version labels add contextual information to the metrics and telemetry Istio collects.
The app label: Each deployment specification should have a distinct app label with a meaningful value. The app label is used to add contextual information in distributed tracing.
The version label: This label indicates the version of the application corresponding to the particular deployment.

Each routing rule is associated with one or more service versions (see glossary in beginning of document). Weights associated with the version determine the proportion of traffic it receives. For example, the following rule will route 25% of traffic for the “reviews” service to instances with the “v2” tag and the remaining traffic (i.e., 75%) to “v1”.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
      weight: 25
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1
      weight: 75

And the associated DestinationRule

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews-destination
spec:
  host: reviews.prod.svc.cluster.local
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

OR

Traffic can also be split across two entirely different services without having to define new subsets. For example, the following rule forwards 25% of traffic to reviews.com and 75% to dev.reviews.com

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route-two-domains
spec:
  hosts:
  - reviews.com
  http:
  - route:
    - destination:
        host: dev.reviews.com
      weight: 25
    - destination:
        host: reviews.com
      weight: 75

EDIT
So actually you would have to add labels to your serviceC 1.0 and 2.0 and virtual service would look like this.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route-two-domains
spec:
  hosts:
  - reviews.com
  http:
  - match:
    - sourceLabels:
        svc: A
    - route:
      - destination:
          host: serviceC
          label: v1
  - match:
    - sourceLabels:
        svc: B
    - route:
      - destination:
          host: serviceC
          label: v2

Check my another answer where I used sourceLabels here

Let me know if you have any more questions.

