Add samples 38/4038/1
authorXinhui Li <xinhui.li@salesforce.com>
Tue, 5 Jan 2021 19:24:35 +0000 (11:24 -0800)
committerXinhui Li <xinhui.li@salesforce.com>
Tue, 5 Jan 2021 19:24:35 +0000 (11:24 -0800)
Signed-off-by: xinhui li <xinhui.li@salesforce.com>
Change-Id: I1eaaa56d6438be86a74e29b6b5aa7c63b5afbb5b

151 files changed:
mash/eks/samples/README.md [new file with mode: 0644]
mash/eks/samples/addons/README.md [new file with mode: 0644]
mash/eks/samples/addons/extras/prometheus-operator.yaml [new file with mode: 0644]
mash/eks/samples/addons/extras/zipkin.yaml [new file with mode: 0644]
mash/eks/samples/addons/grafana.yaml [new file with mode: 0644]
mash/eks/samples/addons/jaeger.yaml [new file with mode: 0644]
mash/eks/samples/addons/kiali.yaml [new file with mode: 0644]
mash/eks/samples/addons/prometheus.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/README.md [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/bookinfo-gateway.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/certmanager-gateway.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/destination-rule-all-mtls.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/destination-rule-all.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/destination-rule-reviews.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/egress-rule-google-apis.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/fault-injection-details-v1.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-all-v1.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-details-v2.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-ratings-db.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-ratings-mysql-vm.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-80-20.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-90-10.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-v2-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/networking/virtual-service-reviews-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/README.md [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/bookinfo.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/cleanup.sh [new file with mode: 0755]
mash/eks/samples/bookinfo/platform/consul/destination-rule-all.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-all-v1.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-ratings-test-abort.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-ratings-test-delay.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-50-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-test-v2.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-v2-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-v3.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/README.md [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-certificate.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-db.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-details.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-ingress.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-mysql.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-discovery.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql-vm.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo-reviews-v2.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/bookinfo.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/platform/kube/cleanup.sh [new file with mode: 0755]
mash/eks/samples/bookinfo/platform/kube/productpage-nodeport.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-ip-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-ip.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-label-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-label.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-serviceaccount.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-whitelist-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-deny-whitelist.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-ingress-denial.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-kubernetesenv-telemetry.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-productpage-ratelimit-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-productpage-redis-quota-fixed-window.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-productpage-redis-quota-rolling-window.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-ratings-denial.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-ratings-ratelimit.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-ratings-redis-quota-fixed-window.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/mixer-rule-ratings-redis-quota-rolling-window.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/prometheus-adapter-deployment.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/policy/prometheus-oop-rule.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/src/mongodb/ratings_data.json [new file with mode: 0644]
mash/eks/samples/bookinfo/src/productpage/requirements.txt [new file with mode: 0644]
mash/eks/samples/bookinfo/src/productpage/test-requirements.txt [new file with mode: 0644]
mash/eks/samples/bookinfo/src/ratings/package.json [new file with mode: 0644]
mash/eks/samples/bookinfo/swagger.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/fluentd-istio-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/fluentd-istio.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/log-entry-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/log-entry.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/metrics-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/metrics.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/tcp-metrics-crd.yaml [new file with mode: 0644]
mash/eks/samples/bookinfo/telemetry/tcp-metrics.yaml [new file with mode: 0644]
mash/eks/samples/certs/README.md [new file with mode: 0644]
mash/eks/samples/certs/ca-cert.pem [new file with mode: 0644]
mash/eks/samples/certs/ca-key.pem [new file with mode: 0644]
mash/eks/samples/certs/cert-chain.pem [new file with mode: 0644]
mash/eks/samples/certs/root-cert.pem [new file with mode: 0644]
mash/eks/samples/certs/workload-bar-cert.pem [new file with mode: 0644]
mash/eks/samples/certs/workload-bar-key.pem [new file with mode: 0644]
mash/eks/samples/certs/workload-foo-cert.pem [new file with mode: 0644]
mash/eks/samples/certs/workload-foo-key.pem [new file with mode: 0644]
mash/eks/samples/cross-network-gateway/cross-network-gateway.yaml [new file with mode: 0644]
mash/eks/samples/custom-bootstrap/README.md [new file with mode: 0644]
mash/eks/samples/custom-bootstrap/custom-bootstrap.yaml [new file with mode: 0644]
mash/eks/samples/custom-bootstrap/example-app.yaml [new file with mode: 0644]
mash/eks/samples/external/README.md [new file with mode: 0644]
mash/eks/samples/external/aptget.yaml [new file with mode: 0644]
mash/eks/samples/external/github.yaml [new file with mode: 0644]
mash/eks/samples/external/pypi.yaml [new file with mode: 0644]
mash/eks/samples/fortio/stackdriver.yaml [new file with mode: 0644]
mash/eks/samples/health-check/liveness-command.yaml [new file with mode: 0644]
mash/eks/samples/health-check/liveness-http-same-port.yaml [new file with mode: 0644]
mash/eks/samples/health-check/liveness-http.yaml [new file with mode: 0644]
mash/eks/samples/helloworld/README.md [new file with mode: 0644]
mash/eks/samples/helloworld/helloworld-gateway.yaml [new file with mode: 0644]
mash/eks/samples/helloworld/helloworld.yaml [new file with mode: 0644]
mash/eks/samples/helloworld/src/requirements.txt [new file with mode: 0644]
mash/eks/samples/httpbin/README.md [new file with mode: 0644]
mash/eks/samples/httpbin/httpbin-gateway.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/httpbin-nodeport.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/httpbin-vault.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/httpbin.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/httpsbin.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/policy/keyval-template.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/policy/keyval.yaml [new file with mode: 0644]
mash/eks/samples/httpbin/sample-client/fortio-deploy.yaml [new file with mode: 0644]
mash/eks/samples/https/default.conf [new file with mode: 0644]
mash/eks/samples/https/nginx-app.yaml [new file with mode: 0644]
mash/eks/samples/kubernetes-blog/bookinfo-ratings.yaml [new file with mode: 0644]
mash/eks/samples/kubernetes-blog/bookinfo-reviews-v2.yaml [new file with mode: 0644]
mash/eks/samples/kubernetes-blog/bookinfo-v1.yaml [new file with mode: 0644]
mash/eks/samples/operator/cni-on.yaml [new file with mode: 0644]
mash/eks/samples/operator/default-install.yaml [new file with mode: 0644]
mash/eks/samples/operator/pilot-advanced-override.yaml [new file with mode: 0644]
mash/eks/samples/operator/pilot-k8s.yaml [new file with mode: 0644]
mash/eks/samples/operator/values-global.yaml [new file with mode: 0644]
mash/eks/samples/operator/values-pilot.yaml [new file with mode: 0644]
mash/eks/samples/rawvm/Makefile [new file with mode: 0644]
mash/eks/samples/rawvm/README.md [new file with mode: 0644]
mash/eks/samples/security/psp/sidecar-psp.yaml [new file with mode: 0644]
mash/eks/samples/sleep/README.md [new file with mode: 0644]
mash/eks/samples/sleep/policy/sni-serviceaccount.yaml [new file with mode: 0644]
mash/eks/samples/sleep/policy/sni-wikipedia.yaml [new file with mode: 0644]
mash/eks/samples/sleep/sleep-vault.yaml [new file with mode: 0644]
mash/eks/samples/sleep/sleep.yaml [new file with mode: 0644]
mash/eks/samples/sleep/telemetry/sni-logging.yaml [new file with mode: 0644]
mash/eks/samples/tcp-echo/README.md [new file with mode: 0644]
mash/eks/samples/tcp-echo/tcp-echo-20-v2.yaml [new file with mode: 0644]
mash/eks/samples/tcp-echo/tcp-echo-all-v1.yaml [new file with mode: 0644]
mash/eks/samples/tcp-echo/tcp-echo-services.yaml [new file with mode: 0644]
mash/eks/samples/tcp-echo/tcp-echo.yaml [new file with mode: 0644]
mash/eks/samples/websockets/README.md [new file with mode: 0644]
mash/eks/samples/websockets/app.yaml [new file with mode: 0644]
mash/eks/samples/websockets/route.yaml [new file with mode: 0644]

diff --git a/mash/eks/samples/README.md b/mash/eks/samples/README.md
new file mode 100644 (file)
index 0000000..a1a140f
--- /dev/null
@@ -0,0 +1,3 @@
+# Istio Samples
+
+This directory contains sample applications highlighting various Istio features.
diff --git a/mash/eks/samples/addons/README.md b/mash/eks/samples/addons/README.md
new file mode 100644 (file)
index 0000000..926bc5e
--- /dev/null
@@ -0,0 +1,89 @@
+# Telemetry Addons
+
+This directory contains sample deployments of various addons that integrate with Istio. While these applications
+are not a part of Istio, they are essential to making the most of Istio's observability features.
+
+The deployments here are meant to quickly get up and running, and are optimized for this case. As a result,
+they may not be suitable for production. See below for more info on integrating a production grade version of each
+addon.
+
+## Getting started
+
+To quickly deploy all addons:
+
+```shell script
+kubectl apply -f samples/addons -n istio-system
+```
+
+Alternatively, you can deploy individual addons:
+
+```shell script
+kubectl apply -f samples/addons/prometheus.yaml -n istio-system
+```
+
+## Addons
+
+### Prometheus
+
+[Prometheus](https://prometheus.io/) is an open source monitoring system and time series database.
+You can use Prometheus with Istio to record metrics that track the health of Istio and of applications within the service mesh.
+You can visualize metrics using tools like [Grafana](#grafana) and [Kiali](#kiali).
+
+For more information about integrating with Prometheus, please see the [Prometheus integration page](https://istio.io/docs/ops/integrations/prometheus/).
+
+### Grafana
+
+[Grafana](http://grafana.com/) is an open source monitoring solution that can be used to configure dashboards for Istio.
+You can use Grafana to monitor the health of Istio and of applications within the service mesh.
+
+This sample provides the following dashboards:
+
+* [Mesh Dashboard](https://grafana.com/grafana/dashboards/7639) provides an overview of all services in the mesh.
+* [Service Dashboard](https://grafana.com/grafana/dashboards/7636) provides a detailed breakdown of metrics for a service.
+* [Workload Dashboard](https://grafana.com/grafana/dashboards/7630) provides a detailed breakdown of metrics for a workload.
+* [Performance Dashboard](https://grafana.com/grafana/dashboards/11829) monitors the resource usage of the mesh.
+* [Control Plane Dashboard](https://grafana.com/grafana/dashboards/7645) monitors the health and performance of the control plane.
+
+For more information about integrating with Grafana, please see the [Grafana integration page](https://istio.io/docs/ops/integrations/grafana/).
+
+### Kiali
+
+[Kiali](https://kiali.io/) is an observability console for Istio with service mesh configuration capabilities.
+It helps you to understand the structure of your service mesh by inferring the topology, and also provides the health of your mesh.
+Kiali provides detailed metrics, and a basic [Grafana](#grafana) integration is available for advanced queries.
+Distributed tracing is provided by integrating [Jaeger](#jaeger).
+
+For more information about using Kiali, see the [Visualizing Your Mesh](istio.io/docs/tasks/observability/kiali/) task.
+
+### Jaeger
+
+[Jaeger](https://www.jaegertracing.io/) is an open source end to end distributed tracing system, allowing users to monitor and troubleshoot transactions in complex distributed systems.
+
+Jaeger helps in a variety of tasks including:
+
+* Distributed context propagation
+* Distributed transaction monitoring
+* Root cause analysis
+* Service dependency analysis
+* Performance / latency optimization
+
+For more information about integrating with Jaeger, please see the [Jaeger integration page](https://istio.io/docs/tasks/observability/distributed-tracing/jaeger/).
+
+### Zipkin
+
+[Zipkin](https://zipkin.io/) is a distributed tracing system. It helps gather timing data needed to troubleshoot latency problems in service architectures. Features include both the collection and lookup of this data.
+
+Zipkin is an alternative to Jaeger and is not deployed by default. To replace Jaeger with Zipkin, run `kubectl apply -f samples/addons/extras/zipkin.yaml -n istio-system`.
+You may also want to remove the Jaeger deployment, which will not be used, with `kubectl delete deployment jaeger`, or avoid installing it
+to begin with by following the selective install steps in [Getting Started](#getting-started).
+
+For more information about integrating with Zipkin, please see the [Zipkin integration page](https://istio.io/docs/tasks/observability/distributed-tracing/zipkin/).
+
+### Prometheus Operator
+
+The [Prometheus Operator](https://github.com/coreos/prometheus-operator) manages and operators a Prometheus instance.
+
+As an alternative to the standard Prometheus deployment, we provide `ServiceMonitors` to monitor the Istio control plane and
+Envoy proxies. To use these, make sure you have the Prometheus operator deployed, then run `kubectl apply -f samples/addons/extras/prometheus-operator.yaml -n istio-system`.
+
+Note: The configurations here are only for Istio deployments, and do not scrape metrics from the Kubernetes components. See the [Cluster Monitoring](https://coreos.com/operators/prometheus/docs/latest/user-guides/cluster-monitoring.html) documentation for configuring this.
diff --git a/mash/eks/samples/addons/extras/prometheus-operator.yaml b/mash/eks/samples/addons/extras/prometheus-operator.yaml
new file mode 100644 (file)
index 0000000..39441db
--- /dev/null
@@ -0,0 +1,51 @@
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: envoy-stats-monitor
+  namespace: istio-system
+  labels:
+    monitoring: istio-proxies
+    release: istio
+spec:
+  selector:
+    matchExpressions:
+    - {key: istio-prometheus-ignore, operator: DoesNotExist}
+  namespaceSelector:
+    any: true
+  jobLabel: envoy-stats
+  endpoints:
+  - path: /stats/prometheus
+    targetPort: 15090
+    interval: 15s
+    relabelings:
+    - sourceLabels: [__meta_kubernetes_pod_container_port_name]
+      action: keep
+      regex: '.*-envoy-prom'
+    - action: labeldrop
+      regex: "__meta_kubernetes_pod_label_(.+)"
+    - sourceLabels: [__meta_kubernetes_namespace]
+      action: replace
+      targetLabel: namespace
+    - sourceLabels: [__meta_kubernetes_pod_name]
+      action: replace
+      targetLabel: pod_name
+---
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+  name: istio-component-monitor
+  namespace: istio-system
+  labels:
+    monitoring: istio-components
+    release: istio
+spec:
+  jobLabel: istio
+  targetLabels: [app]
+  selector:
+    matchExpressions:
+    - {key: istio, operator: In, values: [pilot]}
+  namespaceSelector:
+    any: true
+  endpoints:
+  - port: http-monitoring
+    interval: 15s
diff --git a/mash/eks/samples/addons/extras/zipkin.yaml b/mash/eks/samples/addons/extras/zipkin.yaml
new file mode 100644 (file)
index 0000000..cdb3e47
--- /dev/null
@@ -0,0 +1,56 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: zipkin
+  namespace: istio-system
+  labels:
+    app: zipkin
+spec:
+  selector:
+    matchLabels:
+      app: zipkin
+  template:
+    metadata:
+      labels:
+        app: zipkin
+      annotations:
+        sidecar.istio.io/inject: "false"
+    spec:
+      containers:
+        - name: zipkin
+          image: openzipkin/zipkin-slim:2.20.0
+          env:
+            - name: STORAGE_METHOD
+              value: "mem"
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: tracing
+  namespace: istio-system
+  labels:
+    app: zipkin
+spec:
+  type: ClusterIP
+  ports:
+    - name: http-query
+      port: 80
+      protocol: TCP
+      targetPort: 9411
+  selector:
+    app: zipkin
+---
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    name: zipkin
+  name: zipkin
+  namespace: istio-system
+spec:
+  ports:
+    - port: 9411
+      targetPort: 9411
+      name: http-query
+  selector:
+    app: zipkin
diff --git a/mash/eks/samples/addons/grafana.yaml b/mash/eks/samples/addons/grafana.yaml
new file mode 100644 (file)
index 0000000..dc0a00c
--- /dev/null
@@ -0,0 +1,9019 @@
+---
+# Source: grafana/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  labels:
+    helm.sh/chart: grafana-5.3.5
+    app.kubernetes.io/name: grafana
+    app.kubernetes.io/instance: grafana
+    app.kubernetes.io/version: "7.0.5"
+    app.kubernetes.io/managed-by: Helm
+  name: grafana
+  namespace: istio-system
+---
+# Source: grafana/templates/configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: grafana
+  namespace: istio-system
+  labels:
+    helm.sh/chart: grafana-5.3.5
+    app.kubernetes.io/name: grafana
+    app.kubernetes.io/instance: grafana
+    app.kubernetes.io/version: "7.0.5"
+    app.kubernetes.io/managed-by: Helm
+data:
+  grafana.ini: |
+    [analytics]
+    check_for_updates = true
+    [grafana_net]
+    url = https://grafana.net
+    [log]
+    mode = console
+    [paths]
+    data = /var/lib/grafana/data
+    logs = /var/log/grafana
+    plugins = /var/lib/grafana/plugins
+    provisioning = /etc/grafana/provisioning
+
+  datasources.yaml: |
+    apiVersion: 1
+    datasources:
+    - access: proxy
+      editable: true
+      isDefault: true
+      jsonData:
+        timeInterval: 5s
+      name: Prometheus
+      orgId: 1
+      type: prometheus
+      url: http://prometheus:9090
+  dashboardproviders.yaml: |
+    apiVersion: 1
+    providers:
+    - disableDeletion: false
+      folder: istio
+      name: istio
+      options:
+        path: /var/lib/grafana/dashboards/istio
+      orgId: 1
+      type: file
+    - disableDeletion: false
+      folder: istio
+      name: istio-services
+      options:
+        path: /var/lib/grafana/dashboards/istio-services
+      orgId: 1
+      type: file
+---
+# Source: grafana/templates/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: grafana
+  namespace: istio-system
+  labels:
+    helm.sh/chart: grafana-5.3.5
+    app.kubernetes.io/name: grafana
+    app.kubernetes.io/instance: grafana
+    app.kubernetes.io/version: "7.0.5"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  type: ClusterIP
+  ports:
+    - name: service
+      port: 3000
+      protocol: TCP
+      targetPort: 3000
+
+  selector:
+    app.kubernetes.io/name: grafana
+    app.kubernetes.io/instance: grafana
+---
+# Source: grafana/templates/deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: grafana
+  namespace: istio-system
+  labels:
+    helm.sh/chart: grafana-5.3.5
+    app.kubernetes.io/name: grafana
+    app.kubernetes.io/instance: grafana
+    app.kubernetes.io/version: "7.0.5"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: grafana
+      app.kubernetes.io/instance: grafana
+  strategy:
+    type: RollingUpdate
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: grafana
+        app.kubernetes.io/instance: grafana
+        app: grafana
+      annotations:
+        checksum/config: fe7e580c8af3062a70a8dfda740e0ae1daa655c20dd5b94e78bdd09a79b9b5cb
+        checksum/dashboards-json-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
+        checksum/sc-dashboard-provider-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
+    spec:
+      
+      serviceAccountName: grafana
+      securityContext:
+        fsGroup: 472
+        runAsGroup: 472
+        runAsUser: 472
+      containers:
+        - name: grafana
+          image: "grafana/grafana:7.0.5"
+          imagePullPolicy: IfNotPresent
+          volumeMounts:
+            - name: config
+              mountPath: "/etc/grafana/grafana.ini"
+              subPath: grafana.ini
+            - name: storage
+              mountPath: "/var/lib/grafana"
+            - name: dashboards-istio
+              mountPath: "/var/lib/grafana/dashboards/istio"
+            - name: dashboards-istio-services
+              mountPath: "/var/lib/grafana/dashboards/istio-services"
+            - name: config
+              mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml"
+              subPath: datasources.yaml
+            - name: config
+              mountPath: "/etc/grafana/provisioning/dashboards/dashboardproviders.yaml"
+              subPath: dashboardproviders.yaml
+          ports:
+            - name: service
+              containerPort: 3000
+              protocol: TCP
+            - name: grafana
+              containerPort: 3000
+              protocol: TCP
+          env:
+            - name: "GF_AUTH_ANONYMOUS_ENABLED"
+              value: "true"
+            - name: "GF_AUTH_ANONYMOUS_ORG_ROLE"
+              value: "Admin"
+            - name: "GF_AUTH_BASIC_ENABLED"
+              value: "false"
+            - name: "GF_SECURITY_ADMIN_PASSWORD"
+              value: "-"
+            - name: "GF_SECURITY_ADMIN_USER"
+              value: "-"
+          livenessProbe:
+            failureThreshold: 10
+            httpGet:
+              path: /api/health
+              port: 3000
+            initialDelaySeconds: 60
+            timeoutSeconds: 30
+          readinessProbe:
+            httpGet:
+              path: /api/health
+              port: 3000
+          resources:
+            {}
+      volumes:
+        - name: config
+          configMap:
+            name: grafana
+          
+        - name: dashboards-istio
+          configMap:
+            name: istio-grafana-dashboards
+        - name: dashboards-istio-services
+          configMap:
+            name: istio-services-grafana-dashboards
+        - name: storage
+          emptyDir: {}
+
+---
+
+apiVersion: v1
+data:
+  istio-performance-dashboard.json: |
+    {
+      "annotations": {
+        "list": [
+          {
+            "builtIn": 1,
+            "datasource": "-- Grafana --",
+            "enable": true,
+            "hide": true,
+            "iconColor": "rgba(0, 211, 255, 1)",
+            "name": "Annotations & Alerts",
+            "type": "dashboard"
+          }
+        ]
+      },
+      "editable": false,
+      "gnetId": null,
+      "graphTooltip": 0,
+      "links": [],
+      "panels": [
+        {
+          "collapsed": true,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 0
+          },
+          "id": 21,
+          "panels": [
+            {
+              "content": "The charts on this dashboard are intended to show Istio main components cost in terms resources utilization under steady load.\n\n- **vCPU/1k rps:** shows vCPU utilization by the main Istio components normalized by 1000 requests/second. When idle or low traffic, this chart will be blank. The curve for istio-proxy refers to the services sidecars only.\n- **vCPU:** vCPU utilization by Istio components, not normalized.\n- **Memory:** memory footprint for the components. Telemetry and policy are normalized by 1k rps, and no data is shown  when there is no traffic. For ingress and istio-proxy, the data is per instance.\n- **Bytes transferred/ sec:** shows the number of bytes flowing through each Istio component.\n\n\n",
+              "gridPos": {
+                "h": 6,
+                "w": 24,
+                "x": 0,
+                "y": 1
+              },
+              "id": 19,
+              "links": [],
+              "mode": "markdown",
+              "timeFrom": null,
+              "timeShift": null,
+              "title": "Performance Dashboard README",
+              "transparent": true,
+              "type": "text"
+            }
+          ],
+          "title": "Performance Dashboard Notes",
+          "type": "row"
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 1
+          },
+          "id": 6,
+          "panels": [],
+          "title": "vCPU Usage",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 12,
+            "x": 0,
+            "y": 2
+          },
+          "id": 4,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-telemetry-.*\",container=~\"mixer|istio-proxy\"}[1m]))/ (round(sum(irate(istio_requests_total[1m])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "istio-telemetry",
+              "refId": "A"
+            },
+            {
+              "expr": "(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m])) / (round(sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m])), 0.001)/1000))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "istio-ingressgateway",
+              "refId": "B"
+            },
+            {
+              "expr": "(sum(irate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))/ (round(sum(irate(istio_requests_total[1m])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-proxy",
+              "refId": "C"
+            },
+            {
+              "expr": "(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-policy-.*\",container=~\"mixer|istio-proxy\"}[1m]))/ (round(sum(irate(istio_requests_total[1m])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-policy",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "vCPU / 1k rps",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 12,
+            "x": 12,
+            "y": 2
+          },
+          "id": 7,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-telemetry-.*\",container=~\"mixer|istio-proxy\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-telemetry",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-ingressgateway",
+              "refId": "B"
+            },
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-proxy",
+              "refId": "C"
+            },
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-policy-.*\",container=~\"mixer|istio-proxy\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-policy",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "vCPU",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 10
+          },
+          "id": 13,
+          "panels": [],
+          "title": "Memory and Data Rates",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 12,
+            "x": 0,
+            "y": 11
+          },
+          "id": 902,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "(sum(container_memory_usage_bytes{pod=~\"istio-telemetry-.*\"}) / (sum(irate(istio_requests_total[1m])) / 1000)) / (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-telemetry / 1k rps",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(container_memory_usage_bytes{pod=~\"istio-ingressgateway-.*\"}) / count(container_memory_usage_bytes{pod=~\"istio-ingressgateway-.*\",container!=\"POD\"})",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "per istio-ingressgateway",
+              "refId": "B"
+            },
+            {
+              "expr": "sum(container_memory_usage_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"}) / count(container_memory_usage_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"})",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "per istio proxy",
+              "refId": "C"
+            },
+            {
+              "expr": "(sum(container_memory_usage_bytes{pod=~\"istio-policy-.*\"}) / (sum(irate(istio_requests_total[1m])) / 1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-policy / 1k rps",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Memory Usage",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 12,
+            "x": 12,
+            "y": 11
+          },
+          "id": 11,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(irate(istio_response_bytes_sum{destination_workload=\"istio-telemetry\"}[1m])) + sum(irate(istio_request_bytes_sum{destination_workload=\"istio-telemetry\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-telemetry",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(irate(istio_response_bytes_sum{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-ingressgateway",
+              "refId": "B"
+            },
+            {
+              "expr": "sum(irate(istio_response_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m])) + sum(irate(istio_response_bytes_sum{destination_workload_namespace!=\"istio-system\", reporter=\"destination\"}[1m])) + sum(irate(istio_request_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m])) + sum(irate(istio_request_bytes_sum{destination_workload_namespace!=\"istio-system\", reporter=\"destination\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio-proxy",
+              "refId": "C"
+            },
+            {
+              "expr": "sum(irate(istio_response_bytes_sum{destination_workload=\"istio-policy\"}[1m])) + sum(irate(istio_request_bytes_sum{destination_workload=\"istio-policy\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "istio_policy",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Bytes transferred / sec",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "Bps",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 19
+          },
+          "id": 17,
+          "panels": [],
+          "title": "Istio Component Versions",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 24,
+            "x": 0,
+            "y": 20
+          },
+          "id": 15,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(istio_build) by (component, tag)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "{{ component }}: {{ tag }}",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Istio Components by Version",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 31
+          },
+          "id": 71,
+          "panels": [],
+          "title": "Proxy Resource Usage",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 0,
+            "y": 32
+          },
+          "id": 72,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(container_memory_usage_bytes{container=\"istio-proxy\"})",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }} (k8s)",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Memory",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 6,
+            "y": 32
+          },
+          "id": 73,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Total (k8s)",
+              "refId": "A",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "vCPU",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 12,
+            "y": 32
+          },
+          "id": 702,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(container_fs_usage_bytes{ container=\"istio-proxy\"})",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }}",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Disk",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "decimals": null,
+              "format": "none",
+              "label": "",
+              "logBase": 1024,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 39
+          },
+          "id": 69,
+          "panels": [],
+          "title": "Pilot Resource Usage",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 0,
+            "y": 40
+          },
+          "id": 5,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "process_virtual_memory_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "instant": false,
+              "intervalFactor": 2,
+              "legendFormat": "Virtual Memory",
+              "refId": "I",
+              "step": 2
+            },
+            {
+              "expr": "process_resident_memory_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Resident Memory",
+              "refId": "H",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_heap_sys_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap sys",
+              "refId": "A"
+            },
+            {
+              "expr": "go_memstats_heap_alloc_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap alloc",
+              "refId": "D"
+            },
+            {
+              "expr": "go_memstats_alloc_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Alloc",
+              "refId": "F",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_heap_inuse_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Heap in-use",
+              "refId": "E",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_stack_inuse_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Stack in-use",
+              "refId": "G",
+              "step": 2
+            },
+            {
+              "expr": "sum(container_memory_usage_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"})",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Total (k8s)",
+              "refId": "C",
+              "step": 2
+            },
+            {
+              "expr": "container_memory_usage_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }} (k8s)",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Memory",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 6,
+            "y": 40
+          },
+          "id": 602,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Total (k8s)",
+              "refId": "A",
+              "step": 2
+            },
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m])) by (container)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }} (k8s)",
+              "refId": "B",
+              "step": 2
+            },
+            {
+              "expr": "irate(process_cpu_seconds_total{app=\"istiod\"}[1m])",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "pilot (self-reported)",
+              "refId": "C",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "vCPU",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 12,
+            "y": 40
+          },
+          "id": 74,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "process_open_fds{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": true,
+              "instant": false,
+              "interval": "",
+              "intervalFactor": 2,
+              "legendFormat": "Open FDs (pilot)",
+              "refId": "A"
+            },
+            {
+              "expr": "container_fs_usage_bytes{ container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }}",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Disk",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "decimals": null,
+              "format": "none",
+              "label": "",
+              "logBase": 1024,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 18,
+            "y": 40
+          },
+          "id": 402,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": false,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "go_goroutines{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Number of Goroutines",
+              "refId": "A",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Goroutines",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 47
+          },
+          "id": 93,
+          "panels": [],
+          "title": "Mixer Resource Usage",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 0,
+            "y": 48
+          },
+          "id": 94,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "process_virtual_memory_bytes{job=~\"istio-telemetry|istio-policy\"}",
+              "format": "time_series",
+              "instant": false,
+              "intervalFactor": 2,
+              "legendFormat": "Virtual Memory",
+              "refId": "I",
+              "step": 2
+            },
+            {
+              "expr": "process_resident_memory_bytes{job=~\"istio-telemetry|istio-policy\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Resident Memory",
+              "refId": "H",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_heap_sys_bytes{job=~\"istio-telemetry|istio-policy\"}",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap sys",
+              "refId": "A"
+            },
+            {
+              "expr": "go_memstats_heap_alloc_bytes{job=~\"istio-telemetry|istio-policy\"}",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap alloc",
+              "refId": "D"
+            },
+            {
+              "expr": "go_memstats_alloc_bytes{job=~\"istio-telemetry|istio-policy\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Alloc",
+              "refId": "F",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_heap_inuse_bytes{job=~\"istio-telemetry|istio-policy\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Heap in-use",
+              "refId": "E",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_stack_inuse_bytes{job=~\"istio-policy|istio-telemetry\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Stack in-use",
+              "refId": "G",
+              "step": 2
+            },
+            {
+              "expr": "sum(container_memory_usage_bytes{container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*\"})",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Total (k8s)",
+              "refId": "C",
+              "step": 2
+            },
+            {
+              "expr": "container_memory_usage_bytes{container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }} (k8s)",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Memory",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 6,
+            "y": 48
+          },
+          "id": 95,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Total (k8s)",
+              "refId": "A",
+              "step": 2
+            },
+            {
+              "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*\"}[1m])) by (container)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }} (k8s)",
+              "refId": "B",
+              "step": 2
+            },
+            {
+              "expr": "irate(process_cpu_seconds_total{job=~\"istio-policy|istio-telemetry\"}[1m])",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "mixer (self-reported)",
+              "refId": "C",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "vCPU",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 12,
+            "y": 48
+          },
+          "id": 96,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "process_open_fds{job=~\"istio-policy|istio-telemetry\"}",
+              "format": "time_series",
+              "hide": true,
+              "instant": false,
+              "interval": "",
+              "intervalFactor": 2,
+              "legendFormat": "Open FDs (pilot)",
+              "refId": "A"
+            },
+            {
+              "expr": "container_fs_usage_bytes{container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ container }}",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Disk",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "decimals": null,
+              "format": "none",
+              "label": "",
+              "logBase": 1024,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 18,
+            "y": 48
+          },
+          "id": 97,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": false,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "go_goroutines{job=\"istio-telemetry\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Number of Goroutines",
+              "refId": "A",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Goroutines",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "refresh": "10s",
+      "schemaVersion": 18,
+      "style": "dark",
+      "tags": [],
+      "templating": {
+        "list": []
+      },
+      "time": {
+        "from": "now-5m",
+        "to": "now"
+      },
+      "timepicker": {
+        "refresh_intervals": [
+          "5s",
+          "10s",
+          "30s",
+          "1m",
+          "5m",
+          "15m",
+          "30m",
+          "1h",
+          "2h",
+          "1d"
+        ],
+        "time_options": [
+          "5m",
+          "15m",
+          "1h",
+          "6h",
+          "12h",
+          "24h",
+          "2d",
+          "7d",
+          "30d"
+        ]
+      },
+      "timezone": "",
+      "title": "Istio Performance Dashboard",
+      "uid": "vu8e0VWZk",
+      "version": 22
+    }
+  mixer-dashboard.json: |
+    {
+      "__inputs": [
+        {
+          "name": "DS_PROMETHEUS",
+          "label": "Prometheus",
+          "description": "",
+          "type": "datasource",
+          "pluginId": "prometheus",
+          "pluginName": "Prometheus"
+        }
+      ],
+      "__requires": [
+        {
+          "type": "grafana",
+          "id": "grafana",
+          "name": "Grafana",
+          "version": "5.2.3"
+        },
+        {
+          "type": "panel",
+          "id": "graph",
+          "name": "Graph",
+          "version": "5.0.0"
+        },
+        {
+          "type": "datasource",
+          "id": "prometheus",
+          "name": "Prometheus",
+          "version": "5.0.0"
+        },
+        {
+          "type": "panel",
+          "id": "text",
+          "name": "Text",
+          "version": "5.0.0"
+        }
+      ],
+      "annotations": {
+        "list": [
+          {
+            "builtIn": 1,
+            "datasource": "-- Grafana --",
+            "enable": true,
+            "hide": true,
+            "iconColor": "rgba(0, 211, 255, 1)",
+            "limit": 100,
+            "name": "Annotations & Alerts",
+            "showIn": 0,
+            "type": "dashboard"
+          }
+        ]
+      },
+      "editable": false,
+      "gnetId": null,
+      "graphTooltip": 1,
+      "id": null,
+      "iteration": 1543881232533,
+      "links": [],
+      "panels": [
+        {
+          "content": "<center><h2>Deployed Versions</h2></center>",
+          "gridPos": {
+            "h": 3,
+            "w": 24,
+            "x": 0,
+            "y": 0
+          },
+          "height": "40",
+          "id": 62,
+          "links": [],
+          "mode": "html",
+          "title": "",
+          "transparent": true,
+          "type": "text"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 5,
+            "w": 24,
+            "x": 0,
+            "y": 3
+          },
+          "id": 64,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(istio_build{component=\"mixer\"}) by (tag)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "{{ tag }}",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Mixer Versions",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "content": "<center><h2>Resource Usage</h2></center>",
+          "gridPos": {
+            "h": 3,
+            "w": 24,
+            "x": 0,
+            "y": 8
+          },
+          "height": "40",
+          "id": 29,
+          "links": [],
+          "mode": "html",
+          "title": "",
+          "transparent": true,
+          "type": "text"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 0,
+            "y": 11
+          },
+          "id": 5,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(process_virtual_memory_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "instant": false,
+              "intervalFactor": 2,
+              "legendFormat": "Virtual Memory ({{ job }})",
+              "refId": "I"
+            },
+            {
+              "expr": "sum(process_resident_memory_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Resident Memory ({{ job }})",
+              "refId": "H"
+            },
+            {
+              "expr": "sum(go_memstats_heap_sys_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap sys ({{ job }})",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(go_memstats_heap_alloc_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap alloc ({{ job }})",
+              "refId": "D"
+            },
+            {
+              "expr": "sum(go_memstats_alloc_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Alloc ({{ job }})",
+              "refId": "F"
+            },
+            {
+              "expr": "sum(go_memstats_heap_inuse_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Heap in-use ({{ job }})",
+              "refId": "E"
+            },
+            {
+              "expr": "sum(go_memstats_stack_inuse_bytes{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Stack in-use ({{ job }})",
+              "refId": "G"
+            },
+            {
+              "expr": "sum(label_replace(container_memory_usage_bytes{job=\"kubernetes-cadvisor\", container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*|istio-policy-.*\"}, \"service\", \"$1\" , \"pod\", \"(istio-telemetry|istio-policy)-.*\")) by (service)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ service }} total (k8s)",
+              "refId": "C"
+            },
+            {
+              "expr": "sum(label_replace(container_memory_usage_bytes{job=\"kubernetes-cadvisor\", container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*|istio-policy-.*\"}, \"service\", \"$1\" , \"pod\", \"(istio-telemetry|istio-policy)-.*\")) by (container, service)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ service }} - {{ container }} (k8s)",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Memory",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 6,
+            "y": 11
+          },
+          "id": 6,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "label_replace(sum(rate(container_cpu_usage_seconds_total{job=\"kubernetes-cadvisor\",container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*|istio-policy-.*\"}[1m])) by (pod), \"service\", \"$1\" , \"pod\", \"(istio-telemetry|istio-policy)-.*\")",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ service }} total (k8s)",
+              "refId": "A"
+            },
+            {
+              "expr": "label_replace(sum(rate(container_cpu_usage_seconds_total{job=\"kubernetes-cadvisor\",container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*|istio-policy-.*\"}[1m])) by (container, pod), \"service\", \"$1\" , \"pod\", \"(istio-telemetry|istio-policy)-.*\")",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ service }} - {{ container }} (k8s)",
+              "refId": "B"
+            },
+            {
+              "expr": "sum(irate(process_cpu_seconds_total{job=~\"istio-telemetry|istio-policy\"}[1m])) by (job)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "{{ job }} (self-reported)",
+              "refId": "C"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "CPU",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 12,
+            "y": 11
+          },
+          "id": 7,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(process_open_fds{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "hide": true,
+              "instant": false,
+              "interval": "",
+              "intervalFactor": 2,
+              "legendFormat": "Open FDs ({{ job }})",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(label_replace(container_fs_usage_bytes{job=\"kubernetes-cadvisor\", container=~\"mixer|istio-proxy\", pod=~\"istio-telemetry-.*|istio-policy-.*\"}, \"service\", \"$1\" , \"pod\", \"(istio-telemetry|istio-policy)-.*\")) by (container, service)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ service }} - {{ container }}",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Disk",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "decimals": null,
+              "format": "none",
+              "label": "",
+              "logBase": 1024,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 18,
+            "y": 11
+          },
+          "id": 4,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": false,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(go_goroutines{job=~\"istio-telemetry|istio-policy\"}) by (job)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Number of Goroutines ({{ job }})",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Goroutines",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "content": "<center><h2>Mixer Overview</h2></center>",
+          "gridPos": {
+            "h": 3,
+            "w": 24,
+            "x": 0,
+            "y": 18
+          },
+          "height": "40px",
+          "id": 30,
+          "links": [],
+          "mode": "html",
+          "title": "",
+          "transparent": true,
+          "type": "text"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 6,
+            "w": 6,
+            "x": 0,
+            "y": 21
+          },
+          "id": 9,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(grpc_io_server_completed_rpcs[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "mixer (Total)",
+              "refId": "B"
+            },
+            {
+              "expr": "sum(rate(grpc_io_server_completed_rpcs[1m])) by (grpc_server_method)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "mixer ({{ grpc_server_method }})",
+              "refId": "C"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Incoming Requests",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "ops",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 6,
+            "w": 6,
+            "x": 6,
+            "y": 21
+          },
+          "id": 8,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [
+            {
+              "alias": "{}",
+              "yaxis": 1
+            }
+          ],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "histogram_quantile(0.5, sum(rate(grpc_io_server_server_latency_bucket{}[1m])) by (grpc_server_method, le))",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ grpc_server_method }} 0.5",
+              "refId": "B"
+            },
+            {
+              "expr": "histogram_quantile(0.9, sum(rate(grpc_io_server_server_latency_bucket{}[1m])) by (grpc_server_method, le))",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ grpc_server_method }} 0.9",
+              "refId": "C"
+            },
+            {
+              "expr": "histogram_quantile(0.99, sum(rate(grpc_io_server_server_latency_bucket{}[1m])) by (grpc_server_method, le))",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ grpc_server_method }} 0.99",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Response Durations",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "ms",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 6,
+            "w": 6,
+            "x": 12,
+            "y": 21
+          },
+          "id": 11,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(grpc_server_handled_total{grpc_code=~\"Unknown|Unimplemented|Internal|DataLoss\"}[1m])) by (grpc_method)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Mixer {{ grpc_method }}",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Server Error Rate (5xx responses)",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 6,
+            "w": 6,
+            "x": 18,
+            "y": 21
+          },
+          "id": 12,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(irate(grpc_server_handled_total{grpc_code!=\"OK\",grpc_service=~\".*Mixer\"}[1m])) by (grpc_method)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Mixer {{ grpc_method }}",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Non-successes (4xxs)",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "content": "<center><h2>Adapters and Config</h2></center>",
+          "gridPos": {
+            "h": 3,
+            "w": 24,
+            "x": 0,
+            "y": 27
+          },
+          "id": 28,
+          "links": [],
+          "mode": "html",
+          "title": "",
+          "transparent": true,
+          "type": "text"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 12,
+            "x": 0,
+            "y": 30
+          },
+          "id": 13,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(irate(mixer_runtime_dispatches_total{adapter=~\"$adapter\"}[1m])) by (adapter)",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ adapter }}",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Adapter Dispatch Count",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 12,
+            "x": 12,
+            "y": 30
+          },
+          "id": 14,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "histogram_quantile(0.5, sum(irate(mixer_runtime_dispatch_duration_seconds_bucket{adapter=~\"$adapter\"}[1m])) by (adapter, le))",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ adapter }} - p50",
+              "refId": "A"
+            },
+            {
+              "expr": "histogram_quantile(0.9, sum(irate(mixer_runtime_dispatch_duration_seconds_bucket{adapter=~\"$adapter\"}[1m])) by (adapter, le))",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ adapter }} - p90 ",
+              "refId": "B"
+            },
+            {
+              "expr": "histogram_quantile(0.99, sum(irate(mixer_runtime_dispatch_duration_seconds_bucket{adapter=~\"$adapter\"}[1m])) by (adapter, le))",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ adapter }} - p99",
+              "refId": "C"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Adapter Dispatch Duration",
+          "tooltip": {
+            "shared": true,
+            "sort": 1,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "s",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 0,
+            "y": 37
+          },
+          "id": 60,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "scalar(topk(1, max(mixer_config_rule_config_count) by (configID)))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Rules",
+              "refId": "A"
+            },
+            {
+              "expr": "scalar(topk(1, max(mixer_config_rule_config_error_count) by (configID)))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Config Errors",
+              "refId": "B"
+            },
+            {
+              "expr": "scalar(topk(1, max(mixer_config_rule_config_match_error_count) by (configID)))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Match Errors",
+              "refId": "C"
+            },
+            {
+              "expr": "scalar(topk(1, max(mixer_config_unsatisfied_action_handler_count) by (configID)))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Unsatisfied Actions",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Rules",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 6,
+            "y": 37
+          },
+          "id": 56,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "scalar(topk(1, max(mixer_config_instance_config_count) by (configID)))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Instances",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Instances in Latest Config",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 12,
+            "y": 37
+          },
+          "id": 54,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "scalar(topk(1, max(mixer_config_handler_config_count) by (configID)))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Handlers",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Handlers in Latest Config",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 18,
+            "y": 37
+          },
+          "id": 58,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "scalar(topk(1, max(mixer_config_attribute_count) by (configID)))",
+              "format": "time_series",
+              "instant": false,
+              "intervalFactor": 1,
+              "legendFormat": "Attributes",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Attributes in Latest Config",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "content": "<center><h2>Individual Adapters</h2></center>",
+          "gridPos": {
+            "h": 3,
+            "w": 24,
+            "x": 0,
+            "y": 44
+          },
+          "id": 23,
+          "links": [],
+          "mode": "html",
+          "title": "",
+          "transparent": true,
+          "type": "text"
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 47
+          },
+          "id": 46,
+          "panels": [],
+          "repeat": "adapter",
+          "title": "$adapter Adapter",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 12,
+            "x": 0,
+            "y": 48
+          },
+          "id": 17,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "label_replace(irate(mixer_runtime_dispatches_total{adapter=~\"$adapter\"}[1m]),\"handler\", \"$1 ($3)\", \"handler\", \"(.*)\\\\.(.*)\\\\.(.*)\")",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "{{ handler }} (error: {{  error }})",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Dispatch Count By Handler",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 12,
+            "x": 12,
+            "y": 48
+          },
+          "id": 18,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "label_replace(histogram_quantile(0.5, sum(rate(mixer_runtime_dispatch_duration_seconds_bucket{adapter=~\"$adapter\"}[1m])) by (handler, error, le)),  \"handler_short\", \"$1 ($3)\", \"handler\", \"(.*)\\\\.(.*)\\\\.(.*)\")",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "p50 - {{ handler_short }} (error: {{ error }})",
+              "refId": "A"
+            },
+            {
+              "expr": "label_replace(histogram_quantile(0.9, sum(irate(mixer_runtime_dispatch_duration_seconds_bucket{adapter=~\"$adapter\"}[1m])) by (handler, error, le)),  \"handler_short\", \"$1 ($3)\", \"handler\", \"(.*)\\\\.(.*)\\\\.(.*)\")",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "p90 - {{ handler_short }} (error: {{ error }})",
+              "refId": "D"
+            },
+            {
+              "expr": "label_replace(histogram_quantile(0.99, sum(irate(mixer_runtime_dispatch_duration_seconds_bucket{adapter=~\"$adapter\"}[1m])) by (handler, error, le)),  \"handler_short\", \"$1 ($3)\", \"handler\", \"(.*)\\\\.(.*)\\\\.(.*)\")",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "p99 - {{ handler_short }} (error: {{ error }})",
+              "refId": "E"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Dispatch Duration By Handler",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "s",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "refresh": "5s",
+      "schemaVersion": 16,
+      "style": "dark",
+      "tags": [],
+      "templating": {
+        "list": [
+          {
+            "allValue": null,
+            "current": {},
+            "datasource": "Prometheus",
+            "hide": 0,
+            "includeAll": true,
+            "label": "Adapter",
+            "multi": true,
+            "name": "adapter",
+            "options": [],
+            "query": "label_values(adapter)",
+            "refresh": 2,
+            "regex": "",
+            "sort": 1,
+            "tagValuesQuery": "",
+            "tags": [],
+            "tagsQuery": "",
+            "type": "query",
+            "useTags": false
+          }
+        ]
+      },
+      "time": {
+        "from": "now-5m",
+        "to": "now"
+      },
+      "timepicker": {
+        "refresh_intervals": [
+          "5s",
+          "10s",
+          "30s",
+          "1m",
+          "5m",
+          "15m",
+          "30m",
+          "1h",
+          "2h",
+          "1d"
+        ],
+        "time_options": [
+          "5m",
+          "15m",
+          "1h",
+          "6h",
+          "12h",
+          "24h",
+          "2d",
+          "7d",
+          "30d"
+        ]
+      },
+      "timezone": "",
+      "title": "Istio Mixer Dashboard",
+      "version": 4
+    }
+  pilot-dashboard.json: |-
+    {
+      "annotations": {
+        "list": [
+          {
+            "builtIn": 1,
+            "datasource": "-- Grafana --",
+            "enable": true,
+            "hide": true,
+            "iconColor": "rgba(0, 211, 255, 1)",
+            "name": "Annotations & Alerts",
+            "type": "dashboard"
+          }
+        ]
+      },
+      "editable": false,
+      "gnetId": null,
+      "graphTooltip": 1,
+      "links": [],
+      "panels": [
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 0
+          },
+          "id": 60,
+          "panels": [],
+          "title": "Deployed Versions",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 5,
+            "w": 24,
+            "x": 0,
+            "y": 1
+          },
+          "id": 56,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(istio_build{component=\"pilot\"}) by (tag)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "{{ tag }}",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Pilot Versions",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 6
+          },
+          "id": 62,
+          "panels": [],
+          "title": "Resource Usage",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 0,
+            "y": 7
+          },
+          "id": 5,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "process_virtual_memory_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "instant": false,
+              "intervalFactor": 2,
+              "legendFormat": "Virtual Memory",
+              "refId": "I",
+              "step": 2
+            },
+            {
+              "expr": "process_resident_memory_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Resident Memory",
+              "refId": "H",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_heap_sys_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap sys",
+              "refId": "A"
+            },
+            {
+              "expr": "go_memstats_heap_alloc_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": true,
+              "intervalFactor": 2,
+              "legendFormat": "heap alloc",
+              "refId": "D"
+            },
+            {
+              "expr": "go_memstats_alloc_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Alloc",
+              "refId": "F",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_heap_inuse_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Heap in-use",
+              "refId": "E",
+              "step": 2
+            },
+            {
+              "expr": "go_memstats_stack_inuse_bytes{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Stack in-use",
+              "refId": "G",
+              "step": 2
+            },
+            {
+              "expr": "container_memory_usage_bytes{container=~\"discovery\", pod=~\"istiod-.*|istio-pilot-.*\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Discovery (container)",
+              "refId": "B",
+              "step": 2
+            },
+            {
+              "expr": "container_memory_usage_bytes{container=~\"istio-proxy\", pod=~\"istiod-.*|istio-pilot-.*\"}",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Sidecar (container)",
+              "refId": "C"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Memory",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 6,
+            "y": 7
+          },
+          "id": 6,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(irate(container_cpu_usage_seconds_total{container=\"discovery\", pod=~\"istiod-.*|istio-pilot-.*\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Discovery (container)",
+              "refId": "A"
+            },
+            {
+              "expr": "irate(process_cpu_seconds_total{app=\"istiod\"}[1m])",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Discovery (process)",
+              "refId": "C",
+              "step": 2
+            },
+            {
+              "expr": "sum(irate(container_cpu_usage_seconds_total{container=\"istio-proxy\", pod=~\"istiod-.*|istio-pilot-.*\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 2,
+              "legendFormat": "Sidecar (container)",
+              "refId": "B",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "CPU",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 12,
+            "y": 7
+          },
+          "id": 7,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "container_fs_usage_bytes{container=\"discovery\", pod=~\"istiod-.*|istio-pilot-.*\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Discovery",
+              "refId": "B",
+              "step": 2
+            },
+            {
+              "expr": "container_fs_usage_bytes{container=\"istio-proxy\", pod=~\"istiod-.*|istio-pilot-.*\"}",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Sidecar",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Disk",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "bytes",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "decimals": null,
+              "format": "none",
+              "label": "",
+              "logBase": 1024,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 7,
+            "w": 6,
+            "x": 18,
+            "y": 7
+          },
+          "id": 4,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": false,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "go_goroutines{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "Number of Goroutines",
+              "refId": "A",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Goroutines",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": "",
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 14
+          },
+          "id": 58,
+          "panels": [],
+          "title": "Pilot Push Information",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": true,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "description": "Shows the rate of pilot pushes",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 0,
+            "y": 15
+          },
+          "id": 622,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": false,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null as zero",
+          "paceLength": 10,
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": true,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(irate(pilot_xds_pushes{type=\"cds\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Cluster",
+              "refId": "C"
+            },
+            {
+              "expr": "sum(irate(pilot_xds_pushes{type=\"eds\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Endpoints",
+              "refId": "D"
+            },
+            {
+              "expr": "sum(irate(pilot_xds_pushes{type=\"lds\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Listeners",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(irate(pilot_xds_pushes{type=\"rds\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Routes",
+              "refId": "E"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Pilot Pushes",
+          "tooltip": {
+            "shared": false,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": [
+              "total"
+            ]
+          },
+          "yaxes": [
+            {
+              "format": "ops",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": "0",
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "description": "Captures a variety of pilot errors",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 8,
+            "y": 15
+          },
+          "id": 67,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "hideEmpty": true,
+            "hideZero": true,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(pilot_xds_cds_reject{app=\"istiod\"}) or (absent(pilot_xds_cds_reject{app=\"istiod\"}) - 1)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Rejected CDS Configs",
+              "refId": "C"
+            },
+            {
+              "expr": "sum(pilot_xds_eds_reject{app=\"istiod\"}) or (absent(pilot_xds_eds_reject{app=\"istiod\"}) - 1)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Rejected EDS Configs",
+              "refId": "D"
+            },
+            {
+              "expr": "sum(pilot_xds_rds_reject{app=\"istiod\"}) or (absent(pilot_xds_rds_reject{app=\"istiod\"}) - 1)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Rejected RDS Configs",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(pilot_xds_lds_reject{app=\"istiod\"}) or (absent(pilot_xds_lds_reject{app=\"istiod\"}) - 1)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Rejected LDS Configs",
+              "refId": "B"
+            },
+            {
+              "expr": "sum(rate(pilot_xds_write_timeout{app=\"istiod\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Write Timeouts",
+              "refId": "F"
+            },
+            {
+              "expr": "sum(rate(pilot_total_xds_internal_errors{app=\"istiod\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Internal Errors",
+              "refId": "H"
+            },
+            {
+              "expr": "sum(rate(pilot_total_xds_rejects{app=\"istiod\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Config Rejection Rate",
+              "refId": "E"
+            },
+            {
+              "expr": "sum(rate(pilot_xds_push_context_errors{app=\"istiod\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Push Context Errors",
+              "refId": "K"
+            },
+            {
+              "expr": "sum(rate(pilot_xds_pushes{type!~\"lds|cds|rds|eds\"}[1m])) by (type)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Push Errors ({{ type }})",
+              "refId": "L"
+            },
+            {
+              "expr": "sum(rate(pilot_xds_push_errors{app=\"istiod\"}[1m])) by (type)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Push Errors ({{ type }})",
+              "refId": "I"
+            },
+            {
+              "expr": "sum(rate(pilot_xds_push_timeout{app=\"istiod\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Push Timeouts",
+              "refId": "G"
+            },
+            {
+              "expr": "sum(rate(pilot_xds_push_timeout_failures{app=\"istiod\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Push Timeouts Failures",
+              "refId": "J"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Pilot Errors",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "description": "Shows the total time it takes to push a config update to a proxy",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 16,
+            "y": 15
+          },
+          "id": 624,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "histogram_quantile(0.5, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "p50 ",
+              "refId": "A"
+            },
+            {
+              "expr": "histogram_quantile(0.9, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "p90",
+              "refId": "B"
+            },
+            {
+              "expr": "histogram_quantile(0.99, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "p99",
+              "refId": "C"
+            },
+            {
+              "expr": "histogram_quantile(0.999, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "p99.9",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Proxy Push Time",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "s",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 0,
+            "y": 23
+          },
+          "id": 45,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "hideEmpty": true,
+            "hideZero": true,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null as zero",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "pilot_conflict_inbound_listener{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Inbound Listeners",
+              "refId": "B"
+            },
+            {
+              "expr": "pilot_conflict_outbound_listener_http_over_current_tcp{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Outbound Listeners (http over current tcp)",
+              "refId": "A"
+            },
+            {
+              "expr": "pilot_conflict_outbound_listener_tcp_over_current_tcp{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Outbound Listeners (tcp over current tcp)",
+              "refId": "C"
+            },
+            {
+              "expr": "pilot_conflict_outbound_listener_tcp_over_current_http{app=\"istiod\"}",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "Outbound Listeners (tcp over current http)",
+              "refId": "D"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Conflicts",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 8,
+            "y": 23
+          },
+          "id": 47,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "pilot_virt_services{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Virtual Services",
+              "refId": "A"
+            },
+            {
+              "expr": "pilot_services{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Services",
+              "refId": "B"
+            },
+            {
+              "expr": "pilot_xds{app=\"istiod\"}",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Connected Endpoints",
+              "refId": "E"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "ADS Monitoring",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "columns": [],
+          "datasource": "Prometheus",
+          "description": "Clusters in this table do not have any endpoints known to pilot. This could be from referencing subsets that do not have any instances, or pods marked as NotReady",
+          "fontSize": "100%",
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 16,
+            "y": 23
+          },
+          "id": 51,
+          "links": [],
+          "pageSize": null,
+          "scroll": true,
+          "showHeader": true,
+          "sort": {
+            "col": null,
+            "desc": false
+          },
+          "styles": [
+            {
+              "alias": "Time",
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "pattern": "Time",
+              "type": "date"
+            },
+            {
+              "alias": "Clusters",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "decimals": 2,
+              "pattern": "/.*/",
+              "thresholds": [],
+              "type": "number",
+              "unit": "short"
+            }
+          ],
+          "targets": [
+            {
+              "expr": "sum(pilot_xds_eds_instances{app=\"istiod\", cluster=~\".+\\\\|.+\"}) by (cluster) < 1",
+              "format": "time_series",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{cluster}}",
+              "refId": "B"
+            }
+          ],
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Clusters with no known endpoints",
+          "transform": "timeseries_aggregations",
+          "type": "table"
+        },
+        {
+          "collapsed": false,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 31
+          },
+          "id": 64,
+          "panels": [],
+          "title": "Envoy Information",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "description": "Shows details about Envoy proxies in the mesh",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 0,
+            "y": 32
+          },
+          "id": 40,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(irate(envoy_cluster_upstream_cx_total{cluster_name=\"xds-grpc\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "XDS Connections",
+              "refId": "C"
+            },
+            {
+              "expr": "sum(irate(envoy_cluster_upstream_cx_connect_fail{cluster_name=\"xds-grpc\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "XDS Connection Failures",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(increase(envoy_server_hot_restart_epoch[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "Envoy Restarts",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Envoy Details",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "ops",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "ops",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 8,
+            "y": 32
+          },
+          "id": 41,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(envoy_cluster_upstream_cx_active{cluster_name=\"xds-grpc\"})",
+              "format": "time_series",
+              "intervalFactor": 2,
+              "legendFormat": "XDS Active Connections",
+              "refId": "C",
+              "step": 2
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "XDS Active Connections",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "description": "Shows the size of XDS requests and responses",
+          "fill": 1,
+          "gridPos": {
+            "h": 8,
+            "w": 8,
+            "x": 16,
+            "y": 32
+          },
+          "id": 42,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "hideEmpty": false,
+            "hideZero": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "max(rate(envoy_cluster_upstream_cx_rx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "XDS Response Bytes Max",
+              "refId": "D"
+            },
+            {
+              "expr": "quantile(0.5, rate(envoy_cluster_upstream_cx_rx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "legendFormat": "XDS Response Bytes Average",
+              "refId": "B"
+            },
+            {
+              "expr": "max(rate(envoy_cluster_upstream_cx_tx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "XDS Request Bytes Max",
+              "refId": "A"
+            },
+            {
+              "expr": "quantile(.5, rate(envoy_cluster_upstream_cx_tx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "XDS Request Bytes Average",
+              "refId": "C"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "XDS Requests Size",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "Bps",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "ops",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "collapsed": false,
+          "datasource": null,
+          "gridPos": {
+            "h": 1,
+            "w": 24,
+            "x": 0,
+            "y": 40
+          },
+          "id": 626,
+          "panels": [],
+          "title": "Webhooks",
+          "type": "row"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": null,
+          "fill": 1,
+          "fillGradient": 0,
+          "gridPos": {
+            "h": 8,
+            "w": 12,
+            "x": 0,
+            "y": 41
+          },
+          "hiddenSeries": false,
+          "id": 629,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "hideEmpty": false,
+            "hideZero": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "nullPointMode": "null",
+          "options": {
+            "dataLinks": []
+          },
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(galley_validation_passed[1m]))",
+              "interval": "",
+              "legendFormat": "Validations (Success)",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(rate(galley_validation_failed[1m]))",
+              "interval": "",
+              "legendFormat": "Validation (Failure)",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Configuration Validation",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": null,
+          "description": "",
+          "fill": 1,
+          "fillGradient": 0,
+          "gridPos": {
+            "h": 8,
+            "w": 12,
+            "x": 12,
+            "y": 41
+          },
+          "hiddenSeries": false,
+          "id": 630,
+          "legend": {
+            "avg": false,
+            "current": false,
+            "hideZero": false,
+            "max": false,
+            "min": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "nullPointMode": "null",
+          "options": {
+            "dataLinks": []
+          },
+          "percentage": false,
+          "pointradius": 2,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(rate(sidecar_injection_success_total[1m]))",
+              "interval": "",
+              "legendFormat": "Injections (Success)",
+              "refId": "A"
+            },
+            {
+              "expr": "sum(rate(sidecar_injection_failure_total[1m]))",
+              "interval": "",
+              "legendFormat": "Injections (Failure)",
+              "refId": "B"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Sidecar Injection",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "refresh": "5s",
+      "schemaVersion": 18,
+      "style": "dark",
+      "tags": [],
+      "templating": {
+        "list": []
+      },
+      "time": {
+        "from": "now-5m",
+        "to": "now"
+      },
+      "timepicker": {
+        "refresh_intervals": [
+          "5s",
+          "10s",
+          "30s",
+          "1m",
+          "5m",
+          "15m",
+          "30m",
+          "1h",
+          "2h",
+          "1d"
+        ],
+        "time_options": [
+          "5m",
+          "15m",
+          "1h",
+          "6h",
+          "12h",
+          "24h",
+          "2d",
+          "7d",
+          "30d"
+        ]
+      },
+      "timezone": "browser",
+      "title": "Istio Control Plane Dashboard",
+      "uid": "3--MLVZZk",
+      "version": 11
+    }
+kind: ConfigMap
+metadata:
+  creationTimestamp: null
+  name: istio-grafana-dashboards
+  namespace: istio-system
+
+---
+
+apiVersion: v1
+data:
+  istio-mesh-dashboard.json: |
+    {
+      "annotations": {
+        "list": [
+          {
+            "builtIn": 1,
+            "datasource": "-- Grafana --",
+            "enable": true,
+            "hide": true,
+            "iconColor": "rgba(0, 211, 255, 1)",
+            "name": "Annotations & Alerts",
+            "type": "dashboard"
+          }
+        ]
+      },
+      "editable": false,
+      "gnetId": null,
+      "graphTooltip": 0,
+      "id": null,
+      "links": [],
+      "panels": [
+        {
+          "content": "<div>\n  <div style=\"position: absolute; bottom: 0\">\n    <a href=\"https://istio.io\" target=\"_blank\" style=\"font-size: 30px; text-decoration: none; color: inherit\"><img src=\"https://istio.io/img/istio-logo.svg\" style=\"height: 50px\"> Istio</a>\n  </div>\n  <div style=\"position: absolute; bottom: 0; right: 0; font-size: 15px\">\n    Istio is an <a href=\"https://github.com/istio/istio\" target=\"_blank\">open platform</a> that provides a uniform way to connect,\n    <a href=\"https://istio.io/docs/concepts/traffic-management/overview.html\" target=\"_blank\">manage</a>, and \n    <a href=\"https://istio.io/docs/concepts/network-and-auth/auth.html\" target=\"_blank\">secure</a> microservices.\n    <br>\n    Need help? Join the <a href=\"https://istio.io/community/\" target=\"_blank\">Istio community</a>.\n  </div>\n</div>",
+          "gridPos": {
+            "h": 3,
+            "w": 24,
+            "x": 0,
+            "y": 0
+          },
+          "height": "50px",
+          "id": 13,
+          "links": [],
+          "mode": "html",
+          "style": {
+            "font-size": "18pt"
+          },
+          "title": "",
+          "transparent": true,
+          "type": "text"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "datasource": "Prometheus",
+          "format": "ops",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 0,
+            "y": 3
+          },
+          "id": 20,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": true,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "round(sum(irate(istio_requests_total{reporter=\"destination\"}[1m])), 0.001)",
+              "intervalFactor": 1,
+              "refId": "A",
+              "step": 4
+            }
+          ],
+          "thresholds": "",
+          "title": "Global Request Volume",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "avg"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "datasource": "Prometheus",
+          "format": "percentunit",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 80,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": false
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 6,
+            "y": 3
+          },
+          "id": 21,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": true,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "sum(rate(istio_requests_total{reporter=\"destination\", response_code!~\"5.*\"}[1m])) / sum(rate(istio_requests_total{reporter=\"destination\"}[1m]))",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "refId": "A",
+              "step": 4
+            }
+          ],
+          "thresholds": "95, 99, 99.5",
+          "title": "Global Success Rate (non-5xx responses)",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "avg"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "datasource": "Prometheus",
+          "format": "ops",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 12,
+            "y": 3
+          },
+          "id": 22,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": true,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "sum(irate(istio_requests_total{reporter=\"destination\", response_code=~\"4.*\"}[1m])) ",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "refId": "A",
+              "step": 4
+            }
+          ],
+          "thresholds": "",
+          "title": "4xxs",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "avg"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "rgba(245, 54, 54, 0.9)",
+            "rgba(237, 129, 40, 0.89)",
+            "rgba(50, 172, 45, 0.97)"
+          ],
+          "datasource": "Prometheus",
+          "format": "ops",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 18,
+            "y": 3
+          },
+          "id": 23,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": true,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "sum(irate(istio_requests_total{reporter=\"destination\", response_code=~\"5.*\"}[1m])) ",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "refId": "A",
+              "step": 4
+            }
+          ],
+          "thresholds": "",
+          "title": "5xxs",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "avg"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "#299c46",
+            "rgba(237, 129, 40, 0.89)",
+            "#d44a3a"
+          ],
+          "datasource": "Prometheus",
+          "format": "none",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 0,
+            "y": 6
+          },
+          "id": 113,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": false,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "avg(galley_istio_networking_virtualservices)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "refId": "A"
+            }
+          ],
+          "thresholds": "",
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Virtual Services",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "current"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "#299c46",
+            "rgba(237, 129, 40, 0.89)",
+            "#d44a3a"
+          ],
+          "datasource": "Prometheus",
+          "format": "none",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 6,
+            "y": 6
+          },
+          "id": 114,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": false,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "avg(galley_istio_networking_destinationrules)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "refId": "A"
+            }
+          ],
+          "thresholds": "",
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Destination Rules",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "current"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "#299c46",
+            "rgba(237, 129, 40, 0.89)",
+            "#d44a3a"
+          ],
+          "datasource": "Prometheus",
+          "format": "none",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 12,
+            "y": 6
+          },
+          "id": 115,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": false,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "avg(galley_istio_networking_gateways)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "refId": "A"
+            }
+          ],
+          "thresholds": "",
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Gateways",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "current"
+        },
+        {
+          "cacheTimeout": null,
+          "colorBackground": false,
+          "colorValue": false,
+          "colors": [
+            "#299c46",
+            "rgba(237, 129, 40, 0.89)",
+            "#d44a3a"
+          ],
+          "datasource": "Prometheus",
+          "format": "none",
+          "gauge": {
+            "maxValue": 100,
+            "minValue": 0,
+            "show": false,
+            "thresholdLabels": false,
+            "thresholdMarkers": true
+          },
+          "gridPos": {
+            "h": 3,
+            "w": 6,
+            "x": 18,
+            "y": 6
+          },
+          "id": 116,
+          "interval": null,
+          "links": [],
+          "mappingType": 1,
+          "mappingTypes": [
+            {
+              "name": "value to text",
+              "value": 1
+            },
+            {
+              "name": "range to text",
+              "value": 2
+            }
+          ],
+          "maxDataPoints": 100,
+          "nullPointMode": "connected",
+          "nullText": null,
+          "postfix": "",
+          "postfixFontSize": "50%",
+          "prefix": "",
+          "prefixFontSize": "50%",
+          "rangeMaps": [
+            {
+              "from": "null",
+              "text": "N/A",
+              "to": "null"
+            }
+          ],
+          "sparkline": {
+            "fillColor": "rgba(31, 118, 189, 0.18)",
+            "full": false,
+            "lineColor": "rgb(31, 120, 193)",
+            "show": true
+          },
+          "tableColumn": "",
+          "targets": [
+            {
+              "expr": "avg(galley_istio_authentication_meshpolicies)",
+              "format": "time_series",
+              "hide": false,
+              "intervalFactor": 1,
+              "refId": "A"
+            }
+          ],
+          "thresholds": "",
+          "timeFrom": null,
+          "timeShift": null,
+          "title": "Authentication Mesh Policies",
+          "type": "singlestat",
+          "valueFontSize": "80%",
+          "valueMaps": [
+            {
+              "op": "=",
+              "text": "N/A",
+              "value": "null"
+            }
+          ],
+          "valueName": "current"
+        },
+        {
+          "columns": [],
+          "datasource": "Prometheus",
+          "fontSize": "100%",
+          "gridPos": {
+            "h": 21,
+            "w": 24,
+            "x": 0,
+            "y": 9
+          },
+          "hideTimeOverride": false,
+          "id": 73,
+          "links": [],
+          "pageSize": null,
+          "repeat": null,
+          "repeatDirection": "v",
+          "scroll": true,
+          "showHeader": true,
+          "sort": {
+            "col": 4,
+            "desc": true
+          },
+          "styles": [
+            {
+              "alias": "Workload",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "link": false,
+              "linkTargetBlank": false,
+              "linkTooltip": "Workload dashboard",
+              "linkUrl": "/dashboard/db/istio-workload-dashboard?var-namespace=$__cell_2&var-workload=$__cell_",
+              "pattern": "destination_workload",
+              "preserveFormat": false,
+              "sanitize": false,
+              "thresholds": [],
+              "type": "hidden",
+              "unit": "short"
+            },
+            {
+              "alias": "",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Time",
+              "thresholds": [],
+              "type": "hidden",
+              "unit": "short"
+            },
+            {
+              "alias": "Requests",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #A",
+              "thresholds": [],
+              "type": "number",
+              "unit": "ops"
+            },
+            {
+              "alias": "P50 Latency",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #B",
+              "thresholds": [],
+              "type": "number",
+              "unit": "s"
+            },
+            {
+              "alias": "P90 Latency",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #D",
+              "thresholds": [],
+              "type": "number",
+              "unit": "s"
+            },
+            {
+              "alias": "P99 Latency",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #E",
+              "thresholds": [],
+              "type": "number",
+              "unit": "s"
+            },
+            {
+              "alias": "Success Rate",
+              "colorMode": "cell",
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #F",
+              "thresholds": [
+                ".95",
+                " 1.00"
+              ],
+              "type": "number",
+              "unit": "percentunit"
+            },
+            {
+              "alias": "Workload",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "link": true,
+              "linkTooltip": "$__cell dashboard",
+              "linkUrl": "/dashboard/db/istio-workload-dashboard?var-workload=$__cell_2&var-namespace=$__cell_3",
+              "pattern": "destination_workload_var",
+              "thresholds": [],
+              "type": "number",
+              "unit": "short"
+            },
+            {
+              "alias": "Service",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "link": true,
+              "linkTooltip": "$__cell dashboard",
+              "linkUrl": "/dashboard/db/istio-service-dashboard?var-service=$__cell",
+              "pattern": "destination_service",
+              "thresholds": [],
+              "type": "string",
+              "unit": "short"
+            },
+            {
+              "alias": "",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "destination_workload_namespace",
+              "thresholds": [],
+              "type": "hidden",
+              "unit": "short"
+            }
+          ],
+          "targets": [
+            {
+              "expr": "label_join(sum(rate(istio_requests_total{reporter=\"destination\", response_code=\"200\"}[1m])) by (destination_workload, destination_workload_namespace, destination_service), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload}}.{{ destination_workload_namespace }}",
+              "refId": "A"
+            },
+            {
+              "expr": "label_join((histogram_quantile(0.50, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[1m])) by (le, destination_workload, destination_workload_namespace)) / 1000) or histogram_quantile(0.50, sum(rate(istio_request_duration_seconds_bucket{reporter=\"destination\"}[1m])) by (le, destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload}}.{{ destination_workload_namespace }}",
+              "refId": "B"
+            },
+            {
+              "expr": "label_join((histogram_quantile(0.90, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[1m])) by (le, destination_workload, destination_workload_namespace)) / 1000) or histogram_quantile(0.90, sum(rate(istio_request_duration_seconds_bucket{reporter=\"destination\"}[1m])) by (le, destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}",
+              "refId": "D"
+            },
+            {
+              "expr": "label_join((histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[1m])) by (le, destination_workload, destination_workload_namespace)) / 1000) or histogram_quantile(0.99, sum(rate(istio_request_duration_seconds_bucket{reporter=\"destination\"}[1m])) by (le, destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}",
+              "refId": "E"
+            },
+            {
+              "expr": "label_join((sum(rate(istio_requests_total{reporter=\"destination\", response_code!~\"5.*\"}[1m])) by (destination_workload, destination_workload_namespace) / sum(rate(istio_requests_total{reporter=\"destination\"}[1m])) by (destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "interval": "",
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}",
+              "refId": "F"
+            }
+          ],
+          "timeFrom": null,
+          "title": "HTTP/GRPC Workloads",
+          "transform": "table",
+          "type": "table"
+        },
+        {
+          "columns": [],
+          "datasource": "Prometheus",
+          "fontSize": "100%",
+          "gridPos": {
+            "h": 18,
+            "w": 24,
+            "x": 0,
+            "y": 30
+          },
+          "hideTimeOverride": false,
+          "id": 109,
+          "links": [],
+          "pageSize": null,
+          "repeatDirection": "v",
+          "scroll": true,
+          "showHeader": true,
+          "sort": {
+            "col": 2,
+            "desc": true
+          },
+          "styles": [
+            {
+              "alias": "Workload",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "link": false,
+              "linkTargetBlank": false,
+              "linkTooltip": "$__cell dashboard",
+              "linkUrl": "/dashboard/db/istio-tcp-workload-dashboard?var-namespace=$__cell_2&&var-workload=$__cell",
+              "pattern": "destination_workload",
+              "preserveFormat": false,
+              "sanitize": false,
+              "thresholds": [],
+              "type": "hidden",
+              "unit": "short"
+            },
+            {
+              "alias": "Bytes Sent",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #A",
+              "thresholds": [
+                ""
+              ],
+              "type": "number",
+              "unit": "Bps"
+            },
+            {
+              "alias": "Bytes Received",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Value #C",
+              "thresholds": [],
+              "type": "number",
+              "unit": "Bps"
+            },
+            {
+              "alias": "",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "Time",
+              "thresholds": [],
+              "type": "hidden",
+              "unit": "short"
+            },
+            {
+              "alias": "Workload",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "link": true,
+              "linkTooltip": "$__cell dashboard",
+              "linkUrl": "/dashboard/db/istio-workload-dashboard?var-namespace=$__cell_3&var-workload=$__cell_2",
+              "pattern": "destination_workload_var",
+              "thresholds": [],
+              "type": "string",
+              "unit": "short"
+            },
+            {
+              "alias": "",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "pattern": "destination_workload_namespace",
+              "thresholds": [],
+              "type": "hidden",
+              "unit": "short"
+            },
+            {
+              "alias": "Service",
+              "colorMode": null,
+              "colors": [
+                "rgba(245, 54, 54, 0.9)",
+                "rgba(237, 129, 40, 0.89)",
+                "rgba(50, 172, 45, 0.97)"
+              ],
+              "dateFormat": "YYYY-MM-DD HH:mm:ss",
+              "decimals": 2,
+              "link": true,
+              "linkTooltip": "$__cell dashboard",
+              "linkUrl": "/dashboard/db/istio-service-dashboard?var-service=$__cell",
+              "pattern": "destination_service",
+              "thresholds": [],
+              "type": "number",
+              "unit": "short"
+            }
+          ],
+          "targets": [
+            {
+              "expr": "label_join(sum(rate(istio_tcp_received_bytes_total{reporter=\"source\"}[1m])) by (destination_workload, destination_workload_namespace, destination_service), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload }}",
+              "refId": "C"
+            },
+            {
+              "expr": "label_join(sum(rate(istio_tcp_sent_bytes_total{reporter=\"source\"}[1m])) by (destination_workload, destination_workload_namespace, destination_service), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")",
+              "format": "table",
+              "hide": false,
+              "instant": true,
+              "intervalFactor": 1,
+              "legendFormat": "{{ destination_workload }}",
+              "refId": "A"
+            }
+          ],
+          "timeFrom": null,
+          "title": "TCP Workloads",
+          "transform": "table",
+          "type": "table"
+        },
+        {
+          "aliasColors": {},
+          "bars": false,
+          "dashLength": 10,
+          "dashes": false,
+          "datasource": "Prometheus",
+          "fill": 1,
+          "gridPos": {
+            "h": 9,
+            "w": 24,
+            "x": 0,
+            "y": 48
+          },
+          "id": 111,
+          "legend": {
+            "alignAsTable": false,
+            "avg": false,
+            "current": false,
+            "max": false,
+            "min": false,
+            "rightSide": false,
+            "show": true,
+            "total": false,
+            "values": false
+          },
+          "lines": true,
+          "linewidth": 1,
+          "links": [],
+          "nullPointMode": "null",
+          "percentage": false,
+          "pointradius": 5,
+          "points": false,
+          "renderer": "flot",
+          "seriesOverrides": [],
+          "spaceLength": 10,
+          "stack": false,
+          "steppedLine": false,
+          "targets": [
+            {
+              "expr": "sum(istio_build) by (component, tag)",
+              "format": "time_series",
+              "intervalFactor": 1,
+              "legendFormat": "{{ component }}: {{ tag }}",
+              "refId": "A"
+            }
+          ],
+          "thresholds": [],
+          "timeFrom": null,
+          "timeRegions": [],
+          "timeShift": null,
+          "title": "Istio Components by Version",
+          "tooltip": {
+            "shared": true,
+            "sort": 0,
+            "value_type": "individual"
+          },
+          "type": "graph",
+          "xaxis": {
+            "buckets": null,
+            "mode": "time",
+            "name": null,
+            "show": true,
+            "values": []
+          },
+          "yaxes": [
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": true
+            },
+            {
+              "format": "short",
+              "label": null,
+              "logBase": 1,
+              "max": null,
+              "min": null,
+              "show": false
+            }
+          ],
+          "yaxis": {
+            "align": false,
+            "alignLevel": null
+          }
+        }
+      ],
+      "refresh": "5s",
+      "schemaVersion": 18,
+      "style": "dark",
+      "tags": [],
+      "templating": {
+        "list": []
+      },
+      "time": {
+        "from": "now-5m",
+        "to": "now"
+      },
+      "timepicker": {
+        "refresh_intervals": [
+          "5s",
+          "10s",
+          "30s",
+          "1m",
+          "5m",
+          "15m",
+          "30m",
+          "1h",
+          "2h",
+          "1d"
+        ],
+        "time_options": [
+          "5m",
+          "15m",
+          "1h",
+          "6h",
+          "12h",
+          "24h",
+          "2d",
+          "7d",
+          "30d"
+        ]
+      },
+      "timezone": "browser",
+      "title": "Istio Mesh Dashboard",
+      "uid": "G8wLrJIZk",
+      "version": 5
+    }
+  istio-service-dashboard.json: "{\n  \"annotations\": {\n    \"list\": [\n      {\n
+    \       \"builtIn\": 1,\n        \"datasource\": \"-- Grafana --\",\n        \"enable\":
+    true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0, 211, 255, 1)\",\n
+    \       \"name\": \"Annotations & Alerts\",\n        \"type\": \"dashboard\"\n
+    \     }\n    ]\n  },\n  \"editable\": false,\n  \"gnetId\": null,\n  \"graphTooltip\":
+    0,\n  \"iteration\": 1536442501501,\n  \"links\": [],\n  \"panels\": [\n    {\n
+    \     \"content\": \"<div class=\\\"dashboard-header text-center\\\">\\n<span>SERVICE:
+    $service</span>\\n</div>\",\n      \"gridPos\": {\n        \"h\": 3,\n        \"w\":
+    24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 89,\n      \"links\":
+    [],\n      \"mode\": \"html\",\n      \"title\": \"\",\n      \"transparent\":
+    true,\n      \"type\": \"text\"\n    },\n    {\n      \"cacheTimeout\": null,\n
+    \     \"colorBackground\": false,\n      \"colorValue\": false,\n      \"colors\":
+    [\n        \"rgba(245, 54, 54, 0.9)\",\n        \"rgba(237, 129, 40, 0.89)\",\n
+    \       \"rgba(50, 172, 45, 0.97)\"\n      ],\n      \"datasource\": \"Prometheus\",\n
+    \     \"format\": \"ops\",\n      \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\":
+    0,\n        \"show\": false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\":
+    true\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\":
+    0,\n        \"y\": 3\n      },\n      \"id\": 12,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[5m])),
+    0.001)\",\n          \"format\": \"time_series\",\n          \"intervalFactor\":
+    1,\n          \"refId\": \"A\",\n          \"step\": 4\n        }\n      ],\n
+    \     \"thresholds\": \"\",\n      \"title\": \"Client Request Volume\",\n      \"transparent\":
+    false,\n      \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"current\"\n    },\n    {\n
+    \     \"cacheTimeout\": null,\n      \"colorBackground\": false,\n      \"colorValue\":
+    false,\n      \"colors\": [\n        \"rgba(50, 172, 45, 0.97)\",\n        \"rgba(237,
+    129, 40, 0.89)\",\n        \"rgba(245, 54, 54, 0.9)\"\n      ],\n      \"datasource\":
+    \"Prometheus\",\n      \"decimals\": null,\n      \"format\": \"percentunit\",\n
+    \     \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\": 80,\n        \"show\":
+    false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\": false\n
+    \     },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\":
+    6,\n        \"y\": 3\n      },\n      \"id\": 14,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"source\\\",destination_service=~\\\"$service\\\",response_code!~\\\"5.*\\\"}[5m]))
+    / sum(irate(istio_requests_total{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[5m]))\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"refId\":
+    \"B\"\n        }\n      ],\n      \"thresholds\": \"95, 99, 99.5\",\n      \"title\":
+    \"Client Success Rate (non-5xx responses)\",\n      \"transparent\": false,\n
+    \     \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"avg\"\n    },\n    {\n      \"aliasColors\":
+    {},\n      \"bars\": false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n
+    \     \"datasource\": \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\":
+    {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\": 12,\n        \"y\": 3\n
+    \     },\n      \"id\": 87,\n      \"legend\": {\n        \"alignAsTable\": false,\n
+    \       \"avg\": false,\n        \"current\": false,\n        \"hideEmpty\": false,\n
+    \       \"hideZero\": false,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"rightSide\": true,\n        \"show\": true,\n        \"total\": false,\n
+    \       \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le))\",\n          \"format\": \"time_series\",\n          \"interval\": \"\",\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"P50\",\n          \"refId\":
+    \"A\"\n        },\n        {\n          \"expr\": \"(histogram_quantile(0.90,
+    sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"P90\",\n          \"refId\":
+    \"B\"\n        },\n        {\n          \"expr\": \"(histogram_quantile(0.99,
+    sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"P99\",\n          \"refId\":
+    \"C\"\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Client Request Duration\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"s\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"cacheTimeout\": null,\n      \"colorBackground\":
+    false,\n      \"colorValue\": false,\n      \"colors\": [\n        \"#299c46\",\n
+    \       \"rgba(237, 129, 40, 0.89)\",\n        \"#d44a3a\"\n      ],\n      \"datasource\":
+    \"Prometheus\",\n      \"format\": \"Bps\",\n      \"gauge\": {\n        \"maxValue\":
+    100,\n        \"minValue\": 0,\n        \"show\": false,\n        \"thresholdLabels\":
+    false,\n        \"thresholdMarkers\": true\n      },\n      \"gridPos\": {\n        \"h\":
+    4,\n        \"w\": 6,\n        \"x\": 18,\n        \"y\": 3\n      },\n      \"id\":
+    84,\n      \"interval\": null,\n      \"links\": [],\n      \"mappingType\": 1,\n
+    \     \"mappingTypes\": [\n        {\n          \"name\": \"value to text\",\n
+    \         \"value\": 1\n        },\n        {\n          \"name\": \"range to
+    text\",\n          \"value\": 2\n        }\n      ],\n      \"maxDataPoints\":
+    100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\": null,\n      \"postfix\":
+    \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\": \"\",\n      \"prefixFontSize\":
+    \"50%\",\n      \"rangeMaps\": [\n        {\n          \"from\": \"null\",\n          \"text\":
+    \"N/A\",\n          \"to\": \"null\"\n        }\n      ],\n      \"sparkline\":
+    {\n        \"fillColor\": \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n
+    \       \"lineColor\": \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n
+    \     \"tableColumn\": \"\",\n      \"targets\": [\n        {\n          \"expr\":
+    \"sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\", destination_service=~\\\"$service\\\"}[1m]))\",\n
+    \         \"format\": \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\":
+    1,\n          \"legendFormat\": \"\",\n          \"refId\": \"A\"\n        }\n
+    \     ],\n      \"thresholds\": \"\",\n      \"title\": \"TCP Received Bytes\",\n
+    \     \"transparent\": false,\n      \"type\": \"singlestat\",\n      \"valueFontSize\":
+    \"80%\",\n      \"valueMaps\": [\n        {\n          \"op\": \"=\",\n          \"text\":
+    \"N/A\",\n          \"value\": \"null\"\n        }\n      ],\n      \"valueName\":
+    \"avg\"\n    },\n    {\n      \"cacheTimeout\": null,\n      \"colorBackground\":
+    false,\n      \"colorValue\": false,\n      \"colors\": [\n        \"rgba(245,
+    54, 54, 0.9)\",\n        \"rgba(237, 129, 40, 0.89)\",\n        \"rgba(50, 172,
+    45, 0.97)\"\n      ],\n      \"datasource\": \"Prometheus\",\n      \"format\":
+    \"ops\",\n      \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\":
+    0,\n        \"show\": false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\":
+    true\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\":
+    0,\n        \"y\": 7\n      },\n      \"id\": 97,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[5m])),
+    0.001)\",\n          \"format\": \"time_series\",\n          \"intervalFactor\":
+    1,\n          \"refId\": \"A\",\n          \"step\": 4\n        }\n      ],\n
+    \     \"thresholds\": \"\",\n      \"title\": \"Server Request Volume\",\n      \"transparent\":
+    false,\n      \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"current\"\n    },\n    {\n
+    \     \"cacheTimeout\": null,\n      \"colorBackground\": false,\n      \"colorValue\":
+    false,\n      \"colors\": [\n        \"rgba(50, 172, 45, 0.97)\",\n        \"rgba(237,
+    129, 40, 0.89)\",\n        \"rgba(245, 54, 54, 0.9)\"\n      ],\n      \"datasource\":
+    \"Prometheus\",\n      \"decimals\": null,\n      \"format\": \"percentunit\",\n
+    \     \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\": 80,\n        \"show\":
+    false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\": false\n
+    \     },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\":
+    6,\n        \"y\": 7\n      },\n      \"id\": 98,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\",response_code!~\\\"5.*\\\"}[5m]))
+    / sum(irate(istio_requests_total{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[5m]))\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"refId\":
+    \"B\"\n        }\n      ],\n      \"thresholds\": \"95, 99, 99.5\",\n      \"title\":
+    \"Server Success Rate (non-5xx responses)\",\n      \"transparent\": false,\n
+    \     \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"avg\"\n    },\n    {\n      \"aliasColors\":
+    {},\n      \"bars\": false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n
+    \     \"datasource\": \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\":
+    {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\": 12,\n        \"y\": 7\n
+    \     },\n      \"id\": 99,\n      \"legend\": {\n        \"alignAsTable\": false,\n
+    \       \"avg\": false,\n        \"current\": false,\n        \"hideEmpty\": false,\n
+    \       \"hideZero\": false,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"rightSide\": true,\n        \"show\": true,\n        \"total\": false,\n
+    \       \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le))\",\n          \"format\": \"time_series\",\n          \"interval\": \"\",\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"P50\",\n          \"refId\":
+    \"A\"\n        },\n        {\n          \"expr\": \"(histogram_quantile(0.90,
+    sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"P90\",\n          \"refId\":
+    \"B\"\n        },\n        {\n          \"expr\": \"(histogram_quantile(0.99,
+    sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",destination_service=~\\\"$service\\\"}[1m]))
+    by (le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"P99\",\n          \"refId\":
+    \"C\"\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Server Request Duration\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"s\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"cacheTimeout\": null,\n      \"colorBackground\":
+    false,\n      \"colorValue\": false,\n      \"colors\": [\n        \"#299c46\",\n
+    \       \"rgba(237, 129, 40, 0.89)\",\n        \"#d44a3a\"\n      ],\n      \"datasource\":
+    \"Prometheus\",\n      \"format\": \"Bps\",\n      \"gauge\": {\n        \"maxValue\":
+    100,\n        \"minValue\": 0,\n        \"show\": false,\n        \"thresholdLabels\":
+    false,\n        \"thresholdMarkers\": true\n      },\n      \"gridPos\": {\n        \"h\":
+    4,\n        \"w\": 6,\n        \"x\": 18,\n        \"y\": 7\n      },\n      \"id\":
+    100,\n      \"interval\": null,\n      \"links\": [],\n      \"mappingType\":
+    1,\n      \"mappingTypes\": [\n        {\n          \"name\": \"value to text\",\n
+    \         \"value\": 1\n        },\n        {\n          \"name\": \"range to
+    text\",\n          \"value\": 2\n        }\n      ],\n      \"maxDataPoints\":
+    100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\": null,\n      \"postfix\":
+    \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\": \"\",\n      \"prefixFontSize\":
+    \"50%\",\n      \"rangeMaps\": [\n        {\n          \"from\": \"null\",\n          \"text\":
+    \"N/A\",\n          \"to\": \"null\"\n        }\n      ],\n      \"sparkline\":
+    {\n        \"fillColor\": \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n
+    \       \"lineColor\": \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n
+    \     \"tableColumn\": \"\",\n      \"targets\": [\n        {\n          \"expr\":
+    \"sum(irate(istio_tcp_sent_bytes_total{reporter=\\\"source\\\", destination_service=~\\\"$service\\\"}[1m]))
+    \",\n          \"format\": \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\":
+    1,\n          \"legendFormat\": \"\",\n          \"refId\": \"A\"\n        }\n
+    \     ],\n      \"thresholds\": \"\",\n      \"title\": \"TCP Sent Bytes\",\n
+    \     \"transparent\": false,\n      \"type\": \"singlestat\",\n      \"valueFontSize\":
+    \"80%\",\n      \"valueMaps\": [\n        {\n          \"op\": \"=\",\n          \"text\":
+    \"N/A\",\n          \"value\": \"null\"\n        }\n      ],\n      \"valueName\":
+    \"avg\"\n    },\n    {\n      \"content\": \"<div class=\\\"dashboard-header text-center\\\">\\n<span>CLIENT
+    WORKLOADS</span>\\n</div>\",\n      \"gridPos\": {\n        \"h\": 3,\n        \"w\":
+    24,\n        \"x\": 0,\n        \"y\": 11\n      },\n      \"id\": 45,\n      \"links\":
+    [],\n      \"mode\": \"html\",\n      \"title\": \"\",\n      \"transparent\":
+    true,\n      \"type\": \"text\"\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 0,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 12,\n        \"x\": 0,\n        \"y\": 14\n      },\n      \"id\":
+    25,\n      \"legend\": {\n        \"avg\": false,\n        \"current\": false,\n
+    \       \"hideEmpty\": true,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"show\": true,\n        \"total\": false,\n        \"values\": false\n
+    \     },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\": [],\n
+    \     \"nullPointMode\": \"null as zero\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy=\\\"mutual_tls\\\",destination_service=~\\\"$service\\\",reporter=\\\"source\\\",source_workload=~\\\"$srcwl\\\",source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace, response_code), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace }} : {{ response_code }}
+    (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", reporter=\\\"source\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[5m])) by (source_workload, source_workload_namespace,
+    response_code), 0.001)\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ source_workload
+    }}.{{ source_workload_namespace }} : {{ response_code }}\",\n          \"refId\":
+    \"A\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Incoming
+    Requests by Source And Response Code\",\n      \"tooltip\": {\n        \"shared\":
+    false,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    [\n          \"total\"\n        ]\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"ops\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n
+    \       \"x\": 12,\n        \"y\": 14\n      },\n      \"id\": 26,\n      \"legend\":
+    {\n        \"avg\": false,\n        \"current\": false,\n        \"hideEmpty\":
+    true,\n        \"hideZero\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",response_code!~\\\"5.*\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace) / sum(irate(istio_requests_total{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace)\",\n          \"format\": \"time_series\",\n
+    \         \"hide\": false,\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace }} (\U0001F510mTLS)\",\n
+    \         \"refId\": \"A\",\n          \"step\": 2\n        },\n        {\n          \"expr\":
+    \"sum(irate(istio_requests_total{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\",response_code!~\\\"5.*\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[5m])) by (source_workload, source_workload_namespace)
+    / sum(irate(istio_requests_total{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace)\",\n          \"format\": \"time_series\",\n
+    \         \"hide\": false,\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace }}\",\n          \"refId\":
+    \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Incoming
+    Success Rate (non-5xx responses) By Source\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"percentunit\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": \"1.01\",\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"description\":
+    \"\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\":
+    8,\n        \"x\": 0,\n        \"y\": 20\n      },\n      \"id\": 27,\n      \"legend\":
+    {\n        \"alignAsTable\": false,\n        \"avg\": false,\n        \"current\":
+    false,\n        \"hideEmpty\": true,\n        \"hideZero\": false,\n        \"max\":
+    false,\n        \"min\": false,\n        \"rightSide\": false,\n        \"show\":
+    true,\n        \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.50,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.90,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.95,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.99,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.50,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.90,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.95,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.99,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Request Duration by Source\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"s\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n
+    \       \"x\": 8,\n        \"y\": 20\n      },\n      \"id\": 28,\n      \"legend\":
+    {\n        \"alignAsTable\": false,\n        \"avg\": false,\n        \"current\":
+    false,\n        \"hideEmpty\": true,\n        \"max\": false,\n        \"min\":
+    false,\n        \"rightSide\": false,\n        \"show\": true,\n        \"total\":
+    false,\n        \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Request Size By Source\",\n      \"tooltip\": {\n
+    \       \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"decbytes\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n
+    \       \"x\": 16,\n        \"y\": 20\n      },\n      \"id\": 68,\n      \"legend\":
+    {\n        \"alignAsTable\": false,\n        \"avg\": false,\n        \"current\":
+    false,\n        \"hideEmpty\": true,\n        \"max\": false,\n        \"min\":
+    false,\n        \"rightSide\": false,\n        \"show\": true,\n        \"total\":
+    false,\n        \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Response Size By Source\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"decbytes\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    0,\n        \"y\": 26\n      },\n      \"id\": 80,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ source_workload }}.{{ source_workload_namespace}}
+    (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace}}\",\n          \"refId\":
+    \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Bytes
+    Received from Incoming TCP Connection\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"Bps\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 26\n      },\n      \"id\": 82,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\\\"mutual_tls\\\",
+    reporter=\\\"source\\\", destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace),
+    0.001)\",\n          \"format\": \"time_series\",\n          \"intervalFactor\":
+    1,\n          \"legendFormat\": \"{{ source_workload }}.{{ source_workload_namespace}}
+    (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\\\"mutual_tls\\\",
+    reporter=\\\"source\\\", destination_service=~\\\"$service\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace),
+    0.001)\",\n          \"format\": \"time_series\",\n          \"intervalFactor\":
+    1,\n          \"legendFormat\": \"{{ source_workload }}.{{ source_workload_namespace}}\",\n
+    \         \"refId\": \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\":
+    [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Bytes
+    Sent to Incoming TCP Connection\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"Bps\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"content\": \"<div class=\\\"dashboard-header text-center\\\">\\n<span>SERVICE
+    WORKLOADS</span>\\n</div>\",\n      \"gridPos\": {\n        \"h\": 3,\n        \"w\":
+    24,\n        \"x\": 0,\n        \"y\": 32\n      },\n      \"id\": 69,\n      \"links\":
+    [],\n      \"mode\": \"html\",\n      \"title\": \"\",\n      \"transparent\":
+    true,\n      \"type\": \"text\"\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 0,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 12,\n        \"x\": 0,\n        \"y\": 35\n      },\n      \"id\":
+    90,\n      \"legend\": {\n        \"avg\": false,\n        \"current\": false,\n
+    \       \"hideEmpty\": true,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"show\": true,\n        \"total\": false,\n        \"values\": false\n
+    \     },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\": [],\n
+    \     \"nullPointMode\": \"null as zero\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy=\\\"mutual_tls\\\",destination_service=~\\\"$service\\\",reporter=\\\"destination\\\",destination_workload=~\\\"$dstwl\\\",destination_workload_namespace=~\\\"$dstns\\\"}[5m]))
+    by (destination_workload, destination_workload_namespace, response_code), 0.001)\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ destination_workload }}.{{ destination_workload_namespace }} : {{ response_code
+    }} (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy!=\\\"mutual_tls\\\",
+    destination_service=~\\\"$service\\\", reporter=\\\"destination\\\", destination_workload=~\\\"$dstwl\\\",
+    destination_workload_namespace=~\\\"$dstns\\\"}[5m])) by (destination_workload,
+    destination_workload_namespace, response_code), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} : {{ response_code }}\",\n          \"refId\": \"A\",\n          \"step\":
+    2\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Incoming Requests by Destination
+    And Response Code\",\n      \"tooltip\": {\n        \"shared\": false,\n        \"sort\":
+    0,\n        \"value_type\": \"individual\"\n      },\n      \"type\": \"graph\",\n
+    \     \"xaxis\": {\n        \"buckets\": null,\n        \"mode\": \"time\",\n
+    \       \"name\": null,\n        \"show\": true,\n        \"values\": [\n          \"total\"\n
+    \       ]\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"ops\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 35\n      },\n      \"id\": 91,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"hideEmpty\": true,\n        \"hideZero\":
+    false,\n        \"max\": false,\n        \"min\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",response_code!~\\\"5.*\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[5m]))
+    by (destination_workload, destination_workload_namespace) / sum(irate(istio_requests_total{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[5m]))
+    by (destination_workload, destination_workload_namespace)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",response_code!~\\\"5.*\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[5m]))
+    by (destination_workload, destination_workload_namespace) / sum(irate(istio_requests_total{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[5m]))
+    by (destination_workload, destination_workload_namespace)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }}\",\n          \"refId\": \"B\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Success Rate (non-5xx responses) By Source\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"percentunit\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    \"1.01\",\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"description\": \"\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\":
+    6,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 41\n      },\n      \"id\":
+    94,\n      \"legend\": {\n        \"alignAsTable\": false,\n        \"avg\": false,\n
+    \       \"current\": false,\n        \"hideEmpty\": true,\n        \"hideZero\":
+    false,\n        \"max\": false,\n        \"min\": false,\n        \"rightSide\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"(histogram_quantile(0.50,
+    sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.50,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.90,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.95,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.99,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.50,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.90,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.95,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.99,
+    sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Request Duration by Source\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"s\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n
+    \       \"x\": 8,\n        \"y\": 41\n      },\n      \"id\": 95,\n      \"legend\":
+    {\n        \"alignAsTable\": false,\n        \"avg\": false,\n        \"current\":
+    false,\n        \"hideEmpty\": true,\n        \"max\": false,\n        \"min\":
+    false,\n        \"rightSide\": false,\n        \"show\": true,\n        \"total\":
+    false,\n        \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }}  P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\":
+    2\n        },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }}  P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\":
+    2\n        },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Request Size By Source\",\n      \"tooltip\": {\n
+    \       \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"decbytes\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 8,\n
+    \       \"x\": 16,\n        \"y\": 41\n      },\n      \"id\": 96,\n      \"legend\":
+    {\n        \"alignAsTable\": false,\n        \"avg\": false,\n        \"current\":
+    false,\n        \"hideEmpty\": true,\n        \"max\": false,\n        \"min\":
+    false,\n        \"rightSide\": false,\n        \"show\": true,\n        \"total\":
+    false,\n        \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }}  P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\":
+    2\n        },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }}  P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\":
+    2\n        },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace, le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace
+    }} P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Response Size By Source\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"decbytes\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    0,\n        \"y\": 47\n      },\n      \"id\": 92,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ destination_workload }}.{{ destination_workload_namespace}}
+    (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_service=~\\\"$service\\\",
+    destination_workload=~\\\"$dstwl\\\", destination_workload_namespace=~\\\"$dstns\\\"}[1m]))
+    by (destination_workload, destination_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ destination_workload }}.{{ destination_workload_namespace}}\",\n          \"refId\":
+    \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Bytes
+    Received from Incoming TCP Connection\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"Bps\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        }\n      ],\n
+    \     \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\": null\n
+    \     }\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 47\n      },\n      \"id\": 93,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\\\"mutual_tls\\\",
+    reporter=\\\"source\\\", destination_service=~\\\"$service\\\", destination_workload=~\\\"$dstwl\\\",
+    destination_workload_namespace=~\\\"$dstns\\\"}[1m])) by (destination_workload,
+    destination_workload_namespace), 0.001)\",\n          \"format\": \"time_series\",\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_workload
+    }}.{{destination_workload_namespace }} (\U0001F510mTLS)\",\n          \"refId\":
+    \"A\",\n          \"step\": 2\n        },\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\\\"mutual_tls\\\",
+    reporter=\\\"source\\\", destination_service=~\\\"$service\\\", destination_workload=~\\\"$dstwl\\\",
+    destination_workload_namespace=~\\\"$dstns\\\"}[1m])) by (destination_workload,
+    destination_workload_namespace), 0.001)\",\n          \"format\": \"time_series\",\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_workload
+    }}.{{destination_workload_namespace }}\",\n          \"refId\": \"B\",\n          \"step\":
+    2\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Bytes Sent to Incoming TCP Connection\",\n
+    \     \"tooltip\": {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\":
+    \"individual\"\n      },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"Bps\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": true\n
+    \       }\n      ],\n      \"yaxis\": {\n        \"align\": false,\n        \"alignLevel\":
+    null\n      }\n    }\n  ],\n  \"refresh\": \"10s\",\n  \"schemaVersion\": 16,\n
+    \ \"style\": \"dark\",\n  \"tags\": [],\n  \"templating\": {\n    \"list\": [\n
+    \     {\n        \"allValue\": null,\n        \"datasource\": \"Prometheus\",\n
+    \       \"hide\": 0,\n        \"includeAll\": false,\n        \"label\": \"Service\",\n
+    \       \"multi\": false,\n        \"name\": \"service\",\n        \"options\":
+    [],\n        \"query\": \"label_values(destination_service)\",\n        \"refresh\":
+    1,\n        \"regex\": \"\",\n        \"sort\": 0,\n        \"tagValuesQuery\":
+    \"\",\n        \"tags\": [],\n        \"tagsQuery\": \"\",\n        \"type\":
+    \"query\",\n        \"useTags\": false\n      },\n      {\n        \"allValue\":
+    null,\n        \"current\": {\n          \"text\": \"All\",\n          \"value\":
+    \"$__all\"\n        },\n        \"datasource\": \"Prometheus\",\n        \"hide\":
+    0,\n        \"includeAll\": true,\n        \"label\": \"Client Workload Namespace\",\n
+    \       \"multi\": true,\n        \"name\": \"srcns\",\n        \"options\": [],\n
+    \       \"query\": \"query_result( sum(istio_requests_total{reporter=\\\"destination\\\",
+    destination_service=\\\"$service\\\"}) by (source_workload_namespace) or sum(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\",
+    destination_service=~\\\"$service\\\"}) by (source_workload_namespace))\",\n        \"refresh\":
+    1,\n        \"regex\": \"/.*namespace=\\\"([^\\\"]*).*/\",\n        \"sort\":
+    2,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n        \"tagsQuery\":
+    \"\",\n        \"type\": \"query\",\n        \"useTags\": false\n      },\n      {\n
+    \       \"allValue\": null,\n        \"current\": {\n          \"text\": \"All\",\n
+    \         \"value\": \"$__all\"\n        },\n        \"datasource\": \"Prometheus\",\n
+    \       \"hide\": 0,\n        \"includeAll\": true,\n        \"label\": \"Client
+    Workload\",\n        \"multi\": true,\n        \"name\": \"srcwl\",\n        \"options\":
+    [],\n        \"query\": \"query_result( sum(istio_requests_total{reporter=\\\"destination\\\",
+    destination_service=~\\\"$service\\\", source_workload_namespace=~\\\"$srcns\\\"})
+    by (source_workload) or sum(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\",
+    destination_service=~\\\"$service\\\", source_workload_namespace=~\\\"$srcns\\\"})
+    by (source_workload))\",\n        \"refresh\": 1,\n        \"regex\": \"/.*workload=\\\"([^\\\"]*).*/\",\n
+    \       \"sort\": 3,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n
+    \       \"tagsQuery\": \"\",\n        \"type\": \"query\",\n        \"useTags\":
+    false\n      },\n      {\n        \"allValue\": null,\n        \"current\": {\n
+    \         \"text\": \"All\",\n          \"value\": \"$__all\"\n        },\n        \"datasource\":
+    \"Prometheus\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"label\":
+    \"Service Workload Namespace\",\n        \"multi\": true,\n        \"name\": \"dstns\",\n
+    \       \"options\": [],\n        \"query\": \"query_result( sum(istio_requests_total{reporter=\\\"destination\\\",
+    destination_service=\\\"$service\\\"}) by (destination_workload_namespace) or
+    sum(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\", destination_service=~\\\"$service\\\"})
+    by (destination_workload_namespace))\",\n        \"refresh\": 1,\n        \"regex\":
+    \"/.*namespace=\\\"([^\\\"]*).*/\",\n        \"sort\": 2,\n        \"tagValuesQuery\":
+    \"\",\n        \"tags\": [],\n        \"tagsQuery\": \"\",\n        \"type\":
+    \"query\",\n        \"useTags\": false\n      },\n      {\n        \"allValue\":
+    null,\n        \"current\": {\n          \"text\": \"All\",\n          \"value\":
+    \"$__all\"\n        },\n        \"datasource\": \"Prometheus\",\n        \"hide\":
+    0,\n        \"includeAll\": true,\n        \"label\": \"Service Workload\",\n
+    \       \"multi\": true,\n        \"name\": \"dstwl\",\n        \"options\": [],\n
+    \       \"query\": \"query_result( sum(istio_requests_total{reporter=\\\"destination\\\",
+    destination_service=~\\\"$service\\\", destination_workload_namespace=~\\\"$dstns\\\"})
+    by (destination_workload) or sum(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\",
+    destination_service=~\\\"$service\\\", destination_workload_namespace=~\\\"$dstns\\\"})
+    by (destination_workload))\",\n        \"refresh\": 1,\n        \"regex\": \"/.*workload=\\\"([^\\\"]*).*/\",\n
+    \       \"sort\": 3,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n
+    \       \"tagsQuery\": \"\",\n        \"type\": \"query\",\n        \"useTags\":
+    false\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-5m\",\n    \"to\":
+    \"now\"\n  },\n  \"timepicker\": {\n    \"refresh_intervals\": [\n      \"5s\",\n
+    \     \"10s\",\n      \"30s\",\n      \"1m\",\n      \"5m\",\n      \"15m\",\n
+    \     \"30m\",\n      \"1h\",\n      \"2h\",\n      \"1d\"\n    ],\n    \"time_options\":
+    [\n      \"5m\",\n      \"15m\",\n      \"1h\",\n      \"6h\",\n      \"12h\",\n
+    \     \"24h\",\n      \"2d\",\n      \"7d\",\n      \"30d\"\n    ]\n  },\n  \"timezone\":
+    \"\",\n  \"title\": \"Istio Service Dashboard\",\n  \"uid\": \"LJ_uJAvmk\",\n
+    \ \"version\": 1\n}\n"
+  istio-workload-dashboard.json: "{\n  \"__inputs\": [\n    {\n      \"name\": \"DS_PROMETHEUS\",\n
+    \     \"label\": \"Prometheus\",\n      \"description\": \"\",\n      \"type\":
+    \"datasource\",\n      \"pluginId\": \"prometheus\",\n      \"pluginName\": \"Prometheus\"\n
+    \   }\n  ],\n  \"__requires\": [\n    {\n      \"type\": \"grafana\",\n      \"id\":
+    \"grafana\",\n      \"name\": \"Grafana\",\n      \"version\": \"5.0.4\"\n    },\n
+    \   {\n      \"type\": \"panel\",\n      \"id\": \"graph\",\n      \"name\": \"Graph\",\n
+    \     \"version\": \"5.0.0\"\n    },\n    {\n      \"type\": \"datasource\",\n
+    \     \"id\": \"prometheus\",\n      \"name\": \"Prometheus\",\n      \"version\":
+    \"5.0.0\"\n    },\n    {\n      \"type\": \"panel\",\n      \"id\": \"singlestat\",\n
+    \     \"name\": \"Singlestat\",\n      \"version\": \"5.0.0\"\n    },\n    {\n
+    \     \"type\": \"panel\",\n      \"id\": \"text\",\n      \"name\": \"Text\",\n
+    \     \"version\": \"5.0.0\"\n    }\n  ],\n  \"annotations\": {\n    \"list\":
+    [\n      {\n        \"builtIn\": 1,\n        \"datasource\": \"-- Grafana --\",\n
+    \       \"enable\": true,\n        \"hide\": true,\n        \"iconColor\": \"rgba(0,
+    211, 255, 1)\",\n        \"name\": \"Annotations & Alerts\",\n        \"type\":
+    \"dashboard\"\n      }\n    ]\n  },\n  \"editable\": false,\n  \"gnetId\": null,\n
+    \ \"graphTooltip\": 0,\n  \"id\": null,\n  \"iteration\": 1531345461465,\n  \"links\":
+    [],\n  \"panels\": [\n    {\n      \"content\": \"<div class=\\\"dashboard-header
+    text-center\\\">\\n<span>WORKLOAD: $workload.$namespace</span>\\n</div>\",\n      \"gridPos\":
+    {\n        \"h\": 3,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n
+    \     },\n      \"id\": 89,\n      \"links\": [],\n      \"mode\": \"html\",\n
+    \     \"title\": \"\",\n      \"transparent\": true,\n      \"type\": \"text\"\n
+    \   },\n    {\n      \"cacheTimeout\": null,\n      \"colorBackground\": false,\n
+    \     \"colorValue\": false,\n      \"colors\": [\n        \"rgba(245, 54, 54,
+    0.9)\",\n        \"rgba(237, 129, 40, 0.89)\",\n        \"rgba(50, 172, 45, 0.97)\"\n
+    \     ],\n      \"datasource\": \"Prometheus\",\n      \"format\": \"ops\",\n
+    \     \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\": 0,\n        \"show\":
+    false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\": true\n
+    \     },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 8,\n        \"x\":
+    0,\n        \"y\": 3\n      },\n      \"id\": 12,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{reporter=\\\"destination\\\",destination_workload_namespace=~\\\"$namespace\\\",destination_workload=~\\\"$workload\\\"}[5m])),
+    0.001)\",\n          \"format\": \"time_series\",\n          \"intervalFactor\":
+    1,\n          \"refId\": \"A\",\n          \"step\": 4\n        }\n      ],\n
+    \     \"thresholds\": \"\",\n      \"title\": \"Incoming Request Volume\",\n      \"transparent\":
+    false,\n      \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"current\"\n    },\n    {\n
+    \     \"cacheTimeout\": null,\n      \"colorBackground\": false,\n      \"colorValue\":
+    false,\n      \"colors\": [\n        \"rgba(50, 172, 45, 0.97)\",\n        \"rgba(237,
+    129, 40, 0.89)\",\n        \"rgba(245, 54, 54, 0.9)\"\n      ],\n      \"datasource\":
+    \"Prometheus\",\n      \"decimals\": null,\n      \"format\": \"percentunit\",\n
+    \     \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\": 80,\n        \"show\":
+    false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\": false\n
+    \     },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 8,\n        \"x\":
+    8,\n        \"y\": 3\n      },\n      \"id\": 14,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"destination\\\",destination_workload_namespace=~\\\"$namespace\\\",destination_workload=~\\\"$workload\\\",response_code!~\\\"5.*\\\"}[5m]))
+    / sum(irate(istio_requests_total{reporter=\\\"destination\\\",destination_workload_namespace=~\\\"$namespace\\\",destination_workload=~\\\"$workload\\\"}[5m]))\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"refId\":
+    \"B\"\n        }\n      ],\n      \"thresholds\": \"95, 99, 99.5\",\n      \"title\":
+    \"Incoming Success Rate (non-5xx responses)\",\n      \"transparent\": false,\n
+    \     \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"avg\"\n    },\n    {\n      \"aliasColors\":
+    {},\n      \"bars\": false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n
+    \     \"datasource\": \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\":
+    {\n        \"h\": 4,\n        \"w\": 8,\n        \"x\": 16,\n        \"y\": 3\n
+    \     },\n      \"id\": 87,\n      \"legend\": {\n        \"alignAsTable\": false,\n
+    \       \"avg\": false,\n        \"current\": false,\n        \"hideEmpty\": false,\n
+    \       \"hideZero\": false,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"rightSide\": true,\n        \"show\": true,\n        \"total\": false,\n
+    \       \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le)) / 1000) or
+    histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le))\",\n          \"format\":
+    \"time_series\",\n          \"interval\": \"\",\n          \"intervalFactor\":
+    1,\n          \"legendFormat\": \"P50\",\n          \"refId\": \"A\"\n        },\n
+    \       {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le)) / 1000) or
+    histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"P90\",\n          \"refId\": \"B\"\n        },\n
+    \       {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le)) / 1000) or
+    histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}[1m])) by (le))\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"P99\",\n          \"refId\": \"C\"\n        }\n
+    \     ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\":
+    null,\n      \"title\": \"Request Duration\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"s\",\n          \"label\":
+    null,\n          \"logBase\": 1,\n          \"max\": null,\n          \"min\":
+    null,\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ]\n
+    \   },\n    {\n      \"cacheTimeout\": null,\n      \"colorBackground\": false,\n
+    \     \"colorValue\": false,\n      \"colors\": [\n        \"#299c46\",\n        \"rgba(237,
+    129, 40, 0.89)\",\n        \"#d44a3a\"\n      ],\n      \"datasource\": \"Prometheus\",\n
+    \     \"format\": \"Bps\",\n      \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\":
+    0,\n        \"show\": false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\":
+    true\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 12,\n
+    \       \"x\": 0,\n        \"y\": 7\n      },\n      \"id\": 84,\n      \"interval\":
+    null,\n      \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\":
+    [\n        {\n          \"name\": \"value to text\",\n          \"value\": 1\n
+    \       },\n        {\n          \"name\": \"range to text\",\n          \"value\":
+    2\n        }\n      ],\n      \"maxDataPoints\": 100,\n      \"nullPointMode\":
+    \"connected\",\n      \"nullText\": null,\n      \"postfix\": \"\",\n      \"postfixFontSize\":
+    \"50%\",\n      \"prefix\": \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\":
+    [\n        {\n          \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"sum(irate(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\"}[1m]))
+    + sum(irate(istio_tcp_received_bytes_total{reporter=\\\"destination\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\"}[1m]))\",\n          \"format\": \"time_series\",\n
+    \         \"hide\": false,\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"thresholds\":
+    \"\",\n      \"title\": \"TCP Server Traffic\",\n      \"transparent\": false,\n
+    \     \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"avg\"\n    },\n    {\n      \"cacheTimeout\":
+    null,\n      \"colorBackground\": false,\n      \"colorValue\": false,\n      \"colors\":
+    [\n        \"#299c46\",\n        \"rgba(237, 129, 40, 0.89)\",\n        \"#d44a3a\"\n
+    \     ],\n      \"datasource\": \"Prometheus\",\n      \"format\": \"Bps\",\n
+    \     \"gauge\": {\n        \"maxValue\": 100,\n        \"minValue\": 0,\n        \"show\":
+    false,\n        \"thresholdLabels\": false,\n        \"thresholdMarkers\": true\n
+    \     },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 7\n      },\n      \"id\": 85,\n      \"interval\": null,\n
+    \     \"links\": [],\n      \"mappingType\": 1,\n      \"mappingTypes\": [\n        {\n
+    \         \"name\": \"value to text\",\n          \"value\": 1\n        },\n        {\n
+    \         \"name\": \"range to text\",\n          \"value\": 2\n        }\n      ],\n
+    \     \"maxDataPoints\": 100,\n      \"nullPointMode\": \"connected\",\n      \"nullText\":
+    null,\n      \"postfix\": \"\",\n      \"postfixFontSize\": \"50%\",\n      \"prefix\":
+    \"\",\n      \"prefixFontSize\": \"50%\",\n      \"rangeMaps\": [\n        {\n
+    \         \"from\": \"null\",\n          \"text\": \"N/A\",\n          \"to\":
+    \"null\"\n        }\n      ],\n      \"sparkline\": {\n        \"fillColor\":
+    \"rgba(31, 118, 189, 0.18)\",\n        \"full\": true,\n        \"lineColor\":
+    \"rgb(31, 120, 193)\",\n        \"show\": true\n      },\n      \"tableColumn\":
+    \"\",\n      \"targets\": [\n        {\n          \"expr\": \"sum(irate(istio_tcp_sent_bytes_total{reporter=\\\"source\\\",
+    source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\"}[1m]))
+    + sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\", source_workload_namespace=~\\\"$namespace\\\",
+    source_workload=~\\\"$workload\\\"}[1m]))\",\n          \"format\": \"time_series\",\n
+    \         \"hide\": false,\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"thresholds\":
+    \"\",\n      \"title\": \"TCP Client Traffic\",\n      \"transparent\": false,\n
+    \     \"type\": \"singlestat\",\n      \"valueFontSize\": \"80%\",\n      \"valueMaps\":
+    [\n        {\n          \"op\": \"=\",\n          \"text\": \"N/A\",\n          \"value\":
+    \"null\"\n        }\n      ],\n      \"valueName\": \"avg\"\n    },\n    {\n      \"content\":
+    \"<div class=\\\"dashboard-header text-center\\\">\\n<span>INBOUND WORKLOADS</span>\\n</div>\",\n
+    \     \"gridPos\": {\n        \"h\": 3,\n        \"w\": 24,\n        \"x\": 0,\n
+    \       \"y\": 11\n      },\n      \"id\": 45,\n      \"links\": [],\n      \"mode\":
+    \"html\",\n      \"title\": \"\",\n      \"transparent\": true,\n      \"type\":
+    \"text\"\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n
+    \     \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n
+    \     \"fill\": 0,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n
+    \       \"x\": 0,\n        \"y\": 14\n      },\n      \"id\": 25,\n      \"legend\":
+    {\n        \"avg\": false,\n        \"current\": false,\n        \"hideEmpty\":
+    true,\n        \"max\": false,\n        \"min\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null as zero\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy=\\\"mutual_tls\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\",
+    reporter=\\\"destination\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace, response_code), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace }} : {{ response_code }}
+    (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy!=\\\"mutual_tls\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\",
+    reporter=\\\"destination\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace, response_code), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ source_workload }}.{{ source_workload_namespace
+    }} : {{ response_code }}\",\n          \"refId\": \"A\",\n          \"step\":
+    2\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Incoming Requests by Source And
+    Response Code\",\n      \"tooltip\": {\n        \"shared\": false,\n        \"sort\":
+    0,\n        \"value_type\": \"individual\"\n      },\n      \"type\": \"graph\",\n
+    \     \"xaxis\": {\n        \"buckets\": null,\n        \"mode\": \"time\",\n
+    \       \"name\": null,\n        \"show\": true,\n        \"values\": [\n          \"total\"\n
+    \       ]\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"ops\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ]\n
+    \   },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 14\n      },\n      \"id\": 26,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"hideEmpty\": true,\n        \"hideZero\":
+    false,\n        \"max\": false,\n        \"min\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\",response_code!~\\\"5.*\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[5m])) by (source_workload, source_workload_namespace)
+    / sum(irate(istio_requests_total{reporter=\\\"destination\\\", connection_security_policy=\\\"mutual_tls\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace)\",\n          \"format\": \"time_series\",\n
+    \         \"hide\": false,\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace }} (\U0001F510mTLS)\",\n
+    \         \"refId\": \"A\",\n          \"step\": 2\n        },\n        {\n          \"expr\":
+    \"sum(irate(istio_requests_total{reporter=\\\"destination\\\", connection_security_policy!=\\\"mutual_tls\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", destination_workload=~\\\"$workload\\\",response_code!~\\\"5.*\\\",
+    source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace) / sum(irate(istio_requests_total{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[5m]))
+    by (source_workload, source_workload_namespace)\",\n          \"format\": \"time_series\",\n
+    \         \"hide\": false,\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace }}\",\n          \"refId\":
+    \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Incoming
+    Success Rate (non-5xx responses) By Source\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"percentunit\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": \"1.01\",\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ]\n
+    \   },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"description\":
+    \"\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\":
+    8,\n        \"x\": 0,\n        \"y\": 20\n      },\n      \"id\": 27,\n      \"legend\":
+    {\n        \"alignAsTable\": false,\n        \"avg\": false,\n        \"current\":
+    false,\n        \"hideEmpty\": true,\n        \"hideZero\": false,\n        \"max\":
+    false,\n        \"min\": false,\n        \"rightSide\": false,\n        \"show\":
+    true,\n        \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Request Duration by Source\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"s\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ]\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 8,\n        \"x\": 8,\n        \"y\": 20\n      },\n      \"id\":
+    28,\n      \"legend\": {\n        \"alignAsTable\": false,\n        \"avg\": false,\n
+    \       \"current\": false,\n        \"hideEmpty\": true,\n        \"max\": false,\n
+    \       \"min\": false,\n        \"rightSide\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Incoming Request Size By Source\",\n      \"tooltip\": {\n
+    \       \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"decbytes\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ]\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 8,\n        \"x\": 16,\n        \"y\": 20\n      },\n      \"id\":
+    68,\n      \"legend\": {\n        \"alignAsTable\": false,\n        \"avg\": false,\n
+    \       \"current\": false,\n        \"hideEmpty\": true,\n        \"max\": false,\n
+    \       \"min\": false,\n        \"rightSide\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    \ P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload=~\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$srcwl\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}[1m])) by (source_workload, source_workload_namespace,
+    le))\",\n          \"format\": \"time_series\",\n          \"hide\": false,\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{source_workload}}.{{source_workload_namespace}}
+    P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Response Size By Source\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"decbytes\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ]\n
+    \   },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    0,\n        \"y\": 26\n      },\n      \"id\": 80,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"destination\\\",
+    connection_security_policy=\\\"mutual_tls\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"hide\": false,\n          \"intervalFactor\": 1,\n
+    \         \"legendFormat\": \"{{ source_workload }}.{{ source_workload_namespace}}
+    (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"destination\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace}}\",\n          \"refId\":
+    \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Bytes
+    Received from Incoming TCP Connection\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"Bps\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        }\n      ]\n
+    \   },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 26\n      },\n      \"id\": 82,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\\\"mutual_tls\\\",
+    reporter=\\\"destination\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace}} (\U0001F510mTLS)\",\n          \"refId\":
+    \"A\",\n          \"step\": 2\n        },\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\\\"mutual_tls\\\",
+    reporter=\\\"destination\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    destination_workload=~\\\"$workload\\\", source_workload=~\\\"$srcwl\\\", source_workload_namespace=~\\\"$srcns\\\"}[1m]))
+    by (source_workload, source_workload_namespace), 0.001)\",\n          \"format\":
+    \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ source_workload }}.{{ source_workload_namespace}}\",\n          \"refId\":
+    \"B\",\n          \"step\": 2\n        }\n      ],\n      \"thresholds\": [],\n
+    \     \"timeFrom\": null,\n      \"timeShift\": null,\n      \"title\": \"Bytes
+    Sent to Incoming TCP Connection\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"Bps\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": true\n        }\n      ]\n
+    \   },\n    {\n      \"content\": \"<div class=\\\"dashboard-header text-center\\\">\\n<span>OUTBOUND
+    SERVICES</span>\\n</div>\",\n      \"gridPos\": {\n        \"h\": 3,\n        \"w\":
+    24,\n        \"x\": 0,\n        \"y\": 32\n      },\n      \"id\": 69,\n      \"links\":
+    [],\n      \"mode\": \"html\",\n      \"title\": \"\",\n      \"transparent\":
+    true,\n      \"type\": \"text\"\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 0,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 12,\n        \"x\": 0,\n        \"y\": 35\n      },\n      \"id\":
+    70,\n      \"legend\": {\n        \"avg\": false,\n        \"current\": false,\n
+    \       \"hideEmpty\": true,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"show\": true,\n        \"total\": false,\n        \"values\": false\n
+    \     },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\": [],\n
+    \     \"nullPointMode\": \"null as zero\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy=\\\"mutual_tls\\\",
+    source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\",
+    reporter=\\\"source\\\", destination_service=~\\\"$dstsvc\\\"}[5m])) by (destination_service,
+    response_code), 0.001)\",\n          \"format\": \"time_series\",\n          \"intervalFactor\":
+    1,\n          \"legendFormat\": \"{{ destination_service }} : {{ response_code
+    }} (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"round(sum(irate(istio_requests_total{connection_security_policy!=\\\"mutual_tls\\\",
+    source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\",
+    reporter=\\\"source\\\", destination_service=~\\\"$dstsvc\\\"}[5m])) by (destination_service,
+    response_code), 0.001)\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} : {{ response_code }}\",\n          \"refId\": \"A\",\n          \"step\":
+    2\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Outgoing Requests by Destination
+    And Response Code\",\n      \"tooltip\": {\n        \"shared\": false,\n        \"sort\":
+    0,\n        \"value_type\": \"individual\"\n      },\n      \"type\": \"graph\",\n
+    \     \"xaxis\": {\n        \"buckets\": null,\n        \"mode\": \"time\",\n
+    \       \"name\": null,\n        \"show\": true,\n        \"values\": [\n          \"total\"\n
+    \       ]\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"ops\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ]\n
+    \   },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    12,\n        \"y\": 35\n      },\n      \"id\": 71,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"hideEmpty\": true,\n        \"hideZero\":
+    false,\n        \"max\": false,\n        \"min\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\",
+    source_workload=~\\\"$workload\\\",response_code!~\\\"5.*\\\", destination_service=~\\\"$dstsvc\\\"}[5m]))
+    by (destination_service) / sum(irate(istio_requests_total{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\",
+    source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[5m]))
+    by (destination_service)\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n        },\n
+    \       {\n          \"expr\": \"sum(irate(istio_requests_total{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\",
+    source_workload=~\\\"$workload\\\",response_code!~\\\"5.*\\\", destination_service=~\\\"$dstsvc\\\"}[5m]))
+    by (destination_service) / sum(irate(istio_requests_total{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\",
+    source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[5m]))
+    by (destination_service)\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{destination_service
+    }}\",\n          \"refId\": \"B\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Outgoing Success Rate (non-5xx responses) By Destination\",\n
+    \     \"tooltip\": {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\":
+    \"individual\"\n      },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"percentunit\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    \"1.01\",\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ]\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"description\": \"\",\n      \"fill\": 1,\n      \"gridPos\":
+    {\n        \"h\": 6,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 41\n
+    \     },\n      \"id\": 72,\n      \"legend\": {\n        \"alignAsTable\": false,\n
+    \       \"avg\": false,\n        \"current\": false,\n        \"hideEmpty\": true,\n
+    \       \"hideZero\": false,\n        \"max\": false,\n        \"min\": false,\n
+    \       \"rightSide\": false,\n        \"show\": true,\n        \"total\": false,\n
+    \       \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Outgoing Request Duration by Destination\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"s\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ]\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 8,\n        \"x\": 8,\n        \"y\": 41\n      },\n      \"id\":
+    73,\n      \"legend\": {\n        \"alignAsTable\": false,\n        \"avg\": false,\n
+    \       \"current\": false,\n        \"hideEmpty\": true,\n        \"max\": false,\n
+    \       \"min\": false,\n        \"rightSide\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Outgoing Request Size By Destination\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"decbytes\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": false\n
+    \       }\n      ]\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 8,\n        \"x\": 16,\n        \"y\": 41\n      },\n      \"id\":
+    74,\n      \"legend\": {\n        \"alignAsTable\": false,\n        \"avg\": false,\n
+    \       \"current\": false,\n        \"hideEmpty\": true,\n        \"max\": false,\n
+    \       \"min\": false,\n        \"rightSide\": false,\n        \"show\": true,\n
+    \       \"total\": false,\n        \"values\": false\n      },\n      \"lines\":
+    true,\n      \"linewidth\": 1,\n      \"links\": [],\n      \"nullPointMode\":
+    \"null\",\n      \"percentage\": false,\n      \"pointradius\": 5,\n      \"points\":
+    false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\":
+    10,\n      \"stack\": false,\n      \"steppedLine\": false,\n      \"targets\":
+    [\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P50 (\U0001F510mTLS)\",\n          \"refId\": \"D\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P90 (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P95 (\U0001F510mTLS)\",\n          \"refId\": \"B\",\n          \"step\": 2\n
+    \       },\n        {\n          \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }}  P99 (\U0001F510mTLS)\",\n          \"refId\": \"C\",\n          \"step\":
+    2\n        },\n        {\n          \"expr\": \"histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P50\",\n          \"refId\": \"E\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P90\",\n          \"refId\": \"F\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P95\",\n          \"refId\": \"G\",\n          \"step\": 2\n        },\n        {\n
+    \         \"expr\": \"histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload=~\\\"$workload\\\",
+    source_workload_namespace=~\\\"$namespace\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service, le))\",\n          \"format\": \"time_series\",\n          \"hide\":
+    false,\n          \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }} P99\",\n          \"refId\": \"H\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Response Size By Destination\",\n      \"tooltip\": {\n        \"shared\":
+    true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n      },\n
+    \     \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\": null,\n        \"mode\":
+    \"time\",\n        \"name\": null,\n        \"show\": true,\n        \"values\":
+    []\n      },\n      \"yaxes\": [\n        {\n          \"format\": \"decbytes\",\n
+    \         \"label\": null,\n          \"logBase\": 1,\n          \"max\": null,\n
+    \         \"min\": \"0\",\n          \"show\": true\n        },\n        {\n          \"format\":
+    \"short\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": null,\n          \"show\": false\n        }\n      ]\n
+    \   },\n    {\n      \"aliasColors\": {},\n      \"bars\": false,\n      \"dashLength\":
+    10,\n      \"dashes\": false,\n      \"datasource\": \"Prometheus\",\n      \"fill\":
+    1,\n      \"gridPos\": {\n        \"h\": 6,\n        \"w\": 12,\n        \"x\":
+    0,\n        \"y\": 47\n      },\n      \"id\": 76,\n      \"legend\": {\n        \"avg\":
+    false,\n        \"current\": false,\n        \"max\": false,\n        \"min\":
+    false,\n        \"show\": true,\n        \"total\": false,\n        \"values\":
+    false\n      },\n      \"lines\": true,\n      \"linewidth\": 1,\n      \"links\":
+    [],\n      \"nullPointMode\": \"null\",\n      \"percentage\": false,\n      \"pointradius\":
+    5,\n      \"points\": false,\n      \"renderer\": \"flot\",\n      \"seriesOverrides\":
+    [],\n      \"spaceLength\": 10,\n      \"stack\": false,\n      \"steppedLine\":
+    false,\n      \"targets\": [\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\\\"mutual_tls\\\",
+    reporter=\\\"source\\\", source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\",
+    destination_service=~\\\"$dstsvc\\\"}[1m])) by (destination_service), 0.001)\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ destination_service }} (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n
+    \         \"step\": 2\n        },\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\\\"mutual_tls\\\",
+    reporter=\\\"source\\\", source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\",
+    destination_service=~\\\"$dstsvc\\\"}[1m])) by (destination_service), 0.001)\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ destination_service }}\",\n          \"refId\": \"B\",\n          \"step\":
+    2\n        }\n      ],\n      \"thresholds\": [],\n      \"timeFrom\": null,\n
+    \     \"timeShift\": null,\n      \"title\": \"Bytes Sent on Outgoing TCP Connection\",\n
+    \     \"tooltip\": {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\":
+    \"individual\"\n      },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"Bps\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": true\n
+    \       }\n      ]\n    },\n    {\n      \"aliasColors\": {},\n      \"bars\":
+    false,\n      \"dashLength\": 10,\n      \"dashes\": false,\n      \"datasource\":
+    \"Prometheus\",\n      \"fill\": 1,\n      \"gridPos\": {\n        \"h\": 6,\n
+    \       \"w\": 12,\n        \"x\": 12,\n        \"y\": 47\n      },\n      \"id\":
+    78,\n      \"legend\": {\n        \"avg\": false,\n        \"current\": false,\n
+    \       \"max\": false,\n        \"min\": false,\n        \"show\": true,\n        \"total\":
+    false,\n        \"values\": false\n      },\n      \"lines\": true,\n      \"linewidth\":
+    1,\n      \"links\": [],\n      \"nullPointMode\": \"null\",\n      \"percentage\":
+    false,\n      \"pointradius\": 5,\n      \"points\": false,\n      \"renderer\":
+    \"flot\",\n      \"seriesOverrides\": [],\n      \"spaceLength\": 10,\n      \"stack\":
+    false,\n      \"steppedLine\": false,\n      \"targets\": [\n        {\n          \"expr\":
+    \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\", connection_security_policy=\\\"mutual_tls\\\",
+    source_workload_namespace=~\\\"$namespace\\\", source_workload=~\\\"$workload\\\",
+    destination_service=~\\\"$dstsvc\\\"}[1m])) by (destination_service), 0.001)\",\n
+    \         \"format\": \"time_series\",\n          \"intervalFactor\": 1,\n          \"legendFormat\":
+    \"{{ destination_service }} (\U0001F510mTLS)\",\n          \"refId\": \"A\",\n
+    \         \"step\": 2\n        },\n        {\n          \"expr\": \"round(sum(irate(istio_tcp_received_bytes_total{reporter=\\\"source\\\",
+    connection_security_policy!=\\\"mutual_tls\\\", source_workload_namespace=~\\\"$namespace\\\",
+    source_workload=~\\\"$workload\\\", destination_service=~\\\"$dstsvc\\\"}[1m]))
+    by (destination_service), 0.001)\",\n          \"format\": \"time_series\",\n
+    \         \"intervalFactor\": 1,\n          \"legendFormat\": \"{{ destination_service
+    }}\",\n          \"refId\": \"B\",\n          \"step\": 2\n        }\n      ],\n
+    \     \"thresholds\": [],\n      \"timeFrom\": null,\n      \"timeShift\": null,\n
+    \     \"title\": \"Bytes Received from Outgoing TCP Connection\",\n      \"tooltip\":
+    {\n        \"shared\": true,\n        \"sort\": 0,\n        \"value_type\": \"individual\"\n
+    \     },\n      \"type\": \"graph\",\n      \"xaxis\": {\n        \"buckets\":
+    null,\n        \"mode\": \"time\",\n        \"name\": null,\n        \"show\":
+    true,\n        \"values\": []\n      },\n      \"yaxes\": [\n        {\n          \"format\":
+    \"Bps\",\n          \"label\": null,\n          \"logBase\": 1,\n          \"max\":
+    null,\n          \"min\": \"0\",\n          \"show\": true\n        },\n        {\n
+    \         \"format\": \"short\",\n          \"label\": null,\n          \"logBase\":
+    1,\n          \"max\": null,\n          \"min\": null,\n          \"show\": true\n
+    \       }\n      ]\n    }\n  ],\n  \"refresh\": \"10s\",\n  \"schemaVersion\":
+    16,\n  \"style\": \"dark\",\n  \"tags\": [],\n  \"templating\": {\n    \"list\":
+    [\n      {\n        \"allValue\": null,\n        \"current\": {},\n        \"datasource\":
+    \"Prometheus\",\n        \"hide\": 0,\n        \"includeAll\": false,\n        \"label\":
+    \"Namespace\",\n        \"multi\": false,\n        \"name\": \"namespace\",\n
+    \       \"options\": [],\n        \"query\": \"query_result(sum(istio_requests_total)
+    by (destination_workload_namespace) or sum(istio_tcp_sent_bytes_total) by (destination_workload_namespace))\",\n
+    \       \"refresh\": 1,\n        \"regex\": \"/.*_namespace=\\\"([^\\\"]*).*/\",\n
+    \       \"sort\": 0,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n
+    \       \"tagsQuery\": \"\",\n        \"type\": \"query\",\n        \"useTags\":
+    false\n      },\n      {\n        \"allValue\": null,\n        \"current\": {},\n
+    \       \"datasource\": \"Prometheus\",\n        \"hide\": 0,\n        \"includeAll\":
+    false,\n        \"label\": \"Workload\",\n        \"multi\": false,\n        \"name\":
+    \"workload\",\n        \"options\": [],\n        \"query\": \"query_result((sum(istio_requests_total{destination_workload_namespace=~\\\"$namespace\\\"})
+    by (destination_workload) or sum(istio_requests_total{source_workload_namespace=~\\\"$namespace\\\"})
+    by (source_workload)) or (sum(istio_tcp_sent_bytes_total{destination_workload_namespace=~\\\"$namespace\\\"})
+    by (destination_workload) or sum(istio_tcp_sent_bytes_total{source_workload_namespace=~\\\"$namespace\\\"})
+    by (source_workload)))\",\n        \"refresh\": 1,\n        \"regex\": \"/.*workload=\\\"([^\\\"]*).*/\",\n
+    \       \"sort\": 1,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n
+    \       \"tagsQuery\": \"\",\n        \"type\": \"query\",\n        \"useTags\":
+    false\n      },\n      {\n        \"allValue\": null,\n        \"current\": {},\n
+    \       \"datasource\": \"Prometheus\",\n        \"hide\": 0,\n        \"includeAll\":
+    true,\n        \"label\": \"Inbound Workload Namespace\",\n        \"multi\":
+    true,\n        \"name\": \"srcns\",\n        \"options\": [],\n        \"query\":
+    \"query_result( sum(istio_requests_total{reporter=\\\"destination\\\", destination_workload=\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}) by (source_workload_namespace)
+    or sum(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\", destination_workload=\\\"$workload\\\",
+    destination_workload_namespace=~\\\"$namespace\\\"}) by (source_workload_namespace))\",\n
+    \       \"refresh\": 1,\n        \"regex\": \"/.*namespace=\\\"([^\\\"]*).*/\",\n
+    \       \"sort\": 2,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n
+    \       \"tagsQuery\": \"\",\n        \"type\": \"query\",\n        \"useTags\":
+    false\n      },\n      {\n        \"allValue\": null,\n        \"current\": {},\n
+    \       \"datasource\": \"Prometheus\",\n        \"hide\": 0,\n        \"includeAll\":
+    true,\n        \"label\": \"Inbound Workload\",\n        \"multi\": true,\n        \"name\":
+    \"srcwl\",\n        \"options\": [],\n        \"query\": \"query_result( sum(istio_requests_total{reporter=\\\"destination\\\",
+    destination_workload=\\\"$workload\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}) by (source_workload) or sum(istio_tcp_sent_bytes_total{reporter=\\\"destination\\\",
+    destination_workload=\\\"$workload\\\", destination_workload_namespace=~\\\"$namespace\\\",
+    source_workload_namespace=~\\\"$srcns\\\"}) by (source_workload))\",\n        \"refresh\":
+    1,\n        \"regex\": \"/.*workload=\\\"([^\\\"]*).*/\",\n        \"sort\": 3,\n
+    \       \"tagValuesQuery\": \"\",\n        \"tags\": [],\n        \"tagsQuery\":
+    \"\",\n        \"type\": \"query\",\n        \"useTags\": false\n      },\n      {\n
+    \       \"allValue\": null,\n        \"current\": {},\n        \"datasource\":
+    \"Prometheus\",\n        \"hide\": 0,\n        \"includeAll\": true,\n        \"label\":
+    \"Destination Service\",\n        \"multi\": true,\n        \"name\": \"dstsvc\",\n
+    \       \"options\": [],\n        \"query\": \"query_result( sum(istio_requests_total{reporter=\\\"source\\\",
+    source_workload=~\\\"$workload\\\", source_workload_namespace=~\\\"$namespace\\\"})
+    by (destination_service) or sum(istio_tcp_sent_bytes_total{reporter=\\\"source\\\",
+    source_workload=~\\\"$workload\\\", source_workload_namespace=~\\\"$namespace\\\"})
+    by (destination_service))\",\n        \"refresh\": 1,\n        \"regex\": \"/.*destination_service=\\\"([^\\\"]*).*/\",\n
+    \       \"sort\": 4,\n        \"tagValuesQuery\": \"\",\n        \"tags\": [],\n
+    \       \"tagsQuery\": \"\",\n        \"type\": \"query\",\n        \"useTags\":
+    false\n      }\n    ]\n  },\n  \"time\": {\n    \"from\": \"now-5m\",\n    \"to\":
+    \"now\"\n  },\n  \"timepicker\": {\n    \"refresh_intervals\": [\n      \"5s\",\n
+    \     \"10s\",\n      \"30s\",\n      \"1m\",\n      \"5m\",\n      \"15m\",\n
+    \     \"30m\",\n      \"1h\",\n      \"2h\",\n      \"1d\"\n    ],\n    \"time_options\":
+    [\n      \"5m\",\n      \"15m\",\n      \"1h\",\n      \"6h\",\n      \"12h\",\n
+    \     \"24h\",\n      \"2d\",\n      \"7d\",\n      \"30d\"\n    ]\n  },\n  \"timezone\":
+    \"\",\n  \"title\": \"Istio Workload Dashboard\",\n  \"uid\": \"UbsSZTDik\",\n
+    \ \"version\": 1\n}\n"
+kind: ConfigMap
+metadata:
+  creationTimestamp: null
+  name: istio-services-grafana-dashboards
+  namespace: istio-system
diff --git a/mash/eks/samples/addons/jaeger.yaml b/mash/eks/samples/addons/jaeger.yaml
new file mode 100644 (file)
index 0000000..05b8318
--- /dev/null
@@ -0,0 +1,88 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: jaeger
+  namespace: istio-system
+  labels:
+    app: jaeger
+spec:
+  selector:
+    matchLabels:
+      app: jaeger
+  template:
+    metadata:
+      labels:
+        app: jaeger
+      annotations:
+        sidecar.istio.io/inject: "false"
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "14269"
+    spec:
+      containers:
+        - name: jaeger
+          image: "docker.io/jaegertracing/all-in-one:1.18"
+          env:
+            - name: BADGER_EPHEMERAL
+              value: "false"
+            - name: SPAN_STORAGE_TYPE
+              value: "badger"
+            - name: BADGER_DIRECTORY_VALUE
+              value: "/badger/data"
+            - name: BADGER_DIRECTORY_KEY
+              value: "/badger/key"
+            - name: COLLECTOR_ZIPKIN_HTTP_PORT
+              value: "9411"
+            - name: MEMORY_MAX_TRACES
+              value: "50000"
+            - name: QUERY_BASE_PATH
+              value: /jaeger
+          livenessProbe:
+            httpGet:
+              path: /
+              port: 14269
+          readinessProbe:
+            httpGet:
+              path: /
+              port: 14269
+          volumeMounts:
+            - name: data
+              mountPath: /badger
+          resources:
+            requests:
+              cpu: 10m
+      volumes:
+        - name: data
+          emptyDir: {}
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: tracing
+  namespace: istio-system
+  labels:
+    app: jaeger
+spec:
+  type: ClusterIP
+  ports:
+    - name: http-query
+      port: 80
+      protocol: TCP
+      targetPort: 16686
+  selector:
+    app: jaeger
+---
+# Jaeger implements the Zipkin API. To support swapping out the tracing backend, we use a Service named Zipkin.
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    name: zipkin
+  name: zipkin
+  namespace: istio-system
+spec:
+  ports:
+    - port: 9411
+      targetPort: 9411
+      name: http-query
+  selector:
+    app: jaeger
diff --git a/mash/eks/samples/addons/kiali.yaml b/mash/eks/samples/addons/kiali.yaml
new file mode 100644 (file)
index 0000000..a9601cc
--- /dev/null
@@ -0,0 +1,1615 @@
+---
+# Source: crds/crds.yaml
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+  name: monitoringdashboards.monitoring.kiali.io
+spec:
+  group: monitoring.kiali.io
+  names:
+    kind: MonitoringDashboard
+    listKind: MonitoringDashboardList
+    plural: monitoringdashboards
+    singular: monitoringdashboard
+  scope: Namespaced
+  versions:
+  - name: v1alpha1
+    served: true
+    storage: true
+...
+
+---
+# Source: kiali-server/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: kiali
+  namespace: istio-system
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+...
+---
+# Source: kiali-server/templates/configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: kiali
+  namespace: istio-system
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+data:
+  config.yaml: |
+    additional_display_details:
+    - annotation: kiali.io/api-spec
+      icon_annotation: kiali.io/api-type
+      title: API Documentation
+    api:
+      namespaces:
+        exclude:
+        - istio-operator
+        - kube.*
+        - openshift.*
+        - ibm.*
+        - kiali-operator
+    auth:
+      openid:
+        authentication_timeout: 300
+        authorization_endpoint: ""
+        client_id: ""
+        insecure_skip_verify_tls: false
+        issuer_uri: ""
+        scopes:
+        - openid
+        - profile
+        - email
+        username_claim: sub
+      openshift:
+        client_id_prefix: kiali
+      strategy: anonymous
+    deployment:
+      accessible_namespaces:
+      - '**'
+      additional_service_yaml: {}
+      affinity:
+        node: {}
+        pod: {}
+        pod_anti: {}
+      custom_dashboards:
+        excludes:
+        - ""
+        includes:
+        - '*'
+      image_name: quay.io/kiali/kiali
+      image_pull_policy: Always
+      image_pull_secrets: []
+      image_version: v1.22
+      ingress_enabled: false
+      namespace: istio-system
+      node_selector: {}
+      override_ingress_yaml:
+        metadata: {}
+      pod_annotations: {}
+      priority_class_name: ""
+      replicas: 1
+      resources: {}
+      secret_name: kiali
+      service_annotations: {}
+      service_type: ""
+      tolerations: []
+      verbose_mode: "3"
+      version_label: v1.22.0
+      view_only_mode: false
+    extensions:
+      iter_8:
+        enabled: false
+      threescale:
+        adapter_name: threescale
+        adapter_port: "3333"
+        adapter_service: threescale-istio-adapter
+        enabled: false
+        template_name: threescale-authorization
+    external_services:
+      grafana:
+        auth:
+          ca_file: ""
+          insecure_skip_verify: false
+          password: ""
+          token: ""
+          type: none
+          use_kiali_token: false
+          username: ""
+        dashboards:
+        - name: Istio Service Dashboard
+          variables:
+            namespace: var-namespace
+            service: var-service
+        - name: Istio Workload Dashboard
+          variables:
+            namespace: var-namespace
+            workload: var-workload
+        enabled: true
+        in_cluster_url: http://grafana:3000
+        url: ""
+      istio:
+        istio_identity_domain: svc.cluster.local
+        istio_sidecar_annotation: sidecar.istio.io/status
+        istio_status_enabled: true
+        url_service_version: http://istiod:15014/version
+      prometheus:
+        auth:
+          ca_file: ""
+          insecure_skip_verify: false
+          password: ""
+          token: ""
+          type: none
+          use_kiali_token: false
+          username: ""
+        custom_metrics_url: http://prometheus:9090
+        url: http://prometheus:9090
+      tracing:
+        auth:
+          ca_file: ""
+          insecure_skip_verify: false
+          password: ""
+          token: ""
+          type: none
+          use_kiali_token: false
+          username: ""
+        enabled: true
+        in_cluster_url: http://tracing/jaeger
+        namespace_selector: true
+        url: ""
+        whitelist_istio_system:
+        - jaeger-query
+        - istio-ingressgateway
+    identity:
+      cert_file: ""
+      private_key_file: ""
+    installation_tag: ""
+    istio_labels:
+      app_label_name: app
+      version_label_name: version
+    istio_namespace: istio-system
+    kubernetes_config:
+      burst: 200
+      cache_duration: 300
+      cache_enabled: true
+      cache_istio_types:
+      - DestinationRule
+      - Gateway
+      - ServiceEntry
+      - VirtualService
+      cache_namespaces:
+      - .*
+      cache_token_namespace_duration: 10
+      excluded_workloads:
+      - CronJob
+      - DeploymentConfig
+      - Job
+      - ReplicationController
+      qps: 175
+    login_token:
+      expiration_seconds: 86400
+      signing_key: CHANGEME
+    server:
+      address: ""
+      audit_log: true
+      cors_allow_all: false
+      gzip_enabled: true
+      metrics_enabled: true
+      metrics_port: 9090
+      port: 20001
+      web_fqdn: ""
+      web_root: /kiali
+      web_schema: ""
+...
+---
+# Source: kiali-server/templates/role-viewer.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kiali-viewer
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+rules:
+- apiGroups: [""]
+  resources:
+  - configmaps
+  - endpoints
+  - namespaces
+  - nodes
+  - pods
+  - pods/log
+  - replicationcontrollers
+  - services
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["extensions", "apps"]
+  resources:
+  - deployments
+  - replicasets
+  - statefulsets
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["autoscaling"]
+  resources:
+  - horizontalpodautoscalers
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["batch"]
+  resources:
+  - cronjobs
+  - jobs
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - config.istio.io
+  - networking.istio.io
+  - authentication.istio.io
+  - rbac.istio.io
+  - security.istio.io
+  resources: ["*"]
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["authentication.maistra.io"]
+  resources:
+  - servicemeshpolicies
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["rbac.maistra.io"]
+  resources:
+  - servicemeshrbacconfigs
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["apps.openshift.io"]
+  resources:
+  - deploymentconfigs
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["project.openshift.io"]
+  resources:
+  - projects
+  verbs:
+  - get
+- apiGroups: ["route.openshift.io"]
+  resources:
+  - routes
+  verbs:
+  - get
+- apiGroups: ["monitoring.kiali.io"]
+  resources:
+  - monitoringdashboards
+  verbs:
+  - get
+  - list
+- apiGroups: ["iter8.tools"]
+  resources:
+  - experiments
+  verbs:
+  - get
+  - list
+...
+---
+# Source: kiali-server/templates/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kiali
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+rules:
+- apiGroups: [""]
+  resources:
+  - configmaps
+  - endpoints
+  - namespaces
+  - nodes
+  - pods
+  - pods/log
+  - replicationcontrollers
+  - services
+  verbs:
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups: ["extensions", "apps"]
+  resources:
+  - deployments
+  - replicasets
+  - statefulsets
+  verbs:
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups: ["autoscaling"]
+  resources:
+  - horizontalpodautoscalers
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups: ["batch"]
+  resources:
+  - cronjobs
+  - jobs
+  verbs:
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups:
+  - config.istio.io
+  - networking.istio.io
+  - authentication.istio.io
+  - rbac.istio.io
+  - security.istio.io
+  resources: ["*"]
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups: ["authentication.maistra.io"]
+  resources:
+  - servicemeshpolicies
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups: ["rbac.maistra.io"]
+  resources:
+  - servicemeshrbacconfigs
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups: ["apps.openshift.io"]
+  resources:
+  - deploymentconfigs
+  verbs:
+  - get
+  - list
+  - patch
+  - watch
+- apiGroups: ["project.openshift.io"]
+  resources:
+  - projects
+  verbs:
+  - get
+- apiGroups: ["route.openshift.io"]
+  resources:
+  - routes
+  verbs:
+  - get
+- apiGroups: ["monitoring.kiali.io"]
+  resources:
+  - monitoringdashboards
+  verbs:
+  - get
+  - list
+- apiGroups: ["iter8.tools"]
+  resources:
+  - experiments
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - watch
+...
+---
+# Source: kiali-server/templates/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kiali
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kiali
+subjects:
+- kind: ServiceAccount
+  name: kiali
+  namespace: istio-system
+...
+---
+# Source: kiali-server/templates/service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: kiali
+  namespace: istio-system
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    kiali.io/api-spec: https://kiali.io/api
+    kiali.io/api-type: rest
+spec:
+  ports:
+  - name: http
+    protocol: TCP
+    port: 20001
+  - name: http-metrics
+    protocol: TCP
+    port: 9090
+  selector:
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+...
+---
+# Source: kiali-server/templates/deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: kiali
+  namespace: istio-system
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: kiali
+      app.kubernetes.io/instance: kiali-server
+  strategy:
+    rollingUpdate:
+      maxSurge: 1
+      maxUnavailable: 1
+    type: RollingUpdate
+  template:
+    metadata:
+      name: kiali
+      labels:
+        helm.sh/chart: kiali-server-1.22.0
+        app: kiali
+        app.kubernetes.io/name: kiali
+        app.kubernetes.io/instance: kiali-server
+        version: "v1.22.0"
+        app.kubernetes.io/version: "v1.22.0"
+        app.kubernetes.io/managed-by: Helm
+      annotations:
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "9090"
+        kiali.io/runtimes: go,kiali
+    spec:
+      serviceAccountName: kiali
+      containers:
+      - image: "quay.io/kiali/kiali:v1.22"
+        imagePullPolicy: Always
+        name: kiali
+        command:
+        - "/opt/kiali/kiali"
+        - "-config"
+        - "/kiali-configuration/config.yaml"
+        - "-v"
+        - "3"
+        ports:
+        - name: api-port
+          containerPort: 20001
+        - name: http-metrics
+          containerPort: 9090
+        readinessProbe:
+          httpGet:
+            path: /kiali/healthz
+            port: api-port
+            scheme: HTTP
+          initialDelaySeconds: 5
+          periodSeconds: 30
+        livenessProbe:
+          httpGet:
+            path: /kiali/healthz
+            port: api-port
+            scheme: HTTP
+          initialDelaySeconds: 5
+          periodSeconds: 30
+        env:
+        - name: ACTIVE_NAMESPACE
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.namespace
+        volumeMounts:
+        - name: kiali-configuration
+          mountPath: "/kiali-configuration"
+        - name: kiali-cert
+          mountPath: "/kiali-cert"
+        - name: kiali-secret
+          mountPath: "/kiali-secret"
+      volumes:
+      - name: kiali-configuration
+        configMap:
+          name: kiali
+      - name: kiali-cert
+        secret:
+          secretName: istio.kiali-service-account
+          optional: true
+      - name: kiali-secret
+        secret:
+          secretName: kiali
+          optional: true
+...
+---
+# Source: kiali-server/templates/dashboards/envoy.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: envoy
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  title: Envoy Metrics
+#  discoverOn: "envoy_server_uptime"
+  items:
+  - chart:
+      name: "Pods uptime"
+      spans: 4
+      metricName: "envoy_server_uptime"
+      dataType: "raw"
+  - chart:
+      name: "Allocated memory"
+      unit: "bytes"
+      spans: 4
+      metricName: "envoy_server_memory_allocated"
+      dataType: "raw"
+      min: 0
+  - chart:
+      name: "Heap size"
+      unit: "bytes"
+      spans: 4
+      metricName: "envoy_server_memory_heap_size"
+      dataType: "raw"
+      min: 0
+  - chart:
+      name: "Upstream active connections"
+      spans: 6
+      metricName: "envoy_cluster_upstream_cx_active"
+      dataType: "raw"
+  - chart:
+      name: "Upstream total requests"
+      spans: 6
+      metricName: "envoy_cluster_upstream_rq_total"
+      unit: "rps"
+      dataType: "rate"
+  - chart:
+      name: "Downstream active connections"
+      spans: 6
+      metricName: "envoy_listener_downstream_cx_active"
+      dataType: "raw"
+  - chart:
+      name: "Downstream HTTP requests"
+      spans: 6
+      metricName: "envoy_listener_http_downstream_rq"
+      unit: "rps"
+      dataType: "rate"
+...
+---
+# Source: kiali-server/templates/dashboards/go.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: go
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  title: Go Metrics
+  runtime: Go
+  discoverOn: "go_info"
+  items:
+  - chart:
+      name: "CPU ratio"
+      spans: 6
+      metricName: "process_cpu_seconds_total"
+      dataType: "rate"
+      aggregations:
+      - label: "pod_name"
+        displayName: "Pod"
+  - chart:
+      name: "RSS Memory"
+      unit: "bytes"
+      spans: 6
+      metricName: "process_resident_memory_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "pod_name"
+        displayName: "Pod"
+  - chart:
+      name: "Goroutines"
+      spans: 6
+      metricName: "go_goroutines"
+      dataType: "raw"
+      aggregations:
+      - label: "pod_name"
+        displayName: "Pod"
+  - chart:
+      name: "Heap allocation rate"
+      unit: "bytes/s"
+      spans: 6
+      metricName: "go_memstats_alloc_bytes_total"
+      dataType: "rate"
+      aggregations:
+      - label: "pod_name"
+        displayName: "Pod"
+  - chart:
+      name: "GC rate"
+      spans: 6
+      metricName: "go_gc_duration_seconds_count"
+      dataType: "rate"
+      aggregations:
+      - label: "pod_name"
+        displayName: "Pod"
+  - chart:
+      name: "Next GC"
+      unit: "bytes"
+      spans: 6
+      metricName: "go_memstats_next_gc_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "pod_name"
+        displayName: "Pod"
+...
+---
+# Source: kiali-server/templates/dashboards/kiali.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: kiali
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  title: Kiali Internal Metrics
+  items:
+  - chart:
+      name: "API processing duration"
+      unit: "seconds"
+      spans: 6
+      metricName: "kiali_api_processing_duration_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "route"
+        displayName: "Route"
+  - chart:
+      name: "Functions processing duration"
+      unit: "seconds"
+      spans: 6
+      metricName: "kiali_go_function_processing_duration_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "function"
+        displayName: "Function"
+      - label: "package"
+        displayName: "Package"
+  - chart:
+      name: "Failures"
+      spans: 12
+      metricName: "kiali_go_function_failures_total"
+      dataType: "raw"
+      aggregations:
+      - label: "function"
+        displayName: "Function"
+      - label: "package"
+        displayName: "Package"
+...
+---
+# Source: kiali-server/templates/dashboards/micrometer-1.0.6-jvm-pool.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: micrometer-1.0.6-jvm-pool
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: JVM
+  title: JVM Pool Metrics
+  discoverOn: "jvm_buffer_total_capacity_bytes"
+  items:
+  - chart:
+      name: "Pool buffer memory used"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_buffer_memory_used_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "id"
+        displayName: "Pool"
+  - chart:
+      name: "Pool buffer capacity"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_buffer_total_capacity_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "id"
+        displayName: "Pool"
+  - chart:
+      name: "Pool buffer count"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_buffer_count"
+      dataType: "raw"
+      aggregations:
+      - label: "id"
+        displayName: "Pool"
+...
+---
+# Source: kiali-server/templates/dashboards/micrometer-1.0.6-jvm.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: micrometer-1.0.6-jvm
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: JVM
+  title: JVM Metrics
+  discoverOn: "jvm_threads_live"
+  items:
+  - chart:
+      name: "Total live threads"
+      spans: 4
+      metricName: "jvm_threads_live"
+      dataType: "raw"
+  - chart:
+      name: "Daemon threads"
+      spans: 4
+      metricName: "jvm_threads_daemon"
+      dataType: "raw"
+  - chart:
+      name: "Loaded classes"
+      spans: 4
+      metricName: "jvm_classes_loaded"
+      dataType: "raw"
+
+  - chart:
+      name: "Memory used"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_memory_used_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "area"
+        displayName: "Area"
+      - label: "id"
+        displayName: "Space"
+  - chart:
+      name: "Memory commited"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_memory_committed_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "area"
+        displayName: "Area"
+      - label: "id"
+        displayName: "Space"
+  - chart:
+      name: "Memory max"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_memory_max_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "area"
+        displayName: "Area"
+      - label: "id"
+        displayName: "Space"
+...
+---
+# Source: kiali-server/templates/dashboards/micrometer-1.1-jvm.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: micrometer-1.1-jvm
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: JVM
+  title: JVM Metrics
+  discoverOn: "jvm_threads_live_threads"
+  items:
+  - chart:
+      name: "Memory used"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_memory_used_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "area"
+        displayName: "Area"
+      - label: "id"
+        displayName: "Space"
+  - chart:
+      name: "Memory commited"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_memory_committed_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "area"
+        displayName: "Area"
+      - label: "id"
+        displayName: "Space"
+  - chart:
+      name: "Memory max"
+      unit: "bytes"
+      spans: 4
+      metricName: "jvm_memory_max_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "area"
+        displayName: "Area"
+      - label: "id"
+        displayName: "Space"
+
+  - chart:
+      name: "Total live threads"
+      spans: 4
+      metricName: "jvm_threads_live_threads"
+      dataType: "raw"
+  - chart:
+      name: "Daemon threads"
+      spans: 4
+      metricName: "jvm_threads_daemon_threads"
+      dataType: "raw"
+  - chart:
+      name: "Threads states"
+      spans: 4
+      metricName: "jvm_threads_states_threads"
+      dataType: "raw"
+      aggregations:
+      - label: "state"
+        displayName: "State"
+...
+---
+# Source: kiali-server/templates/dashboards/microprofile-1.1.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: microprofile-1.1
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  title: MicroProfile Metrics
+  runtime: MicroProfile
+  discoverOn: "base:thread_count"
+  items:
+  - chart:
+      name: "Current loaded classes"
+      spans: 6
+      metricName: "base:classloader_current_loaded_class_count"
+      dataType: "raw"
+  - chart:
+      name: "Unloaded classes"
+      spans: 6
+      metricName: "base:classloader_total_unloaded_class_count"
+      dataType: "raw"
+  - chart:
+      name: "Thread count"
+      spans: 4
+      metricName: "base:thread_count"
+      dataType: "raw"
+  - chart:
+      name: "Thread max count"
+      spans: 4
+      metricName: "base:thread_max_count"
+      dataType: "raw"
+  - chart:
+      name: "Thread daemon count"
+      spans: 4
+      metricName: "base:thread_daemon_count"
+      dataType: "raw"
+  - chart:
+      name: "Committed heap"
+      unit: "bytes"
+      spans: 4
+      metricName: "base:memory_committed_heap_bytes"
+      dataType: "raw"
+  - chart:
+      name: "Max heap"
+      unit: "bytes"
+      spans: 4
+      metricName: "base:memory_max_heap_bytes"
+      dataType: "raw"
+  - chart:
+      name: "Used heap"
+      unit: "bytes"
+      spans: 4
+      metricName: "base:memory_used_heap_bytes"
+      dataType: "raw"
+...
+---
+# Source: kiali-server/templates/dashboards/microprofile-x.y.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: microprofile-x.y
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  title: MicroProfile Metrics
+  runtime: MicroProfile
+  discoverOn: "base:gc_complete_scavenger_count"
+  items:
+  - chart:
+      name: "Young GC time"
+      unit: "seconds"
+      spans: 3
+      metricName: "base:gc_young_generation_scavenger_time_seconds"
+      dataType: "raw"
+  - chart:
+      name: "Young GC count"
+      spans: 3
+      metricName: "base:gc_young_generation_scavenger_count"
+      dataType: "raw"
+  - chart:
+      name: "Total GC time"
+      unit: "seconds"
+      spans: 3
+      metricName: "base:gc_complete_scavenger_time_seconds"
+      dataType: "raw"
+  - chart:
+      name: "Total GC count"
+      spans: 3
+      metricName: "base:gc_complete_scavenger_count"
+      dataType: "raw"
+...
+---
+# Source: kiali-server/templates/dashboards/nodejs.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: nodejs
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Node.js
+  title: Node.js Metrics
+  discoverOn: "nodejs_active_handles_total"
+  items:
+  - chart:
+      name: "Active handles"
+      spans: 4
+      metricName: "nodejs_active_handles_total"
+      dataType: "raw"
+  - chart:
+      name: "Active requests"
+      spans: 4
+      metricName: "nodejs_active_requests_total"
+      dataType: "raw"
+  - chart:
+      name: "Event loop lag"
+      unit: "seconds"
+      spans: 4
+      metricName: "nodejs_eventloop_lag_seconds"
+      dataType: "raw"
+  - chart:
+      name: "Total heap size"
+      unit: "bytes"
+      spans: 12
+      metricName: "nodejs_heap_space_size_total_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "space"
+        displayName: "Space"
+  - chart:
+      name: "Used heap size"
+      unit: "bytes"
+      spans: 6
+      metricName: "nodejs_heap_space_size_used_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "space"
+        displayName: "Space"
+  - chart:
+      name: "Available heap size"
+      unit: "bytes"
+      spans: 6
+      metricName: "nodejs_heap_space_size_available_bytes"
+      dataType: "raw"
+      aggregations:
+      - label: "space"
+        displayName: "Space"
+...
+---
+# Source: kiali-server/templates/dashboards/quarkus.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: quarkus
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  title: Quarkus Metrics
+  runtime: Quarkus
+  items:
+  - chart:
+      name: "Thread count"
+      spans: 4
+      metricName: "vendor:thread_count"
+      dataType: "raw"
+  - chart:
+      name: "Used heap"
+      unit: "bytes"
+      spans: 4
+      metricName: "vendor:memory_heap_usage_bytes"
+      dataType: "raw"
+  - chart:
+      name: "Used non-heap"
+      unit: "bytes"
+      spans: 4
+      metricName: "vendor:memory_non_heap_usage_bytes"
+      dataType: "raw"
+  - include: "microprofile-x.y"
+...
+---
+# Source: kiali-server/templates/dashboards/springboot-jvm-pool.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: springboot-jvm-pool
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Spring Boot
+  title: JVM Pool Metrics
+  items:
+  - include: "micrometer-1.0.6-jvm-pool"
+...
+---
+# Source: kiali-server/templates/dashboards/springboot-jvm.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: springboot-jvm
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Spring Boot
+  title: JVM Metrics
+  items:
+  - include: "micrometer-1.0.6-jvm"
+...
+---
+# Source: kiali-server/templates/dashboards/springboot-tomcat.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: springboot-tomcat
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Spring Boot
+  title: Tomcat Metrics
+  items:
+  - include: "tomcat"
+...
+---
+# Source: kiali-server/templates/dashboards/thorntail.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: thorntail
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Thorntail
+  title: Thorntail Metrics
+  discoverOn: "vendor:loaded_modules"
+  items:
+  - include: "microprofile-1.1"
+  - chart:
+      name: "Loaded modules"
+      spans: 6
+      metricName: "vendor:loaded_modules"
+      dataType: "raw"
+...
+---
+# Source: kiali-server/templates/dashboards/tomcat.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: tomcat
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Tomcat
+  title: Tomcat Metrics
+  discoverOn: "tomcat_sessions_created_total"
+  items:
+  - chart:
+      name: "Sessions created"
+      spans: 4
+      metricName: "tomcat_sessions_created_total"
+      dataType: "raw"
+  - chart:
+      name: "Active sessions"
+      spans: 4
+      metricName: "tomcat_sessions_active_current"
+      dataType: "raw"
+  - chart:
+      name: "Sessions rejected"
+      spans: 4
+      metricName: "tomcat_sessions_rejected_total"
+      dataType: "raw"
+
+  - chart:
+      name: "Bytes sent"
+      unit: "bitrate"
+      spans: 6
+      metricName: "tomcat_global_sent_bytes_total"
+      dataType: "rate"
+      aggregations:
+      - label: "name"
+        displayName: "Name"
+  - chart:
+      name: "Bytes received"
+      unit: "bitrate"
+      spans: 6
+      metricName: "tomcat_global_received_bytes_total"
+      dataType: "rate"
+      aggregations:
+      - label: "name"
+        displayName: "Name"
+
+  - chart:
+      name: "Global errors"
+      spans: 6
+      metricName: "tomcat_global_error_total"
+      dataType: "raw"
+      aggregations:
+      - label: "name"
+        displayName: "Name"
+  - chart:
+      name: "Servlet errors"
+      spans: 6
+      metricName: "tomcat_servlet_error_total"
+      dataType: "raw"
+      aggregations:
+      - label: "name"
+        displayName: "Name"
+...
+---
+# Source: kiali-server/templates/dashboards/vertx-client.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: vertx-client
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Vert.x
+  title: Vert.x Client Metrics
+  discoverOn: "vertx_http_client_connections"
+  items:
+  - chart:
+      name: "Client response time"
+      unit: "seconds"
+      spans: 6
+      metricName: "vertx_http_client_responseTime_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "path"
+        displayName: "Path"
+      - label: "method"
+        displayName: "Method"
+  - chart:
+      name: "Client request count rate"
+      unit: "ops"
+      spans: 6
+      metricName: "vertx_http_client_requestCount_total"
+      dataType: "rate"
+      aggregations:
+      - label: "path"
+        displayName: "Path"
+      - label: "method"
+        displayName: "Method"
+  - chart:
+      name: "Client active connections"
+      spans: 6
+      metricName: "vertx_http_client_connections"
+      dataType: "raw"
+  - chart:
+      name: "Client active websockets"
+      spans: 6
+      metricName: "vertx_http_client_wsConnections"
+      dataType: "raw"
+  - chart:
+      name: "Client bytes sent"
+      unit: "bytes"
+      spans: 6
+      metricName: "vertx_http_client_bytesSent"
+      dataType: "histogram"
+  - chart:
+      name: "Client bytes received"
+      unit: "bytes"
+      spans: 6
+      metricName: "vertx_http_client_bytesReceived"
+      dataType: "histogram"
+...
+---
+# Source: kiali-server/templates/dashboards/vertx-eventbus.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: vertx-eventbus
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Vert.x
+  title: Vert.x Eventbus Metrics
+  discoverOn: "vertx_eventbus_handlers"
+  items:
+  - chart:
+      name: "Event bus handlers"
+      spans: 6
+      metricName: "vertx_eventbus_handlers"
+      dataType: "raw"
+      aggregations:
+      - label: "address"
+        displayName: "Eventbus address"
+  - chart:
+      name: "Event bus pending messages"
+      spans: 6
+      metricName: "vertx_eventbus_pending"
+      dataType: "raw"
+      aggregations:
+      - label: "address"
+        displayName: "Eventbus address"
+  - chart:
+      name: "Event bus processing time"
+      unit: "seconds"
+      spans: 6
+      metricName: "vertx_eventbus_processingTime_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "address"
+        displayName: "Eventbus address"
+  - chart:
+      name: "Event bus bytes read"
+      unit: "bytes"
+      spans: 6
+      metricName: "vertx_eventbus_bytesRead"
+      dataType: "histogram"
+      aggregations:
+      - label: "address"
+        displayName: "Eventbus address"
+  - chart:
+      name: "Event bus bytes written"
+      unit: "bytes"
+      spans: 6
+      metricName: "vertx_eventbus_bytesWritten"
+      dataType: "histogram"
+      aggregations:
+      - label: "address"
+        displayName: "Eventbus address"
+...
+---
+# Source: kiali-server/templates/dashboards/vertx-jvm.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: vertx-jvm
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Vert.x
+  title: JVM Metrics
+  items:
+  - include: "micrometer-1.1-jvm"
+...
+---
+# Source: kiali-server/templates/dashboards/vertx-pool.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: vertx-pool
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Vert.x
+  title: Vert.x Pools Metrics
+  discoverOn: "vertx_pool_ratio"
+  items:
+  - chart:
+      name: "Usage duration"
+      unit: "seconds"
+      spans: 6
+      metricName: "vertx_pool_usage_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "pool_name"
+        displayName: "Name"
+      - label: "pool_type"
+        displayName: "Type"
+  - chart:
+      name: "Usage ratio"
+      spans: 6
+      metricName: "vertx_pool_ratio"
+      dataType: "raw"
+      aggregations:
+      - label: "pool_name"
+        displayName: "Name"
+      - label: "pool_type"
+        displayName: "Type"
+  - chart:
+      name: "Queue size"
+      spans: 6
+      metricName: "vertx_pool_queue_size"
+      dataType: "raw"
+      aggregations:
+      - label: "pool_name"
+        displayName: "Name"
+      - label: "pool_type"
+        displayName: "Type"
+  - chart:
+      name: "Time in queue"
+      unit: "seconds"
+      spans: 6
+      metricName: "vertx_pool_queue_delay_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "pool_name"
+        displayName: "Name"
+      - label: "pool_type"
+        displayName: "Type"
+  - chart:
+      name: "Resources used"
+      spans: 6
+      metricName: "vertx_pool_inUse"
+      dataType: "raw"
+      aggregations:
+      - label: "pool_name"
+        displayName: "Name"
+      - label: "pool_type"
+        displayName: "Type"
+...
+---
+# Source: kiali-server/templates/dashboards/vertx-server.yaml
+apiVersion: "monitoring.kiali.io/v1alpha1"
+kind: MonitoringDashboard
+metadata:
+  name: vertx-server
+  labels:
+    helm.sh/chart: kiali-server-1.22.0
+    app: kiali
+    app.kubernetes.io/name: kiali
+    app.kubernetes.io/instance: kiali-server
+    version: "v1.22.0"
+    app.kubernetes.io/version: "v1.22.0"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  runtime: Vert.x
+  title: Vert.x Server Metrics
+  discoverOn: "vertx_http_server_connections"
+  items:
+  - chart:
+      name: "Server response time"
+      unit: "seconds"
+      spans: 6
+      metricName: "vertx_http_server_responseTime_seconds"
+      dataType: "histogram"
+      aggregations:
+      - label: "path"
+        displayName: "Path"
+      - label: "method"
+        displayName: "Method"
+  - chart:
+      name: "Server request count rate"
+      unit: "ops"
+      spans: 6
+      metricName: "vertx_http_server_requestCount_total"
+      dataType: "rate"
+      aggregations:
+      - label: "code"
+        displayName: "Error code"
+      - label: "path"
+        displayName: "Path"
+      - label: "method"
+        displayName: "Method"
+  - chart:
+      name: "Server active connections"
+      spans: 6
+      metricName: "vertx_http_server_connections"
+      dataType: "raw"
+  - chart:
+      name: "Server active websockets"
+      spans: 6
+      metricName: "vertx_http_server_wsConnections"
+      dataType: "raw"
+  - chart:
+      name: "Server bytes sent"
+      unit: "bytes"
+      spans: 6
+      metricName: "vertx_http_server_bytesSent"
+      dataType: "histogram"
+  - chart:
+      name: "Server bytes received"
+      unit: "bytes"
+      spans: 6
+      metricName: "vertx_http_server_bytesReceived"
+      dataType: "histogram"
+...
diff --git a/mash/eks/samples/addons/prometheus.yaml b/mash/eks/samples/addons/prometheus.yaml
new file mode 100644 (file)
index 0000000..303c64e
--- /dev/null
@@ -0,0 +1,464 @@
+---
+# Source: prometheus/templates/server-serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  labels:
+    component: "server"
+    app: prometheus
+    release: prometheus
+    chart: prometheus-11.7.0
+    heritage: Helm
+  name: prometheus
+  namespace: istio-system
+  annotations:
+    {}
+---
+# Source: prometheus/templates/server-configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  labels:
+    component: "server"
+    app: prometheus
+    release: prometheus
+    chart: prometheus-11.7.0
+    heritage: Helm
+  name: prometheus
+  namespace: istio-system
+data:
+  alerting_rules.yml: |
+    {}
+  alerts: |
+    {}
+  prometheus.yml: |
+    global:
+      evaluation_interval: 1m
+      scrape_interval: 15s
+      scrape_timeout: 10s
+    rule_files:
+    - /etc/config/recording_rules.yml
+    - /etc/config/alerting_rules.yml
+    - /etc/config/rules
+    - /etc/config/alerts
+    scrape_configs:
+    - job_name: prometheus
+      static_configs:
+      - targets:
+        - localhost:9090
+    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
+      job_name: kubernetes-apiservers
+      kubernetes_sd_configs:
+      - role: endpoints
+      relabel_configs:
+      - action: keep
+        regex: default;kubernetes;https
+        source_labels:
+        - __meta_kubernetes_namespace
+        - __meta_kubernetes_service_name
+        - __meta_kubernetes_endpoint_port_name
+      scheme: https
+      tls_config:
+        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+        insecure_skip_verify: true
+    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
+      job_name: kubernetes-nodes
+      kubernetes_sd_configs:
+      - role: node
+      relabel_configs:
+      - action: labelmap
+        regex: __meta_kubernetes_node_label_(.+)
+      - replacement: kubernetes.default.svc:443
+        target_label: __address__
+      - regex: (.+)
+        replacement: /api/v1/nodes/$1/proxy/metrics
+        source_labels:
+        - __meta_kubernetes_node_name
+        target_label: __metrics_path__
+      scheme: https
+      tls_config:
+        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+        insecure_skip_verify: true
+    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
+      job_name: kubernetes-nodes-cadvisor
+      kubernetes_sd_configs:
+      - role: node
+      relabel_configs:
+      - action: labelmap
+        regex: __meta_kubernetes_node_label_(.+)
+      - replacement: kubernetes.default.svc:443
+        target_label: __address__
+      - regex: (.+)
+        replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
+        source_labels:
+        - __meta_kubernetes_node_name
+        target_label: __metrics_path__
+      scheme: https
+      tls_config:
+        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+        insecure_skip_verify: true
+    - job_name: kubernetes-service-endpoints
+      kubernetes_sd_configs:
+      - role: endpoints
+      relabel_configs:
+      - action: keep
+        regex: true
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_scrape
+      - action: replace
+        regex: (https?)
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_scheme
+        target_label: __scheme__
+      - action: replace
+        regex: (.+)
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_path
+        target_label: __metrics_path__
+      - action: replace
+        regex: ([^:]+)(?::\d+)?;(\d+)
+        replacement: $1:$2
+        source_labels:
+        - __address__
+        - __meta_kubernetes_service_annotation_prometheus_io_port
+        target_label: __address__
+      - action: labelmap
+        regex: __meta_kubernetes_service_label_(.+)
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_namespace
+        target_label: kubernetes_namespace
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_service_name
+        target_label: kubernetes_name
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_pod_node_name
+        target_label: kubernetes_node
+    - job_name: kubernetes-service-endpoints-slow
+      kubernetes_sd_configs:
+      - role: endpoints
+      relabel_configs:
+      - action: keep
+        regex: true
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_scrape_slow
+      - action: replace
+        regex: (https?)
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_scheme
+        target_label: __scheme__
+      - action: replace
+        regex: (.+)
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_path
+        target_label: __metrics_path__
+      - action: replace
+        regex: ([^:]+)(?::\d+)?;(\d+)
+        replacement: $1:$2
+        source_labels:
+        - __address__
+        - __meta_kubernetes_service_annotation_prometheus_io_port
+        target_label: __address__
+      - action: labelmap
+        regex: __meta_kubernetes_service_label_(.+)
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_namespace
+        target_label: kubernetes_namespace
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_service_name
+        target_label: kubernetes_name
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_pod_node_name
+        target_label: kubernetes_node
+      scrape_interval: 5m
+      scrape_timeout: 30s
+    - honor_labels: true
+      job_name: prometheus-pushgateway
+      kubernetes_sd_configs:
+      - role: service
+      relabel_configs:
+      - action: keep
+        regex: pushgateway
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_probe
+    - job_name: kubernetes-services
+      kubernetes_sd_configs:
+      - role: service
+      metrics_path: /probe
+      params:
+        module:
+        - http_2xx
+      relabel_configs:
+      - action: keep
+        regex: true
+        source_labels:
+        - __meta_kubernetes_service_annotation_prometheus_io_probe
+      - source_labels:
+        - __address__
+        target_label: __param_target
+      - replacement: blackbox
+        target_label: __address__
+      - source_labels:
+        - __param_target
+        target_label: instance
+      - action: labelmap
+        regex: __meta_kubernetes_service_label_(.+)
+      - source_labels:
+        - __meta_kubernetes_namespace
+        target_label: kubernetes_namespace
+      - source_labels:
+        - __meta_kubernetes_service_name
+        target_label: kubernetes_name
+    - job_name: kubernetes-pods
+      kubernetes_sd_configs:
+      - role: pod
+      relabel_configs:
+      - action: keep
+        regex: true
+        source_labels:
+        - __meta_kubernetes_pod_annotation_prometheus_io_scrape
+      - action: replace
+        regex: (.+)
+        source_labels:
+        - __meta_kubernetes_pod_annotation_prometheus_io_path
+        target_label: __metrics_path__
+      - action: replace
+        regex: ([^:]+)(?::\d+)?;(\d+)
+        replacement: $1:$2
+        source_labels:
+        - __address__
+        - __meta_kubernetes_pod_annotation_prometheus_io_port
+        target_label: __address__
+      - action: labelmap
+        regex: __meta_kubernetes_pod_label_(.+)
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_namespace
+        target_label: kubernetes_namespace
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_pod_name
+        target_label: kubernetes_pod_name
+    - job_name: kubernetes-pods-slow
+      kubernetes_sd_configs:
+      - role: pod
+      relabel_configs:
+      - action: keep
+        regex: true
+        source_labels:
+        - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow
+      - action: replace
+        regex: (.+)
+        source_labels:
+        - __meta_kubernetes_pod_annotation_prometheus_io_path
+        target_label: __metrics_path__
+      - action: replace
+        regex: ([^:]+)(?::\d+)?;(\d+)
+        replacement: $1:$2
+        source_labels:
+        - __address__
+        - __meta_kubernetes_pod_annotation_prometheus_io_port
+        target_label: __address__
+      - action: labelmap
+        regex: __meta_kubernetes_pod_label_(.+)
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_namespace
+        target_label: kubernetes_namespace
+      - action: replace
+        source_labels:
+        - __meta_kubernetes_pod_name
+        target_label: kubernetes_pod_name
+      scrape_interval: 5m
+      scrape_timeout: 30s
+  recording_rules.yml: |
+    {}
+  rules: |
+    {}
+---
+# Source: prometheus/templates/server-clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+  labels:
+    component: "server"
+    app: prometheus
+    release: prometheus
+    chart: prometheus-11.7.0
+    heritage: Helm
+  name: prometheus
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - nodes
+      - nodes/proxy
+      - nodes/metrics
+      - services
+      - endpoints
+      - pods
+      - ingresses
+      - configmaps
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - "extensions"
+      - "networking.k8s.io"
+    resources:
+      - ingresses/status
+      - ingresses
+    verbs:
+      - get
+      - list
+      - watch
+  - nonResourceURLs:
+      - "/metrics"
+    verbs:
+      - get
+---
+# Source: prometheus/templates/server-clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRoleBinding
+metadata:
+  labels:
+    component: "server"
+    app: prometheus
+    release: prometheus
+    chart: prometheus-11.7.0
+    heritage: Helm
+  name: prometheus
+subjects:
+  - kind: ServiceAccount
+    name: prometheus
+    namespace: istio-system
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: prometheus
+---
+# Source: prometheus/templates/server-service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    component: "server"
+    app: prometheus
+    release: prometheus
+    chart: prometheus-11.7.0
+    heritage: Helm
+  name: prometheus
+  namespace: istio-system
+spec:
+  ports:
+    - name: http
+      port: 9090
+      protocol: TCP
+      targetPort: 9090
+  selector:
+    component: "server"
+    app: prometheus
+    release: prometheus
+  sessionAffinity: None
+  type: "ClusterIP"
+---
+# Source: prometheus/templates/server-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    component: "server"
+    app: prometheus
+    release: prometheus
+    chart: prometheus-11.7.0
+    heritage: Helm
+  name: prometheus
+  namespace: istio-system
+spec:
+  selector:
+    matchLabels:
+      component: "server"
+      app: prometheus
+      release: prometheus
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        component: "server"
+        app: prometheus
+        release: prometheus
+        chart: prometheus-11.7.0
+        heritage: Helm
+    spec:
+      serviceAccountName: prometheus
+      containers:
+        - name: prometheus-server-configmap-reload
+          image: "jimmidyson/configmap-reload:v0.3.0"
+          imagePullPolicy: "IfNotPresent"
+          args:
+            - --volume-dir=/etc/config
+            - --webhook-url=http://127.0.0.1:9090/-/reload
+          resources:
+            {}
+          volumeMounts:
+            - name: config-volume
+              mountPath: /etc/config
+              readOnly: true
+
+        - name: prometheus-server
+          image: "prom/prometheus:v2.19.0"
+          imagePullPolicy: "IfNotPresent"
+          args:
+            - --storage.tsdb.retention.time=15d
+            - --config.file=/etc/config/prometheus.yml
+            - --storage.tsdb.path=/data
+            - --web.console.libraries=/etc/prometheus/console_libraries
+            - --web.console.templates=/etc/prometheus/consoles
+            - --web.enable-lifecycle
+          ports:
+            - containerPort: 9090
+          readinessProbe:
+            httpGet:
+              path: /-/ready
+              port: 9090
+            initialDelaySeconds: 0
+            periodSeconds: 5
+            timeoutSeconds: 30
+            failureThreshold: 3
+            successThreshold: 1
+          livenessProbe:
+            httpGet:
+              path: /-/healthy
+              port: 9090
+            initialDelaySeconds: 30
+            periodSeconds: 15
+            timeoutSeconds: 30
+            failureThreshold: 3
+            successThreshold: 1
+          resources:
+            {}
+          volumeMounts:
+            - name: config-volume
+              mountPath: /etc/config
+            - name: storage-volume
+              mountPath: /data
+              subPath: ""
+      securityContext:
+        fsGroup: 65534
+        runAsGroup: 65534
+        runAsNonRoot: true
+        runAsUser: 65534
+      terminationGracePeriodSeconds: 300
+      volumes:
+        - name: config-volume
+          configMap:
+            name: prometheus
+        - name: storage-volume
+          emptyDir:
+            {}
diff --git a/mash/eks/samples/bookinfo/README.md b/mash/eks/samples/bookinfo/README.md
new file mode 100644 (file)
index 0000000..34715ec
--- /dev/null
@@ -0,0 +1,35 @@
+# Bookinfo Sample
+
+See <https://istio.io/docs/examples/bookinfo/>
+
+## Build docker images without pushing
+
+```bash
+src/build-services.sh <version> <prefix>
+```
+
+Where `<version>` is the tag and `<prefix>` is the docker registry to tag the images.
+
+For example: `src/build-services.sh 1.1.0 docker.io/istio`.
+
+The bookinfo versions are different from Istio versions since the sample should work with any version of Istio.
+
+## Update docker images in the yaml files
+
+```bash
+sed -i "s/\(istio\/examples-bookinfo-.*\):[[:digit:]]\.[[:digit:]]\.[[:digit:]]/<your docker image with tag>/g" */bookinfo*.yaml
+```
+
+## Push docker images to docker hub
+
+One script to build the docker images, push them to docker hub and to update the yaml files
+
+```bash
+build_push_update_images.sh <version>
+```
+
+## Tests
+
+Bookinfo is tested by istio.io integration tests. You can find them under [tests/examples](https://github.com/istio/istio.io/tree/master/tests/examples) in the [istio/istio.io](https://github.com/istio/istio.io) repository.
+
+The reference productpage HTML files are in [tests/apps/bookinfo/output](https://github.com/istio/istio/tree/master/tests/apps/bookinfo/output). If the productpage HTML produced by the app is changed, remember to regenerate the reference HTML files and commit them with the same PR.
diff --git a/mash/eks/samples/bookinfo/networking/bookinfo-gateway.yaml b/mash/eks/samples/bookinfo/networking/bookinfo-gateway.yaml
new file mode 100644 (file)
index 0000000..951f069
--- /dev/null
@@ -0,0 +1,41 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: bookinfo-gateway
+spec:
+  selector:
+    istio: ingressgateway # use istio default controller
+  servers:
+  - port:
+      number: 80
+      name: http
+      protocol: HTTP
+    hosts:
+    - "*"
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: bookinfo
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - bookinfo-gateway
+  http:
+  - match:
+    - uri:
+        exact: /productpage
+    - uri:
+        prefix: /static
+    - uri:
+        exact: /login
+    - uri:
+        exact: /logout
+    - uri:
+        prefix: /api/v1/products
+    route:
+    - destination:
+        host: productpage
+        port:
+          number: 9080
diff --git a/mash/eks/samples/bookinfo/networking/certmanager-gateway.yaml b/mash/eks/samples/bookinfo/networking/certmanager-gateway.yaml
new file mode 100644 (file)
index 0000000..3fa6537
--- /dev/null
@@ -0,0 +1,35 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: cert-manager-gateway
+  namespace: istio-system
+spec:
+  selector:
+    istio: ingressgateway
+  servers:
+  - port:
+      number: 80
+      name: http
+      protocol: HTTP
+    hosts:
+    - "*"
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: cert-manager
+  namespace: istio-system
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - cert-manager-gateway
+  http:
+  - match:
+    - uri:
+        prefix: /.well-known/acme-challenge/
+    route:
+    - destination:
+        host: cert-manager-resolver
+        port:
+          number: 8089
diff --git a/mash/eks/samples/bookinfo/networking/destination-rule-all-mtls.yaml b/mash/eks/samples/bookinfo/networking/destination-rule-all-mtls.yaml
new file mode 100644 (file)
index 0000000..2a19c3f
--- /dev/null
@@ -0,0 +1,74 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: productpage
+spec:
+  host: productpage
+  trafficPolicy:
+    tls:
+      mode: ISTIO_MUTUAL
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews
+spec:
+  host: reviews
+  trafficPolicy:
+    tls:
+      mode: ISTIO_MUTUAL
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+  - name: v3
+    labels:
+      version: v3
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: ratings
+spec:
+  host: ratings
+  trafficPolicy:
+    tls:
+      mode: ISTIO_MUTUAL
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+  - name: v2-mysql
+    labels:
+      version: v2-mysql
+  - name: v2-mysql-vm
+    labels:
+      version: v2-mysql-vm
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: details
+spec:
+  host: details
+  trafficPolicy:
+    tls:
+      mode: ISTIO_MUTUAL
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+---
diff --git a/mash/eks/samples/bookinfo/networking/destination-rule-all.yaml b/mash/eks/samples/bookinfo/networking/destination-rule-all.yaml
new file mode 100644 (file)
index 0000000..96be699
--- /dev/null
@@ -0,0 +1,62 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: productpage
+spec:
+  host: productpage
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews
+spec:
+  host: reviews
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+  - name: v3
+    labels:
+      version: v3
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: ratings
+spec:
+  host: ratings
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+  - name: v2-mysql
+    labels:
+      version: v2-mysql
+  - name: v2-mysql-vm
+    labels:
+      version: v2-mysql-vm
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: details
+spec:
+  host: details
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+---
diff --git a/mash/eks/samples/bookinfo/networking/destination-rule-reviews.yaml b/mash/eks/samples/bookinfo/networking/destination-rule-reviews.yaml
new file mode 100644 (file)
index 0000000..69f30f1
--- /dev/null
@@ -0,0 +1,19 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews
+spec:
+  host: reviews
+  trafficPolicy:
+    loadBalancer:
+      simple: RANDOM
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+  - name: v3
+    labels:
+      version: v3
diff --git a/mash/eks/samples/bookinfo/networking/egress-rule-google-apis.yaml b/mash/eks/samples/bookinfo/networking/egress-rule-google-apis.yaml
new file mode 100644 (file)
index 0000000..d35e3ac
--- /dev/null
@@ -0,0 +1,46 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: googleapis
+spec:
+  hosts:
+  - www.googleapis.com
+  ports:
+  - number: 80
+    name: http
+    protocol: HTTP
+  - number: 443
+    name: https
+    protocol: HTTPS
+  resolution: DNS
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: rewrite-port-for-googleapis
+spec:
+  hosts:
+  - www.googleapis.com
+  http:
+  - match:
+    - port: 80
+    route:
+    - destination:
+        host: www.googleapis.com
+        port:
+          number: 443
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: originate-tls-for-googleapis
+spec:
+  host: www.googleapis.com
+  trafficPolicy:
+    loadBalancer:
+      simple: ROUND_ROBIN
+    portLevelSettings:
+    - port:
+        number: 443
+      tls:
+        mode: SIMPLE # initiates HTTPS when accessing www.googleapis.com
diff --git a/mash/eks/samples/bookinfo/networking/fault-injection-details-v1.yaml b/mash/eks/samples/bookinfo/networking/fault-injection-details-v1.yaml
new file mode 100644 (file)
index 0000000..c455092
--- /dev/null
@@ -0,0 +1,32 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: details
+spec:
+  hosts:
+  - details
+  http:
+  - fault:
+      abort:
+        httpStatus: 555
+        percentage:
+          value: 100
+    route:
+    - destination:
+        host: details
+        subset: v1
+  - route:
+    - destination:
+        host: details
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: details
+spec:
+  host: details
+  subsets:
+  - name: v1
+    labels:
+      version: v1
\ No newline at end of file
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-all-v1.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-all-v1.yaml
new file mode 100644 (file)
index 0000000..6811e31
--- /dev/null
@@ -0,0 +1,52 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: productpage
+spec:
+  hosts:
+  - productpage
+  http:
+  - route:
+    - destination:
+        host: productpage
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+  - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        host: ratings
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: details
+spec:
+  hosts:
+  - details
+  http:
+  - route:
+    - destination:
+        host: details
+        subset: v1
+---
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-details-v2.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-details-v2.yaml
new file mode 100644 (file)
index 0000000..5f21fa5
--- /dev/null
@@ -0,0 +1,12 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: details
+spec:
+  hosts:
+  - details
+  http:
+  - route:
+    - destination:
+        host: details
+        subset: v2
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-ratings-db.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-ratings-db.yaml
new file mode 100644 (file)
index 0000000..1698ec2
--- /dev/null
@@ -0,0 +1,26 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+  - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v3
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        host: ratings
+        subset: v2
+---
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-ratings-mysql-vm.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-ratings-mysql-vm.yaml
new file mode 100644 (file)
index 0000000..fdf8827
--- /dev/null
@@ -0,0 +1,26 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+  - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v3
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        host: ratings
+        subset: v2-mysql-vm
+---
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-ratings-mysql.yaml
new file mode 100644 (file)
index 0000000..03a700e
--- /dev/null
@@ -0,0 +1,26 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+  - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v3
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings
+  http:
+  - route:
+    - destination:
+        host: ratings
+        subset: v2-mysql
+---
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
new file mode 100644 (file)
index 0000000..51c6fe9
--- /dev/null
@@ -0,0 +1,25 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    fault:
+      abort:
+        percentage:
+          value: 100.0
+        httpStatus: 500
+    route:
+    - destination:
+        host: ratings
+        subset: v1
+  - route:
+    - destination:
+        host: ratings
+        subset: v1
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
new file mode 100644 (file)
index 0000000..6c4e19d
--- /dev/null
@@ -0,0 +1,25 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    fault:
+      delay:
+        percentage:
+          value: 100.0
+        fixedDelay: 7s
+    route:
+    - destination:
+        host: ratings
+        subset: v1
+  - route:
+    - destination:
+        host: ratings
+        subset: v1
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
new file mode 100644 (file)
index 0000000..aad8c31
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v1
+      weight: 50
+    - destination:
+        host: reviews
+        subset: v3
+      weight: 50
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-80-20.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-80-20.yaml
new file mode 100644 (file)
index 0000000..7304d86
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v1
+      weight: 80
+    - destination:
+        host: reviews
+        subset: v2
+      weight: 20
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-90-10.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
new file mode 100644 (file)
index 0000000..d211dd1
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v1
+      weight: 90
+    - destination:
+        host: reviews
+        subset: v2
+      weight: 10
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml
new file mode 100644 (file)
index 0000000..fb35713
--- /dev/null
@@ -0,0 +1,20 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+  - reviews
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    route:
+    - destination:
+        host: reviews
+        subset: v2
+  - route:
+    - destination:
+        host: reviews
+        subset: v3
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
new file mode 100644 (file)
index 0000000..ea07efb
--- /dev/null
@@ -0,0 +1,20 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    route:
+    - destination:
+        host: reviews
+        subset: v2
+  - route:
+    - destination:
+        host: reviews
+        subset: v1
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-v2-v3.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-v2-v3.yaml
new file mode 100644 (file)
index 0000000..7ae7b80
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v2
+      weight: 50
+    - destination:
+        host: reviews
+        subset: v3
+      weight: 50
diff --git a/mash/eks/samples/bookinfo/networking/virtual-service-reviews-v3.yaml b/mash/eks/samples/bookinfo/networking/virtual-service-reviews-v3.yaml
new file mode 100644 (file)
index 0000000..5da999d
--- /dev/null
@@ -0,0 +1,12 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews
+  http:
+  - route:
+    - destination:
+        host: reviews
+        subset: v3
diff --git a/mash/eks/samples/bookinfo/platform/consul/README.md b/mash/eks/samples/bookinfo/platform/consul/README.md
new file mode 100644 (file)
index 0000000..92a5250
--- /dev/null
@@ -0,0 +1,75 @@
+# Consul Adapter for Istio on Docker
+
+Make Istio run in docker environment by integrating Consul as a service registry.
+
+## Disclaimer
+
+This example is not included in Istio's release verification testing, so it may not function exactly as documented.
+
+## Design Principle
+
+The key issue is how to implement the ServiceDiscovery interface functions in Istio.
+This platform adapter uses Consul Server to help Istio monitor service instances running in the underlying platform.
+When a service instance is brought up in docker, the [Registrator](http://gliderlabs.github.io/registrator/latest/)
+automatically registers the service in Consul.
+
+Note that Istio pilot is running inside each app container so as to coordinate Envoy and the service mesh.
+
+## Prerequisites
+
+* Clone Istio Pilot [repo](https://github.com/istio/pilot) (required only if building images locally)
+
+* Download istioctl from Istio's [releases page](https://github.com/istio/istio/releases) or build from
+source in Istio Pilot repository
+
+## Bookinfo Demo
+
+The ingress controller is still under construction, routing functionalities can be tested by curling a service container directly.
+
+To build all images for the bookinfo sample for the consul adapter, run:
+
+```bash
+samples/bookinfo/src/build-services.sh <version> <prefix>
+```
+
+Where `<version>` is the tag and `<prefix>` is the docker registry to tag the images.
+
+For example: `src/build-services.sh 1.1.0 docker.io/istio`.
+
+For Linux users, configure the `DOCKER_GATEWAY` environment variable
+
+```bash
+export DOCKER_GATEWAY=172.28.0.1:
+```
+
+To bring up the control plane containers directly, from the root repository directory run
+
+```bash
+docker-compose -f install/consul/istio.yaml up -d
+```
+
+This will pull images from docker hub to your local computing space.
+
+Now you can see all the containers in the mesh by running `docker ps -a`.
+
+If the webpage is not displaying properly, you may need to run the previous command once more to resolve a timing issue during start up.
+
+To bring up the app containers, from the `samples/bookinfo/consul` directory run
+
+```bash
+docker-compose -f bookinfo.yaml up -d
+```
+
+To view the productpage webpage, open a web browser and enter `localhost:9081/productpage`.
+
+If you refresh the page several times, you should see different versions of reviews shown in productpage presented in a round robin style (red stars, black stars, no stars).
+
+Configure `kubectl` to use the locally mapped port for the Istio api server
+
+```bash
+kubectl config set-context istio --cluster=istio
+kubectl config set-cluster istio --server=http://localhost:8080
+kubectl config use-context istio
+```
+
+If you are an advanced consul and docker network user, you may choose to configure your own envoymesh network dns and consul port mapping and istio-apiserver ipv4_address in the `istio.yaml` file.
diff --git a/mash/eks/samples/bookinfo/platform/consul/bookinfo.yaml b/mash/eks/samples/bookinfo/platform/consul/bookinfo.yaml
new file mode 100644 (file)
index 0000000..552e1bb
--- /dev/null
@@ -0,0 +1,128 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+############################################################################
+version: '2'
+services:
+  details-v1:
+    image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
+    networks:
+      istiomesh:
+    dns:
+      - 172.28.0.1
+      - 8.8.8.8
+    dns_search:
+        - service.consul
+    environment:
+      - SERVICE_NAME=details
+      - SERVICE_TAGS=version|v1
+      - SERVICE_PROTOCOL=http
+      - SERVICE_VERSION=v1
+    expose:
+      - "9080"
+
+  ratings-v1:
+    image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
+    networks:
+      istiomesh:
+    dns:
+      - 172.28.0.1
+      - 8.8.8.8
+    dns_search:
+        - service.consul
+    environment:
+      - SERVICE_NAME=ratings
+      - SERVICE_TAGS=version|v1
+      - SERVICE_PROTOCOL=http
+      - SERVICE_VERSION=v1
+    expose:
+      - "9080"
+
+  reviews-v1:
+    image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
+    networks:
+      istiomesh:
+    dns:
+      - 172.28.0.1
+      - 8.8.8.8
+    dns_search:
+        - service.consul
+    environment:
+      - SERVICE_9080_NAME=reviews
+      - SERVICE_TAGS=version|v1
+      - SERVICE_PROTOCOL=http
+      - SERVICE_9443_IGNORE=1
+      - SERVICE_VERSION=v1
+    expose:
+      - "9080"
+
+  reviews-v2:
+    image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
+    networks:
+      istiomesh:
+    dns:
+      - 172.28.0.1
+      - 8.8.8.8
+    dns_search:
+        - service.consul
+    environment:
+      - SERVICE_9080_NAME=reviews
+      - SERVICE_TAGS=version|v2
+      - SERVICE_PROTOCOL=http
+      - SERVICE_9443_IGNORE=1
+      - SERVICE_VERSION=v2
+    expose:
+      - "9080"
+
+  reviews-v3:
+    image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
+    networks:
+      istiomesh:
+    dns:
+      - 172.28.0.1
+      - 8.8.8.8
+    dns_search:
+        - service.consul
+    environment:
+      - SERVICE_9080_NAME=reviews
+      - SERVICE_TAGS=version|v3
+      - SERVICE_PROTOCOL=http
+      - SERVICE_9443_IGNORE=1
+      - SERVICE_VERSION=v3
+    expose:
+      - "9080"
+
+  productpage-v1:
+    image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
+    networks:
+      istiomesh:
+        ipv4_address: 172.28.0.14
+    dns:
+      - 172.28.0.1
+      - 8.8.8.8
+    dns_search:
+        - service.consul
+    environment:
+      - SERVICE_NAME=productpage
+      - SERVICE_TAGS=version|v1
+      - SERVICE_PROTOCOL=http
+      - SERVICE_VERSION=v1
+    ports:
+      - "9081:9080"
+    expose:
+      - "9080"
+networks:
+  istiomesh:
+    external:
+      name: consul_istiomesh
diff --git a/mash/eks/samples/bookinfo/platform/consul/cleanup.sh b/mash/eks/samples/bookinfo/platform/consul/cleanup.sh
new file mode 100755 (executable)
index 0000000..ca7fd57
--- /dev/null
@@ -0,0 +1,61 @@
+#!/bin/bash
+#
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+
+# only ask if in interactive mode
+if [[ -t 0 ]];then
+  echo -n "namespace ? [default] "
+  read -r NAMESPACE
+fi
+
+if [[ -z ${NAMESPACE} ]];then
+  NAMESPACE=default
+fi
+
+echo "using NAMESPACE=${NAMESPACE}"
+
+protos=( destinationrules virtualservices gateways )
+for proto in "${protos[@]}"; do
+  for resource in $(kubectl get -n ${NAMESPACE} "$proto" -o name); do
+    kubectl delete -n ${NAMESPACE} "$resource";
+  done
+done
+
+OUTPUT=$(mktemp)
+export OUTPUT
+echo "Application cleanup may take up to one minute"
+docker-compose -f "$SCRIPTDIR/bookinfo.sidecars.yaml" down > "${OUTPUT}" 2>&1
+docker-compose -f "$SCRIPTDIR/bookinfo.yaml" down > "${OUTPUT}" 2>&1
+ret=$?
+function cleanup() {
+  rm -f "${OUTPUT}"
+}
+
+trap cleanup EXIT
+
+if [[ ${ret} -eq 0 ]];then
+  cat "${OUTPUT}"
+else
+  # ignore NotFound errors
+  OUT2=$(grep -v NotFound "${OUTPUT}")
+  if [[ -n ${OUT2} ]];then
+    cat "${OUTPUT}"
+    exit ${ret}
+  fi
+fi
+
+echo "Application cleanup successful"
diff --git a/mash/eks/samples/bookinfo/platform/consul/destination-rule-all.yaml b/mash/eks/samples/bookinfo/platform/consul/destination-rule-all.yaml
new file mode 100644 (file)
index 0000000..e28055a
--- /dev/null
@@ -0,0 +1,53 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: productpage
+spec:
+  host: productpage.service.consul
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: reviews
+spec:
+  host: reviews.service.consul
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+  - name: v3
+    labels:
+      version: v3
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: ratings
+spec:
+  host: ratings.service.consul
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: details
+spec:
+  host: details.service.consul
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+---
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-all-v1.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-all-v1.yaml
new file mode 100644 (file)
index 0000000..19b4772
--- /dev/null
@@ -0,0 +1,52 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: productpage
+spec:
+  hosts:
+  - productpage.service.consul
+  http:
+  - route:
+    - destination:
+        host: productpage.service.consul
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+  - reviews.service.consul
+  http:
+  - route:
+    - destination:
+        host: reviews.service.consul
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings.service.consul
+  http:
+  - route:
+    - destination:
+        host: ratings.service.consul
+        subset: v1
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: details
+spec:
+  hosts:
+  - details.service.consul
+  http:
+  - route:
+    - destination:
+        host: details.service.consul
+        subset: v1
+---
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-ratings-test-abort.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-ratings-test-abort.yaml
new file mode 100644 (file)
index 0000000..f0c8f6d
--- /dev/null
@@ -0,0 +1,25 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings.service.consul
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    fault:
+      abort:
+        percentage:
+          value: 100.0
+        httpStatus: 500
+    route:
+    - destination:
+        host: ratings.service.consul
+        subset: v1
+  - route:
+    - destination:
+        host: ratings.service.consul
+        subset: v1
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-ratings-test-delay.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-ratings-test-delay.yaml
new file mode 100644 (file)
index 0000000..1978632
--- /dev/null
@@ -0,0 +1,25 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: ratings
+spec:
+  hosts:
+  - ratings.service.consul
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    fault:
+      delay:
+        percentage:
+          value: 100.0
+        fixedDelay: 7s
+    route:
+    - destination:
+        host: ratings.service.consul
+        subset: v1
+  - route:
+    - destination:
+        host: ratings.service.consul
+        subset: v1
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-50-v3.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-50-v3.yaml
new file mode 100644 (file)
index 0000000..7e91c8c
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews.service.consul
+  http:
+  - route:
+    - destination:
+        host: reviews.service.consul
+        subset: v1
+      weight: 50
+    - destination:
+        host: reviews.service.consul
+        subset: v3
+      weight: 50
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-test-v2.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-test-v2.yaml
new file mode 100644 (file)
index 0000000..92fa461
--- /dev/null
@@ -0,0 +1,20 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews.service.consul
+  http:
+  - match:
+    - headers:
+        end-user:
+          exact: jason
+    route:
+    - destination:
+        host: reviews.service.consul
+        subset: v2
+  - route:
+    - destination:
+        host: reviews.service.consul
+        subset: v1
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-v2-v3.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-v2-v3.yaml
new file mode 100644 (file)
index 0000000..60271c0
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews.service.consul
+  http:
+  - route:
+    - destination:
+        host: reviews.service.consul
+        subset: v2
+      weight: 50
+    - destination:
+        host: reviews.service.consul
+        subset: v3
+      weight: 50
diff --git a/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-v3.yaml b/mash/eks/samples/bookinfo/platform/consul/virtual-service-reviews-v3.yaml
new file mode 100644 (file)
index 0000000..da9440c
--- /dev/null
@@ -0,0 +1,12 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: reviews
+spec:
+  hosts:
+    - reviews.service.consul
+  http:
+  - route:
+    - destination:
+        host: reviews.service.consul
+        subset: v3
diff --git a/mash/eks/samples/bookinfo/platform/kube/README.md b/mash/eks/samples/bookinfo/platform/kube/README.md
new file mode 100644 (file)
index 0000000..d1189be
--- /dev/null
@@ -0,0 +1,2 @@
+See the [Bookinfo guide](https://istio.io/docs/guides/bookinfo.html) in Istio
+docs for instructions on how to run this demo application.
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-certificate.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-certificate.yaml
new file mode 100644 (file)
index 0000000..bce874d
--- /dev/null
@@ -0,0 +1,37 @@
+---
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: ClusterIssuer
+metadata:
+  name: letsencrypt-staging
+  namespace: istio-system
+spec:
+  acme:
+    # The ACME server URL
+    server: https://acme-staging-v02.api.letsencrypt.org/directory
+    # Email address used for ACME registration
+    email: stage@istio.io
+    # Name of a secret used to store the ACME account private key
+    privateKeySecretRef:
+      name: letsencrypt-staging
+    # Enable the HTTP-01 challenge provider
+    http01: {}
+---
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+  name: istio-ingressgateway-certs
+  namespace: istio-system
+spec:
+  secretName: istio-ingressgateway-certs
+  issuerRef:
+    name: letsencrypt-staging
+    kind: ClusterIssuer
+  commonName: bookinfo.example.com
+  dnsNames:
+  - bookinfo.example.com
+  acme:
+    config:
+    - http01:
+        ingressClass: none
+      domains:
+      - bookinfo.example.com
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-db.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-db.yaml
new file mode 100644 (file)
index 0000000..b0e0f17
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: mongodb
+  labels:
+    app: mongodb
+spec:
+  ports:
+  - port: 27017
+    name: mongo
+  selector:
+    app: mongodb
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mongodb-v1
+  labels:
+    app: mongodb
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: mongodb
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: mongodb
+        version: v1
+    spec:
+      containers:
+      - name: mongodb 
+        image: docker.io/istio/examples-bookinfo-mongodb:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 27017
+        volumeMounts:
+        - name: data-db
+          mountPath: /data/db
+      volumes:
+      - name: data-db
+        emptyDir: {}
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-details-v2.yaml
new file mode 100644 (file)
index 0000000..8b29910
--- /dev/null
@@ -0,0 +1,46 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Details service v2
+##################################################################################################
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: details-v2
+  labels:
+    app: details
+    version: v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: details
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: details
+        version: v2
+    spec:
+      containers:
+      - name: details
+        image: docker.io/istio/examples-bookinfo-details-v2:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+        env:
+        - name: DO_NOT_ENCRYPT
+          value: "true"
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-details.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-details.yaml
new file mode 100644 (file)
index 0000000..ee8c616
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Details service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: details
+  labels:
+    app: details
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: details
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: details-v1
+  labels:
+    app: details
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: details
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: details
+        version: v1
+    spec:
+      containers:
+      - name: details
+        image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-ingress.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-ingress.yaml
new file mode 100644 (file)
index 0000000..0a2bb9d
--- /dev/null
@@ -0,0 +1,48 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+###########################################################################
+# Ingress resource (gateway)
+##########################################################################
+apiVersion: networking.k8s.io/v1beta1
+kind: Ingress
+metadata:
+  name: gateway
+  annotations:
+    kubernetes.io/ingress.class: "istio"
+spec:
+  rules:
+  - http:
+      paths:
+      - path: /productpage
+        backend:
+          serviceName: productpage
+          servicePort: 9080
+      - path: /static/*
+        backend:
+          serviceName: productpage
+          servicePort: 9080
+      - path: /login
+        backend:
+          serviceName: productpage
+          servicePort: 9080
+      - path: /logout
+        backend:
+          serviceName: productpage
+          servicePort: 9080
+      - path: /api/v1/products.*
+        backend:
+          serviceName: productpage
+          servicePort: 9080
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-mysql.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-mysql.yaml
new file mode 100644 (file)
index 0000000..3c9d633
--- /dev/null
@@ -0,0 +1,78 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Mysql db services
+# credentials: root/password
+##################################################################################################
+apiVersion: v1
+kind: Secret
+metadata:
+  name: mysql-credentials
+type: Opaque
+data:
+  rootpasswd: cGFzc3dvcmQ=
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: mysqldb
+  labels:
+    app: mysqldb
+spec:
+  ports:
+  - port: 3306
+    name: tcp
+  selector:
+    app: mysqldb
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: mysqldb-v1
+  labels:
+    app: mysqldb
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: mysqldb
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: mysqldb
+        version: v1
+    spec:
+      containers:
+      - name: mysqldb
+        image: docker.io/istio/examples-bookinfo-mysqldb:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 3306
+        env:
+          - name: MYSQL_ROOT_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: mysql-credentials
+                key: rootpasswd
+        args: ["--default-authentication-plugin","mysql_native_password"]
+        volumeMounts:
+        - name: var-lib-mysql
+          mountPath: /var/lib/mysql
+      volumes:
+      - name: var-lib-mysql
+        emptyDir: {}
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-discovery.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-discovery.yaml
new file mode 100644 (file)
index 0000000..9967d51
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Ratings service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: ratings
+  labels:
+    app: ratings
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: ratings
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql-vm.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql-vm.yaml
new file mode 100644 (file)
index 0000000..6fd844b
--- /dev/null
@@ -0,0 +1,53 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ratings-v2-mysql-vm
+  labels:
+    app: ratings
+    version: v2-mysql-vm
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ratings
+      version: v2-mysql-vm
+  template:
+    metadata:
+      labels:
+        app: ratings
+        version: v2-mysql-vm
+    spec:
+      containers:
+      - name: ratings
+        image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+          # This assumes you registered your mysql vm as
+          # istioctl register -n vm mysqldb 1.2.3.4 3306
+          - name: DB_TYPE
+            value: "mysql"
+          - name: MYSQL_DB_HOST
+            value: mysqldb.vm.svc.cluster.local
+          - name: MYSQL_DB_PORT
+            value: "3306"
+          - name: MYSQL_DB_USER
+            value: root
+          - name: MYSQL_DB_PASSWORD
+            value: password
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql.yaml
new file mode 100644 (file)
index 0000000..daf48b4
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ratings-v2-mysql
+  labels:
+    app: ratings
+    version: v2-mysql
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ratings
+      version: v2-mysql
+  template:
+    metadata:
+      labels:
+        app: ratings
+        version: v2-mysql
+    spec:
+      containers:
+      - name: ratings
+        image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+          # ratings-v2 will use mongodb as the default db backend.
+          # if you would like to use mysqldb then you can use this file
+          # which sets DB_TYPE = 'mysql' and the rest of the parameters shown
+          # here and also create the # mysqldb service using bookinfo-mysql.yaml
+          # NOTE: This file is mutually exclusive to bookinfo-ratings-v2.yaml
+          - name: DB_TYPE
+            value: "mysql"
+          - name: MYSQL_DB_HOST
+            value: mysqldb
+          - name: MYSQL_DB_PORT
+            value: "3306"
+          - name: MYSQL_DB_USER
+            value: root
+          - name: MYSQL_DB_PASSWORD
+            value: password
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings-v2.yaml
new file mode 100644 (file)
index 0000000..656f4c4
--- /dev/null
@@ -0,0 +1,63 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: bookinfo-ratings-v2
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ratings-v2
+  labels:
+    app: ratings
+    version: v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ratings
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: ratings
+        version: v2
+    spec:
+      serviceAccountName: bookinfo-ratings-v2
+      containers:
+      - name: ratings
+        image: docker.io/istio/examples-bookinfo-ratings-v2:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+          # ratings-v2 will use mongodb as the default db backend.
+          # if you would like to use mysqldb then set DB_TYPE = 'mysql', set
+          # the rest of the parameters shown here and also create the
+          # mysqldb service using bookinfo-mysql.yaml
+          # - name: DB_TYPE #default to
+          #   value: "mysql"
+          # - name: MYSQL_DB_HOST
+          #   value: mysqldb
+          # - name: MYSQL_DB_PORT
+          #   value: "3306"
+          # - name: MYSQL_DB_USER
+          #   value: root
+          # - name: MYSQL_DB_PASSWORD
+          #  value: password
+          - name: MONGO_DB_URL
+            value: mongodb://mongodb:27017/test
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-ratings.yaml
new file mode 100644 (file)
index 0000000..aeb56d6
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Ratings service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: ratings
+  labels:
+    app: ratings
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: ratings
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ratings-v1
+  labels:
+    app: ratings
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ratings
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: ratings
+        version: v1
+    spec:
+      containers:
+      - name: ratings
+        image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo-reviews-v2.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo-reviews-v2.yaml
new file mode 100644 (file)
index 0000000..3b1709c
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Reviews service v2
+##################################################################################################
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: reviews-v2
+  labels:
+    app: reviews
+    version: v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: reviews
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: reviews
+        version: v2
+    spec:
+      containers:
+      - name: reviews
+        image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+        - name: LOG_DIR
+          value: "/tmp/logs"
+        ports:
+        - containerPort: 9080
+        volumeMounts:
+        - name: tmp
+          mountPath: /tmp
+        - name: wlp-output
+          mountPath: /opt/ibm/wlp/output
+      volumes:
+      - name: wlp-output
+        emptyDir: {}
+      - name: tmp
+        emptyDir: {}
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/bookinfo.yaml b/mash/eks/samples/bookinfo/platform/kube/bookinfo.yaml
new file mode 100644 (file)
index 0000000..1f68bca
--- /dev/null
@@ -0,0 +1,331 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# This file defines the services, service accounts, and deployments for the Bookinfo sample.
+#
+# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
+#
+#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
+#
+# Alternatively, you can deploy any resource separately:
+#
+#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
+#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
+#   kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
+##################################################################################################
+
+##################################################################################################
+# Details service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: details
+  labels:
+    app: details
+    service: details
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: details
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: bookinfo-details
+  labels:
+    account: details
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: details-v1
+  labels:
+    app: details
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: details
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: details
+        version: v1
+    spec:
+      serviceAccountName: bookinfo-details
+      containers:
+      - name: details
+        image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
+##################################################################################################
+# Ratings service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: ratings
+  labels:
+    app: ratings
+    service: ratings
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: ratings
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: bookinfo-ratings
+  labels:
+    account: ratings
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ratings-v1
+  labels:
+    app: ratings
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: ratings
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: ratings
+        version: v1
+    spec:
+      serviceAccountName: bookinfo-ratings
+      containers:
+      - name: ratings
+        image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
+##################################################################################################
+# Reviews service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: reviews
+  labels:
+    app: reviews
+    service: reviews
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: reviews
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: bookinfo-reviews
+  labels:
+    account: reviews
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: reviews-v1
+  labels:
+    app: reviews
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: reviews
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: reviews
+        version: v1
+    spec:
+      serviceAccountName: bookinfo-reviews
+      containers:
+      - name: reviews
+        image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+        - name: LOG_DIR
+          value: "/tmp/logs"
+        ports:
+        - containerPort: 9080
+        volumeMounts:
+        - name: tmp
+          mountPath: /tmp
+        - name: wlp-output
+          mountPath: /opt/ibm/wlp/output
+      volumes:
+      - name: wlp-output
+        emptyDir: {}
+      - name: tmp
+        emptyDir: {}
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: reviews-v2
+  labels:
+    app: reviews
+    version: v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: reviews
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: reviews
+        version: v2
+    spec:
+      serviceAccountName: bookinfo-reviews
+      containers:
+      - name: reviews
+        image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+        - name: LOG_DIR
+          value: "/tmp/logs"
+        ports:
+        - containerPort: 9080
+        volumeMounts:
+        - name: tmp
+          mountPath: /tmp
+        - name: wlp-output
+          mountPath: /opt/ibm/wlp/output
+      volumes:
+      - name: wlp-output
+        emptyDir: {}
+      - name: tmp
+        emptyDir: {}
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: reviews-v3
+  labels:
+    app: reviews
+    version: v3
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: reviews
+      version: v3
+  template:
+    metadata:
+      labels:
+        app: reviews
+        version: v3
+    spec:
+      serviceAccountName: bookinfo-reviews
+      containers:
+      - name: reviews
+        image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
+        imagePullPolicy: IfNotPresent
+        env:
+        - name: LOG_DIR
+          value: "/tmp/logs"
+        ports:
+        - containerPort: 9080
+        volumeMounts:
+        - name: tmp
+          mountPath: /tmp
+        - name: wlp-output
+          mountPath: /opt/ibm/wlp/output
+      volumes:
+      - name: wlp-output
+        emptyDir: {}
+      - name: tmp
+        emptyDir: {}
+---
+##################################################################################################
+# Productpage services
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: productpage
+  labels:
+    app: productpage
+    service: productpage
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: productpage
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: bookinfo-productpage
+  labels:
+    account: productpage
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: productpage-v1
+  labels:
+    app: productpage
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: productpage
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: productpage
+        version: v1
+    spec:
+      serviceAccountName: bookinfo-productpage
+      containers:
+      - name: productpage
+        image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+        volumeMounts:
+        - name: tmp
+          mountPath: /tmp
+      volumes:
+      - name: tmp
+        emptyDir: {}
+---
diff --git a/mash/eks/samples/bookinfo/platform/kube/cleanup.sh b/mash/eks/samples/bookinfo/platform/kube/cleanup.sh
new file mode 100755 (executable)
index 0000000..ca80ec5
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/bash
+#
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+SCRIPTDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+
+# only ask if in interactive mode
+if [[ -t 0 && -z ${NAMESPACE} ]];then
+  echo -n "namespace ? [default] "
+  read -r NAMESPACE
+fi
+
+# verify if the namespace exists, otherwise use default namespace
+if [[ -n ${NAMESPACE} ]];then
+  ns=$(kubectl get namespace "${NAMESPACE}" --no-headers --output=go-template="{{.metadata.name}}" 2>/dev/null)
+  if [[ -z ${ns} ]];then
+    echo "NAMESPACE ${NAMESPACE} not found."
+    NAMESPACE=default
+  fi
+fi
+
+# if no namesapce is provided, use default namespace
+if [[ -z ${NAMESPACE} ]];then
+  NAMESPACE=default
+fi
+
+echo "using NAMESPACE=${NAMESPACE}"
+
+protos=( destinationrules virtualservices gateways )
+for proto in "${protos[@]}"; do
+  for resource in $(kubectl get -n ${NAMESPACE} "$proto" -o name); do
+    kubectl delete -n ${NAMESPACE} "$resource";
+  done
+done
+
+OUTPUT=$(mktemp)
+export OUTPUT
+echo "Application cleanup may take up to one minute"
+kubectl delete -n ${NAMESPACE} -f "$SCRIPTDIR/bookinfo.yaml" > "${OUTPUT}" 2>&1
+ret=$?
+function cleanup() {
+  rm -f "${OUTPUT}"
+}
+
+trap cleanup EXIT
+
+if [[ ${ret} -eq 0 ]];then
+  cat "${OUTPUT}"
+else
+  # ignore NotFound errors
+  OUT2=$(grep -v NotFound "${OUTPUT}")
+  if [[ -n ${OUT2} ]];then
+    cat "${OUTPUT}"
+    exit ${ret}
+  fi
+fi
+
+# wait for 30 sec for bookinfo to clean up
+sleep 30
+
+echo "Application cleanup successful"
diff --git a/mash/eks/samples/bookinfo/platform/kube/productpage-nodeport.yaml b/mash/eks/samples/bookinfo/platform/kube/productpage-nodeport.yaml
new file mode 100644 (file)
index 0000000..aadba2e
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Productpage services
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: productpage
+  labels:
+    app: productpage
+    service: productpage
+spec:
+  type: NodePort
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: productpage
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-ip-crd.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-ip-crd.yaml
new file mode 100644 (file)
index 0000000..63fc5e6
--- /dev/null
@@ -0,0 +1,29 @@
+apiVersion: config.istio.io/v1alpha2
+kind: listchecker
+metadata:
+  name: whitelistip
+spec:
+  # providerUrl: ordinarily black and white lists are maintained
+  # externally and fetched asynchronously using the providerUrl.
+  overrides: ["10.57.0.0/16"]  # overrides provide a static list
+  blacklist: false
+  entryType: IP_ADDRESSES
+---
+apiVersion: config.istio.io/v1alpha2
+kind: listentry
+metadata:
+  name: sourceip
+spec:
+  value: source.ip | ip("0.0.0.0")
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: checkip
+spec:
+  match: source.labels["istio"] == "ingressgateway"
+  actions:
+  - handler: whitelistip.listchecker
+    instances:
+    - sourceip.listentry
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-ip.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-ip.yaml
new file mode 100644 (file)
index 0000000..b771fd6
--- /dev/null
@@ -0,0 +1,32 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: whitelistip
+spec:
+  compiledAdapter: listchecker
+  params:
+    # providerUrl: ordinarily black and white lists are maintained
+    # externally and fetched asynchronously using the providerUrl.
+    overrides: ["10.57.0.0/16"]  # overrides provide a static list
+    blacklist: false
+    entryType: IP_ADDRESSES
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: sourceip
+spec:
+  compiledTemplate: listentry
+  params:
+    value: source.ip | ip("0.0.0.0")
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: checkip
+spec:
+  match: source.labels["istio"] == "ingressgateway"
+  actions:
+  - handler: whitelistip
+    instances: [ sourceip ]
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-label-crd.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-label-crd.yaml
new file mode 100644 (file)
index 0000000..249d505
--- /dev/null
@@ -0,0 +1,24 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: denier
+metadata:
+  name: denyreviewsv3handler
+spec:
+  status:
+    code: 7
+    message: Not allowed
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: checknothing
+metadata:
+  name: denyreviewsv3request
+spec:
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: denyreviewsv3
+spec:
+  match: destination.labels["app"] == "ratings" && source.labels["app"]=="reviews" && source.labels["version"] == "v3"
+  actions:
+  - handler: denyreviewsv3handler.denier
+    instances: [ denyreviewsv3request.checknothing ]
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-label.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-label.yaml
new file mode 100644 (file)
index 0000000..0d1e85e
--- /dev/null
@@ -0,0 +1,27 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: denyreviewsv3handler
+spec:
+  compiledAdapter: denier
+  params:
+    status:
+      code: 7
+      message: Not allowed
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: denyreviewsv3request
+spec:
+  compiledTemplate: checknothing
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: denyreviewsv3
+spec:
+  match: destination.labels["app"] == "ratings" && source.labels["app"]=="reviews" && source.labels["version"] == "v3"
+  actions:
+  - handler: denyreviewsv3handler
+    instances: [ denyreviewsv3request ]
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-serviceaccount.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-serviceaccount.yaml
new file mode 100644 (file)
index 0000000..c7b91c1
--- /dev/null
@@ -0,0 +1,27 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: denyproductpagehandler
+spec:
+  compiledAdapter: denier
+  params:
+    status:
+      code: 7
+      message: Not allowed
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: denyproductpagerequest
+spec:
+  compiledTemplate: checknothing
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: denyproductpage
+spec:
+  match: destination.labels["app"] == "details" && source.user == "cluster.local/ns/default/sa/bookinfo-productpage"
+  actions:
+  - handler: denyproductpagehandler
+    instances: [ denyproductpagerequest ]
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-whitelist-crd.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-whitelist-crd.yaml
new file mode 100644 (file)
index 0000000..7486e6e
--- /dev/null
@@ -0,0 +1,28 @@
+apiVersion: config.istio.io/v1alpha2
+kind: listchecker
+metadata:
+  name: whitelist
+spec:
+  # providerUrl: ordinarily black and white lists are maintained
+  # externally and fetched asynchronously using the providerUrl.
+  overrides: ["v1", "v2"]  # overrides provide a static list
+  blacklist: false
+---
+apiVersion: config.istio.io/v1alpha2
+kind: listentry
+metadata:
+  name: appversion
+spec:
+  value: source.labels["version"]
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: checkversion
+spec:
+  match: destination.labels["app"] == "ratings"
+  actions:
+  - handler: whitelist.listchecker
+    instances:
+    - appversion.listentry
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-deny-whitelist.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-deny-whitelist.yaml
new file mode 100644 (file)
index 0000000..4c51279
--- /dev/null
@@ -0,0 +1,31 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: whitelist
+spec:
+  compiledAdapter: listchecker
+  params:
+    # providerUrl: ordinarily black and white lists are maintained
+    # externally and fetched asynchronously using the providerUrl.
+    overrides: ["v1", "v2"]  # overrides provide a static list
+    blacklist: false
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: appversion
+spec:
+  compiledTemplate: listentry
+  params:
+    value: source.labels["version"]
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: checkversion
+spec:
+  match: destination.labels["app"] == "ratings"
+  actions:
+  - handler: whitelist
+    instances: [ appversion ]
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-ingress-denial.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-ingress-denial.yaml
new file mode 100644 (file)
index 0000000..0199373
--- /dev/null
@@ -0,0 +1,30 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: handler
+  namespace: istio-system
+spec:
+  compiledAdapter: denier
+  params:
+    status:
+      code: 7
+      message: Not allowed
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: denyrequest
+  namespace: istio-system
+spec:
+  compiledTemplate: checknothing
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: denyingress
+  namespace: istio-system
+spec:
+  match: (source.labels["istio"] | "") == "ingressgateway" && (request.headers["x-user"] | "") == "john"
+  actions:
+  - handler: handler
+    instances: [ denyrequest ]
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-kubernetesenv-telemetry.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-kubernetesenv-telemetry.yaml
new file mode 100644 (file)
index 0000000..10c2c95
--- /dev/null
@@ -0,0 +1,56 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: kubeenvhandler
+  namespace: istio-system
+spec:
+  compiledAdapter: prometheus
+  params:
+    metrics:
+    - name: kube_request_count
+      instance_name: kubeenvrequestcount.instance.istio-system
+      kind: COUNTER
+      label_names:
+      - response_code
+      - source_pod
+      - source_workload_uid
+      - source_workload
+      - source_owner
+      - destination_pod
+      - destination_workload_uid
+      - destination_workload
+      - destination_owner
+      - destination_container
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: kubeenvrequestcount
+  namespace: istio-system
+spec:
+  compiledTemplate: metric
+  params:
+    value: "1"
+    dimensions:
+      response_code: response.code | 200
+      source_pod: source.name | "unknown"
+      source_workload_uid: source.workload.uid | "unknown"
+      source_workload: source.workload.name | "unknown"
+      source_owner: source.owner | "unknown"
+      destination_pod: destination.name | "unknown"
+      destination_workload: destination.workload.name | "unknown"
+      destination_workload_uid: destination.workload.uid | "unknown"
+      destination_owner: destination.owner | "unknown"
+      destination_container: destination.container.name | "unknown"
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: promkubeenv
+  namespace: istio-system
+spec:
+  match: "true"
+  actions:
+  - handler: kubeenvhandler
+    instances: [ kubeenvrequestcount ]
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-ratelimit-crd.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-ratelimit-crd.yaml
new file mode 100644 (file)
index 0000000..2262035
--- /dev/null
@@ -0,0 +1,81 @@
+apiVersion: config.istio.io/v1alpha2
+kind: memquota
+metadata:
+  name: handler
+  namespace: istio-system
+spec:
+  quotas:
+  - name: requestcount.quota.istio-system
+    maxAmount: 500
+    validDuration: 1s
+    # The first matching override is applied.
+    # A requestcount instance is checked against override dimensions.
+    overrides:
+    # The following override applies to 'reviews' regardless
+    # of the source.
+    - dimensions:
+        destination: reviews
+      maxAmount: 1
+      validDuration: 5s
+    # The following override applies to 'productpage' when
+    # the source is a specific ip address.
+    - dimensions:
+        destination: productpage
+        source: "10.28.11.20"
+      maxAmount: 500
+      validDuration: 1s
+    # The following override applies to 'productpage' regardless
+    # of the source.
+    - dimensions:
+        destination: productpage
+      maxAmount: 2
+      validDuration: 5s
+---
+apiVersion: config.istio.io/v1alpha2
+kind: quota
+metadata:
+  name: requestcount
+  namespace: istio-system
+spec:
+  dimensions:
+    source: request.headers["x-forwarded-for"] | "unknown"
+    destination: destination.labels["app"] | destination.service.name | "unknown"
+    destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcount
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: productpage
+    namespace: default
+    #  - service: '*'  # Uncomment this to bind *all* services to request-count
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  # quota only applies if you are not logged in.
+  # match: match(request.headers["cookie"], "user=*") == false
+  actions:
+  - handler: handler.memquota
+    instances:
+    - requestcount.quota
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-ratelimit.yaml
new file mode 100644 (file)
index 0000000..5b2233b
--- /dev/null
@@ -0,0 +1,85 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: quotahandler
+  namespace: istio-system
+spec:
+  compiledAdapter: memquota
+  params:
+    quotas:
+    - name: requestcountquota.instance.istio-system
+      maxAmount: 500
+      validDuration: 1s
+      # The first matching override is applied.
+      # A requestcount instance is checked against override dimensions.
+      overrides:
+      # The following override applies to 'reviews' regardless
+      # of the source.
+      - dimensions:
+          destination: reviews
+        maxAmount: 1
+        validDuration: 5s
+      # The following override applies to 'productpage' when
+      # the source is a specific ip address.
+      - dimensions:
+          destination: productpage
+          source: "10.28.11.20"
+        maxAmount: 500
+        validDuration: 1s
+      # The following override applies to 'productpage' regardless
+      # of the source.
+      - dimensions:
+          destination: productpage
+        maxAmount: 2
+        validDuration: 5s
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requestcountquota
+  namespace: istio-system
+spec:
+  compiledTemplate: quota
+  params:
+    dimensions:
+      source: request.headers["x-forwarded-for"] | "unknown"
+      destination: destination.labels["app"] | destination.service.name | "unknown"
+      destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcountquota
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: productpage
+    namespace: default
+    #  - service: '*'  # Uncomment this to bind *all* services to request-count
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  # quota only applies if you are not logged in.
+  # match: match(request.headers["cookie"], "user=*") == false
+  actions:
+  - handler: quotahandler
+    instances:
+    - requestcountquota
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-redis-quota-fixed-window.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-redis-quota-fixed-window.yaml
new file mode 100644 (file)
index 0000000..85787a2
--- /dev/null
@@ -0,0 +1,83 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: redishandler
+  namespace: istio-system
+spec:
+  compiledAdapter: redisquota
+  params:
+    redisServerUrl: redis-release-master:6379
+    connectionPoolSize: 10
+    quotas:
+    - name: requestcountquota.instance.istio-system
+      maxAmount: 1
+      validDuration: 30s
+      rateLimitAlgorithm: FIXED_WINDOW
+      # The first matching override is applied.
+      # A requestquotacount instance is checked against override dimensions.
+      overrides:
+      # The following override applies to 'productpage' when
+      # the source is 'istio-ingressgateway'.
+      - dimensions:
+          destination: productpage
+          source: istio-ingressgateway
+        maxAmount: 50
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requestcountquota
+  namespace: istio-system
+spec:
+  compiledTemplate: quota
+  params:
+    dimensions:
+      source: source.labels["app"] | "unknown"
+      sourceVersion: source.labels["version"] | "unknown"
+      destination: destination.labels["app"] | "unknown"
+      destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcountquota
+---
+# Note: change the default namespace to the namespace of the bookinfo app
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: ratings
+    namespace: default
+  - name: reviews
+    namespace: default
+  - name: details
+    namespace: default
+  - name: productpage
+    namespace: default
+  - name: istio-ingressgateway
+    namespace: istio-system
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  match: (destination.labels["app"]|"unknown") == "productpage"
+  actions:
+  - handler: redishandler
+    instances:
+    - requestcountquota
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-redis-quota-rolling-window.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-productpage-redis-quota-rolling-window.yaml
new file mode 100644 (file)
index 0000000..ec524b9
--- /dev/null
@@ -0,0 +1,87 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: redishandler
+  namespace: istio-system
+spec:
+  compiledAdapter: redisquota
+  params:
+    redisServerUrl: redis-release-master:6379
+    connectionPoolSize: 10
+    quotas:
+    - name: requestcountquota.instance.istio-system
+      maxAmount: 500
+      validDuration: 1s
+      bucketDuration: 500ms
+      rateLimitAlgorithm: ROLLING_WINDOW
+      # The first matching override is applied.
+      # A requestcount instance is checked against override dimensions.
+      overrides:
+      # The following override applies to 'reviews' regardless
+      # of the source.
+      - dimensions:
+          destination: reviews
+        maxAmount: 1
+      # The following override applies to 'productpage' when
+      # the source is a specific ip address.
+      - dimensions:
+          destination: productpage
+          source: "10.28.11.20"
+        maxAmount: 500
+      # The following override applies to 'productpage' regardless
+      # of the source.
+      - dimensions:
+          destination: productpage
+        maxAmount: 2
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requestcountquota
+  namespace: istio-system
+spec:
+  compiledTemplate: quota
+  params:
+    dimensions:
+      source: request.headers["x-forwarded-for"] | "unknown"
+      destination: destination.labels["app"] | destination.workload.name | "unknown"
+      destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcountquota
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: productpage
+    namespace: default
+    #  - service: '*'  # Uncomment this to bind *all* services to request-count
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  # quota only applies if you are not logged in.
+  # match: match(request.headers["cookie"], "session=*") == false
+  actions:
+  - handler: redishandler
+    instances:
+    - requestcountquota
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-denial.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-denial.yaml
new file mode 100644 (file)
index 0000000..4239b03
--- /dev/null
@@ -0,0 +1,31 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: denierhandler
+  namespace: istio-system
+spec:
+  compiledAdapter: denier
+  params:
+    status:
+      code: 7
+      message: Not allowed
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: denyrequest
+  namespace: istio-system
+spec:
+  compiledTemplate: checknothing
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: denyreviewsv3
+  namespace: istio-system
+spec:
+  #FIXME match: destination.labels["app"]=="productpage" && request.headers["x-user"] == ""
+  match: (request.headers["x-user"] | "") == "john"
+  actions:
+  - handler: denierhandler
+    instances: [ denyrequest ]
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-ratelimit.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-ratelimit.yaml
new file mode 100644 (file)
index 0000000..4989262
--- /dev/null
@@ -0,0 +1,81 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: quotahandler
+  namespace: istio-system
+spec:
+  compiledAdapter: memquota
+  params:
+    quotas:
+    - name: requestcountquota.instance.istio-system
+      maxAmount: 5000
+      validDuration: 1s
+      # The first matching override is applied.
+      # A requestcount instance is checked against override dimensions.
+      overrides:
+      # The following override applies to 'ratings' when
+      # the source is 'reviews'.
+      - dimensions:
+          destination: ratings
+          source: reviews
+        maxAmount: 1
+        validDuration: 1s
+      # The following override applies to 'ratings' regardless
+      # of the source.
+      - dimensions:
+          destination: ratings
+        maxAmount: 100
+        validDuration: 1s
+
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: requestcountquota
+  namespace: istio-system
+spec:
+  compiledTemplate: quota
+  params:
+    dimensions:
+      source: source.labels["app"] | "unknown"
+      sourceVersion: source.labels["version"] | "unknown"
+      destination: destination.labels["app"] | destination.service.name | "unknown"
+      destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  actions:
+  - handler: quotahandler
+    instances:
+    - requestcountquota
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcountquota
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: ratings
+  - name: reviews
+  - name: details
+  - name: productpage
+
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-redis-quota-fixed-window.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-redis-quota-fixed-window.yaml
new file mode 100644 (file)
index 0000000..a8bce7c
--- /dev/null
@@ -0,0 +1,87 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: redishandler
+  namespace: istio-system
+spec:
+  compiledAdapter: redisquota
+  params:
+    redisServerUrl: redis-release-master:6379
+    connectionPoolSize: 10
+    quotas:
+    - name: requestcountquota.instance.istio-system
+      maxAmount: 5000
+      validDuration: 30s
+      rateLimitAlgorithm: FIXED_WINDOW
+      # The first matching override is applied.
+      # A requestcount instance is checked against override dimensions.
+      overrides:
+      # The following override applies to 'ratings' when
+      # the source is 'reviews'.
+      - dimensions:
+          destination: ratings
+          source: reviews
+        maxAmount: 50
+      # The following override applies to 'ratings' regardless
+      # of the source.
+      - dimensions:
+          destination: ratings
+        maxAmount: 100
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requestcountquota
+  namespace: istio-system
+spec:
+  compiledTemplate: quota
+  params:
+    dimensions:
+      source: source.labels["app"] | "unknown"
+      sourceVersion: source.labels["version"] | "unknown"
+      destination: destination.labels["app"] | "unknown"
+      destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcountquota
+---
+# Note: change the default namespace to the namespace of the bookinfo app
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: ratings
+    namespace: default
+  - name: reviews
+    namespace: default
+  - name: details
+    namespace: default
+  - name: productpage
+    namespace: default
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  match: (destination.labels["app"]|"unknown") == "ratings"
+  actions:
+  - handler: redishandler
+    instances:
+    - requestcountquota
+---
diff --git a/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-redis-quota-rolling-window.yaml b/mash/eks/samples/bookinfo/policy/mixer-rule-ratings-redis-quota-rolling-window.yaml
new file mode 100644 (file)
index 0000000..b713637
--- /dev/null
@@ -0,0 +1,88 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: redishandler
+  namespace: istio-system
+spec:
+  compiledAdapter: redisquota
+  params:
+    redisServerUrl: redis-release-master:6379
+    connectionPoolSize: 10
+    quotas:
+    - name: requestcountquota.instance.istio-system
+      maxAmount: 5000
+      validDuration: 30s
+      bucketDuration: 9s
+      rateLimitAlgorithm: ROLLING_WINDOW
+      # The first matching override is applied.
+      # A requestcount instance is checked against override dimensions.
+      overrides:
+      # The following override applies to 'ratings' when
+      # the source is 'reviews'.
+      - dimensions:
+          destination: ratings
+          source: reviews
+        maxAmount: 50
+      # The following override applies to 'ratings' regardless
+      # of the source.
+      - dimensions:
+          destination: ratings
+        maxAmount: 100
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requestcountquota
+  namespace: istio-system
+spec:
+  compiledTemplate: quota
+  params:
+    dimensions:
+      source: source.labels["app"] | "unknown"
+      sourceVersion: source.labels["version"] | "unknown"
+      destination: destination.labels["app"] | "unknown"
+      destinationVersion: destination.labels["version"] | "unknown"
+---
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpec
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  rules:
+  - quotas:
+    - charge: 1
+      quota: requestcountquota
+---
+# Note: change the default namespace to the namespace of the bookinfo app
+apiVersion: config.istio.io/v1alpha2
+kind: QuotaSpecBinding
+metadata:
+  name: request-count
+  namespace: istio-system
+spec:
+  quotaSpecs:
+  - name: request-count
+    namespace: istio-system
+  services:
+  - name: ratings
+    namespace: default
+  - name: reviews
+    namespace: default
+  - name: details
+    namespace: default
+  - name: productpage
+    namespace: default
+---
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: quota
+  namespace: istio-system
+spec:
+  match: (destination.labels["app"]|"unknown") == "ratings"
+  actions:
+  - handler: redishandler
+    instances:
+    - requestcountquota
+---
diff --git a/mash/eks/samples/bookinfo/policy/prometheus-adapter-deployment.yaml b/mash/eks/samples/bookinfo/policy/prometheus-adapter-deployment.yaml
new file mode 100644 (file)
index 0000000..f744947
--- /dev/null
@@ -0,0 +1,44 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: prometheusadapter
+  namespace: istio-system
+  labels:
+    app: prometheusadapter
+spec:
+  ports:
+  - name: http
+    port: 8080
+  - name: prometheus
+    port: 42422
+  selector:
+    app: prometheusadapter
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: prometheusadapter
+  namespace: istio-system
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: prometheusadapter
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: prometheusadapter
+        version: v1
+      annotations:
+        prometheus.io/scrape: "true"
+        prometheus.io/port: "42422"
+    spec:
+      containers:
+      - image: gcr.io/istio-testing/prometheusadapter:release-1.1
+        imagePullPolicy: Always
+        name: prometheusadapter
+        ports:
+        - containerPort: 8080
+        - containerPort: 42422
+---
diff --git a/mash/eks/samples/bookinfo/policy/prometheus-oop-rule.yaml b/mash/eks/samples/bookinfo/policy/prometheus-oop-rule.yaml
new file mode 100644 (file)
index 0000000..059d067
--- /dev/null
@@ -0,0 +1,78 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: requestcount-oop
+  namespace: istio-system
+spec:
+  template: metric
+  params:
+    value: "1"
+    dimensions:
+      reporter: conditional((context.reporter.kind | "inbound") == "outbound", "source", "destination")
+      source_workload: source.workload.name | "unknown"
+      source_workload_namespace: source.workload.namespace | "unknown"
+      source_principal: source.principal | "unknown"
+      source_app: source.labels["app"] | "unknown"
+      source_version: source.labels["version"] | "unknown"
+      destination_workload: destination.workload.name | "unknown"
+      destination_workload_namespace: destination.workload.namespace | "unknown"
+      destination_principal: destination.principal | "unknown"
+      destination_app: destination.labels["app"] | "unknown"
+      destination_version: destination.labels["version"] | "unknown"
+      destination_service: destination.service.host | "unknown"
+      destination_service_name: destination.service.name | "unknown"
+      destination_service_namespace: destination.service.namespace | "unknown"
+      request_protocol: api.protocol | context.protocol | "unknown"
+      response_code: response.code | 200
+      response_flags: context.proxy_error_code | "-"
+      permissive_response_code: rbac.permissive.response_code | "none"
+      permissive_response_policyid: rbac.permissive.effective_policy_id | "none"
+      connection_security_policy: conditional((context.reporter.kind | "inbound") == "outbound", "unknown", conditional(connection.mtls | false, "mutual_tls", "none"))
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: prometheus-handler
+  namespace: istio-system
+spec:
+  adapter: prometheus-nosession
+  connection:
+    address: "prometheusadapter:8080"
+  params:
+    metrics:
+    - name: request_count_oop
+      instance_name: requestcount-oop.instance.istio-system
+      kind: COUNTER
+      label_names:
+      - reporter
+      - source_workload
+      - source_workload_namespace
+      - source_principal
+      - source_app
+      - source_version
+      - destination_workload
+      - destination_workload_namespace
+      - destination_principal
+      - destination_app
+      - destination_version
+      - destination_service
+      - destination_service_name
+      - destination_service_namespace
+      - request_protocol
+      - response_code
+      - response_flags
+      - permissive_response_code
+      - permissive_response_policyid
+      - connection_security_policy
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: promhttp-oop
+  namespace: istio-system
+spec:
+  actions:
+  - handler: prometheus-handler
+    instances: [ requestcount-oop ]
+---
diff --git a/mash/eks/samples/bookinfo/src/mongodb/ratings_data.json b/mash/eks/samples/bookinfo/src/mongodb/ratings_data.json
new file mode 100644 (file)
index 0000000..b4563b5
--- /dev/null
@@ -0,0 +1,2 @@
+{rating: 5}
+{rating: 4}
diff --git a/mash/eks/samples/bookinfo/src/productpage/requirements.txt b/mash/eks/samples/bookinfo/src/productpage/requirements.txt
new file mode 100644 (file)
index 0000000..c1968c8
--- /dev/null
@@ -0,0 +1,31 @@
+certifi==2019.3.9
+chardet==3.0.4
+Click==7.0
+contextlib2==0.5.5
+dominate==2.3.5
+Flask==1.0.2
+Flask-Bootstrap==3.3.7.1
+Flask-JSON==0.3.3
+future==0.17.1
+futures==3.1.1
+gevent==1.4.0
+greenlet==0.4.15
+idna==2.8
+itsdangerous==1.1.0
+jaeger-client==3.13.0
+Jinja2==2.10.1
+json2html==1.2.1
+MarkupSafe==0.23
+nose==1.3.7
+opentracing==1.2.2
+opentracing-instrumentation==2.4.3
+requests==2.21.0
+simplejson==3.16.0
+six==1.12.0
+threadloop==1.0.2
+thrift==0.11.0
+tornado==4.5.3
+urllib3==1.24.2
+visitor==0.1.3
+Werkzeug==0.15.5
+wrapt==1.11.1
diff --git a/mash/eks/samples/bookinfo/src/productpage/test-requirements.txt b/mash/eks/samples/bookinfo/src/productpage/test-requirements.txt
new file mode 100644 (file)
index 0000000..f756640
--- /dev/null
@@ -0,0 +1 @@
+requests-mock==1.5.2
diff --git a/mash/eks/samples/bookinfo/src/ratings/package.json b/mash/eks/samples/bookinfo/src/ratings/package.json
new file mode 100644 (file)
index 0000000..9417ace
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "scripts": {
+    "start": "node ratings.js"
+  },
+  "dependencies": {
+    "httpdispatcher": "1.0.0",
+    "mongodb": "^3.6.0",
+    "mysql": "^2.15.0"
+  }
+}
diff --git a/mash/eks/samples/bookinfo/swagger.yaml b/mash/eks/samples/bookinfo/swagger.yaml
new file mode 100644 (file)
index 0000000..6782e73
--- /dev/null
@@ -0,0 +1,248 @@
+swagger: "2.0"
+info:
+  description: "This is the API of the Istio BookInfo sample application."
+  version: "1.0.0"
+  title: "BookInfo API"
+  termsOfService: "https://istio.io/"
+  license:
+    name: "Apache 2.0"
+    url: "http://www.apache.org/licenses/LICENSE-2.0.html"
+basePath: "/api/v1"
+tags:
+- name: "product"
+  description: "Information about a product (in this case a book)"
+- name: "review"
+  description: "Review information for a product"
+- name: "rating"
+  description: "Rating information for a product"
+externalDocs:
+  description: "Learn more about the Istio BookInfo application"
+  url: "https://istio.io/docs/samples/bookinfo.html"
+paths:
+  /products:
+    get:
+      tags:
+      - "product"
+      summary: "List all products"
+      description: "List all products available in the application with a minimum amount of information."
+      operationId: "getProducts"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      responses:
+        200:
+          description: "successful operation"
+          schema:
+            type: "array"
+            items:
+              $ref: "#/definitions/Product"
+  /products/{id}:
+    get:
+      tags:
+      - "product"
+      summary: "Get individual product"
+      description: "Get detailed information about an individual product with the given id."
+      operationId: "getProduct"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "id"
+        in: "path"
+        description: "Product id"
+        required: true
+        type: "integer"
+        format: "int32"
+      responses:
+        200:
+          description: "successful operation"
+          schema:
+            $ref: "#/definitions/ProductDetails"
+        400:
+          description: "Invalid product id"
+  /products/{id}/reviews:
+    get:
+      tags:
+      - "review"
+      summary: "Get reviews for a product"
+      description: "Get reviews for a product, including review text and possibly ratings information."
+      operationId: "getProductReviews"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "id"
+        in: "path"
+        description: "Product id"
+        required: true
+        type: "integer"
+        format: "int32"
+      responses:
+        200:
+          description: "successful operation"
+          schema:
+            $ref: "#/definitions/ProductReviews"
+        400:
+          description: "Invalid product id"
+  /products/{id}/ratings:
+    get:
+      tags:
+      - "rating"
+      summary: "Get ratings for a product"
+      description: "Get ratings for a product, including stars and their color."
+      operationId: "getProductRatings"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "id"
+        in: "path"
+        description: "Product id"
+        required: true
+        type: "integer"
+        format: "int32"
+      responses:
+        200:
+          description: "successful operation"
+          schema:
+            $ref: "#/definitions/ProductRatings"
+        400:
+          description: "Invalid product id"
+
+
+definitions:
+  Product:
+    type: "object"
+    description: "Basic information about a product"
+    properties:
+      id:
+        type: "integer"
+        format: "int32"
+        description: "Product id"
+      title:
+        type: "string"
+        description: "Title of the book"
+      descriptionHtml:
+        type: "string"
+        description: "Description of the book - may contain HTML tags"
+    required:
+    - "id"
+    - "title"
+    - "descriptionHtml"
+  ProductDetails:
+    type: "object"
+    description: "Detailed information about a product"
+    properties:
+      id:
+        type: "integer"
+        format: "int32"
+        description: "Product id"
+      publisher:
+        type: "string"
+        description: "Publisher of the book"
+      language:
+        type: "string"
+        description: "Language of the book"
+      author:
+        type: "string"
+        description: "Author of the book"
+      ISBN-10:
+        type: "string"
+        description: "ISBN-10 of the book"
+      ISBN-13:
+        type: "string"
+        description: "ISBN-13 of the book"
+      year:
+        type: "integer"
+        format: "int32"
+        description: "Year the book was first published in"
+      type:
+        type: "string"
+        enum:
+          - "paperback"
+          - "hardcover"
+        description: "Type of the book"
+      pages:
+        type: "integer"
+        format: "int32"
+        description: "Number of pages of the book"
+    required:
+    - "id"
+    - "publisher"
+    - "language"
+    - "author"
+    - "ISBN-10"
+    - "ISBN-13"
+    - "year"
+    - "type"
+    - "pages"
+  ProductReviews:
+    type: "object"
+    description: "Object containing reviews for a product"
+    properties:
+      id:
+        type: "integer"
+        format: "int32"
+        description: "Product id"
+      reviews:
+        type: "array"
+        description: "List of reviews"
+        items:
+          $ref: "#/definitions/Review"
+    required:
+    - "id"
+    - "reviews"
+  Review:
+    type: "object"
+    description: "Review of a product"
+    properties:
+      reviewer:
+        type: "string"
+        description: "Name of the reviewer"
+      text:
+        type: "string"
+        description: "Review text"
+      rating:
+        $ref: "#/definitions/Rating"
+    required:
+    - "reviewer"
+    - "text"
+  Rating:
+    type: "object"
+    description: "Rating of a product"
+    properties:
+      stars:
+        type: "integer"
+        format: "int32"
+        minimum: 1
+        maximum: 5
+        description: "Number of stars"
+      color:
+        type: "string"
+        enum:
+          - "red"
+          - "black"
+        description: "Color in which stars should be displayed"
+    required:
+    - "stars"
+    - "color"
+  ProductRatings:
+    type: "object"
+    description: "Object containing ratings of a product"
+    properties:
+      id:
+        type: "integer"
+        format: "int32"
+        description: "Product id"
+      ratings:
+        type: "object"
+        description: "A hashmap where keys are reviewer names, values are number of stars"
+        additionalProperties: 
+          type: "string"
+    required:
+    - "id"
+    - "ratings"
\ No newline at end of file
diff --git a/mash/eks/samples/bookinfo/telemetry/fluentd-istio-crd.yaml b/mash/eks/samples/bookinfo/telemetry/fluentd-istio-crd.yaml
new file mode 100644 (file)
index 0000000..4df061e
--- /dev/null
@@ -0,0 +1,40 @@
+# Configuration for logentry instances
+apiVersion: "config.istio.io/v1alpha2"
+kind: logentry
+metadata:
+  name: newlog
+  namespace: istio-system
+spec:
+  severity: '"info"'
+  timestamp: request.time
+  variables:
+    source: source.labels["app"] | source.workload.name | "unknown"
+    user: source.user | "unknown"
+    destination: destination.labels["app"] | destination.workload.name | "unknown"
+    responseCode: response.code | 0
+    responseSize: response.size | 0
+    latency: response.duration | "0ms"
+  monitored_resource_type: '"UNSPECIFIED"'
+---
+# Configuration for a Fluentd handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: fluentd
+metadata:
+  name: handler
+  namespace: istio-system
+spec:
+  address: "fluentd-es.logging:24224"
+---
+# Rule to send logentry instances to the Fluentd handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: newlogtofluentd
+  namespace: istio-system
+spec:
+  match: "true" # match for all requests
+  actions:
+   - handler: handler.fluentd
+     instances:
+     - newlog.logentry
+---
diff --git a/mash/eks/samples/bookinfo/telemetry/fluentd-istio.yaml b/mash/eks/samples/bookinfo/telemetry/fluentd-istio.yaml
new file mode 100644 (file)
index 0000000..c416f31
--- /dev/null
@@ -0,0 +1,44 @@
+# Configuration for logentry instances
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: newlog
+  namespace: istio-system
+spec:
+  compiledTemplate: logentry
+  params:
+    severity: '"info"'
+    timestamp: request.time
+    variables:
+      source: source.labels["app"] | source.workload.name | "unknown"
+      user: source.user | "unknown"
+      destination: destination.labels["app"] | destination.workload.name | "unknown"
+      responseCode: response.code | 0
+      responseSize: response.size | 0
+      latency: response.duration | "0ms"
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+# Configuration for a Fluentd handler
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: handler
+  namespace: istio-system
+spec:
+  compiledAdapter: fluentd
+  params:
+    address: "fluentd-es.logging:24224"
+---
+# Rule to send logentry instances to the Fluentd handler
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: newlogtofluentd
+  namespace: istio-system
+spec:
+  match: "true" # match for all requests
+  actions:
+   - handler: handler
+     instances:
+     - newlog
+---
diff --git a/mash/eks/samples/bookinfo/telemetry/log-entry-crd.yaml b/mash/eks/samples/bookinfo/telemetry/log-entry-crd.yaml
new file mode 100644 (file)
index 0000000..d439676
--- /dev/null
@@ -0,0 +1,42 @@
+# Configuration for logentry instances
+apiVersion: "config.istio.io/v1alpha2"
+kind: logentry
+metadata:
+  name: newlog
+  namespace: istio-system
+spec:
+  severity: '"warning"'
+  timestamp: request.time
+  variables:
+    source: source.labels["app"] | source.workload.name | "unknown"
+    user: source.user | "unknown"
+    destination: destination.labels["app"] | destination.workload.name | "unknown"
+    responseCode: response.code | 0
+    responseSize: response.size | 0
+    latency: response.duration | "0ms"
+  monitored_resource_type: '"UNSPECIFIED"'
+---
+# Configuration for a stdio handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: stdio
+metadata:
+  name: newloghandler
+  namespace: istio-system
+spec:
+ severity_levels:
+   warning: 1 # Params.Level.WARNING
+ outputAsJson: true
+---
+# Rule to send logentry instances to a stdio handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: newlogstdio
+  namespace: istio-system
+spec:
+  match: "true" # match for all requests
+  actions:
+   - handler: newloghandler.stdio
+     instances:
+     - newlog.logentry
+---
diff --git a/mash/eks/samples/bookinfo/telemetry/log-entry.yaml b/mash/eks/samples/bookinfo/telemetry/log-entry.yaml
new file mode 100644 (file)
index 0000000..43f47e7
--- /dev/null
@@ -0,0 +1,46 @@
+# Configuration for logentry instances
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: newlog
+  namespace: istio-system
+spec:
+  compiledTemplate: logentry
+  params:
+    severity: '"warning"'
+    timestamp: request.time
+    variables:
+      source: source.labels["app"] | source.workload.name | "unknown"
+      user: source.user | "unknown"
+      destination: destination.labels["app"] | destination.workload.name | "unknown"
+      responseCode: response.code | 0
+      responseSize: response.size | 0
+      latency: response.duration | "0ms"
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+# Configuration for a stdio handler
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: newloghandler
+  namespace: istio-system
+spec:
+  compiledAdapter: stdio
+  params:
+    severity_levels:
+      warning: 1 # Params.Level.WARNING
+    outputAsJson: true
+---
+# Rule to send logentry instances to a stdio handler
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: newlogstdio
+  namespace: istio-system
+spec:
+  match: "true" # match for all requests
+  actions:
+   - handler: newloghandler
+     instances:
+     - newlog
+---
diff --git a/mash/eks/samples/bookinfo/telemetry/metrics-crd.yaml b/mash/eks/samples/bookinfo/telemetry/metrics-crd.yaml
new file mode 100644 (file)
index 0000000..9ee2f5f
--- /dev/null
@@ -0,0 +1,45 @@
+# Configuration for metric instances
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: doublerequestcount
+  namespace: istio-system
+spec:
+  compiledTemplate: metric
+  params:
+    value: "2" # count each request twice
+    dimensions:
+      reporter: conditional((context.reporter.kind | "inbound") == "outbound", "client", "server")
+      source: source.workload.name | "unknown"
+      destination: destination.workload.name | "unknown"
+      message: '"twice the fun!"'
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+# Configuration for a Prometheus handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: prometheus
+metadata:
+  name: doublehandler
+  namespace: istio-system
+spec:
+  metrics:
+  - name: double_request_count # Prometheus metric name
+    instance_name: doublerequestcount.instance.istio-system # Mixer instance name (fully-qualified)
+    kind: COUNTER
+    label_names:
+    - reporter
+    - source
+    - destination
+    - message
+---
+# Rule to send metric instances to a Prometheus handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: doubleprom
+  namespace: istio-system
+spec:
+  actions:
+  - handler: doublehandler.prometheus
+    instances:
+    - doublerequestcount
diff --git a/mash/eks/samples/bookinfo/telemetry/metrics.yaml b/mash/eks/samples/bookinfo/telemetry/metrics.yaml
new file mode 100644 (file)
index 0000000..45d9877
--- /dev/null
@@ -0,0 +1,46 @@
+# Configuration for metric instances
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: doublerequestcount
+  namespace: istio-system
+spec:
+  compiledTemplate: metric
+  params:
+    value: "2" # count each request twice
+    dimensions:
+      reporter: conditional((context.reporter.kind | "inbound") == "outbound", "client", "server")
+      source: source.workload.name | "unknown"
+      destination: destination.workload.name | "unknown"
+      message: '"twice the fun!"'
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+# Configuration for a Prometheus handler
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: doublehandler
+  namespace: istio-system
+spec:
+  compiledAdapter: prometheus
+  params:
+    metrics:
+    - name: double_request_count # Prometheus metric name
+      instance_name: doublerequestcount.instance.istio-system # Mixer instance name (fully-qualified)
+      kind: COUNTER
+      label_names:
+      - reporter
+      - source
+      - destination
+      - message
+---
+# Rule to send metric instances to a Prometheus handler
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: doubleprom
+  namespace: istio-system
+spec:
+  actions:
+  - handler: doublehandler
+    instances: [ doublerequestcount ]
diff --git a/mash/eks/samples/bookinfo/telemetry/tcp-metrics-crd.yaml b/mash/eks/samples/bookinfo/telemetry/tcp-metrics-crd.yaml
new file mode 100644 (file)
index 0000000..36ba5ec
--- /dev/null
@@ -0,0 +1,67 @@
+# Configuration for a metric measuring bytes sent from a server
+# to a client
+apiVersion: "config.istio.io/v1alpha2"
+kind: metric
+metadata:
+  name: mongosentbytes
+  namespace: default
+spec:
+  value: connection.sent.bytes | 0 # uses a TCP-specific attribute
+  dimensions:
+    source_service: source.workload.name | "unknown"
+    source_version: source.labels["version"] | "unknown"
+    destination_version: destination.labels["version"] | "unknown"
+  monitoredResourceType: '"UNSPECIFIED"'
+---
+# Configuration for a metric measuring bytes sent from a client
+# to a server
+apiVersion: "config.istio.io/v1alpha2"
+kind: metric
+metadata:
+  name: mongoreceivedbytes
+  namespace: default
+spec:
+  value: connection.received.bytes | 0 # uses a TCP-specific attribute
+  dimensions:
+    source_service: source.workload.name | "unknown"
+    source_version: source.labels["version"] | "unknown"
+    destination_version: destination.labels["version"] | "unknown"
+  monitoredResourceType: '"UNSPECIFIED"'
+---
+# Configuration for a Prometheus handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: prometheus
+metadata:
+  name: mongohandler
+  namespace: default
+spec:
+  metrics:
+  - name: mongo_sent_bytes # Prometheus metric name
+    instance_name: mongosentbytes.metric.default # Mixer instance name (fully-qualified)
+    kind: COUNTER
+    label_names:
+    - source_service
+    - source_version
+    - destination_version
+  - name: mongo_received_bytes # Prometheus metric name
+    instance_name: mongoreceivedbytes.metric.default # Mixer instance name (fully-qualified)
+    kind: COUNTER
+    label_names:
+    - source_service
+    - source_version
+    - destination_version
+---
+# Rule to send metric instances to a Prometheus handler
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: mongoprom
+  namespace: default
+spec:
+  match: context.protocol == "tcp"
+         && destination.service.host == "mongodb.default.svc.cluster.local"
+  actions:
+  - handler: mongohandler.prometheus
+    instances:
+    - mongoreceivedbytes.metric
+    - mongosentbytes.metric
diff --git a/mash/eks/samples/bookinfo/telemetry/tcp-metrics.yaml b/mash/eks/samples/bookinfo/telemetry/tcp-metrics.yaml
new file mode 100644 (file)
index 0000000..817507b
--- /dev/null
@@ -0,0 +1,73 @@
+# Configuration for a metric measuring bytes sent from a server
+# to a client
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: mongosentbytes
+  namespace: default
+spec:
+  compiledTemplate: metric
+  params:
+    value: connection.sent.bytes | 0 # uses a TCP-specific attribute
+    dimensions:
+      source_service: source.workload.name | "unknown"
+      source_version: source.labels["version"] | "unknown"
+      destination_version: destination.labels["version"] | "unknown"
+    monitoredResourceType: '"UNSPECIFIED"'
+---
+# Configuration for a metric measuring bytes sent from a client
+# to a server
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: mongoreceivedbytes
+  namespace: default
+spec:
+  compiledTemplate: metric
+  params:
+    value: connection.received.bytes | 0 # uses a TCP-specific attribute
+    dimensions:
+      source_service: source.workload.name | "unknown"
+      source_version: source.labels["version"] | "unknown"
+      destination_version: destination.labels["version"] | "unknown"
+    monitoredResourceType: '"UNSPECIFIED"'
+---
+# Configuration for a Prometheus handler
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: mongohandler
+  namespace: default
+spec:
+  compiledAdapter: prometheus
+  params:
+    metrics:
+    - name: mongo_sent_bytes # Prometheus metric name
+      instance_name: mongosentbytes.instance.default # Mixer instance name (fully-qualified)
+      kind: COUNTER
+      label_names:
+      - source_service
+      - source_version
+      - destination_version
+    - name: mongo_received_bytes # Prometheus metric name
+      instance_name: mongoreceivedbytes.instance.default # Mixer instance name (fully-qualified)
+      kind: COUNTER
+      label_names:
+      - source_service
+      - source_version
+      - destination_version
+---
+# Rule to send metric instances to a Prometheus handler
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: mongoprom
+  namespace: default
+spec:
+  match: context.protocol == "tcp"
+         && destination.service.host == "mongodb.default.svc.cluster.local"
+  actions:
+  - handler: mongohandler
+    instances:
+    - mongoreceivedbytes
+    - mongosentbytes
diff --git a/mash/eks/samples/certs/README.md b/mash/eks/samples/certs/README.md
new file mode 100644 (file)
index 0000000..38621df
--- /dev/null
@@ -0,0 +1,20 @@
+# Istio plugin CA sample certificates
+
+This directory contains sample pre-generated certificate and keys to demonstrate how an operator could configure Citadel with an existing root certificate, signing certificates and keys. In such
+a deployment, Citadel acts as an intermediate certificate authority (CA), under the given root CA.
+Instructions are available [here](https://istio.io/docs/tasks/security/cert-management/plugin-ca-cert/).
+
+The included sample files are:
+
+- `root-cert.pem`: root CA certificate.
+- `ca-[cert|key].pem`: Citadel intermediate certificate and corresponding private key.
+- `cert-chain.pem`: certificate trust chain.
+- `workload-foo-[cert|key].pem`: workload certificate and key for URI SAN `spiffe://trust-domain-foo/ns/foo/sa/foo` signed by `ca-cert.key`.
+- `workload-bar-[cert|key].pem`: workload certificate and key for URI SAN `spiffe://trust-domain-bar/ns/bar/sa/bar` signed by `ca-cert.key`.
+
+The workload cert and key are generated by:
+
+```shell script
+ ./generate-workload.sh foo
+ ./generate-workload.sh bar
+```
diff --git a/mash/eks/samples/certs/ca-cert.pem b/mash/eks/samples/certs/ca-cert.pem
new file mode 100644 (file)
index 0000000..a460e03
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIJAON1ifrBZ2/BMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxl
+MQ4wDAYDVQQKDAVJc3RpbzENMAsGA1UECwwEVGVzdDEQMA4GA1UEAwwHUm9vdCBD
+QTEiMCAGCSqGSIb3DQEJARYTdGVzdHJvb3RjYUBpc3Rpby5pbzAgFw0xODAxMjQx
+OTE1NTFaGA8yMTE3MTIzMTE5MTU1MVowWTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+CkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTEOMAwGA1UEChMFSXN0aW8x
+ETAPBgNVBAMTCElzdGlvIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAyzCxr/xu0zy5rVBiso9ffgl00bRKvB/HF4AX9/ytmZ6Hqsy13XIQk8/u/By9
+iCvVwXIMvyT0CbiJq/aPEj5mJUy0lzbrUs13oneXqrPXf7ir3HzdRw+SBhXlsh9z
+APZJXcF93DJU3GabPKwBvGJ0IVMJPIFCuDIPwW4kFAI7R/8A5LSdPrFx6EyMXl7K
+M8jekC0y9DnTj83/fY72WcWX7YTpgZeBHAeeQOPTZ2KYbFal2gLsar69PgFS0Tom
+ESO9M14Yit7mzB1WDK2z9g3r+zLxENdJ5JG/ZskKe+TO4Diqi5OJt/h8yspS1ck8
+LJtCole9919umByg5oruflqIlQIDAQABozUwMzALBgNVHQ8EBAMCAgQwDAYDVR0T
+BAUwAwEB/zAWBgNVHREEDzANggtjYS5pc3Rpby5pbzANBgkqhkiG9w0BAQsFAAOC
+AQEAltHEhhyAsve4K4bLgBXtHwWzo6SpFzdAfXpLShpOJNtQNERb3qg6iUGQdY+w
+A2BpmSkKr3Rw/6ClP5+cCG7fGocPaZh+c+4Nxm9suMuZBZCtNOeYOMIfvCPcCS+8
+PQ/0hC4/0J3WJKzGBssaaMufJxzgFPPtDJ998kY8rlROghdSaVt423/jXIAYnP3Y
+05n8TGERBj7TLdtIVbtUIx3JHAo3PWJywA6mEDovFMJhJERp9sDHIr1BbhXK1TFN
+Z6HNH6gInkSSMtvC4Ptejb749PTaePRPF7ID//eq/3AH8UK50F3TQcLjEqWUsJUn
+aFKltOc+RAjzDklcUPeG4Y6eMA==
+-----END CERTIFICATE-----
diff --git a/mash/eks/samples/certs/ca-key.pem b/mash/eks/samples/certs/ca-key.pem
new file mode 100644 (file)
index 0000000..faa77f3
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyzCxr/xu0zy5rVBiso9ffgl00bRKvB/HF4AX9/ytmZ6Hqsy1
+3XIQk8/u/By9iCvVwXIMvyT0CbiJq/aPEj5mJUy0lzbrUs13oneXqrPXf7ir3Hzd
+Rw+SBhXlsh9zAPZJXcF93DJU3GabPKwBvGJ0IVMJPIFCuDIPwW4kFAI7R/8A5LSd
+PrFx6EyMXl7KM8jekC0y9DnTj83/fY72WcWX7YTpgZeBHAeeQOPTZ2KYbFal2gLs
+ar69PgFS0TomESO9M14Yit7mzB1WDK2z9g3r+zLxENdJ5JG/ZskKe+TO4Diqi5OJ
+t/h8yspS1ck8LJtCole9919umByg5oruflqIlQIDAQABAoIBAGZI8fnUinmd5R6B
+C941XG3XFs6GAuUm3hNPcUFuGnntmv/5I0gBpqSyFO0nDqYg4u8Jma8TTCIkmnFN
+ogIeFU+LiJFinR3GvwWzTE8rTz1FWoaY+M9P4ENd/I4pVLxUPuSKhfA2ChAVOupU
+8F7D9Q/dfBXQQCT3VoUaC+FiqjL4HvIhji1zIqaqpK7fChGPraC/4WHwLMNzI0Zg
+oDdAanwVygettvm6KD7AeKzhK94gX1PcnsOi3KuzQYvkenQE1M6/K7YtEc5qXCYf
+QETj0UCzB55btgdF36BGoZXf0LwHqxys9ubfHuhwKBpY0xg2z4/4RXZNhfIDih3w
+J3mihcECgYEA6FtQ0cfh0Zm03OPDpBGc6sdKxTw6aBDtE3KztfI2hl26xHQoeFqp
+FmV/TbnExnppw+gWJtwx7IfvowUD8uRR2P0M2wGctWrMpnaEYTiLAPhXsj69HSM/
+CYrh54KM0YWyjwNhtUzwbOTrh1jWtT9HV5e7ay9Atk3UWljuR74CFMUCgYEA392e
+DVoDLE0XtbysmdlfSffhiQLP9sT8+bf/zYnr8Eq/4LWQoOtjEARbuCj3Oq7bP8IE
+Vz45gT1mEE3IacC9neGwuEa6icBiuQi86NW8ilY/ZbOWrRPLOhk3zLiZ+yqkt+sN
+cqWx0JkIh7IMKWI4dVQgk4I0jcFP7vNG/So4AZECgYEA426eSPgxHQwqcBuwn6Nt
+yJCRq0UsljgbFfIr3Wfb3uFXsntQMZ3r67QlS1sONIgVhmBhbmARrcfQ0+xQ1SqO
+wqnOL4AAd8K11iojoVXLGYP7ssieKysYxKpgPE8Yru0CveE9fkx0+OGJeM2IO5hY
+qHAoTt3NpaPAuz5Y3XgqaVECgYA0TONS/TeGjxA9/jFY1Cbl8gp35vdNEKKFeM5D
+Z7h+cAg56FE8tyFyqYIAGVoBFL7WO26mLzxiDEUfA/0Rb90c2JBfzO5hpleqIPd5
+cg3VR+cRzI4kK16sWR3nLy2SN1k6OqjuovVS5Z3PjfI3bOIBz0C5FY9Pmt0g1yc7
+mDRzcQKBgQCXWCZStbdjewaLd5u5Hhbw8tIWImMVfcfs3H1FN669LLpbARM8RtAa
+8dYwDVHmWmevb/WX03LiSE+GCjCBO79fa1qc5RKAalqH/1OYxTuvYOeTUebSrg8+
+lQFlP2OC4GGolKrN6HVWdxtf+F+SdjwX6qGCfYkXJRLYXIFSFjFeuw==
+-----END RSA PRIVATE KEY-----
diff --git a/mash/eks/samples/certs/cert-chain.pem b/mash/eks/samples/certs/cert-chain.pem
new file mode 100644 (file)
index 0000000..a460e03
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIJAON1ifrBZ2/BMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxl
+MQ4wDAYDVQQKDAVJc3RpbzENMAsGA1UECwwEVGVzdDEQMA4GA1UEAwwHUm9vdCBD
+QTEiMCAGCSqGSIb3DQEJARYTdGVzdHJvb3RjYUBpc3Rpby5pbzAgFw0xODAxMjQx
+OTE1NTFaGA8yMTE3MTIzMTE5MTU1MVowWTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+CkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTEOMAwGA1UEChMFSXN0aW8x
+ETAPBgNVBAMTCElzdGlvIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAyzCxr/xu0zy5rVBiso9ffgl00bRKvB/HF4AX9/ytmZ6Hqsy13XIQk8/u/By9
+iCvVwXIMvyT0CbiJq/aPEj5mJUy0lzbrUs13oneXqrPXf7ir3HzdRw+SBhXlsh9z
+APZJXcF93DJU3GabPKwBvGJ0IVMJPIFCuDIPwW4kFAI7R/8A5LSdPrFx6EyMXl7K
+M8jekC0y9DnTj83/fY72WcWX7YTpgZeBHAeeQOPTZ2KYbFal2gLsar69PgFS0Tom
+ESO9M14Yit7mzB1WDK2z9g3r+zLxENdJ5JG/ZskKe+TO4Diqi5OJt/h8yspS1ck8
+LJtCole9919umByg5oruflqIlQIDAQABozUwMzALBgNVHQ8EBAMCAgQwDAYDVR0T
+BAUwAwEB/zAWBgNVHREEDzANggtjYS5pc3Rpby5pbzANBgkqhkiG9w0BAQsFAAOC
+AQEAltHEhhyAsve4K4bLgBXtHwWzo6SpFzdAfXpLShpOJNtQNERb3qg6iUGQdY+w
+A2BpmSkKr3Rw/6ClP5+cCG7fGocPaZh+c+4Nxm9suMuZBZCtNOeYOMIfvCPcCS+8
+PQ/0hC4/0J3WJKzGBssaaMufJxzgFPPtDJ998kY8rlROghdSaVt423/jXIAYnP3Y
+05n8TGERBj7TLdtIVbtUIx3JHAo3PWJywA6mEDovFMJhJERp9sDHIr1BbhXK1TFN
+Z6HNH6gInkSSMtvC4Ptejb749PTaePRPF7ID//eq/3AH8UK50F3TQcLjEqWUsJUn
+aFKltOc+RAjzDklcUPeG4Y6eMA==
+-----END CERTIFICATE-----
diff --git a/mash/eks/samples/certs/root-cert.pem b/mash/eks/samples/certs/root-cert.pem
new file mode 100644 (file)
index 0000000..64c3fd5
--- /dev/null
@@ -0,0 +1,24 @@
+-----BEGIN CERTIFICATE-----
+MIID7TCCAtWgAwIBAgIJAOIRDhOcxsx6MA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxl
+MQ4wDAYDVQQKDAVJc3RpbzENMAsGA1UECwwEVGVzdDEQMA4GA1UEAwwHUm9vdCBD
+QTEiMCAGCSqGSIb3DQEJARYTdGVzdHJvb3RjYUBpc3Rpby5pbzAgFw0xODAxMjQx
+OTE1NTFaGA8yMTE3MTIzMTE5MTU1MVowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
+DApDYWxpZm9ybmlhMRIwEAYDVQQHDAlTdW5ueXZhbGUxDjAMBgNVBAoMBUlzdGlv
+MQ0wCwYDVQQLDARUZXN0MRAwDgYDVQQDDAdSb290IENBMSIwIAYJKoZIhvcNAQkB
+FhN0ZXN0cm9vdGNhQGlzdGlvLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA38uEfAatzQYqbaLou1nxJ348VyNzumYMmDDt5pbLYRrCo2pS3ki1ZVDN
+8yxIENJFkpKw9UctTGdbNGuGCiSDP7uqF6BiVn+XKAU/3pnPFBbTd0S33NqbDEQu
+IYraHSl/tSk5rARbC1DrQRdZ6nYD2KrapC4g0XbjY6Pu5l4y7KnFwSunnp9uqpZw
+uERv/BgumJ5QlSeSeCmhnDhLxooG8w5tC2yVr1yDpsOHGimP/mc8Cds4V0zfIhQv
+YzfIHphhE9DKjmnjBYLOdj4aycv44jHnOGc+wvA1Jqsl60t3wgms+zJTiWwABLdw
+zgMAa7yxLyoV0+PiVQud6k+8ZoIFcwIDAQABo1AwTjAdBgNVHQ4EFgQUOUYGtUyh
+euxO4lGe4Op1y8NVoagwHwYDVR0jBBgwFoAUOUYGtUyheuxO4lGe4Op1y8NVoagw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANXLyfAs7J9rmBamGJvPZ
+ltx390WxzzLFQsBRAaH6rgeipBq3dR9qEjAwb6BTF+ROmtQzX+fjstCRrJxCto9W
+tC8KvXTdRfIjfCCZjhtIOBKqRxE4KJV/RBfv9xD5lyjtCPCQl3Ia6MSf42N+abAK
+WCdU6KCojA8WB9YhSCzza3aQbPTzd26OC/JblJpVgtus5f8ILzCsz+pbMimgTkhy
+AuhYRppJaQ24APijsEC9+GIaVKPg5IwWroiPoj+QXNpshuvqVQQXvGaRiq4zoSnx
+xAJz+w8tjrDWcf826VN14IL+/Cmqlg/rIfB5CHdwVIfWwpuGB66q/UiPegZMNs8a
+3g==
+-----END CERTIFICATE-----
diff --git a/mash/eks/samples/certs/workload-bar-cert.pem b/mash/eks/samples/certs/workload-bar-cert.pem
new file mode 100644 (file)
index 0000000..c614ffc
--- /dev/null
@@ -0,0 +1,43 @@
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIUBn+v5JAoezzNx9s3Euvzlny0LWcwDQYJKoZIhvcNAQEL
+BQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcT
+CVN1bm55dmFsZTEOMAwGA1UEChMFSXN0aW8xETAPBgNVBAMTCElzdGlvIENBMB4X
+DTIwMDgxNDIyMTA1M1oXDTMwMDgxMjIyMTA1M1owADCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAMD18u/U1ouLwc2VblyFQCDN7XdGODoLV2eYA3NQrzMv
+0873zS5wbvte2eRc+MX9jnwg8rW+Won7KUaEzD62a9QZv5ilO1137YUBZrTgQIkO
+bhOnmpJRmR3Cxck8ZTEBMFsM+xyGAGc8ptdGJjEuxifFJHT3IB0ibXsnYuHnzpj1
+totq3sIPTRSkjsSOnKpyaOfBFiAyDQ0Rnm4+O32cJ654l0Co6iRABTnO9vIq1Tjn
+fQm6+F99w3Wvv9Ik8HxB4HBLZ3+qgXQIJOD+d5+z88OnsiEMYKO4XHy2D/OAh9ND
+7i9lzr+wXLYb5H1+TcEJuHFTHQcsm5YCl/zFt4YHgX0CAwEAAaN2MHQwDgYDVR0P
+AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
+Af8EAjAAMDUGA1UdEQEB/wQrMCmGJ3NwaWZmZTovL3RydXN0LWRvbWFpbi1iYXIv
+bnMvYmFyL3NhL2JhcjANBgkqhkiG9w0BAQsFAAOCAQEAGAWE6bLO4L8fDFg2hVCJ
+G+8uTVVeO2H8wFiDOqB0xq9OCrzSp39cZsBZLj9KFBWx/V0PEAlcmGlgHozdGkVG
+Z1/B+ukeRgALYBmHgOegoC2zHOz5qacqiRnV8Kijxa6nFyU0qbJCFVWs76DSZZDm
+872SMmoURs2VrAQTWInbtWxR4tAyEdmecYOdHEIXQDc13LQSwu7TINLs7JnjKlv7
+xIv6TsOyAyx305DSK0htxYfgrvo4cc33JmDOtL81bHfyUfx2B8HKeDYTaDh+V01G
+OesJNzqECzW6IMMFJey0f/4W7hbldpZmgXs8qa/g1CR8pCRs2eTWKTS336glXLCG
+MA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIJAON1ifrBZ2/BMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxl
+MQ4wDAYDVQQKDAVJc3RpbzENMAsGA1UECwwEVGVzdDEQMA4GA1UEAwwHUm9vdCBD
+QTEiMCAGCSqGSIb3DQEJARYTdGVzdHJvb3RjYUBpc3Rpby5pbzAgFw0xODAxMjQx
+OTE1NTFaGA8yMTE3MTIzMTE5MTU1MVowWTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+CkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTEOMAwGA1UEChMFSXN0aW8x
+ETAPBgNVBAMTCElzdGlvIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAyzCxr/xu0zy5rVBiso9ffgl00bRKvB/HF4AX9/ytmZ6Hqsy13XIQk8/u/By9
+iCvVwXIMvyT0CbiJq/aPEj5mJUy0lzbrUs13oneXqrPXf7ir3HzdRw+SBhXlsh9z
+APZJXcF93DJU3GabPKwBvGJ0IVMJPIFCuDIPwW4kFAI7R/8A5LSdPrFx6EyMXl7K
+M8jekC0y9DnTj83/fY72WcWX7YTpgZeBHAeeQOPTZ2KYbFal2gLsar69PgFS0Tom
+ESO9M14Yit7mzB1WDK2z9g3r+zLxENdJ5JG/ZskKe+TO4Diqi5OJt/h8yspS1ck8
+LJtCole9919umByg5oruflqIlQIDAQABozUwMzALBgNVHQ8EBAMCAgQwDAYDVR0T
+BAUwAwEB/zAWBgNVHREEDzANggtjYS5pc3Rpby5pbzANBgkqhkiG9w0BAQsFAAOC
+AQEAltHEhhyAsve4K4bLgBXtHwWzo6SpFzdAfXpLShpOJNtQNERb3qg6iUGQdY+w
+A2BpmSkKr3Rw/6ClP5+cCG7fGocPaZh+c+4Nxm9suMuZBZCtNOeYOMIfvCPcCS+8
+PQ/0hC4/0J3WJKzGBssaaMufJxzgFPPtDJ998kY8rlROghdSaVt423/jXIAYnP3Y
+05n8TGERBj7TLdtIVbtUIx3JHAo3PWJywA6mEDovFMJhJERp9sDHIr1BbhXK1TFN
+Z6HNH6gInkSSMtvC4Ptejb749PTaePRPF7ID//eq/3AH8UK50F3TQcLjEqWUsJUn
+aFKltOc+RAjzDklcUPeG4Y6eMA==
+-----END CERTIFICATE-----
diff --git a/mash/eks/samples/certs/workload-bar-key.pem b/mash/eks/samples/certs/workload-bar-key.pem
new file mode 100644 (file)
index 0000000..bc11603
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAwPXy79TWi4vBzZVuXIVAIM3td0Y4OgtXZ5gDc1CvMy/TzvfN
+LnBu+17Z5Fz4xf2OfCDytb5aifspRoTMPrZr1Bm/mKU7XXfthQFmtOBAiQ5uE6ea
+klGZHcLFyTxlMQEwWwz7HIYAZzym10YmMS7GJ8UkdPcgHSJteydi4efOmPW2i2re
+wg9NFKSOxI6cqnJo58EWIDINDRGebj47fZwnrniXQKjqJEAFOc728irVOOd9Cbr4
+X33Dda+/0iTwfEHgcEtnf6qBdAgk4P53n7Pzw6eyIQxgo7hcfLYP84CH00PuL2XO
+v7BcthvkfX5NwQm4cVMdByyblgKX/MW3hgeBfQIDAQABAoIBAQCKn6bZ2YQQWGTw
+tsvEOA5sAsT4jT/To1Y1nCXOcEaNdWyrIacMF8YDXI8Y2hn200PLtTfojUoqGn/6
+o2jAHPm2NJFKrlnJumCuzuTkSL7UN8Oo5x3KxEhF8yl4eqUP4ZTFtLuqMDKV+CK8
+QS8q4jmFVMHuLaOqipMwiIknVgs8IvmQSZf3LBPOLRX9vcTtT0YnOAhFQjb3048s
+Da+pDSsKesVkcsTx9aw4pUHWcLFuDHxZ1f0hAXcOfkzjzuBkQ0uoUxSIE+kcA2i0
+9vZB7fSqL/5zKrKooDSjW189WHd8wMEtmGZW6VDeH0fMuC+KWEVZnyjMrrlCMesJ
+MismTSABAoGBAPD2XAf01iMy4Y84XtI4vku0uO+pseyhZ2nyqLJW2q3M0bXKFMiD
+jiE7GlxBjynZFfU5R/H7QJ3rDwH4PpKyd13mgnlUImyLTUVaSbC3Bu0rJ+NFLtsQ
+7OCxi4F3pOvOAWUL5WJc0gyqmSBywoGFuCT1x0wch2si1/XGUH973EwBAoGBAM0A
+te01yywQ+X17fApIh/R+LLPkORecpDJgC3vTcMvuvC9Rq1HEC4S4b7X0SfrUzvCw
+BO+J3KUMBJXHC2S4VsWBn/jHA8vJ1RD11gDVUV776WLxhXiBekwneFyFlNUukkTa
+2bcnM3vtXZBl8z8Fhddfo5i9MR0Wh6jXF3HpemV9AoGAW1k6CHYkHBH0+sOnBtEm
+KzMnDQxq/EcwGjU5COruWgcU1XL3sBBXeHecha8A5B99OIrvoGfc1kE/XkLLDfgE
+Up/JhM+FgVrJ/2m8F/c68/xxUbJvkfL3qjMErR87cX2Wf8Ujv8dqhgzCok9/N3UH
+G1PlqxABsnbyIiV9bOb63AECgYEAqbsd5YF1b026k3dK8uSsk/RnpKWf03ngxMia
+mXIt4NsPugnfU3qCoudlrnvNSL0rfUHvRDibk5dIsI21VDX/udUiEwMLlI3OOBWi
+ktwLXB4sVLxtaqGhFS5UzB3ZZUwC1LlyKt9tE/0qS2Ttqc8zymcn900lPdUqitNT
+WQAbU60CgYBsR9gyXA4SXFjKmk5WKFhHlvTf87UfaOrPeeDE7zeEo2iVgjq9gSHw
+7zBaiVvrwcSn3COszrPgtOUM+Vl/T7Z2QmPTteP2R8mKxOJk4BWQ5q/bhoc3sEH7
+EjR9twDPRg3V9xEKtcTiJhzm4TitKGYBH8FQ22B4X6mouVE8KfXkyA==
+-----END RSA PRIVATE KEY-----
diff --git a/mash/eks/samples/certs/workload-foo-cert.pem b/mash/eks/samples/certs/workload-foo-cert.pem
new file mode 100644 (file)
index 0000000..e369742
--- /dev/null
@@ -0,0 +1,43 @@
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIUKR+dap3TpKhxmpwtNLchLa7E4JEwDQYJKoZIhvcNAQEL
+BQAwWTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAcT
+CVN1bm55dmFsZTEOMAwGA1UEChMFSXN0aW8xETAPBgNVBAMTCElzdGlvIENBMB4X
+DTIwMDgxNDIyMTA0OVoXDTMwMDgxMjIyMTA0OVowADCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBAM3y5xVP1qYDsy4DSEG7eXhQEGL/XUbXOR1kTEXTAhAk
+/Wo0YclowxRQuIyeXpLM+nRN2z0xDttkMRpI0m6Qb1vK43XtPkBieVm/tBSUyis+
+iBV6KBOhw7ionoAlyq6tOkwL2V3siMK5LvkpeeC7lJPJamaRN19LJcnWS214bcur
+lq6g6+owQGb4BS4STqfiRkIciw7MHTN5vWQcNmWNT3ME19KNQGKLXPkJGJoNlq4P
+98pIuO58k0mow8xESpmrJ1zOtMtUUDicXV67m8BV2xkn7YLDehfAyKsqMJjsdWB3
+LUlk/kFia9n/AwFz+3mMSPWe4OnRQGdtwUMuanknfSUCAwEAAaN2MHQwDgYDVR0P
+AQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMB
+Af8EAjAAMDUGA1UdEQEB/wQrMCmGJ3NwaWZmZTovL3RydXN0LWRvbWFpbi1mb28v
+bnMvZm9vL3NhL2ZvbzANBgkqhkiG9w0BAQsFAAOCAQEAO3Rcr/CEnEieuKujrQ/j
+ZrM5cjQckt/+NcpkXsTQaqpkARmUL23D/g3Cg3P9rfJVIfSIfN2509meX+ouDzIm
+JWoFW3XVFLiev18aBBO6rmLaMMMKiVOZYAYzeM8Zt/3qH8mLxNq2CQYUL8EtAd7V
+P1FVx6vauFqlyqPn2BWZO3CgdGyPwPRQkBUTrItcUI8OTgAFYd/Q5vQuLt82QIAl
+givsPvGaKEWV02tpf8PfAZDgXrFkJLeFhFd0pgf7RSIdvShNdPyyz4r9/2CqEVmc
+BRDyTw09OLceF0Mhi4HqcnzgVeLWvWT+yUo3FYf6kzeavK93CEdSU8c9OvQbyi9D
+cQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIJAON1ifrBZ2/BMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJU3Vubnl2YWxl
+MQ4wDAYDVQQKDAVJc3RpbzENMAsGA1UECwwEVGVzdDEQMA4GA1UEAwwHUm9vdCBD
+QTEiMCAGCSqGSIb3DQEJARYTdGVzdHJvb3RjYUBpc3Rpby5pbzAgFw0xODAxMjQx
+OTE1NTFaGA8yMTE3MTIzMTE5MTU1MVowWTELMAkGA1UEBhMCVVMxEzARBgNVBAgT
+CkNhbGlmb3JuaWExEjAQBgNVBAcTCVN1bm55dmFsZTEOMAwGA1UEChMFSXN0aW8x
+ETAPBgNVBAMTCElzdGlvIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAyzCxr/xu0zy5rVBiso9ffgl00bRKvB/HF4AX9/ytmZ6Hqsy13XIQk8/u/By9
+iCvVwXIMvyT0CbiJq/aPEj5mJUy0lzbrUs13oneXqrPXf7ir3HzdRw+SBhXlsh9z
+APZJXcF93DJU3GabPKwBvGJ0IVMJPIFCuDIPwW4kFAI7R/8A5LSdPrFx6EyMXl7K
+M8jekC0y9DnTj83/fY72WcWX7YTpgZeBHAeeQOPTZ2KYbFal2gLsar69PgFS0Tom
+ESO9M14Yit7mzB1WDK2z9g3r+zLxENdJ5JG/ZskKe+TO4Diqi5OJt/h8yspS1ck8
+LJtCole9919umByg5oruflqIlQIDAQABozUwMzALBgNVHQ8EBAMCAgQwDAYDVR0T
+BAUwAwEB/zAWBgNVHREEDzANggtjYS5pc3Rpby5pbzANBgkqhkiG9w0BAQsFAAOC
+AQEAltHEhhyAsve4K4bLgBXtHwWzo6SpFzdAfXpLShpOJNtQNERb3qg6iUGQdY+w
+A2BpmSkKr3Rw/6ClP5+cCG7fGocPaZh+c+4Nxm9suMuZBZCtNOeYOMIfvCPcCS+8
+PQ/0hC4/0J3WJKzGBssaaMufJxzgFPPtDJ998kY8rlROghdSaVt423/jXIAYnP3Y
+05n8TGERBj7TLdtIVbtUIx3JHAo3PWJywA6mEDovFMJhJERp9sDHIr1BbhXK1TFN
+Z6HNH6gInkSSMtvC4Ptejb749PTaePRPF7ID//eq/3AH8UK50F3TQcLjEqWUsJUn
+aFKltOc+RAjzDklcUPeG4Y6eMA==
+-----END CERTIFICATE-----
diff --git a/mash/eks/samples/certs/workload-foo-key.pem b/mash/eks/samples/certs/workload-foo-key.pem
new file mode 100644 (file)
index 0000000..bfad4d4
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAzfLnFU/WpgOzLgNIQbt5eFAQYv9dRtc5HWRMRdMCECT9ajRh
+yWjDFFC4jJ5eksz6dE3bPTEO22QxGkjSbpBvW8rjde0+QGJ5Wb+0FJTKKz6IFXoo
+E6HDuKiegCXKrq06TAvZXeyIwrku+Sl54LuUk8lqZpE3X0slydZLbXhty6uWrqDr
+6jBAZvgFLhJOp+JGQhyLDswdM3m9ZBw2ZY1PcwTX0o1AYotc+QkYmg2Wrg/3yki4
+7nyTSajDzERKmasnXM60y1RQOJxdXrubwFXbGSftgsN6F8DIqyowmOx1YHctSWT+
+QWJr2f8DAXP7eYxI9Z7g6dFAZ23BQy5qeSd9JQIDAQABAoIBAQDLs7PpGnze284A
+dvKjQYFWBSsQIDDsfrhZX/kpHxptSYj14TXPdzVtBKJlQ8ebP++B1fhBwCJH0gPX
+UawB/A6JJlZxL+Vg3YXVxY2ixcBpoYIMbDTzpg7muLF9YuPkfiapTRcElY53u57A
+h8urAx5kRtZc+MliEfwgdTtJ3dILnbXxGanKfi+nz9P5YuLkKzqIolbqu9ZxlJFD
+/V4DKITA0IootE0OhCKP0GfeA6L9z3tH2OuEn/LXl2S8FbbFCeY4ji8FQBr2icSB
+pXdee0gYIrvrU8G0eoE0ZV9bAGXkRhA3057HF9RqlAqhRc012s4ojbl/q4uINdWp
+R+UiUecJAoGBAP4Pzo+NwS054kOgSYu+NMSi63j2OJD9aeHYJT6QwVYZurTMChxx
+x283Da4qsCBGI37YjU5Ygd6DYc0T57GXfeka8tZQb5+v/ZvV1oIY+pVN5cp0xben
+Ttm0qskF2H57TmPcH5atWkW7b5CjrSo7DYFtd6jKzzoAJ9uPH4DCM5ufAoGBAM+F
+IRkSmzAPpiyPA1P7OlWy0vQLsNrFwZ59HOmovpQTgDLVW5Xbq+etEiAXmSvuxBU0
+OKiHMgGK2Pmg/vsM3mUVskrx+bDk+6GGM52feqa8N1rtxDTjamI5EHx29896jX/U
+HGSW+8YYVZ/jbSSneY71AO1E2INsNEi1Ei5qWTC7AoGABOdnNEwnK2lPncCNSt48
+BIOkiewuwVWy4oIaje+bW78ZZH3/v/bOQ65LXE5EogrYio1BhP6eWx4sGBpHQZ1L
+9+DmSQ66aNmryoNBJbe3toQPaG4Clv3qvrcHCORM/nwA0lqgXXcxI+FvUNpn8EW9
+h/8F7UMk5tiz7EAB+qlE978CgYAJBj8UOgzpoCSX13hLlKdKxsYJuuBsAyGSZNp3
+BtGS2u4+R6z97Vmib5JUNvKASJfaXDUCjy6LhqA86tVr0XlyZ+ki/TbgjHSs54sj
+FaZdzd2SZLidnC4qK1UeNIY+TZQNtQmvDinQyYofs+IxL99HajwqFU5dGL2FU+qA
+fjt2tQKBgQDrnpSRmAhhGcazmNVnzF8PVJGPwY4clGKB2jo6ru57tL0QRc/N+5pJ
+8boLB7CqRpC0mHpijJLKkLoJ0oVoC9jsn3e8tfVuVqbO3AfwdB+nkABQVHRxRRGt
+AlUeHXbjlY7OpemfK3smhLGBoOZKJVL7cKwyJc5MTPjcUgMwlwbW5w==
+-----END RSA PRIVATE KEY-----
diff --git a/mash/eks/samples/cross-network-gateway/cross-network-gateway.yaml b/mash/eks/samples/cross-network-gateway/cross-network-gateway.yaml
new file mode 100644 (file)
index 0000000..9c747e8
--- /dev/null
@@ -0,0 +1,17 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: cross-network-gateway
+  namespace: istio-system
+spec:
+  selector:
+    istio: ingressgateway
+  servers:
+    - port:
+        number: 15443
+        name: tls
+        protocol: TLS
+      tls:
+        mode: AUTO_PASSTHROUGH
+      hosts:
+        - "*.local"
diff --git a/mash/eks/samples/custom-bootstrap/README.md b/mash/eks/samples/custom-bootstrap/README.md
new file mode 100644 (file)
index 0000000..2d39c09
--- /dev/null
@@ -0,0 +1,52 @@
+# Custom Envoy Bootstrap Configuration
+
+This sample creates a simple helloworld service that bootstraps the Envoy proxy with a custom configuration file.
+
+## Starting the service
+
+First, we need to create a `ConfigMap` resource with our bootstrap configuration.
+
+```bash
+kubectl apply -f custom-bootstrap.yaml
+```
+
+Next, we can create a service that uses this bootstrap configuration.
+
+To do this, we need to add an annotation, `sidecar.istio.io/bootstrapOverride`, with the name of our ConfigMap as the value.
+
+We can create our helloworld app, using the custom config, with:
+
+```bash
+kubectl apply -f example-app.yaml
+```
+
+If you don't have [automatic sidecar injection](https://istio.io/docs/setup/additional-setup/sidecar-injection/#automatic-sidecar-injection)
+set in your cluster you will need to manually inject it to the services instead:
+
+```bash
+istioctl kube-inject -f example-app.yaml -o example-app-istio.yaml
+kubectl apply -f example-app-istio.yaml
+```
+
+## Checking the Bootstrap Configuration
+
+To see what bootstrap configuration a pod is using:
+
+```bash
+istioctl proxy-config bootstrap <POD-NAME>
+```
+
+## Customizing the Bootstrap
+
+The configuration provided will be passed to envoy using the [`--config-yaml`](https://www.envoyproxy.io/docs/envoy/v1.7.1/operations/cli#cmdoption-config-yaml) flag.
+
+This will merge the passed in configuration with the default configuration. Singular values will replace the default values, while repeated values will be appended.
+
+For reference, [the default bootstrap configuration](/tools/packaging/common/envoy_bootstrap.json) and Envoy's [configuration reference](https://www.envoyproxy.io/docs/envoy/latest/configuration/configuration#config) may be useful
+
+## Cleanup
+
+```bash
+kubectl delete -f custom-bootstrap.yaml
+kubectl delete -f example-app.yaml
+```
\ No newline at end of file
diff --git a/mash/eks/samples/custom-bootstrap/custom-bootstrap.yaml b/mash/eks/samples/custom-bootstrap/custom-bootstrap.yaml
new file mode 100644 (file)
index 0000000..7ef8d1d
--- /dev/null
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: istio-custom-bootstrap-config
+  namespace: default
+data:
+  custom_bootstrap.json: |
+    {
+      "tracing": {
+        "http": {
+          "name": "envoy.zipkin",
+          "config": {
+            "collector_cluster": "zipkin",
+            "collector_endpoint": "/api/v1/spans/custom",
+            "trace_id_128bit": "true"
+          }
+        }
+      }
+    }
diff --git a/mash/eks/samples/custom-bootstrap/example-app.yaml b/mash/eks/samples/custom-bootstrap/example-app.yaml
new file mode 100644 (file)
index 0000000..24b4fdc
--- /dev/null
@@ -0,0 +1,27 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: helloworld-v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: helloworld
+      version: v1
+  template:
+    metadata:
+      annotations:
+        sidecar.istio.io/bootstrapOverride: "istio-custom-bootstrap-config"
+      labels:
+        app: helloworld
+        version: v1
+    spec:
+      containers:
+        - name: helloworld
+          image: docker.io/istio/examples-helloworld-v1
+          resources:
+            requests:
+              cpu: "100m"
+          imagePullPolicy: IfNotPresent
+          ports:
+            - containerPort: 5000
diff --git a/mash/eks/samples/external/README.md b/mash/eks/samples/external/README.md
new file mode 100644 (file)
index 0000000..e17198b
--- /dev/null
@@ -0,0 +1,34 @@
+# External Services
+
+By default Istio-enabled services are unable to access services and URLs outside of the cluster. Pods use <i>iptables</i> to transparently redirect all outbound traffic to the sidecar proxy, which only handles intra-cluster destinations.
+
+See [the Egress Task](https://istio.io/docs/tasks/traffic-management/egress/) for
+information on configuring Istio to contact external services.
+
+This directory contains samples showing how to enable pods to contact a few well
+known services.
+
+If Istio is not configured to allow pods to contact external services, the pods will
+see errors such as 404s, HTTPS connection problems, and TCP connection problems.  If
+ServiceEntries are misconfigured pods may see problems with server names.
+
+## Try it out
+
+After an operator runs `kubectl create -f aptget.yaml` pods will be able to
+succeed with `apt-get update` and `apt-get install`.
+
+After an operator runs `kubectl create -f github.yaml` pods will be able to
+succeed with `git clone https://github.com/fortio/fortio.git`.
+
+Running `kubectl create -f pypi.yaml` allows pods to update Python libraries using `pip`.
+
+It is not a best practice to enable pods to update libraries dynamically.
+We are providing these samples
+because they have proven to be helpful with interactive troubleshooting.  Security minded clusters should only allow traffic to service dependencies such as cloud
+services.
+
+### Enable communication by default
+
+Note that [this note](https://istio.io/docs/tasks/traffic-management/egress/#install-istio-with-access-to-all-external-services-by-default) shows how to configure Istio to contact services by default.  The technique
+discussed there does not allow HTTP on port 80 or SSH on port 22.  These examples will
+allow external communication for ports 80 and 22.
diff --git a/mash/eks/samples/external/aptget.yaml b/mash/eks/samples/external/aptget.yaml
new file mode 100644 (file)
index 0000000..fa24fa4
--- /dev/null
@@ -0,0 +1,20 @@
+# This ServiceEntry exposes the hosts needed for installing packages with apt-get.
+# After applying this file, Istio-enabled pods (configured apt-get) be able to execute
+# `apt-get upgrade` and `apt-get install`.  If this is not installed you may get
+# "404  Not Found"
+
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: make-aptget-work
+spec:
+  hosts:
+  - deb.debian.org
+  - cdn-fastly.deb.debian.org
+  - security.debian.org
+  - archive.ubuntu.com
+  - security.ubuntu.com
+  ports:
+  - number: 80
+    name: http
+    protocol: HTTP
diff --git a/mash/eks/samples/external/github.yaml b/mash/eks/samples/external/github.yaml
new file mode 100644 (file)
index 0000000..832cbc3
--- /dev/null
@@ -0,0 +1,53 @@
+# This ServiceEntry exposes the hosts needed for github.com.
+# After applying this file, Istio-enabled pods will be able to execute
+# `git clone https://github.com/istio/api.git` and (with local identification
+# config and certificate) `git clone git@github.com:istio/api.git`
+
+# HTTP and TLS, the host must be specified
+# See https://istio.io/docs/tasks/traffic-management/egress/
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: github-https
+spec:
+  hosts:
+  - github.com
+  ports:
+  - number: 443
+    name: https
+    protocol: HTTPS
+---
+# For TCP services the IP ranges SHOULD be specified to avoid problems
+# if multiple SEs use the same port number.
+# See https://istio.io/blog/2018/egress-tcp/#mesh-external-service-entry-for-an-external-mysql-instance
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: github-tcp
+spec:
+  hosts:
+  - dummy.github.com # not used
+  addresses: # from https://help.github.com/articles/about-github-s-ip-addresses/
+  - "13.229.188.59/32"
+  - "13.250.177.223/32"
+  - "140.82.112.0/20"
+  - "18.194.104.89/32"
+  - "18.195.85.27/32"
+  - "185.199.108.0/22"
+  - "185.199.108.153/32"
+  - "185.199.109.153/32"
+  - "185.199.110.153/32"
+  - "185.199.111.153/32"
+  - "192.30.252.0/22"
+  - "192.30.252.153/32"
+  - "192.30.252.154/32"
+  - "23.20.92.3/32"
+  - "35.159.8.160/32"
+  - "52.74.223.119/32"
+  - "54.166.52.62/32"
+  - "54.87.5.173/32"
+  ports:
+  - name: tcp
+    number: 22
+    protocol: tcp
+  location: MESH_EXTERNAL
diff --git a/mash/eks/samples/external/pypi.yaml b/mash/eks/samples/external/pypi.yaml
new file mode 100644 (file)
index 0000000..7f457a5
--- /dev/null
@@ -0,0 +1,44 @@
+# This ServiceEntry exposes the hosts needed for Python `pip`.
+# After applying this file, Istio-enabled pods will be able to execute
+# `pip search istio`.
+
+# HTTP and TLS, the host must be specified
+# See https://istio.io/docs/tasks/traffic-management/egress/
+
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: python-https
+spec:
+  hosts:
+  - pypi.python.org
+  ports:
+  - number: 443
+    name: https
+    protocol: HTTPS
+---
+# pypi.python.org may 301 redirect to pypi.org, so we need this too.
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: pypi-https
+spec:
+  hosts:
+  - pypi.org
+  ports:
+  - number: 443
+    name: https
+    protocol: HTTPS
+---
+# pip install may fetch files from files.pythonhosted.org
+apiVersion: networking.istio.io/v1alpha3
+kind: ServiceEntry
+metadata:
+  name: pythonhosted-https
+spec:
+  hosts:
+  - files.pythonhosted.org
+  ports:
+  - number: 443
+    name: https
+    protocol: HTTPS
diff --git a/mash/eks/samples/fortio/stackdriver.yaml b/mash/eks/samples/fortio/stackdriver.yaml
new file mode 100644 (file)
index 0000000..2bc93dc
--- /dev/null
@@ -0,0 +1,245 @@
+apiVersion: "config.istio.io/v1alpha2"
+kind: handler
+metadata:
+  name: stackdriver
+spec:
+  compiledAdapter: stackdriver
+  params:
+    appCredentials: y
+    pushInterval: 5s
+    metricInfo:
+      server-request-count.instance.{{.Namespace}}:
+        kind: 3 # CUMULATIVE
+        value: 2 # INT64
+        metric_type: "istio.io/service/server/request_count"
+    logInfo:
+      server-accesslog-stackdriver.instance.{{.Namespace}}:
+        labelNames:
+        - source_uid
+        - source_ip
+        - source_app
+        - source_principal
+        - source_name
+        - source_workload
+        - source_namespace
+        - source_owner
+        - destination_uid
+        - destination_app
+        - destination_ip
+        - destination_service_host
+        - destination_workload
+        - destination_name
+        - destination_namespace
+        - destination_owner
+        - destination_principal
+        - api_name
+        - api_version
+        - api_claims
+        - api_key
+        - request_operation
+        - protocol
+        - method
+        - url
+        - response_code
+        - response_size
+        - request_size
+        - request_id
+        - client_trace_id
+        - latency
+        - service_authentication_policy
+        - user_agent
+        - response_timestamp
+        - received_bytes
+        - sent_bytes
+        - referer
+    trace:
+      sampleProbability: 1.0
+---
+# For future Context Graph test.
+# apiVersion: "config.istio.io/v1alpha2"
+# kind: edge
+# metadata:
+#   name: default
+# spec:
+#   timestamp: request.time | context.time
+#   sourceUid: source.uid | "Unknown"
+#   sourceOwner: source.owner | "Unknown"
+#   sourceWorkloadName: source.workload.name | "Unknown"
+#   sourceWorkloadNamespace: source.workload.namespace | "Unknown"
+#   destinationUid: destination.uid | "Unknown"
+#   destinationOwner: destination.owner | "Unknown"
+#   destinationWorkloadName: destination.workload.name | "Unknown"
+#   destinationWorkloadNamespace: destination.workload.namespace | "Unknown"
+#   contextProtocol: context.protocol | "Unknown"
+#   apiProtocol: api.protocol | "Unknown"
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: server-accesslog-stackdriver
+spec:
+  compiledTemplate: logentry
+  params:
+    severity: '"Info"'
+    timestamp: request.time
+    variables:
+      source_uid: source.uid | ""
+      source_ip: source.ip | ip("0.0.0.0")
+      source_app: source.labels["app"] | ""
+      source_principal: source.principal | ""
+      source_name: source.name | ""
+      source_workload: source.workload.name | ""
+      source_namespace: source.namespace | ""
+      source_owner: source.owner | ""
+      destination_uid: destination.uid | ""
+      destination_app: destination.labels["app"] | ""
+      destination_ip: destination.ip | ip("0.0.0.0")
+      destination_service_host: destination.service.host | ""
+      destination_workload: destination.workload.name | ""
+      destination_name: destination.name | ""
+      destination_namespace: destination.namespace | ""
+      destination_owner: destination.owner | ""
+      destination_principal: destination.principal | ""
+      api_name: api.service | ""
+      api_version: api.version | ""
+      api_claims: request.auth.raw_claims | ""
+      api_key: request.api_key | request.headers["x-api-key"] | ""
+      request_operation: conditional((context.protocol | "unknown") == "grpc", request.path | "unknown", request.method | "unknown")
+      protocol: request.scheme | context.protocol | "http"
+      method: request.method | ""
+      url: request.path | ""
+      response_code: response.code | 0
+      response_size: response.size | 0
+      request_size: request.size | 0
+      request_id: request.headers["x-request-id"] | ""
+      client_trace_id: request.headers["x-client-trace-id"] | ""
+      latency: response.duration | "0ms"
+      service_authentication_policy: conditional((context.reporter.kind | "inbound") == "outbound", "unknown", conditional(connection.mtls | false, "mutual_tls", "none"))
+      user_agent: request.useragent | ""
+      response_timestamp: response.time
+      received_bytes: request.total_size | 0
+      sent_bytes: response.total_size | 0
+      referer: request.referer | ""
+    monitored_resource_type: '"k8s_container"'
+    monitoredResourceDimensions:
+      project_id: '""'
+      cluster_name: '""'
+      namespace_name: destination.namespace | "unknown"
+      location: '""'
+      container_name: destination.container.name | "unknown"
+      pod_name: destination.name | "unknown"
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: server-request-count
+spec:
+  compiledTemplate: metric
+  params:
+    value: "1"
+    dimensions:
+      destination_service_name: destination.service.name | "unknown"
+      destination_service_namespace: destination.service.namespace | "unknown"
+      destination_port: destination.port | 0
+      request_operation: conditional((context.protocol | "unknown") == "grpc", request.path | "unknown", request.method | "unknown")
+      request_protocol: context.protocol | "unknown"
+      api_version: api.version | "unknown"
+      api_name: api.service | "unknown"
+      response_code: response.code | 0
+      service_authentication_policy: conditional((context.reporter.kind | "inbound") == "outbound", "unknown", conditional(connection.mtls | false, "mutual_tls", "none"))
+      source_workload_namespace: source.workload.namespace | "unknown"
+      source_workload_name: source.workload.name | "unknown"
+      source_owner: source.owner | "unknown"
+      destination_workload_namespace: destination.workload.namespace | "unknown"
+      destination_workload_name: destination.workload.name | "unknown"
+      destination_owner: destination.owner | "unknown"
+    monitoredResourceType: '"k8s_container"'
+    monitoredResourceDimensions:
+      project_id: '""'
+      cluster_name: '""'
+      namespace_name: destination.workload.namespace | "unknown"
+      location: '""'
+      container_name: destination.container.name | "unknown"
+      pod_name: destination.name | "unknown"
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: instance
+metadata:
+  name: stackdriver-span
+spec:
+  compiledTemplate: tracespan
+  params:
+    traceId: request.headers["x-b3-traceid"]
+    spanId: request.headers["x-b3-spanid"] | ""
+    parentSpanId: request.headers["x-b3-parentspanid"] | ""
+    spanName: destination.service.host | destination.service.name | destination.workload.name | "unknown"
+    startTime: request.time
+    endTime: response.time
+    clientSpan: (context.reporter.kind | "inbound") == "outbound"
+    rewriteClientSpanId: "true"
+    spanTags:
+      destination_service_name: destination.service.name | "unknown"
+      destination_service_namespace: destination.service.namespace | "unknown"
+      destination_port: destination.port | 0
+      request_operation: conditional((context.protocol | "unknown") == "grpc", request.path | "unknown", request.method | "unknown")
+      request_protocol: context.protocol | "unknown"
+      api_version: api.version | "unknown"
+      api_name: api.service | "unknown"
+      response_code: response.code | 0
+      service_authentication_policy: conditional((context.reporter.kind | "inbound") == "outbound", "unknown", conditional(connection.mtls | false, "mutual_tls", "none"))
+      source_workload_namespace: source.workload.namespace | "unknown"
+      source_workload_name: source.workload.name | "unknown"
+      source_owner: source.owner | "unknown"
+      destination_workload_namespace: destination.workload.namespace | "unknown"
+      destination_workload_name: destination.workload.name | "unknown"
+      destination_owner: destination.owner | "unknown"
+      http_url: request.path | ""
+      request_size: request.size | 0
+      response_size: response.size | 0
+      source_ip: source.ip | ip("0.0.0.0")
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: stackdriver-log
+spec:
+  match: (context.protocol == "http" || context.protocol == "grpc") && (context.reporter.kind | "inbound" == "inbound")
+  actions:
+  - handler: stackdriver.handler
+    instances:
+    - server-accesslog-stackdriver
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: stackdriver-server
+spec:
+  match: (context.protocol == "http" || context.protocol == "grpc") && (context.reporter.kind | "inbound" == "inbound")
+  actions:
+  - handler: stackdriver.handler
+    instances:
+    - server-request-count
+---
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: stackdriver-tracing-rule
+spec:
+  match: context.protocol == "http" || context.protocol == "grpc"  # If omitted match is true.
+  actions:
+  - handler: stackdriver.handler
+    instances:
+    - stackdriver-span
+---
+# For future Context Graph test.
+# apiVersion: "config.istio.io/v1alpha2"
+# kind: rule
+# metadata:
+#   name: edgetosd
+# spec:
+#   match: (context.reporter.kind | "inbound" == "inbound") && (context.protocol | "unknown" != "unknown")
+#   actions:
+#    - handler: stackdriver.handler
+#      instances:
+#      - default.edge
+---
diff --git a/mash/eks/samples/health-check/liveness-command.yaml b/mash/eks/samples/health-check/liveness-command.yaml
new file mode 100644 (file)
index 0000000..7485a35
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Liveness service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: liveness
+  labels:
+    app: liveness
+spec:
+  ports:
+  - port: 80
+    name: http
+  selector:
+    app: liveness
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: liveness
+spec:
+  selector:
+    matchLabels:
+      app: liveness
+  template:
+    metadata:
+      labels:
+        app: liveness
+    spec:
+      containers:
+      - name: liveness
+        image: k8s.gcr.io/busybox
+        args:
+        - /bin/sh
+        - -c
+        - touch /tmp/healthy; sleep 3600
+        livenessProbe:
+          exec:
+            command:
+            - cat
+            - /tmp/healthy
+          initialDelaySeconds: 5
+          periodSeconds: 5
diff --git a/mash/eks/samples/health-check/liveness-http-same-port.yaml b/mash/eks/samples/health-check/liveness-http-same-port.yaml
new file mode 100644 (file)
index 0000000..ff776fa
--- /dev/null
@@ -0,0 +1,39 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: liveness-http
+  labels:
+    app: liveness-http
+spec:
+  ports:
+  - name: http
+    port: 8001
+  selector:
+    app: liveness-http
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: liveness-http
+spec:
+  selector:
+    matchLabels:
+      app: liveness-http
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: liveness-http
+        version: v1
+    spec:
+      containers:
+      - name: liveness-http
+        image: docker.io/istio/health:example
+        ports:
+        - containerPort: 8001
+        livenessProbe:
+          httpGet:
+            path: /foo
+            port: 8001
+          initialDelaySeconds: 5
+          periodSeconds: 5
diff --git a/mash/eks/samples/health-check/liveness-http.yaml b/mash/eks/samples/health-check/liveness-http.yaml
new file mode 100644 (file)
index 0000000..2ad1f6c
--- /dev/null
@@ -0,0 +1,39 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: liveness-http
+  labels:
+    app: liveness-http
+spec:
+  ports:
+  - name: http
+    port: 8001
+  selector:
+    app: liveness-http
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: liveness-http
+spec:
+  selector:
+    matchLabels:
+      app: liveness-http
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: liveness-http
+        version: v1
+    spec:
+      containers:
+      - name: liveness-http
+        image: docker.io/istio/health:example
+        ports:
+        - containerPort: 8001
+        livenessProbe:
+          httpGet:
+            path: /foo
+            port: 8002
+          initialDelaySeconds: 5
+          periodSeconds: 5
diff --git a/mash/eks/samples/helloworld/README.md b/mash/eks/samples/helloworld/README.md
new file mode 100644 (file)
index 0000000..c980582
--- /dev/null
@@ -0,0 +1,90 @@
+# Helloworld service
+
+This sample includes two versions of a simple helloworld service that returns its version
+and instance (hostname) when called.
+It can be used as a test service when experimenting with version routing.
+
+This service is also used to demonstrate canary deployments working in conjunction with autoscaling.
+See [Canary deployments using Istio](https://istio.io/blog/2017/0.1-canary.html).
+
+## Start the helloworld service
+
+The following commands assume you have
+[automatic sidecar injection](https://istio.io/docs/setup/additional-setup/sidecar-injection/#automatic-sidecar-injection)
+enabled in your cluster.
+If not, you'll need to modify them to include
+[manual sidecar injection](https://istio.io/docs/setup/additional-setup/sidecar-injection/#manual-sidecar-injection).
+
+To run both versions of the helloworld service, use the following command:
+
+```bash
+kubectl apply -f helloworld.yaml
+```
+
+Alternatively, you can run just one version at a time by first defining the service:
+
+```bash
+kubectl apply -f helloworld.yaml -l app=helloworld
+```
+
+and then deploying version v1, v2, or both:
+
+```bash
+kubectl apply -f helloworld.yaml -l version=v1
+kubectl apply -f helloworld.yaml -l version=v2
+```
+
+## Configure the helloworld gateway
+
+Apply the helloworld gateway configuration:
+
+```bash
+kubectl apply -f helloworld-gateway.yaml
+```
+
+Follow [these instructions](https://istio.io/docs/tasks/traffic-management/ingress/ingress-control/#determining-the-ingress-ip-and-ports)
+to set the INGRESS_HOST and INGRESS_PORT variables and then confirm the sample is running using curl:
+
+```bash
+export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
+curl http://$GATEWAY_URL/hello
+```
+
+## Autoscale the services
+
+Note that a Kubernetes [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
+only works if all containers in the pods request cpu. In this sample the deployment
+containers in `helloworld.yaml` are configured with the request.
+The injected istio-proxy containers also include cpu requests,
+making the helloworld service ready for autoscaling.
+
+Enable autoscaling on both versions of the service:
+
+```bash
+kubectl autoscale deployment helloworld-v1 --cpu-percent=50 --min=1 --max=10
+kubectl autoscale deployment helloworld-v2 --cpu-percent=50 --min=1 --max=10
+kubectl get hpa
+```
+
+## Generate load
+
+```bash
+./loadgen.sh &
+./loadgen.sh & # run it twice to generate lots of load
+```
+
+Wait for about 2 minutes and then check the number of replicas:
+
+```bash
+kubectl get hpa
+```
+
+If the autoscaler is functioning correctly, the `REPLICAS` column should have a value > 1.
+
+## Cleanup
+
+```bash
+kubectl delete -f helloworld.yaml
+kubectl delete -f helloworld-gateway.yaml
+kubectl delete hpa helloworld-v1 helloworld-v2
+```
diff --git a/mash/eks/samples/helloworld/helloworld-gateway.yaml b/mash/eks/samples/helloworld/helloworld-gateway.yaml
new file mode 100644 (file)
index 0000000..43afc14
--- /dev/null
@@ -0,0 +1,33 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: helloworld-gateway
+spec:
+  selector:
+    istio: ingressgateway # use istio default controller
+  servers:
+  - port:
+      number: 80
+      name: http
+      protocol: HTTP
+    hosts:
+    - "*"
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: helloworld
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - helloworld-gateway
+  http:
+  - match:
+    - uri:
+        exact: /hello
+    route:
+    - destination:
+        host: helloworld
+        port:
+          number: 5000
diff --git a/mash/eks/samples/helloworld/helloworld.yaml b/mash/eks/samples/helloworld/helloworld.yaml
new file mode 100644 (file)
index 0000000..2563918
--- /dev/null
@@ -0,0 +1,68 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: helloworld
+  labels:
+    app: helloworld
+spec:
+  ports:
+  - port: 5000
+    name: http
+  selector:
+    app: helloworld
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: helloworld-v1
+  labels:
+    version: v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: helloworld
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: helloworld
+        version: v1
+    spec:
+      containers:
+      - name: helloworld
+        image: docker.io/istio/examples-helloworld-v1
+        resources:
+          requests:
+            cpu: "100m"
+        imagePullPolicy: IfNotPresent #Always
+        ports:
+        - containerPort: 5000
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: helloworld-v2
+  labels:
+    version: v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: helloworld
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: helloworld
+        version: v2
+    spec:
+      containers:
+      - name: helloworld
+        image: docker.io/istio/examples-helloworld-v2
+        resources:
+          requests:
+            cpu: "100m"
+        imagePullPolicy: IfNotPresent #Always
+        ports:
+        - containerPort: 5000
diff --git a/mash/eks/samples/helloworld/src/requirements.txt b/mash/eks/samples/helloworld/src/requirements.txt
new file mode 100644 (file)
index 0000000..ac286ea
--- /dev/null
@@ -0,0 +1,7 @@
+requests
+flask
+flask_json
+flask_bootstrap
+json2html
+simplejson
+gevent
diff --git a/mash/eks/samples/httpbin/README.md b/mash/eks/samples/httpbin/README.md
new file mode 100644 (file)
index 0000000..ab84877
--- /dev/null
@@ -0,0 +1,39 @@
+# Httpbin service
+
+This sample runs [httpbin](https://httpbin.org) as an Istio service.
+Httpbin is a well known HTTP testing service that can be used for experimenting
+with all kinds of Istio features.
+
+To use it:
+
+1. Install Istio by following the [istio install instructions](https://istio.io/docs/setup/).
+
+1. Start the httpbin service inside the Istio service mesh:
+
+    If you have [automatic sidecar injection](https://istio.io/docs/setup/additional-setup/sidecar-injection/#automatic-sidecar-injection) enabled:
+
+    ```bash
+    kubectl apply -f httpbin.yaml
+    ```
+
+    Otherwise manually inject the sidecars before applying:
+
+    ```bash
+    kubectl apply -f <(istioctl kube-inject -f httpbin.yaml)
+    ```
+
+Because the httpbin service is not exposed outside of the cluster
+you cannot _curl_ it directly, however you can verify that it is working correctly using
+a _curl_ command against `httpbin:8000` *from inside the cluster* using the public _dockerqa/curl_
+image from Docker hub:
+
+```bash
+kubectl run -i --rm --restart=Never dummy --image=dockerqa/curl:ubuntu-trusty --command -- curl --silent httpbin:8000/html
+kubectl run -i --rm --restart=Never dummy --image=dockerqa/curl:ubuntu-trusty --command -- curl --silent --head httpbin:8000/status/500
+time kubectl run -i --rm --restart=Never dummy --image=dockerqa/curl:ubuntu-trusty --command -- curl --silent httpbin:8000/delay/5
+```
+
+You can also test the httpbin service by starting the [sleep service](../sleep) and calling httpbin from it.
+
+A third option is to access the service from outside of the mesh through an Ingress Gateway.
+The [Ingress Gateways](https://istio.io/docs/tasks/traffic-management/ingress/ingress-control/) task explains how to do it.
diff --git a/mash/eks/samples/httpbin/httpbin-gateway.yaml b/mash/eks/samples/httpbin/httpbin-gateway.yaml
new file mode 100644 (file)
index 0000000..99ac6ee
--- /dev/null
@@ -0,0 +1,30 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: httpbin-gateway
+spec:
+  selector:
+    istio: ingressgateway
+  servers:
+  - port:
+      number: 80
+      name: http
+      protocol: HTTP
+    hosts:
+    - "*"
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: httpbin
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - httpbin-gateway
+  http:
+  - route:
+    - destination:
+        host: httpbin
+        port:
+          number: 8000
diff --git a/mash/eks/samples/httpbin/httpbin-nodeport.yaml b/mash/eks/samples/httpbin/httpbin-nodeport.yaml
new file mode 100644 (file)
index 0000000..8ff593f
--- /dev/null
@@ -0,0 +1,54 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# httpbin service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: httpbin
+  labels:
+    app: httpbin
+spec:
+  type: NodePort
+  ports:
+  - name: http
+    port: 8000
+    targetPort: 80
+  selector:
+    app: httpbin
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpbin
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: httpbin
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: httpbin
+        version: v1
+    spec:
+      containers:
+      - image: docker.io/kennethreitz/httpbin
+        imagePullPolicy: IfNotPresent
+        name: httpbin
+        ports:
+        - containerPort: 80
diff --git a/mash/eks/samples/httpbin/httpbin-vault.yaml b/mash/eks/samples/httpbin/httpbin-vault.yaml
new file mode 100644 (file)
index 0000000..d05e954
--- /dev/null
@@ -0,0 +1,54 @@
+# Copyright 2019 Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# httpbin service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: httpbin
+  labels:
+    app: httpbin
+spec:
+  ports:
+  - name: http
+    port: 8000
+    targetPort: 80
+  selector:
+    app: httpbin
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpbin
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: httpbin
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: httpbin
+        version: v1
+    spec:
+      serviceAccountName: vault-citadel-sa    
+      containers:
+      - image: docker.io/kennethreitz/httpbin
+        imagePullPolicy: IfNotPresent
+        name: httpbin
+        ports:
+        - containerPort: 80
diff --git a/mash/eks/samples/httpbin/httpbin.yaml b/mash/eks/samples/httpbin/httpbin.yaml
new file mode 100644 (file)
index 0000000..8bfe4a6
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# httpbin service
+##################################################################################################
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: httpbin
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: httpbin
+  labels:
+    app: httpbin
+spec:
+  ports:
+  - name: http
+    port: 8000
+    targetPort: 80
+  selector:
+    app: httpbin
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpbin
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: httpbin
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: httpbin
+        version: v1
+    spec:
+      serviceAccountName: httpbin
+      containers:
+      - image: docker.io/kennethreitz/httpbin
+        imagePullPolicy: IfNotPresent
+        name: httpbin
+        ports:
+        - containerPort: 80
diff --git a/mash/eks/samples/httpbin/httpsbin.yaml b/mash/eks/samples/httpbin/httpsbin.yaml
new file mode 100644 (file)
index 0000000..6e11de7
--- /dev/null
@@ -0,0 +1,59 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# httpbin service
+##################################################################################################
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: httpbin
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: httpbin
+  labels:
+    app: httpbin
+spec:
+  ports:
+  - name: http
+    port: 8443
+    targetPort: 443
+  selector:
+    app: httpbin
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpbin
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: httpbin
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: httpbin
+        version: v1
+    spec:
+      serviceAccountName: httpbin
+      containers:
+      - image: docker.io/kennethreitz/httpbin
+        imagePullPolicy: IfNotPresent
+        name: httpbin
+        ports:
+        - containerPort: 443
diff --git a/mash/eks/samples/httpbin/policy/keyval-template.yaml b/mash/eks/samples/httpbin/policy/keyval-template.yaml
new file mode 100644 (file)
index 0000000..c194bc5
--- /dev/null
@@ -0,0 +1,10 @@
+# this config is created through command
+# mixgen template -d $GOPATH/src/istio.io/istio/mixer/test/keyval/template_handler_service.descriptor_set -o $GOPATH/src/istio.io/istio/mixer/test/keyval/template.yaml -n keyval
+apiVersion: "config.istio.io/v1alpha2"
+kind: template
+metadata:
+  name: keyval
+  namespace: istio-system
+spec:
+  descriptor: "CvD6AgogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJNChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUi5AQKE0ZpbGVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIYCgdwYWNrYWdlGAIgASgJUgdwYWNrYWdlEh4KCmRlcGVuZGVuY3kYAyADKAlSCmRlcGVuZGVuY3kSKwoRcHVibGljX2RlcGVuZGVuY3kYCiADKAVSEHB1YmxpY0RlcGVuZGVuY3kSJwoPd2Vha19kZXBlbmRlbmN5GAsgAygFUg53ZWFrRGVwZW5kZW5jeRJDCgxtZXNzYWdlX3R5cGUYBCADKAsyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvUgttZXNzYWdlVHlwZRJBCgllbnVtX3R5cGUYBSADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90b1IIZW51bVR5cGUSQQoHc2VydmljZRgGIAMoCzInLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvUgdzZXJ2aWNlEkMKCWV4dGVuc2lvbhgHIAMoCzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90b1IJZXh0ZW5zaW9uEjYKB29wdGlvbnMYCCABKAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNSB29wdGlvbnMSSQoQc291cmNlX2NvZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mb1IOc291cmNlQ29kZUluZm8SFgoGc3ludGF4GAwgASgJUgZzeW50YXgiuQYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRp6Cg5FeHRlbnNpb25SYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQSQAoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnNSB29wdGlvbnMaNwoNUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQifAoVRXh0ZW5zaW9uUmFuZ2VPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAYKFEZpZWxkRGVzY3JpcHRvclByb3RvEhIKBG5hbWUYASABKAlSBG5hbWUSFgoGbnVtYmVyGAMgASgFUgZudW1iZXISQQoFbGFiZWwYBCABKA4yKy5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWxSBWxhYmVsEj4KBHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZVIEdHlwZRIbCgl0eXBlX25hbWUYBiABKAlSCHR5cGVOYW1lEhoKCGV4dGVuZGVlGAIgASgJUghleHRlbmRlZRIjCg1kZWZhdWx0X3ZhbHVlGAcgASgJUgxkZWZhdWx0VmFsdWUSHwoLb25lb2ZfaW5kZXgYCSABKAVSCm9uZW9mSW5kZXgSGwoJanNvbl9uYW1lGAogASgJUghqc29uTmFtZRI3CgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1IHb3B0aW9ucyK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJFRBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyLjAgoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRo7ChFFbnVtUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQigwEKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgCIAEoBVIGbnVtYmVyEjsKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1IHb3B0aW9ucyKnAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj4KBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG9SBm1ldGhvZBI5CgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zUgdvcHRpb25zIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyK5CAoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSNwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZhbHNlUhJwaHBHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2VSDmNjRW5hYmxlQXJlbmFzEioKEW9iamNfY2xhc3NfcHJlZml4GCQgASgJUg9vYmpjQ2xhc3NQcmVmaXgSKQoQY3NoYXJwX25hbWVzcGFjZRglIAEoCVIPY3NoYXJwTmFtZXNwYWNlEiEKDHN3aWZ0X3ByZWZpeBgnIAEoCVILc3dpZnRQcmVmaXgSKAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCVIOcGhwQ2xhc3NQcmVmaXgSIwoNcGhwX25hbWVzcGFjZRgpIAEoCVIMcGhwTmFtZXNwYWNlElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci0QIKDk1lc3NhZ2VPcHRpb25zEjwKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZVIUbWVzc2FnZVNldFdpcmVGb3JtYXQSTAofbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2VSHG5vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3ISJQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSGwoJbWFwX2VudHJ5GAcgASgIUghtYXBFbnRyeRJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQICBAJSgQICRAKIuIDCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIZCgR3ZWFrGAogASgIOgVmYWxzZVIEd2VhaxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJKBAgEEAUicwoMT25lb2ZPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiwAEKC0VudW1PcHRpb25zEh8KC2FsbG93X2FsaWFzGAIgASgIUgphbGxvd0FsaWFzEiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYingEKEEVudW1WYWx1ZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKcAQoOU2VydmljZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiLgAgoNTWV0aG9kT3B0aW9ucxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJxChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV05SEGlkZW1wb3RlbmN5TGV2ZWwSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIimgMKE1VuaW50ZXJwcmV0ZWRPcHRpb24SQQoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0UgRuYW1lEikKEGlkZW50aWZpZXJfdmFsdWUYAyABKAlSD2lkZW50aWZpZXJWYWx1ZRIsChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKARSEHBvc2l0aXZlSW50VmFsdWUSLAoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDUhBuZWdhdGl2ZUludFZhbHVlEiEKDGRvdWJsZV92YWx1ZRgGIAEoAVILZG91YmxlVmFsdWUSIQoMc3RyaW5nX3ZhbHVlGAcgASgMUgtzdHJpbmdWYWx1ZRInCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAlSDmFnZ3JlZ2F0ZVZhbHVlGkoKCE5hbWVQYXJ0EhsKCW5hbWVfcGFydBgBIAIoCVIIbmFtZVBhcnQSIQoMaXNfZXh0ZW5zaW9uGAIgAigIUgtpc0V4dGVuc2lvbiKnAgoOU291cmNlQ29kZUluZm8SRAoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25SCGxvY2F0aW9uGs4BCghMb2NhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIWCgRzcGFuGAIgAygFQgIQAVIEc3BhbhIpChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJUg9sZWFkaW5nQ29tbWVudHMSKwoRdHJhaWxpbmdfY29tbWVudHMYBCABKAlSEHRyYWlsaW5nQ29tbWVudHMSOgoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCVIXbGVhZGluZ0RldGFjaGVkQ29tbWVudHMi0QEKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhptCgpBbm5vdGF0aW9uEhYKBHBhdGgYASADKAVCAhABUgRwYXRoEh8KC3NvdXJjZV9maWxlGAIgASgJUgpzb3VyY2VGaWxlEhQKBWJlZ2luGAMgASgFUgViZWdpbhIQCgNlbmQYBCABKAVSA2VuZEKPAQoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gBWj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90b2MtZ2VuLWdvL2Rlc2NyaXB0b3I7ZGVzY3JpcHRvcvgBAaICA0dQQqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9uSqrAAgoHEgUnAOcGAQqqDwoBDBIDJwASMsEMIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAogQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLwoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KCiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogKElOQ0xVRElORyBORUdMSUdF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bm5vdAogc3RvcmUgdGhlIHZhbHVlcyBpbiB0aGVtLiAgSW5zdGVhZCBpdCBzdG9yZXMgdGhlbSBpbiBhIGZpZWxkIGluIHRoZSAqT3B0aW9ucwogbWVzc2FnZSBjYWxsZWQgdW5pbnRlcnByZXRlZF9vcHRpb24uIFRoaXMgZmllbGQgbXVzdCBoYXZlIHRoZSBzYW1lIG5hbWUKIGFjcm9zcyBhbGwgKk9wdGlvbnMgbWVzc2FnZXMuIFdlIHRoZW4gdXNlIHRoaXMgZmllbGQgdG8gcG9wdWxhdGUgdGhlCiBleHRlbnNpb25zIHdoZW4gd2UgYnVpbGQgYSBkZXNjcmlwdG9yLCBhdCB3aGljaCBwb2ludCBhbGwgcHJvdG9zIGhhdmUgYmVlbgogcGFyc2VkIGFuZCBzbyBhbGwgZXh0ZW5zaW9ucyBhcmUga25vd24uCgogRXh0ZW5zaW9uIG51bWJlcnMgZm9yIGN1c3RvbSBvcHRpb25zIG1heSBiZSBjaG9zZW4gYXMgZm9sbG93czoKICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBvbmx5IGJlIHVzZWQgd2l0aGluIGEgc2luZ2xlIGFwcGxpY2F0aW9uIG9yCiAgIG9yZ2FuaXphdGlvbiwgb3IgZm9yIGV4cGVyaW1lbnRhbCBvcHRpb25zLCB1c2UgZmllbGQgbnVtYmVycyA1MDAwMAogICB0aHJvdWdoIDk5OTk5LiAgSXQgaXMgdXAgdG8geW91IHRvIGVuc3VyZSB0aGF0IHlvdSBkbyBub3QgdXNlIHRoZQogICBzYW1lIG51bWJlciBmb3IgbXVsdGlwbGUgb3B0aW9ucy4KICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBiZSBwdWJsaXNoZWQgYW5kIHVzZWQgcHVibGljbHkgYnkgbXVsdGlwbGUKICAgaW5kZXBlbmRlbnQgZW50aXRpZXMsIGUtbWFpbCBwcm90b2J1Zi1nbG9iYWwtZXh0ZW5zaW9uLXJlZ2lzdHJ5QGdvb2dsZS5jb20KICAgdG8gcmVzZXJ2ZSBleHRlbnNpb24gbnVtYmVycy4gU2ltcGx5IHByb3ZpZGUgeW91ciBwcm9qZWN0IG5hbWUgKGUuZy4KICAgT2JqZWN0aXZlLUMgcGx1Z2luKSBhbmQgeW91ciBwcm9qZWN0IHdlYnNpdGUgKGlmIGF2YWlsYWJsZSkgLS0gdGhlcmUncyBubwogICBuZWVkIHRvIGV4cGxhaW4gaG93IHlvdSBpbnRlbmQgdG8gdXNlIHRoZW0uIFVzdWFsbHkgeW91IG9ubHkgbmVlZCBvbmUKICAgZXh0ZW5zaW9uIG51bWJlci4gWW91IGNhbiBkZWNsYXJlIG11bHRpcGxlIG9wdGlvbnMgd2l0aCBvbmx5IG9uZSBleHRlbnNpb24KICAgbnVtYmVyIGJ5IHB1dHRpbmcgdGhlbSBpbiBhIHN1Yi1tZXNzYWdlLiBTZWUgdGhlIEN1c3RvbSBPcHRpb25zIHNlY3Rpb24gb2YKICAgdGhlIGRvY3MgZm9yIGV4YW1wbGVzOgogICBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzL2RvY3MvcHJvdG8jb3B0aW9ucwogICBJZiB0aGlzIHR1cm5zIG91dCB0byBiZSBwb3B1bGFyLCBhIHdlYiBzZXJ2aWNlIHdpbGwgYmUgc2V0IHVwCiAgIHRvIGF1dG9tYXRpY2FsbHkgYXNzaWduIG9wdGlvbiBudW1iZXJzLgoKCwoDBAoBEgS9AggTCvQBCgQECgIAEgTDAgIjGuUBIFNldHMgdGhlIEphdmEgcGFja2FnZSB3aGVyZSBjbGFzc2VzIGdlbmVyYXRlZCBmcm9tIHRoaXMgLnByb3RvIHdpbGwgYmUKIHBsYWNlZC4gIEJ5IGRlZmF1bHQsIHRoZSBwcm90byBwYWNrYWdlIGlzIHVzZWQsIGJ1dCB0aGlzIGlzIG9mdGVuCiBpbmFwcHJvcHJpYXRlIGJlY2F1c2UgcHJvdG8gcGFja2FnZXMgZG8gbm90IG5vcm1hbGx5IHN0YXJ0IHdpdGggYmFja3dhcmRzCiBkb21haW4gbmFtZXMuCgoNCgUECgIABBIEwwICCgoNCgUECgIABRIEwwILEQoNCgUECgIAARIEwwISHgoNCgUECgIAAxIEwwIhIgq/AgoEBAoCARIEywICKxqwAiBJZiBzZXQsIGFsbCB0aGUgY2xhc3NlcyBmcm9tIHRoZSAucHJvdG8gZmlsZSBhcmUgd3JhcHBlZCBpbiBhIHNpbmdsZQogb3V0ZXIgY2xhc3Mgd2l0aCB0aGUgZ2l2ZW4gbmFtZS4gIFRoaXMgYXBwbGllcyB0byBib3RoIFByb3RvMQogKGVxdWl2YWxlbnQgdG8gdGhlIG9sZCAiLS1vbmVfamF2YV9maWxlIiBvcHRpb24pIGFuZCBQcm90bzIgKHdoZXJlCiBhIC5wcm90byBhbHdheXMgdHJhbnNsYXRlcyB0byBhIHNpbmdsZSBjbGFzcywgYnV0IHlvdSBtYXkgd2FudCB0bwogZXhwbGljaXRseSBjaG9vc2UgdGhlIGNsYXNzIG5hbWUpLgoKDQoFBAoCAQQSBMsCAgoKDQoFBAoCAQUSBMsCCxEKDQoFBAoCAQESBMsCEiYKDQoFBAoCAQMSBMsCKSoKowMKBAQKAgISBNMCAjkalAMgSWYgc2V0IHRydWUsIHRoZW4gdGhlIEphdmEgY29kZSBnZW5lcmF0b3Igd2lsbCBnZW5lcmF0ZSBhIHNlcGFyYXRlIC5qYXZhCiBmaWxlIGZvciBlYWNoIHRvcC1sZXZlbCBtZXNzYWdlLCBlbnVtLCBhbmQgc2VydmljZSBkZWZpbmVkIGluIHRoZSAucHJvdG8KIGZpbGUuICBUaHVzLCB0aGVzZSB0eXBlcyB3aWxsICpub3QqIGJlIG5lc3RlZCBpbnNpZGUgdGhlIG91dGVyIGNsYXNzCiBuYW1lZCBieSBqYXZhX291dGVyX2NsYXNzbmFtZS4gIEhvd2V2ZXIsIHRoZSBvdXRlciBjbGFzcyB3aWxsIHN0aWxsIGJlCiBnZW5lcmF0ZWQgdG8gY29udGFpbiB0aGUgZmlsZSdzIGdldERlc2NyaXB0b3IoKSBtZXRob2QgYXMgd2VsbCBhcyBhbnkKIHRvcC1sZXZlbCBleHRlbnNpb25zIGRlZmluZWQgaW4gdGhlIGZpbGUuCgoNCgUECgICBBIE0wICCgoNCgUECgICBRIE0wILDwoNCgUECgICARIE0wIQIwoNCgUECgICAxIE0wImKAoNCgUECgICCBIE0wIpOAoNCgUECgICBxIE0wIyNwopCgQECgIDEgTWAgJFGhsgVGhpcyBvcHRpb24gZG9lcyBub3RoaW5nLgoKDQoFBAoCAwQSBNYCAgoKDQoFBAoCAwUSBNYCCw8KDQoFBAoCAwESBNYCEC0KDQoFBAoCAwMSBNYCMDIKDQoFBAoCAwgSBNYCM0QKEAoIBAoCAwjnBwASBNYCNEMKEQoJBAoCAwjnBwACEgTWAjQ+ChIKCgQKAgMI5wcAAgASBNYCND4KEwoLBAoCAwjnBwACAAESBNYCND4KEQoJBAoCAwjnBwADEgTWAj9DCuYCCgQECgIEEgTeAgI8GtcCIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhMiBjb2RlIGdlbmVyYXRvciB3aWxsIGdlbmVyYXRlIGNvZGUgdGhhdAogdGhyb3dzIGFuIGV4Y2VwdGlvbiB3aGVuZXZlciBhbiBhdHRlbXB0IGlzIG1hZGUgdG8gYXNzaWduIGEgbm9uLVVURi04CiBieXRlIHNlcXVlbmNlIHRvIGEgc3RyaW5nIGZpZWxkLgogTWVzc2FnZSByZWZsZWN0aW9uIHdpbGwgZG8gdGhlIHNhbWUuCiBIb3dldmVyLCBhbiBleHRlbnNpb24gZmllbGQgc3RpbGwgYWNjZXB0cyBub24tVVRGLTggYnl0ZSBzZXF1ZW5jZXMuCiBUaGlzIG9wdGlvbiBoYXMgbm8gZWZmZWN0IG9uIHdoZW4gdXNlZCB3aXRoIHRoZSBsaXRlIHJ1bnRpbWUuCgoNCgUECgIEBBIE3gICCgoNCgUECgIEBRIE3gILDwoNCgUECgIEARIE3gIQJgoNCgUECgIEAxIE3gIpKwoNCgUECgIECBIE3gIsOwoNCgUECgIEBxIE3gI1OgpMCgQECgQAEgbiAgLnAgMaPCBHZW5lcmF0ZWQgY2xhc3NlcyBjYW4gYmUgb3B0aW1pemVkIGZvciBzcGVlZCBvciBjb2RlIHNpemUuCgoNCgUECgQAARIE4gIHEwpECgYECgQAAgASBOMCBA4iNCBHZW5lcmF0ZSBjb21wbGV0ZSBjb2RlIGZvciBwYXJzaW5nLCBzZXJpYWxpemF0aW9uLAoKDwoHBAoEAAIAARIE4wIECQoPCgcECgQAAgACEgTjAgwNCkcKBgQKBAACARIE5QIEEhoGIGV0Yy4KIi8gVXNlIFJlZmxlY3Rpb25PcHMgdG8gaW1wbGVtZW50IHRoZXNlIG1ldGhvZHMuCgoPCgcECgQAAgEBEgTlAgQNCg8KBwQKBAACAQISBOUCEBEKRwoGBAoEAAICEgTmAgQVIjcgR2VuZXJhdGUgY29kZSB1c2luZyBNZXNzYWdlTGl0ZSBhbmQgdGhlIGxpdGUgcnVudGltZS4KCg8KBwQKBAACAgESBOYCBBAKDwoHBAoEAAICAhIE5gITFAoMCgQECgIFEgToAgI5Cg0KBQQKAgUEEgToAgIKCg0KBQQKAgUGEgToAgsXCg0KBQQKAgUBEgToAhgkCg0KBQQKAgUDEgToAicoCg0KBQQKAgUIEgToAik4Cg0KBQQKAgUHEgToAjI3CuICCgQECgIGEgTvAgIiGtMCIFNldHMgdGhlIEdvIHBhY2thZ2Ugd2hlcmUgc3RydWN0cyBnZW5lcmF0ZWQgZnJvbSB0aGlzIC5wcm90byB3aWxsIGJlCiBwbGFjZWQuIElmIG9taXR0ZWQsIHRoZSBHbyBwYWNrYWdlIHdpbGwgYmUgZGVyaXZlZCBmcm9tIHRoZSBmb2xsb3dpbmc6CiAgIC0gVGhlIGJhc2VuYW1lIG9mIHRoZSBwYWNrYWdlIGltcG9ydCBwYXRoLCBpZiBwcm92aWRlZC4KICAgLSBPdGhlcndpc2UsIHRoZSBwYWNrYWdlIHN0YXRlbWVudCBpbiB0aGUgLnByb3RvIGZpbGUsIGlmIHByZXNlbnQuCiAgIC0gT3RoZXJ3aXNlLCB0aGUgYmFzZW5hbWUgb2YgdGhlIC5wcm90byBmaWxlLCB3aXRob3V0IGV4dGVuc2lvbi4KCg0KBQQKAgYEEgTvAgIKCg0KBQQKAgYFEgTvAgsRCg0KBQQKAgYBEgTvAhIcCg0KBQQKAgYDEgTvAh8hCtQECgQECgIHEgT9AgI5GsUEIFNob3VsZCBnZW5lcmljIHNlcnZpY2VzIGJlIGdlbmVyYXRlZCBpbiBlYWNoIGxhbmd1YWdlPyAgIkdlbmVyaWMiIHNlcnZpY2VzCiBhcmUgbm90IHNwZWNpZmljIHRvIGFueSBwYXJ0aWN1bGFyIFJQQyBzeXN0ZW0uICBUaGV5IGFyZSBnZW5lcmF0ZWQgYnkgdGhlCiBtYWluIGNvZGUgZ2VuZXJhdG9ycyBpbiBlYWNoIGxhbmd1YWdlICh3aXRob3V0IGFkZGl0aW9uYWwgcGx1Z2lucykuCiBHZW5lcmljIHNlcnZpY2VzIHdlcmUgdGhlIG9ubHkga2luZCBvZiBzZXJ2aWNlIGdlbmVyYXRpb24gc3VwcG9ydGVkIGJ5CiBlYXJseSB2ZXJzaW9ucyBvZiBnb29nbGUucHJvdG9idWYuCgogR2VuZXJpYyBzZXJ2aWNlcyBhcmUgbm93IGNvbnNpZGVyZWQgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiB1c2luZyBwbHVnaW5zCiB0aGF0IGdlbmVyYXRlIGNvZGUgc3BlY2lmaWMgdG8geW91ciBwYXJ0aWN1bGFyIFJQQyBzeXN0ZW0uICBUaGVyZWZvcmUsCiB0aGVzZSBkZWZhdWx0IHRvIGZhbHNlLiAgT2xkIGNvZGUgd2hpY2ggZGVwZW5kcyBvbiBnZW5lcmljIHNlcnZpY2VzIHNob3VsZAogZXhwbGljaXRseSBzZXQgdGhlbSB0byB0cnVlLgoKDQoFBAoCBwQSBP0CAgoKDQoFBAoCBwUSBP0CCw8KDQoFBAoCBwESBP0CECMKDQoFBAoCBwMSBP0CJigKDQoFBAoCBwgSBP0CKTgKDQoFBAoCBwcSBP0CMjcKDAoEBAoCCBIE/gICOwoNCgUECgIIBBIE/gICCgoNCgUECgIIBRIE/gILDwoNCgUECgIIARIE/gIQJQoNCgUECgIIAxIE/gIoKgoNCgUECgIICBIE/gIrOgoNCgUECgIIBxIE/gI0OQoMCgQECgIJEgT/AgI5Cg0KBQQKAgkEEgT/AgIKCg0KBQQKAgkFEgT/AgsPCg0KBQQKAgkBEgT/AhAjCg0KBQQKAgkDEgT/AiYoCg0KBQQKAgkIEgT/Aik4Cg0KBQQKAgkHEgT/AjI3CgwKBAQKAgoSBIADAjoKDQoFBAoCCgQSBIADAgoKDQoFBAoCCgUSBIADCw8KDQoFBAoCCgESBIADECQKDQoFBAoCCgMSBIADJykKDQoFBAoCCggSBIADKjkKDQoFBAoCCgcSBIADMzgK8wEKBAQKAgsSBIYDAjAa5AEgSXMgdGhpcyBmaWxlIGRlcHJlY2F0ZWQ/CiBEZXBlbmRpbmcgb24gdGhlIHRhcmdldCBwbGF0Zm9ybSwgdGhpcyBjYW4gZW1pdCBEZXByZWNhdGVkIGFubm90YXRpb25zCiBmb3IgZXZlcnl0aGluZyBpbiB0aGUgZmlsZSwgb3IgaXQgd2lsbCBiZSBjb21wbGV0ZWx5IGlnbm9yZWQ7IGluIHRoZSB2ZXJ5CiBsZWFzdCwgdGhpcyBpcyBhIGZvcm1hbGl6YXRpb24gZm9yIGRlcHJlY2F0aW5nIGZpbGVzLgoKDQoFBAoCCwQSBIYDAgoKDQoFBAoCCwUSBIYDCw8KDQoFBAoCCwESBIYDEBoKDQoFBAoCCwMSBIYDHR8KDQoFBAoCCwgSBIYDIC8KDQoFBAoCCwcSBIYDKS4KfwoEBAoCDBIEigMCNhpxIEVuYWJsZXMgdGhlIHVzZSBvZiBhcmVuYXMgZm9yIHRoZSBwcm90byBtZXNzYWdlcyBpbiB0aGlzIGZpbGUuIFRoaXMgYXBwbGllcwogb25seSB0byBnZW5lcmF0ZWQgY2xhc3NlcyBmb3IgQysrLgoKDQoFBAoCDAQSBIoDAgoKDQoFBAoCDAUSBIoDCw8KDQoFBAoCDAESBIoDECAKDQoFBAoCDAMSBIoDIyUKDQoFBAoCDAgSBIoDJjUKDQoFBAoCDAcSBIoDLzQKkgEKBAQKAg0SBI8DAikagwEgU2V0cyB0aGUgb2JqZWN0aXZlIGMgY2xhc3MgcHJlZml4IHdoaWNoIGlzIHByZXBlbmRlZCB0byBhbGwgb2JqZWN0aXZlIGMKIGdlbmVyYXRlZCBjbGFzc2VzIGZyb20gdGhpcyAucHJvdG8uIFRoZXJlIGlzIG5vIGRlZmF1bHQuCgoNCgUECgINBBIEjwMCCgoNCgUECgINBRIEjwMLEQoNCgUECgINARIEjwMSIwoNCgUECgINAxIEjwMmKApJCgQECgIOEgSSAwIoGjsgTmFtZXNwYWNlIGZvciBnZW5lcmF0ZWQgY2xhc3NlczsgZGVmYXVsdHMgdG8gdGhlIHBhY2thZ2UuCgoNCgUECgIOBBIEkgMCCgoNCgUECgIOBRIEkgMLEQoNCgUECgIOARIEkgMSIgoNCgUECgIOAxIEkgMlJwqRAgoEBAoCDxIEmAMCJBqCAiBCeSBkZWZhdWx0IFN3aWZ0IGdlbmVyYXRvcnMgd2lsbCB0YWtlIHRoZSBwcm90byBwYWNrYWdlIGFuZCBDYW1lbENhc2UgaXQKIHJlcGxhY2luZyAnLicgd2l0aCB1bmRlcnNjb3JlIGFuZCB1c2UgdGhhdCB0byBwcmVmaXggdGhlIHR5cGVzL3N5bWJvbHMKIGRlZmluZWQuIFdoZW4gdGhpcyBvcHRpb25zIGlzIHByb3ZpZGVkLCB0aGV5IHdpbGwgdXNlIHRoaXMgdmFsdWUgaW5zdGVhZAogdG8gcHJlZml4IHRoZSB0eXBlcy9zeW1ib2xzIGRlZmluZWQuCgoNCgUECgIPBBIEmAMCCgoNCgUECgIPBRIEmAMLEQoNCgUECgIPARIEmAMSHgoNCgUECgIPAxIEmAMhIwp+CgQECgIQEgScAwIoGnAgU2V0cyB0aGUgcGhwIGNsYXNzIHByZWZpeCB3aGljaCBpcyBwcmVwZW5kZWQgdG8gYWxsIHBocCBnZW5lcmF0ZWQgY2xhc3NlcwogZnJvbSB0aGlzIC5wcm90by4gRGVmYXVsdCBpcyBlbXB0eS4KCg0KBQQKAhAEEgScAwIKCg0KBQQKAhAFEgScAwsRCg0KBQQKAhABEgScAxIiCg0KBQQKAhADEgScAyUnCr4BCgQECgIREgShAwIlGq8BIFVzZSB0aGlzIG9wdGlvbiB0byBjaGFuZ2UgdGhlIG5hbWVzcGFjZSBvZiBwaHAgZ2VuZXJhdGVkIGNsYXNzZXMuIERlZmF1bHQKIGlzIGVtcHR5LiBXaGVuIHRoaXMgb3B0aW9uIGlzIGVtcHR5LCB0aGUgcGFja2FnZSBuYW1lIHdpbGwgYmUgdXNlZCBmb3IKIGRldGVybWluaW5nIHRoZSBuYW1lc3BhY2UuCgoNCgUECgIRBBIEoQMCCgoNCgUECgIRBRIEoQMLEQoNCgUECgIRARIEoQMSHwoNCgUECgIRAxIEoQMiJAp8CgQECgISEgSlAwI6Gm4gVGhlIHBhcnNlciBzdG9yZXMgb3B0aW9ucyBpdCBkb2Vzbid0IHJlY29nbml6ZSBoZXJlLgogU2VlIHRoZSBkb2N1bWVudGF0aW9uIGZvciB0aGUgIk9wdGlvbnMiIHNlY3Rpb24gYWJvdmUuCgoNCgUECgISBBIEpQMCCgoNCgUECgISBhIEpQMLHgoNCgUECgISARIEpQMfMwoNCgUECgISAxIEpQM2OQqHAQoDBAoFEgSpAwIZGnogQ2xpZW50cyBjYW4gZGVmaW5lIGN1c3RvbSBvcHRpb25zIGluIGV4dGVuc2lvbnMgb2YgdGhpcyBtZXNzYWdlLgogU2VlIHRoZSBkb2N1bWVudGF0aW9uIGZvciB0aGUgIk9wdGlvbnMiIHNlY3Rpb24gYWJvdmUuCgoMCgQECgUAEgSpAw0YCg0KBQQKBQABEgSpAw0RCg0KBQQKBQACEgSpAxUYCgsKAwQKCRIEqwMLDgoMCgQECgkAEgSrAwsNCg0KBQQKCQABEgSrAwsNCg0KBQQKCQACEgSrAwsNCgwKAgQLEgauAwDtAwEKCwoDBAsBEgSuAwgWCtgFCgQECwIAEgTBAwI8GskFIFNldCB0cnVlIHRvIHVzZSB0aGUgb2xkIHByb3RvMSBNZXNzYWdlU2V0IHdpcmUgZm9ybWF0IGZvciBleHRlbnNpb25zLgogVGhpcyBpcyBwcm92aWRlZCBmb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgTWVzc2FnZVNldCB3aXJlCiBmb3JtYXQuICBZb3Ugc2hvdWxkIG5vdCB1c2UgdGhpcyBmb3IgYW55IG90aGVyIHJlYXNvbjogIEl0J3MgbGVzcwogZWZmaWNpZW50LCBoYXMgZmV3ZXIgZmVhdHVyZXMsIGFuZCBpcyBtb3JlIGNvbXBsaWNhdGVkLgoKIFRoZSBtZXNzYWdlIG11c3QgYmUgZGVmaW5lZCBleGFjdGx5IGFzIGZvbGxvd3M6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOwogICAgIGV4dGVuc2lvbnMgNCB0byBtYXg7CiAgIH0KIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBjYW5ub3QgaGF2ZSBhbnkgZGVmaW5lZCBmaWVsZHM7IE1lc3NhZ2VTZXRzIG9ubHkKIGhhdmUgZXh0ZW5zaW9ucy4KCiBBbGwgZXh0ZW5zaW9ucyBvZiB5b3VyIHR5cGUgbXVzdCBiZSBzaW5ndWxhciBtZXNzYWdlczsgZS5nLiB0aGV5IGNhbm5vdAogYmUgaW50MzJzLCBlbnVtcywgb3IgcmVwZWF0ZWQgbWVzc2FnZXMuCgogQmVjYXVzZSB0aGlzIGlzIGFuIG9wdGlvbiwgdGhlIGFib3ZlIHR3byByZXN0cmljdGlvbnMgYXJlIG5vdCBlbmZvcmNlZCBieQogdGhlIHByb3RvY29sIGNvbXBpbGVyLgoKDQoFBAsCAAQSBMEDAgoKDQoFBAsCAAUSBMEDCw8KDQoFBAsCAAESBMEDECcK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CiBhIG1vcmUgZWZmaWNpZW50IHJlcHJlc2VudGF0aW9uIG9uIHRoZSB3aXJlLiBSYXRoZXIgdGhhbiByZXBlYXRlZGx5CiB3cml0aW5nIHRoZSB0YWcgYW5kIHR5cGUgZm9yIGVhY2ggZWxlbWVudCwgdGhlIGVudGlyZSBhcnJheSBpcyBlbmNvZGVkIGFzCiBhIHNpbmdsZSBsZW5ndGgtZGVsaW1pdGVkIGJsb2IuIEluIHByb3RvMywgb25seSBleHBsaWNpdCBzZXR0aW5nIGl0IHRvCiBmYWxzZSB3aWxsIGF2b2lkIHVzaW5nIHBhY2tlZCBlbmNvZGluZy4KCg0KBQQMAgEEEgSCBAIKCg0KBQQMAgEFEgSCBAsPCg0KBQQMAgEBEgSCBBAWCg0KBQQMAgEDEgSCBBkaCpoFCgQEDAICEgSPBAIzGosFIFRoZSBqc3R5cGUgb3B0aW9uIGRldGVybWluZXMgdGhlIEphdmFTY3JpcHQgdHlwZSB1c2VkIGZvciB2YWx1ZXMgb2YgdGhlCiBmaWVsZC4gIFRoZSBvcHRpb24gaXMgcGVybWl0dGVkIG9ubHkgZm9yIDY0IGJpdCBpbnRlZ3JhbCBhbmQgZml4ZWQgdHlwZXMKIChpbnQ2NCwgdWludDY0LCBzaW50NjQsIGZpeGVkNjQsIHNmaXhlZDY0KS4gIEEgZmllbGQgd2l0aCBqc3R5cGUgSlNfU1RSSU5HCiBpcyByZXByZXNlbnRlZCBhcyBKYXZhU2NyaXB0IHN0cmluZywgd2hpY2ggYXZvaWRzIGxvc3Mgb2YgcHJlY2lzaW9uIHRoYXQKIGNhbiBoYXBwZW4gd2hlbiBhIGxhcmdlIHZhbHVlIGlzIGNvbnZlcnRlZCB0byBhIGZsb2F0aW5nIHBvaW50IEphdmFTY3JpcHQuCiBTcGVjaWZ5aW5nIEpTX05VTUJFUiBmb3IgdGhlIGpzdHlwZSBjYXVzZXMgdGhlIGdlbmVyYXRlZCBKYXZhU2NyaXB0IGNvZGUgdG8KIHVzZSB0aGUgSmF2YVNjcmlwdCAibnVtYmVyIiB0eXBlLiAgVGhlIGJlaGF2aW9yIG9mIHRoZSBkZWZhdWx0IG9wdGlvbgogSlNfTk9STUFMIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KCiBUaGlzIG9wdGlvbiBpcyBhbiBlbnVtIHRvIHBlcm1pdCBhZGRpdGlvbmFsIHR5cGVzIHRvIGJlIGFkZGVkLCBlLmcuCiBnb29nLm1hdGguSW50ZWdlci4KCg0KBQQMAgIEEgSPBAIKCg0KBQQMAgIGEgSPBAsRCg0KBQQMAgIBEgSPBBIYCg0KBQQMAgIDEgSPBBscCg0KBQQMAgIIEgSPBB0yCg0KBQQMAgIHEgSPBCgxCg4KBAQMBAESBpAEApkEAwoNCgUEDAQBARIEkAQHDQonCgYEDAQBAgASBJIEBBIaFyBVc2UgdGhlIGRlZmF1bHQgdHlwZS4KCg8KBwQMBAECAAESBJIEBA0KDwoHBAwEAQIAAhIEkgQQEQopCgYEDAQBAgESBJUEBBIaGSBVc2UgSmF2YVNjcmlwdCBzdHJpbmdzLgoKDwoHBAwEAQIBARIElQQEDQoPCgcEDAQBAgECEgSVBBARCikKBgQMBAECAhIEmAQEEhoZIFVzZSBKYXZhU2NyaXB0IG51bWJlcnMuCgoPCgcEDAQBAgIBEgSYBAQNCg8KBwQMBAECAgISBJgEEBEK7wwKBAQMAgMSBLcEAika4AwgU2hvdWxkIHRoaXMgZmllbGQgYmUgcGFyc2VkIGxhemlseT8gIExhenkgYXBwbGllcyBvbmx5IHRvIG1lc3NhZ2UtdHlwZQogZmllbGRzLiAgSXQgbWVhbnMgdGhhdCB3aGVuIHRoZSBvdXRlciBtZXNzYWdlIGlzIGluaXRpYWxseSBwYXJzZWQsIHRoZQogaW5uZXIgbWVzc2FnZSdzIGNvbnRlbnRzIHdpbGwgbm90IGJlIHBhcnNlZCBidXQgaW5zdGVhZCBzdG9yZWQgaW4gZW5jb2RlZAogZm9ybS4gIFRoZSBpbm5lciBtZXNzYWdlIHdpbGwgYWN0dWFsbHkgYmUgcGFyc2VkIHdoZW4gaXQgaXMgZmlyc3QgYWNjZXNzZWQuCgogVGhpcyBpcyBvbmx5IGEgaGludC4gIEltcGxlbWVudGF0aW9ucyBhcmUgZnJlZSB0byBjaG9vc2Ugd2hldGhlciB0byB1c2UKIGVhZ2VyIG9yIGxhenkgcGFyc2luZyByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIG9wdGlvbi4gIEhvd2V2ZXIsCiBzZXR0aW5nIHRoaXMgb3B0aW9uIHRydWUgc3VnZ2VzdHMgdGhhdCB0aGUgcHJvdG9jb2wgYXV0aG9yIGJlbGlldmVzIHRoYXQKIHVzaW5nIGxhenkgcGFyc2luZyBvbiB0aGlzIGZpZWxkIGlzIHdvcnRoIHRoZSBhZGRpdGlvbmFsIGJvb2trZWVwaW5nCiBvdmVyaGVhZCB0eXBpY2FsbHkgbmVlZGVkIHRvIGltcGxlbWVudCBpdC4KCiBUaGlzIG9wdGlvbiBkb2VzIG5vdCBhZmZlY3QgdGhlIHB1YmxpYyBpbnRlcmZhY2Ugb2YgYW55IGdlbmVyYXRlZCBjb2RlOwogYWxsIG1ldGhvZCBzaWduYXR1cmVzIHJlbWFpbiB0aGUgc2FtZS4gIEZ1cnRoZXJtb3JlLCB0aHJlYWQtc2FmZXR5IG9mIHRoZQogaW50ZXJmYWNlIGlzIG5vdCBhZmZlY3RlZCBieSB0aGlzIG9wdGlvbjsgY29uc3QgbWV0aG9kcyByZW1haW4gc2FmZSB0bwogY2FsbCBmcm9tIG11bHRpcGxlIHRocmVhZHMgY29uY3VycmVudGx5LCB3aGlsZSBub24tY29uc3QgbWV0aG9kcyBjb250aW51ZQogdG8gcmVxdWlyZSBleGNsdXNpdmUgYWNjZXNzLgoKCiBOb3RlIHRoYXQgaW1wbGVtZW50YXRpb25zIG1heSBjaG9vc2Ugbm90IHRvIGNoZWNrIHJlcXVpcmVkIGZpZWxkcyB3aXRoaW4KIGEgbGF6eSBzdWItbWVzc2FnZS4gIFRoYXQgaXMsIGNhbGxpbmcgSXNJbml0aWFsaXplZCgpIG9uIHRoZSBvdXRlciBtZXNzYWdlCiBtYXkgcmV0dXJuIHRydWUgZXZlbiBpZiB0aGUgaW5uZXIgbWVzc2FnZSBoYXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIG90aGVyd2lzZSB0aGUgaW5uZXIgbWVzc2FnZSB3b3VsZCBoYXZlIHRvIGJlCiBwYXJzZWQgaW4gb3JkZXIgdG8gcGVyZm9ybSB0aGUgY2hlY2ssIGRlZmVhdGluZyB0aGUgcHVycG9zZSBvZiBsYXp5CiBwYXJzaW5nLiAgQW4gaW1wbGVtZW50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dCByZWNvZ25pemUuIFRoaXMgb25seQogYXBwZWFycyBpbiBvcHRpb25zIHByb3RvcyBjcmVhdGVkIGJ5IHRoZSBjb21waWxlcjo6UGFyc2VyIGNsYXNzLgogRGVzY3JpcHRvclBvb2wgcmVzb2x2ZXMgdGhlc2Ugd2hlbiBidWlsZGluZyBEZXNjcmlwdG9yIG9iamVjdHMuIFRoZXJlZm9yZSwKIG9wdGlvbnMgcHJvdG9zIGluIGRlc2NyaXB0b3Igb2JqZWN0cyAoZS5nLiByZXR1cm5lZCBieSBEZXNjcmlwdG9yOjpvcHRpb25zKCksCiBvciBwcm9kdWNlZCBieSBEZXNjcmlwdG9yOjpDb3B5VG8oKSkgd2lsbCBuZXZlciBoYXZlIFVuaW50ZXJwcmV0ZWRPcHRpb25zCiBpbiB0aGVtLgoKCwoDBBIBEgSxBQgbCssCCgQEEgMAEga3BQK6BQMaugIgVGhlIG5hbWUgb2YgdGhlIHVuaW50ZXJwcmV0ZWQgb3B0aW9uLiAgRWFjaCBzdHJpbmcgcmVwcmVzZW50cyBhIHNlZ21lbnQgaW4KIGEgZG90LXNlcGFyYXRlZCBuYW1lLiAgaXNfZXh0ZW5zaW9uIGlzIHRydWUgaWZmIGEgc2VnbWVudCByZXByZXNlbnRzIGFuCiBleHRlbnNpb24gKGRlbm90ZWQgd2l0aCBwYXJlbnRoZXNlcyBpbiBvcHRpb25zIHNwZWNzIGluIC5wcm90byBmaWxlcykuCiBFLmcuLHsgWyJmb28iLCBmYWxzZV0sIFsiYmFyLmJheiIsIHRydWVdLCBbInF1eCIsIGZhbHNlXSB9IHJlcHJlc2VudHMKICJmb28uKGJhci5iYXopLnF1eCIuCgoNCgUEEgMAARIEtwUKEgoOCgYEEgMAAgASBLgFBCIKDwoHBBIDAAIABBIEuAUEDAoPCgcEEgMAAgAFEgS4BQ0TCg8KBwQSAwACAAESBLgFFB0KDwoHBBIDAAIAAxIEuAUgIQoOCgYEEgMAAgESBLkFBCMKDwoHBBIDAAIBBBIEuQUEDAoPCgcEEgMAAgEFEgS5BQ0RCg8KBwQSAwACAQESBLkFEh4KDwoHBBIDAAIBAxIEuQUhIgoMCgQEEgIAEgS7BQIdCg0KBQQSAgAEEgS7BQIKCg0KBQQSAgAGEgS7BQsTCg0KBQQSAgABEgS7BRQYCg0KBQQSAgADEgS7BRscCpwBCgQEEgIBEgS/BQInGo0BIFRoZSB2YWx1ZSBvZiB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb24sIGluIHdoYXRldmVyIHR5cGUgdGhlIHRva2VuaXplcgogaWRlbnRpZmllZCBpdCBhcyBkdXJpbmcgcGFyc2luZy4gRXhhY3RseSBvbmUgb2YgdGhlc2Ugc2hvdWxkIGJlIHNldC4KCg0KBQQSAgEEEgS/BQIKCg0KBQQSAgEFEgS/BQsRCg0KBQQSAgEBEgS/BRIiCg0KBQQSAgEDEgS/BSUmCgwKBAQSAgISBMAFAikKDQoFBBICAgQSBMAFAgoKDQoFBBICAgUSBMAFCxEKDQoFBBICAgESBMAFEiQKDQoFBBICAgMSBMAFJygKDAoEBBICAxIEwQUCKAoNCgUEEgIDBBIEwQUCCgoNCgUEEgIDBRIEwQULEAoNCgUEEgIDARIEwQURIwoNCgUEEgIDAxIEwQUmJwoMCgQEEgIEEgTCBQIjCg0KBQQSAgQEEgTCBQIKCg0KBQQSAgQFEgTCBQsRCg0KBQQSAgQBEgTCBRIeCg0KBQQSAgQDEgTCBSEiCgwKBAQSAgUSBMMFAiIKDQoFBBICBQQSBMMFAgoKDQoFBBICBQUSBMMFCxAKDQoFBBICBQESBMMFER0KDQoFBBICBQMSBMMFICEKDAoEBBICBhIExAUCJgoNCgUEEgIGBBIExAUCCgoNCgUEEgIGBRIExAULEQoNCgUEEgIGARIExAUSIQoNCgUEEgIGAxIExAUkJQraAQoCBBMSBswFAM0GARpqIEVuY2Fwc3VsYXRlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGUgZnJvbSB3aGljaCBhCiBGaWxlRGVzY3JpcHRvclByb3RvIHdhcyBnZW5lcmF0ZWQuCjJgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIE9wdGlvbmFsIHNvdXJjZSBjb2RlIGluZm8KCgsKAwQTARIEzAUIFgqCEQoEBBMCABIE+AUCIRrzECBBIExvY2F0aW9uIGlkZW50aWZpZXMgYSBwaWVjZSBvZiBzb3VyY2UgY29kZSBpbiBhIC5wcm90byBmaWxlIHdoaWNoCiBjb3JyZXNwb25kcyB0byBhIHBhcnRpY3VsYXIgZGVmaW5pdGlvbi4gIFRoaXMgaW5mb3JtYXRpb24gaXMgaW50ZW5kZWQKIHRvIGJlIHVzZWZ1bCB0byBJREVzLCBjb2RlIGluZGV4ZXJzLCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcnMsIGFuZCBzaW1pbGFyCiB0b29scy4KCiBGb3IgZXhhbXBsZSwgc2F5IHdlIGhhdmUgYSBmaWxlIGxpa2U6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKICAgfQogTGV0J3MgbG9vayBhdCBqdXN0IHRoZSBmaWVsZCBkZWZpbml0aW9uOgogICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKICAgXiAgICAgICBeXiAgICAgXl4gIF4gIF5eXgogICBhICAgICAgIGJjICAgICBkZSAgZiAgZ2hpCiBXZSBoYXZlIHRoZSBmb2xsb3dpbmcgbG9jYXRpb25zOgogICBzcGFuICAgcGF0aCAgICAgICAgICAgICAgIHJlcHJlc2VudHMKICAgW2EsaSkgIFsgNCwgMCwgMiwgMCBdICAgICBUaGUgd2hvbGUgZmllbGQgZGVmaW5pdGlvbi4KICAgW2EsYikgIFsgNCwgMCwgMiwgMCwgNCBdICBUaGUgbGFiZWwgKG9wdGlvbmFsKS4KICAgW2MsZCkgIFsgNCwgMCwgMiwgMCwgNSBdICBUaGUgdHlwZSAoc3RyaW5nKS4KICAgW2UsZikgIFsgNCwgMCwgMiwgMCwgMSBdICBUaGUgbmFtZSAoZm9vKS4KICAgW2csaCkgIFsgNCwgMCwgMiwgMCwgMyBdICBUaGUgbnVtYmVyICgxKS4KCiBOb3RlczoKIC0gQSBsb2NhdGlvbiBtYXkgcmVmZXIgdG8gYSByZXBlYXRlZCBmaWVsZCBpdHNlbGYgKGkuZS4gbm90IHRvIGFueQogICBwYXJ0aWN1bGFyIGluZGV4IHdpdGhpbiBpdCkuICBUaGlzIGlzIHVzZWQgd2hlbmV2ZXIgYSBzZXQgb2YgZWxlbWVudHMgYXJlCiAgIGxvZ2ljYWxseSBlbmNsb3NlZCBpbiBhIHNpbmdsZSBjb2RlIHNlZ21lbnQuICBGb3IgZXhhbXBsZSwgYW4gZW50aXJlCiAgIGV4dGVuZCBibG9jayAocG9zc2libHkgY29udGFpbmluZyBtdWx0aXBsZSBleHRlbnNpb24gZGVmaW5pdGlvbnMpIHdpbGwKICAgaGF2ZSBhbiBvdXRlciBsb2NhdGlvbiB3aG9zZSBwYXRoIHJlZmVycyB0byB0aGUgImV4dGVuc2lvbnMiIHJlcGVhdGVkCiAgIGZpZWxkIHdpdGhvdXQgYW4gaW5kZXguCiAtIE11bHRpcGxlIGxvY2F0aW9ucyBtYXkgaGF2ZSB0aGUgc2FtZSBwYXRoLiAgVGhpcyBoYXBwZW5zIHdoZW4gYSBzaW5nbGUKICAgbG9naWNhbCBkZWNsYXJhdGlvbiBpcyBzcHJlYWQgb3V0IGFjcm9zcyBtdWx0aXBsZSBwbGFjZXMuICBUaGUgbW9zdAogICBvYnZpb3VzIGV4YW1wbGUgaXMgdGhlICJleHRlbmQiIGJsb2NrIGFnYWluIC0tIHRoZXJlIG1heSBiZSBtdWx0aXBsZQogICBleHRlbmQgYmxvY2tzIGluIHRoZSBzYW1lIHNjb3BlLCBlYWNoIG9mIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBwYXRoLgogLSBBIGxvY2F0aW9uJ3Mgc3BhbiBpcyBub3QgYWx3YXlzIGEgc3Vic2V0IG9mIGl0cyBwYXJlbnQncyBzcGFuLiAgRm9yCiAgIGV4YW1wbGUsIHRoZSAiZXh0ZW5kZWUiIG9mIGFuIGV4dGVuc2lvbiBkZWNsYXJhdGlvbiBhcHBlYXJzIGF0IHRoZQogICBiZWdpbm5pbmcgb2YgdGhlICJleHRlbmQiIGJsb2NrIGFuZCBpcyBzaGFyZWQgYnkgYWxsIGV4dGVuc2lvbnMgd2l0aGluCiAgIHRoZSBibG9jay4KIC0gSnVzdCBiZWNhdXNlIGEgbG9jYXRpb24ncyBzcGFuIGlzIGEgc3Vic2V0IG9mIHNvbWUgb3RoZXIgbG9jYXRpb24ncyBzcGFuCiAgIGRvZXMgbm90IG1lYW4gdGhhdCBpdCBpcyBhIGRlc2NlbmRlbnQuICBGb3IgZXhhbXBsZSwgYSAiZ3JvdXAiIGRlZmluZXMKICAgYm90aCBhIHR5cGUgYW5kIGEgZmllbGQgaW4gYSBzaW5nbGUgZGVjbGFyYXRpb24uICBUaHVzLCB0aGUgbG9jYXRpb25zCiAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUgYW5kIGZpZWxkIGFuZCB0aGVpciBjb21wb25lbnRzIHdpbGwgb3ZlcmxhcC4KIC0gQ29kZSB3aGljaCB0cmllcyB0byBpbnRlcnByZXQgbG9jYXRpb25zIHNob3VsZCBwcm9iYWJseSBiZSBkZXNpZ25lZCB0bwogICBpZ25vcmUgdGhvc2UgdGhhdCBpdCBkb2Vzbid0IHVuZGVyc3RhbmQsIGFzIG1vcmUgdHlwZXMgb2YgbG9jYXRpb25zIGNvdWxkCiAgIGJlIHJlY29yZGVkIGluIHRoZSBmdXR1cmUuCgoNCgUEEwIABBIE+AUCCgoNCgUEEwIABhIE+AULEwoNCgUEEwIAARIE+AUUHAoNCgUEEwIAAxIE+AUfIAoOCgQEEwMAEgb5BQLMBgMKDQoFBBMDAAESBPkFChIKgwcKBgQTAwACABIEkQYEKhryBiBJZGVudGlmaWVzIHdoaWNoIHBhcnQgb2YgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2FzIGRlZmluZWQgYXQgdGhpcwogbG9jYXRpb24uCgogRWFjaCBlbGVtZW50IGlzIGEgZmllbGQgbnVtYmVyIG9yIGFuIGluZGV4LiAgVGhleSBmb3JtIGEgcGF0aCBmcm9tCiB0aGUgcm9vdCBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBwbGFjZSB3aGVyZSB0aGUgZGVmaW5pdGlvbi4gIEZvcgogZXhhbXBsZSwgdGhpcyBwYXRoOgogICBbIDQsIDMsIDIsIDcsIDEgXQogcmVmZXJzIHRvOgogICBmaWxlLm1lc3NhZ2VfdHlwZSgzKSAgLy8gNCwgMwogICAgICAgLmZpZWxkKDcpICAgICAgICAgLy8gMiwgNwogICAgICAgLm5hbWUoKSAgICAgICAgICAgLy8gMQogVGhpcyBpcyBiZWNhdXNlIEZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlIGhhcyBmaWVsZCBudW1iZXIgNDoKICAgcmVwZWF0ZWQgRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CiBhbmQgRGVzY3JpcHRvclByb3RvLmZpZWxkIGhhcyBmaWVsZCBudW1iZXIgMjoKICAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOwogYW5kIEZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUgaGFzIGZpZWxkIG51bWJlciAxOgogICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CgogVGh1cywgdGhlIGFib3ZlIHBhdGggZ2l2ZXMgdGhlIGxvY2F0aW9uIG9mIGEgZmllbGQgbmFtZS4gIElmIHdlIHJlbW92ZWQKIHRoZSBsYXN0IGVsZW1lbnQ6CiAgIFsgNCwgMywgMiwgNyBdCiB0aGlzIHBhdGggcmVmZXJzIHRvIHRoZSB3aG9sZSBmaWVsZCBkZWNsYXJhdGlvbiAoZnJvbSB0aGUgYmVnaW5uaW5nCiBvZiB0aGUgbGFiZWwgdG8gdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbikuCgoPCgcEEwMAAgAEEgSRBgQMCg8KBwQTAwACAAUSBJEGDRIKDwoHBBMDAAIAARIEkQYTFwoPCgcEEwMAAgADEgSRBhobCg8KBwQTAwACAAgSBJEGHCkKEgoKBBMDAAIACOcHABIEkQYdKAoTCgsEEwMAAgAI5wcAAhIEkQYdIwoUCgwEEwMAAgAI5wcAAgASBJEGHSMKFQoNBBMDAAIACOcHAAIAARIEkQYdIwoTCgsEEwMAAgAI5wcAAxIEkQYkKArSAgoGBBMDAAIBEgSYBgQqGsECIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCiBlbmQgbGluZSAob3B0aW9uYWwsIG90aGVyd2lzZSBhc3N1bWVkIHNhbWUgYXMgc3RhcnQgbGluZSksIGVuZCBjb2x1bW4uCiBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQogYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAogMSB0byBlYWNoIGJlZm9yZSBkaXNwbGF5aW5nIHRvIGEgdXNlci4KCg8KBwQTAwACAQQSBJgGBAwKDwoHBBMDAAIBBRIEmAYNEgoPCgcEEwMAAgEBEgSYBhMXCg8KBwQTAwACAQMSBJgGGhsKDwoHBBMDAAIBCBIEmAYcKQoSCgoEEwMAAgEI5wcAEgSYBh0oChMKCwQTAwACAQjnBwACEgSYBh0jChQKDAQTAwACAQjnBwACABIEmAYdIwoVCg0EEwMAAgEI5wcAAgABEgSYBh0jChMKCwQTAwACAQjnBwADEgSYBiQoCqUMCgYEEwMAAgISBMkGBCkalAwgSWYgdGhpcyBTb3VyY2VDb2RlSW5mbyByZXByZXNlbnRzIGEgY29tcGxldGUgZGVjbGFyYXRpb24sIHRoZXNlIGFyZSBhbnkKIGNvbW1lbnRzIGFwcGVhcmluZyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBkZWNsYXJhdGlvbiB3aGljaCBhcHBlYXIgdG8gYmUKIGF0dGFjaGVkIHRvIHRoZSBkZWNsYXJhdGlvbi4KCiBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgogdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCgogbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyB3aWxsIGtlZXAgcGFyYWdyYXBocyBvZiBjb21tZW50cyB0aGF0IGFwcGVhcgogYmVmb3JlIChidXQgbm90IGNvbm5lY3RlZCB0bykgdGhlIGN1cnJlbnQgZWxlbWVudC4gRWFjaCBwYXJhZ3JhcGgsCiBzZXBhcmF0ZWQgYnkgZW1wdHkgbGluZXMsIHdpbGwgYmUgb25lIGNvbW1lbnQgZWxlbWVudCBpbiB0aGUgcmVwZWF0ZWQKIGZpZWxkLgoKIE9ubHkgdGhlIGNvbW1lbnQgY29udGVudCBpcyBwcm92aWRlZDsgY29tbWVudCBtYXJrZXJzIChlLmcuIC8vKSBhcmUKIHN0cmlwcGVkIG91dC4gIEZvciBibG9jayBjb21tZW50cywgbGVhZGluZyB3aGl0ZXNwYWNlIGFuZCBhbiBhc3Rlcmlzawogd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LgogTmV3bGluZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQuCgogRXhhbXBsZXM6CgogICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmFyLgogICBvcHRpb25hbCBpbnQzMiBiYXIgPSAyOwoKICAgb3B0aW9uYWwgc3RyaW5nIGJheiA9IDM7CiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmF6LgogICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgoKICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBxdXguCiAgIC8vCiAgIC8vIEFub3RoZXIgbGluZSBhdHRhY2hlZCB0byBxdXguCiAgIG9wdGlvbmFsIGRvdWJsZSBxdXggPSA0OwoKICAgLy8gRGV0YWNoZWQgY29tbWVudCBmb3IgY29yZ2UuIFRoaXMgaXMgbm90IGxlYWRpbmcgb3IgdHJhaWxpbmcgY29tbWVudHMKICAgLy8gdG8gcXV4IG9yIGNvcmdlIGJlY2F1c2UgdGhlcmUgYXJlIGJsYW5rIGxpbmVzIHNlcGFyYXRpbmcgaXQgZnJvbQogICAvLyBib3RoLgoKICAgLy8gRGV0YWNoZWQgY29tbWVudCBmb3IgY29yZ2UgcGFyYWdyYXBoIDIuCgogICBvcHRpb25hbCBzdHJpbmcgY29yZ2UgPSA1OwogICAvKiBCbG9jayBjb21tZW50IGF0dGFjaGVkCiAgICAqIHRvIGNvcmdlLiAgTGVhZGluZyBhc3Rlcmlza3MKICAgICogd2lsbCBiZSByZW1vdmVkLiAqLwogICAvKiBCbG9jayBjb21tZW50IGF0dGFjaGVkIHRvCiAgICAqIGdyYXVsdC4gKi8KICAgb3B0aW9uYWwgaW50MzIgZ3JhdWx0ID0gNjsKCiAgIC8vIGlnbm9yZWQgZGV0YWNoZWQgY29tbWVudHMuCgoPCgcEEwMAAgIEEgTJBgQMCg8KBwQTAwACAgUSBMkGDRMKDwoHBBMDAAICARIEyQYUJAoPCgcEEwMAAgIDEgTJBicoCg4KBgQTAwACAxIEygYEKgoPCgcEEwMAAgMEEgTKBgQMCg8KBwQTAwACAwUSBMoGDRMKDwoHBBMDAAIDARIEygYUJQoPCgcEEwMAAgMDEgTKBigpCg4KBgQTAwACBBIEywYEMgoPCgcEEwMAAgQEEgTLBgQMCg8KBwQTAwACBAUSBMsGDRMKDwoHBBMDAAIEARIEywYULQoPCgcEEwMAAgQDEgTLBjAxCu4BCgIEFBIG0gYA5wYBGt8BIERlc2NyaWJlcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZ2VuZXJhdGVkIGNvZGUgYW5kIGl0cyBvcmlnaW5hbCBzb3VyY2UKIGZpbGUuIEEgR2VuZXJhdGVkQ29kZUluZm8gbWVzc2FnZSBpcyBhc3NvY2lhdGVkIHdpdGggb25seSBvbmUgZ2VuZXJhdGVkCiBzb3VyY2UgZmlsZSwgYnV0IG1heSBjb250YWluIHJlZmVyZW5jZXMgdG8gZGlmZmVyZW50IHNvdXJjZSAucHJvdG8gZmlsZXMuCgoLCgMEFAESBNIGCBkKeAoEBBQCABIE1QYCJRpqIEFuIEFubm90YXRpb24gY29ubmVjdHMgc29tZSBzcGFuIG9mIHRleHQgaW4gZ2VuZXJhdGVkIGNvZGUgdG8gYW4gZWxlbWVudAogb2YgaXRzIGdlbmVyYXRpbmcgLnByb3RvIGZpbGUuCgoNCgUEFAIABBIE1QYCCgoNCgUEFAIABhIE1QYLFQoNCgUEFAIAARIE1QYWIAoNCgUEFAIAAxIE1QYjJAoOCgQEFAMAEgbWBgLmBgMKDQoFBBQDAAESBNYGChQKjwEKBgQUAwACABIE2QYEKhp/IElkZW50aWZpZXMgdGhlIGVsZW1lbnQgaW4gdGhlIG9yaWdpbmFsIHNvdXJjZSAucHJvdG8gZmlsZS4gVGhpcyBmaWVsZAogaXMgZm9ybWF0dGVkIHRoZSBzYW1lIGFzIFNvdXJjZUNvZGVJbmZvLkxvY2F0aW9uLnBhdGguCgoPCgcEFAMAAgAEEgTZBgQMCg8KBwQUAwACAAUSBNkGDRIKDwoHBBQDAAIAARIE2QYTFwoPCgcEFAMAAgADEgTZBhobCg8KBwQUAwACAAgSBNkGHCkKEgoKBBQDAAIACOcHABIE2QYdKAoTCgsEFAMAAgAI5wcAAhIE2QYdIwoUCgwEFAMAAgAI5wcAAgASBNkGHSMKFQoNBBQDAAIACOcHAAIAARIE2QYdIwoTCgsEFAMAAgAI5wcAAxIE2QYkKApPCgYEFAMAAgESBNwGBCQaPyBJZGVudGlmaWVzIHRoZSBmaWxlc3lzdGVtIHBhdGggdG8gdGhlIG9yaWdpbmFsIHNvdXJjZSAucHJvdG8uCgoPCgcEFAMAAgEEEgTcBgQMCg8KBwQUAwACAQUSBNwGDRMKDwoHBBQDAAIBARIE3AYUHwoPCgcEFAMAAgEDEgTcBiIjCncKBgQUAwACAhIE4AYEHRpnIElkZW50aWZpZXMgdGhlIHN0YXJ0aW5nIG9mZnNldCBpbiBieXRlcyBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUKIHRoYXQgcmVsYXRlcyB0byB0aGUgaWRlbnRpZmllZCBvYmplY3QuCgoPCgcEFAMAAgIEEgTgBgQMCg8KBwQUAwACAgUSBOAGDRIKDwoHBBQDAAICARIE4AYTGAoPCgcEFAMAAgIDEgTgBhscCtsBCgYEFAMAAgMSBOUGBBsaygEgSWRlbnRpZmllcyB0aGUgZW5kaW5nIG9mZnNldCBpbiBieXRlcyBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdGhhdAogcmVsYXRlcyB0byB0aGUgaWRlbnRpZmllZCBvZmZzZXQuIFRoZSBlbmQgb2Zmc2V0IHNob3VsZCBiZSBvbmUgcGFzdAogdGhlIGxhc3QgcmVsZXZhbnQgYnl0ZSAoc28gdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCA9IGVuZCAtIGJlZ2luKS4KCg8KBwQUAwACAwQSBOUGBAwKDwoHBBQDAAIDBRIE5QYNEgoPCgcEFAMAAgMBEgTlBhMWCg8KBwQUAwACAwMSBOUGGRoKqV0KFGdvZ29wcm90by9nb2dvLnByb3RvEglnb2dvcHJvdG8aIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvOk4KE2dvcHJvdG9fZW51bV9wcmVmaXgSHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMYseQDIAEoCFIRZ29wcm90b0VudW1QcmVmaXg6UgoVZ29wcm90b19lbnVtX3N0cmluZ2VyEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMXkAyABKAhSE2dvcHJvdG9FbnVtU3RyaW5nZXI6QwoNZW51bV9zdHJpbmdlchIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxjG5AMgASgIUgxlbnVtU3RyaW5nZXI6RwoPZW51bV9jdXN0b21uYW1lEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMfkAyABKAlSDmVudW1DdXN0b21uYW1lOjoKCGVudW1kZWNsEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMjkAyABKAhSCGVudW1kZWNsOlYKFGVudW12YWx1ZV9jdXN0b21uYW1lEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY0YMEIAEoCVITZW51bXZhbHVlQ3VzdG9tbmFtZTpOChNnb3Byb3RvX2dldHRlcnNfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJnsAyABKAhSEWdvcHJvdG9HZXR0ZXJzQWxsOlUKF2dvcHJvdG9fZW51bV9wcmVmaXhfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJrsAyABKAhSFGdvcHJvdG9FbnVtUHJlZml4QWxsOlAKFGdvcHJvdG9fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJvsAyABKAhSEmdvcHJvdG9TdHJpbmdlckFsbDpKChF2ZXJib3NlX2VxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxic7AMgASgIUg92ZXJib3NlRXF1YWxBbGw6OQoIZmFjZV9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnewDIAEoCFIHZmFjZUFsbDpBCgxnb3N0cmluZ19hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnuwDIAEoCFILZ29zdHJpbmdBbGw6QQoMcG9wdWxhdGVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJ/sAyABKAhSC3BvcHVsYXRlQWxsOkEKDHN0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxig7AMgASgIUgtzdHJpbmdlckFsbDo/Cgtvbmx5b25lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxih7AMgASgIUgpvbmx5b25lQWxsOjsKCWVxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxil7AMgASgIUghlcXVhbEFsbDpHCg9kZXNjcmlwdGlvbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYpuwDIAEoCFIOZGVzY3JpcHRpb25BbGw6PwoLdGVzdGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYp+wDIAEoCFIKdGVzdGdlbkFsbDpBCgxiZW5jaGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYqOwDIAEoCFILYmVuY2hnZW5BbGw6QwoNbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxip7AMgASgIUgxtYXJzaGFsZXJBbGw6RwoPdW5tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKrsAyABKAhSDnVubWFyc2hhbGVyQWxsOlAKFHN0YWJsZV9tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKvsAyABKAhSEnN0YWJsZU1hcnNoYWxlckFsbDo7CglzaXplcl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYrOwDIAEoCFIIc2l6ZXJBbGw6WQoZZ29wcm90b19lbnVtX3N0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxit7AMgASgIUhZnb3Byb3RvRW51bVN0cmluZ2VyQWxsOkoKEWVudW1fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGK7sAyABKAhSD2VudW1TdHJpbmdlckFsbDpQChR1bnNhZmVfbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiv7AMgASgIUhJ1bnNhZmVNYXJzaGFsZXJBbGw6VAoWdW5zYWZlX3VubWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiw7AMgASgIUhR1bnNhZmVVbm1hcnNoYWxlckFsbDpbChpnb3Byb3RvX2V4dGVuc2lvbnNfbWFwX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxix7AMgASgIUhdnb3Byb3RvRXh0ZW5zaW9uc01hcEFsbDpYChhnb3Byb3RvX3VucmVjb2duaXplZF9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYsuwDIAEoCFIWZ29wcm90b1VucmVjb2duaXplZEFsbDpJChBnb2dvcHJvdG9faW1wb3J0EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLPsAyABKAhSD2dvZ29wcm90b0ltcG9ydDpFCg5wcm90b3NpemVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi07AMgASgIUg1wcm90b3NpemVyQWxsOj8KC2NvbXBhcmVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLXsAyABKAhSCmNvbXBhcmVBbGw6QQoMdHlwZWRlY2xfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLbsAyABKAhSC3R5cGVkZWNsQWxsOkEKDGVudW1kZWNsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi37AMgASgIUgtlbnVtZGVjbEFsbDpRChRnb3Byb3RvX3JlZ2lzdHJhdGlvbhIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi47AMgASgIUhNnb3Byb3RvUmVnaXN0cmF0aW9uOkcKD21lc3NhZ2VuYW1lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi57AMgASgIUg5tZXNzYWdlbmFtZUFsbDpKCg9nb3Byb3RvX2dldHRlcnMSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYgfQDIAEoCFIOZ29wcm90b0dldHRlcnM6TAoQZ29wcm90b19zdHJpbmdlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiD9AMgASgIUg9nb3Byb3RvU3RyaW5nZXI6RgoNdmVyYm9zZV9lcXVhbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiE9AMgASgIUgx2ZXJib3NlRXF1YWw6NQoEZmFjZRIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiF9AMgASgIUgRmYWNlOj0KCGdvc3RyaW5nEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIb0AyABKAhSCGdvc3RyaW5nOj0KCHBvcHVsYXRlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIf0AyABKAhSCHBvcHVsYXRlOj0KCHN0cmluZ2VyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGMCLBCABKAhSCHN0cmluZ2VyOjsKB29ubHlvbmUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYifQDIAEoCFIHb25seW9uZTo3CgVlcXVhbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiN9AMgASgIUgVlcXVhbDpDCgtkZXNjcmlwdGlvbhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiO9AMgASgIUgtkZXNjcmlwdGlvbjo7Cgd0ZXN0Z2VuEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI/0AyABKAhSB3Rlc3RnZW46PQoIYmVuY2hnZW4SHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYkPQDIAEoCFIIYmVuY2hnZW46PwoJbWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJH0AyABKAhSCW1hcnNoYWxlcjpDCgt1bm1hcnNoYWxlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiS9AMgASgIUgt1bm1hcnNoYWxlcjpMChBzdGFibGVfbWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJP0AyABKAhSD3N0YWJsZU1hcnNoYWxlcjo3CgVzaXplchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiU9AMgASgIUgVzaXplcjpMChB1bnNhZmVfbWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJf0AyABKAhSD3Vuc2FmZU1hcnNoYWxlcjpQChJ1bnNhZmVfdW5tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYmPQDIAEoCFIRdW5zYWZlVW5tYXJzaGFsZXI6VwoWZ29wcm90b19leHRlbnNpb25zX21hcBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiZ9AMgASgIUhRnb3Byb3RvRXh0ZW5zaW9uc01hcDpUChRnb3Byb3RvX3VucmVjb2duaXplZBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxia9AMgASgIUhNnb3Byb3RvVW5yZWNvZ25pemVkOkEKCnByb3Rvc2l6ZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnPQDIAEoCFIKcHJvdG9zaXplcjo7Cgdjb21wYXJlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJ30AyABKAhSB2NvbXBhcmU6PQoIdHlwZWRlY2wSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnvQDIAEoCFIIdHlwZWRlY2w6QwoLbWVzc2FnZW5hbWUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYofQDIAEoCFILbWVzc2FnZW5hbWU6OwoIbnVsbGFibGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOn7AyABKAhSCG51bGxhYmxlOjUKBWVtYmVkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjq+wMgASgIUgVlbWJlZDo/CgpjdXN0b210eXBlEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjr+wMgASgJUgpjdXN0b210eXBlOj8KCmN1c3RvbW5hbWUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOz7AyABKAlSCmN1c3RvbW5hbWU6OQoHanNvbnRhZxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7fsDIAEoCVIHanNvbnRhZzo7Cghtb3JldGFncxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7vsDIAEoCVIIbW9yZXRhZ3M6OwoIY2FzdHR5cGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGO/7AyABKAlSCGNhc3R0eXBlOjkKB2Nhc3RrZXkSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPD7AyABKAlSB2Nhc3RrZXk6PQoJY2FzdHZhbHVlEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjx+wMgASgJUgljYXN0dmFsdWU6OQoHc3RkdGltZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8vsDIAEoCFIHc3RkdGltZTpBCgtzdGRkdXJhdGlvbhIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8/sDIAEoCFILc3RkZHVyYXRpb25CRQoTY29tLmdvb2dsZS5wcm90b2J1ZkIKR29Hb1Byb3Rvc1oiZ2l0aHViLmNvbS9nb2dvL3Byb3RvYnVmL2dvZ29wcm90b0qaNQoHEgUcAIcBAQr8CgoBDBIDHAASMvEKIFByb3RvY29sIEJ1ZmZlcnMgZm9yIEdvIHdpdGggR2FkZ2V0cwoKIENvcHlyaWdodCAoYykgMjAxMywgVGhlIEdvR28gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIGh0dHA6Ly9naXRodWIuY29tL2dvZ28vcHJvdG9idWYKCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgoKIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklM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B0USBIUBCCYKCgoDB0UCEgN6ByMKCwoDB0UEEgSFAQgQCgsKAwdFBRIEhQERFQoLCgMHRQESBIUBFh0KCwoDB0UDEgSFASAlCgoKAgdGEgSGAQgqCgoKAwdGAhIDegcjCgsKAwdGBBIEhgEIEAoLCgMHRgUSBIYBERUKCwoDB0YBEgSGARYhCgsKAwdGAxIEhgEkKQqMFwosbWl4ZXIvYWRhcHRlci9tb2RlbC92MWJldGExL2V4dGVuc2lvbnMucHJvdG8SIWlzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMRogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8quAEKD1RlbXBsYXRlVmFyaWV0eRIaChZURU1QTEFURV9WQVJJRVRZX0NIRUNLEAASGwoXVEVNUExBVEVfVkFSSUVUWV9SRVBPUlQQARIaChZURU1QTEFURV9WQVJJRVRZX1FVT1RBEAISKAokVEVNUExBVEVfVkFSSUVUWV9BVFRSSUJVVEVfR0VORVJBVE9SEAMSJgoiVEVNUExBVEVfVkFSSUVUWV9DSEVDS19XSVRIX09VVFBVVBAEOn4KEHRlbXBsYXRlX3ZhcmlldHkSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYr8q8IiABKA4yMi5pc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEuVGVtcGxhdGVWYXJpZXR5Ug90ZW1wbGF0ZVZhcmlldHk6RAoNdGVtcGxhdGVfbmFtZRIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxjQy7wiIAEoCVIMdGVtcGxhdGVOYW1lQipaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTFK4RIKBhIEDgAyAQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIKQoICgEIEgMSAD0KCwoECOcHABIDEgA9CgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEjwKCQoCAwASAxQHKQp5CgIFABIEGAAoARptIFRoZSBhdmFpbGFibGUgdmFyaWV0aWVzIG9mIHRlbXBsYXRlcywgY29udHJvbGxpbmcgdGhlIHNlbWFudGljcyBvZiB3aGF0IGFuIGFkYXB0ZXIgZG9lcyB3aXRoIGVhY2ggaW5zdGFuY2UuCgoKCgMFAAESAxgFFArHAQoEBQACABIDGwQfGrkBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIGNoZWNrIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIGNoZWNrIGNhbGxzIGluIE1peGVyIGFuZCBwYXNzZWQgdG8gdGhlIGhhbmRsZXJzIGJhc2VkIG9uIHRoZSBydWxlIGNvbmZpZ3VyYXRpb25zLgoKDAoFBQACAAESAxsEGgoMCgUFAAIAAhIDGx0eCskBCgQFAAIBEgMeBCAauwEgTWFrZXMgdGhlIHRlbXBsYXRlIGFwcGxpY2FibGUgZm9yIE1peGVyJ3MgcmVwb3J0IGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHJlcG9ydCBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgEBEgMeBBsKDAoFBQACAQISAx4eHwrNAQoEBQACAhIDIQQfGr8BIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHF1b3RhIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHF1b3RhIGNoZWNrIGNhbGxzIGluIE1peGVyIGFuZCBwYXNzZWQgdG8gdGhlIGhhbmRsZXJzIGJhc2VkIG9uIHRoZSBydWxlIGNvbmZpZ3VyYXRpb25zLgoKDAoFBQACAgESAyEEGgoMCgUFAAICAhIDIR0eCusBCgQFAAIDEgMkBC0a3QEgTWFrZXMgdGhlIHRlbXBsYXRlIGFwcGxpY2FibGUgZm9yIE1peGVyJ3MgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UuIEluc3RhbmNlcyBvZiBzdWNoIHRlbXBsYXRlIGFyZSBjcmVhdGVkIGR1cmluZwogcHJlLXByb2Nlc3NpbmcgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UgYW5kIHBhc3NlZCB0byB0aGUgaGFuZGxlcnMgYmFzZWQgb24gdGhlIHJ1bGUgY29uZmlndXJhdGlvbnMuCgoMCgUFAAIDARIDJAQoCgwKBQUAAgMCEgMkKywKugEKBAUAAgQSAycEKxqsASBNYWtlcyB0aGUgdGVtcGxhdGUgYXBwbGljYWJsZSBmb3IgTWl4ZXIncyBjaGVjayBjYWxscy4gSW5zdGFuY2VzIG9mIHN1Y2ggdGVtcGxhdGUgYXJlIGNyZWF0ZWQgZHVyaW5nCiBjaGVjayBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyB0aGF0IHByb2R1Y2UgdmFsdWVzLgoKDAoFBQACBAESAycEJgoMCgUFAAIEAhIDJykqCjEKAQcSBCsAMgEaJiBGaWxlIGxldmVsIG9wdGlvbnMgZm9yIHRoZSB0ZW1wbGF0ZS4KCjYKAgcAEgMtBDAaKyBSZXF1aXJlZDogb3B0aW9uIGZvciB0aGUgVGVtcGxhdGVWYXJpZXR5LgoKCgoDBwACEgMrByIKCwoDBwAEEgQtBCskCgoKAwcABhIDLQQTCgoKAwcAARIDLRQkCgoKAwcAAxIDLScvCqQBCgIHARIDMQQkGpgBIE9wdGlvbmFsOiBvcHRpb24gZm9yIHRoZSB0ZW1wbGF0ZSBuYW1lLgogSWYgbm90IHNwZWNpZmllZCwgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgdGVtcGxhdGUgcHJvdG8ncyBwYWNrYWdlIG5hbWUgaXMgdXNlZCB0bwogZGVyaXZlIHRoZSB0ZW1wbGF0ZSBuYW1lLgoKCgoDBwECEgMrByIKCwoDBwEEEgQxBC0wCgoKAwcBBRIDMQQKCgoKAwcBARIDMQsYCgoKAwcBAxIDMRsjYgZwcm90bzMK3CwKGWdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiI2CgNBbnkSGQoIdHlwZV91cmwYASABKAlSB3R5cGVVcmwSFAoFdmFsdWUYAiABKAxSBXZhbHVlQm8KE2NvbS5nb29nbGUucHJvdG9idWZCCEFueVByb3RvUAFaJWdpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3B0eXBlcy9hbnmiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNK/CoKBxIFHgCUAQEKzAwKAQwSAx4AEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFO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cGFjayBhIG1lc3NhZ2UgaW4gR28KCiAgICAgIGZvbyA6PSAmcGIuRm9vey4uLn0KICAgICAgYW55LCBlcnIgOj0gcHR5cGVzLk1hcnNoYWxBbnkoZm9vKQogICAgICAuLi4KICAgICAgZm9vIDo9ICZwYi5Gb297fQogICAgICBpZiBlcnIgOj0gcHR5cGVzLlVubWFyc2hhbEFueShhbnksIGZvbyk7IGVyciAhPSBuaWwgewogICAgICAgIC4uLgogICAgICB9CgogVGhlIHBhY2sgbWV0aG9kcyBwcm92aWRlZCBieSBwcm90b2J1ZiBsaWJyYXJ5IHdpbGwgYnkgZGVmYXVsdCB1c2UKICd0eXBlLmdvb2dsZWFwaXMuY29tL2Z1bGwudHlwZS5uYW1lJyBhcyB0aGUgdHlwZSBVUkwgYW5kIHRoZSB1bnBhY2sKIG1ldGhvZHMgb25seSB1c2UgdGhlIGZ1bGx5IHF1YWxpZmllZCB0eXBlIG5hbWUgYWZ0ZXIgdGhlIGxhc3QgJy8nCiBpbiB0aGUgdHlwZSBVUkwsIGZvciBleGFtcGxlICJmb28uYmFyLmNvbS94L3kueiIgd2lsbCB5aWVsZCB0eXBlCiBuYW1lICJ5LnoiLgoKCiBKU09OCiA9PT09CiBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhbiBgQW55YCB2YWx1ZSB1c2VzIHRoZSByZWd1bGFyCiByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGVzZXJpYWxpemVkLCBlbWJlZGRlZCBtZXNzYWdlLCB3aXRoIGFuCiBhZGRpdGlvbmFsIGZpZWxkIGBAdHlwZWAgd2hpY2ggY29udGFpbnMgdGhlIHR5cGUgVVJMLiBFeGFtcGxlOgoKICAgICBwYWNrYWdlIGdvb2dsZS5wcm9maWxlOwogICAgIG1lc3NhZ2UgUGVyc29uIHsKICAgICAgIHN0cmluZyBmaXJzdF9uYW1lID0gMTsKICAgICAgIHN0cmluZyBsYXN0X25hbWUgPSAyOwogICAgIH0KCiAgICAgewogICAgICAgIkB0eXBlIjogInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb2ZpbGUuUGVyc29uIiwKICAgICAgICJmaXJzdE5hbWUiOiA8c3RyaW5nPiwKICAgICAgICJsYXN0TmFtZSI6IDxzdHJpbmc+CiAgICAgfQoKIElmIHRoZSBlbWJlZGRlZCBtZXNzYWdlIHR5cGUgaXMgd2VsbC1rbm93biBhbmQgaGFzIGEgY3VzdG9tIEpTT04KIHJlcHJlc2VudGF0aW9uLCB0aGF0IHJlcHJlc2VudGF0aW9uIHdpbGwgYmUgZW1iZWRkZWQgYWRkaW5nIGEgZmllbGQKIGB2YWx1ZWAgd2hpY2ggaG9sZHMgdGhlIGN1c3RvbSBKU09OIGluIGFkZGl0aW9uIHRvIHRoZSBgQHR5cGVgCiBmaWVsZC4gRXhhbXBsZSAoZm9yIG1lc3NhZ2UgW2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbl1bXSk6CgogICAgIHsKICAgICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIsCiAgICAgICAidmFsdWUiOiAiMS4yMTJzIgogICAgIH0KCgoKCgMEAAESA3kICwrkBwoEBAACABIEkAECFhrVByBBIFVSTC9yZXNvdXJjZSBuYW1lIHdob3NlIGNvbnRlbnQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZQogc2VyaWFsaXplZCBwcm90b2NvbCBidWZmZXIgbWVzc2FnZS4KCiBGb3IgVVJMcyB3aGljaCB1c2UgdGhlIHNjaGVtZSBgaHR0cGAsIGBodHRwc2AsIG9yIG5vIHNjaGVtZSwgdGhlCiBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIGFuZCBpbnRlcnByZXRhdGlvbnMgYXBwbHk6CgogKiBJZiBubyBzY2hlbWUgaXMgcHJvdmlkZWQsIGBodHRwc2AgaXMgYXNzdW1lZC4KICogVGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgVVJMJ3MgcGF0aCBtdXN0IHJlcHJlc2VudCB0aGUgZnVsbHkKICAgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgKGFzIGluIGBwYXRoL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbmApLgogICBUaGUgbmFtZSBzaG91bGQgYmUgaW4gYSBjYW5vbmljYWwgZm9ybSAoZS5nLiwgbGVhZGluZyAiLiIgaXMKICAgbm90IGFjY2VwdGVkKS4KICogQW4gSFRUUCBHRVQgb24gdGhlIFVSTCBtdXN0IHlpZWxkIGEgW2dvb2dsZS5wcm90b2J1Zi5UeXBlXVtdCiAgIHZhbHVlIGluIGJpbmFyeSBmb3JtYXQsIG9yIHByb2R1Y2UgYW4gZXJyb3IuCiAqIEFwcGxpY2F0aW9ucyBhcmUgYWxsb3dlZCB0byBjYWNoZSBsb29rdXAgcmVzdWx0cyBiYXNlZCBvbiB0aGUKICAgVVJMLCBvciBoYXZlIHRoZW0gcHJlY29tcGlsZWQgaW50byBhIGJpbmFyeSB0byBhdm9pZCBhbnkKICAgbG9va3VwLiBUaGVyZWZvcmUsIGJpbmFyeSBjb21wYXRpYmlsaXR5IG5lZWRzIHRvIGJlIHByZXNlcnZlZAogICBvbiBjaGFuZ2VzIHRvIHR5cGVzLiAoVXNlIHZlcnNpb25lZCB0eXBlIG5hbWVzIHRvIG1hbmFnZQogICBicmVha2luZyBjaGFuZ2VzLikKCiBTY2hlbWVzIG90aGVyIHRoYW4gYGh0dHBgLCBgaHR0cHNgIChvciB0aGUgZW1wdHkgc2NoZW1lKSBtaWdodCBiZQogdXNlZCB3aXRoIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHNlbWFudGljcy4KCgoOCgUEAAIABBIFkAECeQ0KDQoFBAACAAUSBJABAggKDQoFBAACAAESBJABCREKDQoFBAACAAMSBJABFBUKVwoEBAACARIEkwECEhpJIE11c3QgYmUgYSB2YWxpZCBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBvZiB0aGUgYWJvdmUgc3BlY2lmaWVkIHR5cGUuCgoPCgUEAAIBBBIGkwECkAEWCg0KBQQAAgEFEgSTAQIHCg0KBQQAAgEBEgSTAQgNCg0KBQQAAgEDEgSTARARYgZwcm90bzMKmikKHmdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90bxIPZ29vZ2xlLnByb3RvYnVmIjoKCER1cmF0aW9uEhgKB3NlY29uZHMYASABKANSB3NlY29uZHMSFAoFbmFub3MYAiABKAVSBW5hbm9zQnwKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoqZ2l0aHViLmNvbS9nb2xhbmcvcHJvdG9idWYvcHR5cGVzL2R1cmF0aW9u+AEBogIDR1BCqgIeR29vZ2xlLlByb3RvYnVmLldlbGxLbm93blR5cGVzSqQnCgYSBB4AdAEKzAwKAQwSAx4AEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KCggKAQISAyAIFwoICgEIEgMiADsKCwoECOcHABIDIgA7CgwKBQjnBwACEgMiBxcKDQoGCOcHAAIAEgMiBxcKDgoHCOcHAAIAARIDIgcXCgwKBQjnBwAHEgMiGjoKCAoBCBIDIwAfCgsKBAjnBwESAyMAHwoMCgUI5wcBAhIDIwcXCg0KBgjnBwECABIDIwcXCg4KBwjnBwECAAESAyMHFwoMCgUI5wcBAxIDIxoeCggKAQgSAyQAQQoLCgQI5wcCEgMkAEEKDAoFCOcHAgISAyQHEQoNCgYI5wcCAgASAyQHEQoOCgcI5wcCAgABEgMkBxEKDAoFCOcHAgcSAyQUQAoICgEIEgMlACwKCwoECOcHAxIDJQAsCgwKBQjnBwMCEgMlBxMKDQoGCOcHAwIAEgMlBxMKDgoHCOcHAwIAARIDJQcTCgwKBQjnBwMHEgMlFisKCAoBCBIDJgAuCgsKBAjnBwQSAyYALgoMCgUI5wcEAhIDJgcbCg0KBgjnBwQCABIDJgcbCg4KBwjnBwQCAAESAyYHGwoMCgUI5wcEBxIDJh4tCggKAQgSAycAIgoLCgQI5wcFEgMnACIKDAoFCOcHBQISAycHGgoNCgYI5wcFAgASAycHGgoOCgcI5wcFAgABEgMnBxoKDAoFCOcHBQMSAycdIQoICgEIEgMoACEKCwoECOcHBhIDKAAhCgwKBQjnBwYCEgMoBxgKDQoGCOcHBgIAEgMoBxgKDgoHCOcHBgIAARIDKAcYCgwKBQjnBwYHEgMoGyAKnxAKAgQAEgRmAHQBGpIQIEEgRHVyYXRpb24gcmVwcmVzZW50cyBhIHNpZ25lZCwgZml4ZWQtbGVuZ3RoIHNwYW4gb2YgdGltZSByZXByZXNlbnRlZAogYXMgYSBjb3VudCBvZiBzZWNvbmRzIGFuZCBmcmFjdGlvbnMgb2Ygc2Vjb25kcyBhdCBuYW5vc2Vjb25kCiByZXNvbHV0aW9uLiBJdCBpcyBpbmRlcGVuZGVudCBvZiBhbnkgY2FsZW5kYXIgYW5kIGNvbmNlcHRzIGxpa2UgImRheSIKIG9yICJtb250aCIuIEl0IGlzIHJlbGF0ZWQgdG8gVGltZXN0YW1wIGluIHRoYXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbgogdHdvIFRpbWVzdGFtcCB2YWx1ZXMgaXMgYSBEdXJhdGlvbiBhbmQgaXQgY2FuIGJlIGFkZGVkIG9yIHN1YnRyYWN0ZWQKIGZyb20gYSBUaW1lc3RhbXAuIFJhbmdlIGlzIGFwcHJveGltYXRlbHkgKy0xMCwwMDAgeWVhcnMuCgogIyBFeGFtcGxlcwoKIEV4YW1wbGUgMTogQ29tcHV0ZSBEdXJhdGlvbiBmcm9tIHR3byBUaW1lc3RhbXBzIGluIHBzZXVkbyBjb2RlLgoKICAgICBUaW1lc3RhbXAgc3RhcnQgPSAuLi47CiAgICAgVGltZXN0YW1wIGVuZCA9IC4uLjsKICAgICBEdXJhdGlvbiBkdXJhdGlvbiA9IC4uLjsKCiAgICAgZHVyYXRpb24uc2Vjb25kcyA9IGVuZC5zZWNvbmRzIC0gc3RhcnQuc2Vjb25kczsKICAgICBkdXJhdGlvbi5uYW5vcyA9IGVuZC5uYW5vcyAtIHN0YXJ0Lm5hbm9zOwoKICAgICBpZiAoZHVyYXRpb24uc2Vjb25kcyA8IDAgJiYgZHVyYXRpb24ubmFub3MgPiAwKSB7CiAgICAgICBkdXJhdGlvbi5zZWNvbmRzICs9IDE7CiAgICAgICBkdXJhdGlvbi5uYW5vcyAtPSAxMDAwMDAwMDAwOwogICAgIH0gZWxzZSBpZiAoZHVyYXRpb25zLnNlY29uZHMgPiAwICYmIGR1cmF0aW9uLm5hbm9zIDwgMCkgewogICAgICAgZHVyYXRpb24uc2Vjb25kcyAtPSAxOwogICAgICAgZHVyYXRpb24ubmFub3MgKz0gMTAwMDAwMDAwMDsKICAgICB9CgogRXhhbXBsZSAyOiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIFRpbWVzdGFtcCArIER1cmF0aW9uIGluIHBzZXVkbyBjb2RlLgoKICAgICBUaW1lc3RhbXAgc3RhcnQgPSAuLi47CiAgICAgRHVyYXRpb24gZHVyYXRpb24gPSAuLi47CiAgICAgVGltZXN0YW1wIGVuZCA9IC4uLjsKCiAgICAgZW5kLnNlY29uZHMgPSBzdGFydC5zZWNvbmRzICsgZHVyYXRpb24uc2Vjb25kczsKICAgICBlbmQubmFub3MgPSBzdGFydC5uYW5vcyArIGR1cmF0aW9uLm5hbm9zOwoKICAgICBpZiAoZW5kLm5hbm9zIDwgMCkgewogICAgICAgZW5kLnNlY29uZHMgLT0gMTsKICAgICAgIGVuZC5uYW5vcyArPSAxMDAwMDAwMDAwOwogICAgIH0gZWxzZSBpZiAoZW5kLm5hbm9zID49IDEwMDAwMDAwMDApIHsKICAgICAgIGVuZC5zZWNvbmRzICs9IDE7CiAgICAgICBlbmQubmFub3MgLT0gMTAwMDAwMDAwMDsKICAgICB9CgogRXhhbXBsZSAzOiBDb21wdXRlIER1cmF0aW9uIGZyb20gZGF0ZXRpbWUudGltZWRlbHRhIGluIFB5dGhvbi4KCiAgICAgdGQgPSBkYXRldGltZS50aW1lZGVsdGEoZGF5cz0zLCBtaW51dGVzPTEwKQogICAgIGR1cmF0aW9uID0gRHVyYXRpb24oKQogICAgIGR1cmF0aW9uLkZyb21UaW1lZGVsdGEodGQpCgogIyBKU09OIE1hcHBpbmcKCiBJbiBKU09OIGZvcm1hdCwgdGhlIER1cmF0aW9uIHR5cGUgaXMgZW5jb2RlZCBhcyBhIHN0cmluZyByYXRoZXIgdGhhbiBhbgogb2JqZWN0LCB3aGVyZSB0aGUgc3RyaW5nIGVuZHMgaW4gdGhlIHN1ZmZpeCAicyIgKGluZGljYXRpbmcgc2Vjb25kcykgYW5kCiBpcyBwcmVjZWRlZCBieSB0aGUgbnVtYmVyIG9mIHNlY29uZHMsIHdpdGggbmFub3NlY29uZHMgZXhwcmVzc2VkIGFzCiBmcmFjdGlvbmFsIHNlY29uZHMuIEZvciBleGFtcGxlLCAzIHNlY29uZHMgd2l0aCAwIG5hbm9zZWNvbmRzIHNob3VsZCBiZQogZW5jb2RlZCBpbiBKU09OIGZvcm1hdCBhcyAiM3MiLCB3aGlsZSAzIHNlY29uZHMgYW5kIDEgbmFub3NlY29uZCBzaG91bGQKIGJlIGV4cHJlc3NlZCBpbiBKU09OIGZvcm1hdCBhcyAiMy4wMDAwMDAwMDFzIiwgYW5kIDMgc2Vjb25kcyBhbmQgMQogbWljcm9zZWNvbmQgc2hvdWxkIGJlIGV4cHJlc3NlZCBpbiBKU09OIGZvcm1hdCBhcyAiMy4wMDAwMDFzIi4KCgoKCgoDBAABEgNmCBAK3AEKBAQAAgASA2sCFBrOASBTaWduZWQgc2Vjb25kcyBvZiB0aGUgc3BhbiBvZiB0aW1lLiBNdXN0IGJlIGZyb20gLTMxNSw1NzYsMDAwLDAwMAogdG8gKzMxNSw1NzYsMDAwLDAwMCBpbmNsdXNpdmUuIE5vdGU6IHRoZXNlIGJvdW5kcyBhcmUgY29tcHV0ZWQgZnJvbToKIDYwIHNlYy9taW4gKiA2MCBtaW4vaHIgKiAyNCBoci9kYXkgKiAzNjUuMjUgZGF5cy95ZWFyICogMTAwMDAgeWVhcnMKCg0KBQQAAgAEEgRrAmYSCgwKBQQAAgAFEgNrAgcKDAoFBAACAAESA2sIDwoMCgUEAAIAAxIDaxITCoMDCgQEAAIBEgNzAhIa9QIgU2lnbmVkIGZyYWN0aW9ucyBvZiBhIHNlY29uZCBhdCBuYW5vc2Vjb25kIHJlc29sdXRpb24gb2YgdGhlIHNwYW4KIG9mIHRpbWUuIER1cmF0aW9ucyBsZXNzIHRoYW4gb25lIHNlY29uZCBhcmUgcmVwcmVzZW50ZWQgd2l0aCBhIDAKIGBzZWNvbmRzYCBmaWVsZCBhbmQgYSBwb3NpdGl2ZSBvciBuZWdhdGl2ZSBgbmFub3NgIGZpZWxkLiBGb3IgZHVyYXRpb25zCiBvZiBvbmUgc2Vjb25kIG9yIG1vcmUsIGEgbm9uLXplcm8gdmFsdWUgZm9yIHRoZSBgbmFub3NgIGZpZWxkIG11c3QgYmUKIG9mIHRoZSBzYW1lIHNpZ24gYXMgdGhlIGBzZWNvbmRzYCBmaWVsZC4gTXVzdCBiZSBmcm9tIC05OTksOTk5LDk5OQogdG8gKzk5OSw5OTksOTk5IGluY2x1c2l2ZS4KCg0KBQQAAgEEEgRzAmsUCgwKBQQAAgEFEgNzAgcKDAoFBAACAQESA3MIDQoMCgUEAAIBAxIDcxARYgZwcm90bzMKqyIKF2dvb2dsZS9ycGMvc3RhdHVzLnByb3RvEgpnb29nbGUucnBjGhlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvImYKBlN0YXR1cxISCgRjb2RlGAEgASgFUgRjb2RlEhgKB21lc3NhZ2UYAiABKAlSB21lc3NhZ2USLgoHZGV0YWlscxgDIAMoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnlSB2RldGFpbHNCKgoOY29tLmdvb2dsZS5ycGNCC1N0YXR1c1Byb3RvUAFaA3JwY6ICA1JQQ0rMIAoGEgQOAFsBCr0ECgEMEgMOABIysgQgQ29weXJpZ2h0IDIwMTcgR29vZ2xlIEluYy4KCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIEgoJCgIDABIDEgciCggKAQgSAxQAGgoLCgQI5wcAEgMUABoKDAoFCOcHAAISAxQHEQoNCgYI5wcAAgASAxQHEQoOCgcI5wcAAgABEgMUBxEKDAoFCOcHAAcSAxQUGQoICgEIEgMVACIKCwoECOcHARIDFQAiCgwKBQjnBwECEgMVBxoKDQoGCOcHAQIAEgMVBxoKDgoHCOcHAQIAARIDFQcaCgwKBQjnBwEDEgMVHSEKCAoBCBIDFgAsCgsKBAjnBwISAxYALAoMCgUI5wcCAhIDFgcbCg0KBgjnBwICABIDFgcbCg4KBwjnBwICAAESAxYHGwoMCgUI5wcCBxIDFh4rCggKAQgSAxcAJwoLCgQI5wcDEgMXACcKDAoFCOcHAwISAxcHEwoNCgYI5wcDAgASAxcHEwoOCgcI5wcDAgABEgMXBxMKDAoFCOcHAwcSAxcWJgoICgEIEgMYACEKCwoECOcHBBIDGAAhCgwKBQjnBwQCEgMYBxgKDQoGCOcHBAIAEgMYBxgKDgoHCOcHBAIAARIDGAcYCgwKBQjnBwQHEgMYGyAKzRMKAgQAEgRPAFsBGsATIFRoZSBgU3RhdHVzYCB0eXBlIGRlZmluZXMgYSBsb2dpY2FsIGVycm9yIG1vZGVsIHRoYXQgaXMgc3VpdGFibGUgZm9yIGRpZmZlcmVudAogcHJvZ3JhbW1pbmcgZW52aXJvbm1lbnRzLCBpbmNsdWRpbmcgUkVTVCBBUElzIGFuZCBSUEMgQVBJcy4gSXQgaXMgdXNlZCBieQogW2dSUENdKGh0dHBzOi8vZ2l0aHViLmNvbS9ncnBjKS4gVGhlIGVycm9yIG1vZGVsIGlzIGRlc2lnbmVkIHRvIGJlOgoKIC0gU2ltcGxlIHRvIHVzZSBhbmQgdW5kZXJzdGFuZCBmb3IgbW9zdCB1c2VycwogLSBGbGV4aWJsZSBlbm91Z2ggdG8gbWVldCB1bmV4cGVjdGVkIG5lZWRzCgogIyBPdmVydmlldwoKIFRoZSBgU3RhdHVzYCBtZXNzYWdlIGNvbnRhaW5zIHRocmVlIHBpZWNlcyBvZiBkYXRhOiBlcnJvciBjb2RlLCBlcnJvciBtZXNzYWdlLAogYW5kIGVycm9yIGRldGFpbHMuIFRoZSBlcnJvciBjb2RlIHNob3VsZCBiZSBhbiBlbnVtIHZhbHVlIG9mCiBbZ29vZ2xlLnJwYy5Db2RlXVtnb29nbGUucnBjLkNvZGVdLCBidXQgaXQgbWF5IGFjY2VwdCBhZGRpdGlvbmFsIGVycm9yIGNvZGVzIGlmIG5lZWRlZC4gIFRoZQogZXJyb3IgbWVzc2FnZSBzaG91bGQgYmUgYSBkZXZlbG9wZXItZmFjaW5nIEVuZ2xpc2ggbWVzc2FnZSB0aGF0IGhlbHBzCiBkZXZlbG9wZXJzICp1bmRlcnN0YW5kKiBhbmQgKnJlc29sdmUqIHRoZSBlcnJvci4gSWYgYSBsb2NhbGl6ZWQgdXNlci1mYWNpbmcKIGVycm9yIG1lc3NhZ2UgaXMgbmVlZGVkLCBwdXQgdGhlIGxvY2FsaXplZCBtZXNzYWdlIGluIHRoZSBlcnJvciBkZXRhaWxzIG9yCiBsb2NhbGl6ZSBpdCBpbiB0aGUgY2xpZW50LiBUaGUgb3B0aW9uYWwgZXJyb3IgZGV0YWlscyBtYXkgY29udGFpbiBhcmJpdHJhcnkKIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlcnJvci4gVGhlcmUgaXMgYSBwcmVkZWZpbmVkIHNldCBvZiBlcnJvciBkZXRhaWwgdHlwZXMKIGluIHRoZSBwYWNrYWdlIGBnb29nbGUucnBjYCB0aGF0IGNhbiBiZSB1c2VkIGZvciBjb21tb24gZXJyb3IgY29uZGl0aW9ucy4KCiAjIExhbmd1YWdlIG1hcHBpbmcKCiBUaGUgYFN0YXR1c2AgbWVzc2FnZSBpcyB0aGUgbG9naWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgZXJyb3IgbW9kZWwsIGJ1dCBpdAogaXMgbm90IG5lY2Vzc2FyaWx5IHRoZSBhY3R1YWwgd2lyZSBmb3JtYXQuIFdoZW4gdGhlIGBTdGF0dXNgIG1lc3NhZ2UgaXMKIGV4cG9zZWQgaW4gZGlmZmVyZW50IGNsaWVudCBsaWJyYXJpZXMgYW5kIGRpZmZlcmVudCB3aXJlIHByb3RvY29scywgaXQgY2FuIGJlCiBtYXBwZWQgZGlmZmVyZW50bHkuIEZvciBleGFtcGxlLCBpdCB3aWxsIGxpa2VseSBiZSBtYXBwZWQgdG8gc29tZSBleGNlcHRpb25zCiBpbiBKYXZhLCBidXQgbW9yZSBsaWtlbHkgbWFwcGVkIHRvIHNvbWUgZXJyb3IgY29kZXMgaW4gQy4KCiAjIE90aGVyIHVzZXMKCiBUaGUgZXJyb3IgbW9kZWwgYW5kIHRoZSBgU3RhdHVzYCBtZXNzYWdlIGNhbiBiZSB1c2VkIGluIGEgdmFyaWV0eSBvZgogZW52aXJvbm1lbnRzLCBlaXRoZXIgd2l0aCBvciB3aXRob3V0IEFQSXMsIHRvIHByb3ZpZGUgYQogY29uc2lzdGVudCBkZXZlbG9wZXIgZXhwZXJpZW5jZSBhY3Jvc3MgZGlmZmVyZW50IGVudmlyb25tZW50cy4KCiBFeGFtcGxlIHVzZXMgb2YgdGhpcyBlcnJvciBtb2RlbCBpbmNsdWRlOgoKIC0gUGFydGlhbCBlcnJvcnMuIElmIGEgc2VydmljZSBuZWVkcyB0byByZXR1cm4gcGFydGlhbCBlcnJvcnMgdG8gdGhlIGNsaWVudCwKICAgICBpdCBtYXkgZW1iZWQgdGhlIGBTdGF0dXNgIGluIHRoZSBub3JtYWwgcmVzcG9uc2UgdG8gaW5kaWNhdGUgdGhlIHBhcnRpYWwKICAgICBlcnJvcnMuCgogLSBXb3JrZmxvdyBlcnJvcnMuIEEgdHlwaWNhbCB3b3JrZmxvdyBoYXMgbXVsdGlwbGUgc3RlcHMuIEVhY2ggc3RlcCBtYXkKICAgICBoYXZlIGEgYFN0YXR1c2AgbWVzc2FnZSBmb3IgZXJyb3IgcmVwb3J0aW5nLgoKIC0gQmF0Y2ggb3BlcmF0aW9ucy4gSWYgYSBjbGllbnQgdXNlcyBiYXRjaCByZXF1ZXN0IGFuZCBiYXRjaCByZXNwb25zZSwgdGhlCiAgICAgYFN0YXR1c2AgbWVzc2FnZSBzaG91bGQgYmUgdXNlZCBkaXJlY3RseSBpbnNpZGUgYmF0Y2ggcmVzcG9uc2UsIG9uZSBmb3IKICAgICBlYWNoIGVycm9yIHN1Yi1yZXNwb25zZS4KCiAtIEFzeW5jaHJvbm91cyBvcGVyYXRpb25zLiBJZiBhbiBBUEkgY2FsbCBlbWJlZHMgYXN5bmNocm9ub3VzIG9wZXJhdGlvbgogICAgIHJlc3VsdHMgaW4gaXRzIHJlc3BvbnNlLCB0aGUgc3RhdHVzIG9mIHRob3NlIG9wZXJhdGlvbnMgc2hvdWxkIGJlCiAgICAgcmVwcmVzZW50ZWQgZGlyZWN0bHkgdXNpbmcgdGhlIGBTdGF0dXNgIG1lc3NhZ2UuCgogLSBMb2dnaW5nLiBJZiBzb21lIEFQSSBlcnJvcnMgYXJlIHN0b3JlZCBpbiBsb2dzLCB0aGUgbWVzc2FnZSBgU3RhdHVzYCBjb3VsZAogICAgIGJlIHVzZWQgZGlyZWN0bHkgYWZ0ZXIgYW55IHN0cmlwcGluZyBuZWVkZWQgZm9yIHNlY3VyaXR5L3ByaXZhY3kgcmVhc29ucy4KCgoKAwQAARIDTwgOCmQKBAQAAgASA1ECERpXIFRoZSBzdGF0dXMgY29kZSwgd2hpY2ggc2hvdWxkIGJlIGFuIGVudW0gdmFsdWUgb2YgW2dvb2dsZS5ycGMuQ29kZV1bZ29vZ2xlLnJwYy5Db2RlXS4KCg0KBQQAAgAEEgRRAk8QCgwKBQQAAgAFEgNRAgcKDAoFBAACAAESA1EIDAoMCgUEAAIAAxIDUQ8QCusBCgQEAAIBEgNWAhUa3QEgQSBkZXZlbG9wZXItZmFjaW5nIGVycm9yIG1lc3NhZ2UsIHdoaWNoIHNob3VsZCBiZSBpbiBFbmdsaXNoLiBBbnkKIHVzZXItZmFjaW5nIGVycm9yIG1lc3NhZ2Ugc2hvdWxkIGJlIGxvY2FsaXplZCBhbmQgc2VudCBpbiB0aGUKIFtnb29nbGUucnBjLlN0YXR1cy5kZXRhaWxzXVtnb29nbGUucnBjLlN0YXR1cy5kZXRhaWxzXSBmaWVsZCwgb3IgbG9jYWxpemVkIGJ5IHRoZSBjbGllbnQuCgoNCgUEAAIBBBIEVgJREQoMCgUEAAIBBRIDVgIICgwKBQQAAgEBEgNWCRAKDAoFBAACAQMSA1YTFAp5CgQEAAICEgNaAisabCBBIGxpc3Qgb2YgbWVzc2FnZXMgdGhhdCBjYXJyeSB0aGUgZXJyb3IgZGV0YWlscy4gIFRoZXJlIGlzIGEgY29tbW9uIHNldCBvZgogbWVzc2FnZSB0eXBlcyBmb3IgQVBJcyB0byB1c2UuCgoMCgUEAAICBBIDWgIKCgwKBQQAAgIGEgNaCx4KDAoFBAACAgESA1ofJgoMCgUEAAICAxIDWikqYgZwcm90bzMKvBEKJ21peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9jaGVjay5wcm90bxIhaXN0aW8ubWl4ZXIuYWRhcHRlci5tb2RlbC52MWJldGExGhRnb2dvcHJvdG8vZ29nby5wcm90bxoeZ29vZ2xlL3Byb3RvYnVmL2R1cmF0aW9uLnByb3RvGhdnb29nbGUvcnBjL3N0YXR1cy5wcm90byKzAQoLQ2hlY2tSZXN1bHQSMAoGc3RhdHVzGAEgASgLMhIuZ29vZ2xlLnJwYy5TdGF0dXNCBMjeHwBSBnN0YXR1cxJKCg52YWxpZF9kdXJhdGlvbhgCIAEoCzIZLmdvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbkIIyN4fAJjfHwFSDXZhbGlkRHVyYXRpb24SJgoPdmFsaWRfdXNlX2NvdW50GAMgASgFUg12YWxpZFVzZUNvdW50QjZaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTHI4R4AqOIe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CgUEAAICBRIDJAIHCgwKBQQAAgIBEgMkCBcKDAoFBAACAgMSAyQaG2IGcHJvdG8zCoEhCjBtaXhlci90ZXN0L2tleXZhbC90ZW1wbGF0ZV9oYW5kbGVyX3NlcnZpY2UucHJvdG8SBmtleXZhbBoUZ29nb3Byb3RvL2dvZ28ucHJvdG8aLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvGhlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvGidtaXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTEvY2hlY2sucHJvdG8ingEKE0hhbmRsZUtleXZhbFJlcXVlc3QSLwoIaW5zdGFuY2UYASABKAsyEy5rZXl2YWwuSW5zdGFuY2VNc2dSCGluc3RhbmNlEjsKDmFkYXB0ZXJfY29uZmlnGAIgASgLMhQuZ29vZ2xlLnByb3RvYnVmLkFueVINYWRhcHRlckNvbmZpZxIZCghkZWR1cF9pZBgDIAEoCVIHZGVkdXBJZCKJAQoUSGFuZGxlS2V5dmFsUmVzcG9uc2USRgoGcmVzdWx0GAEgASgLMi4uaXN0aW8ubWl4ZXIuYWRhcHRlci5tb2RlbC52MWJldGExLkNoZWNrUmVzdWx0UgZyZXN1bHQSKQoGb3V0cHV0GAIgASgLMhEua2V5dmFsLk91dHB1dE1zZ1IGb3V0cHV0IiEKCU91dHB1dE1zZxIUCgV2YWx1ZRgCIAEoCVIFdmFsdWUiNgoLSW5zdGFuY2VNc2cSFQoEbmFtZRivyrwiIAEoCVIEbmFtZRIQCgNrZXkYASABKAlSA2tleSIGCgRUeXBlIiEKDUluc3RhbmNlUGFyYW0SEAoDa2V5GAEgASgJUgNrZXkyYAoTSGFuZGxlS2V5dmFsU2VydmljZRJJCgxIYW5kbGVLZXl2YWwSGy5rZXl2YWwuSGFuZGxlS2V5dmFsUmVxdWVzdBocLmtleXZhbC5IYW5kbGVLZXl2YWxSZXNwb25zZUIe+NLkkwIEgt3kkwIGa2V5dmFsyOEeAKjiHgDw4R4ASv8aCgYSBBAAZQEK8gQKAQwSAxAAEjK0BCBDb3B5cmlnaHQgMjAxNyBJc3RpbyBBdXRob3JzCgogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKCiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCjIxIFRISVMgRklMRSBJUyBBVVRPTUFUSUNBTExZIEdFTkVSQVRFRCBCWSBNSVhHRU4uCgobCgECEgMWCA4aEQogSW5wdXQgdGVtcGxhdGUKCgkKAgMAEgMZBx0KCQoCAwESAxoHNQoJCgIDAhIDGwciCgkKAgMDEgMcBzAKCAoBCBIDHwBhCgsKBAjnBwASAx8AYQoMCgUI5wcAAhIDHwc7Cg0KBgjnBwACABIDHwc7Cg4KBwjnBwACAAESAx8IOgoMCgUI5wcAAxIDHz5gCggKAQgSAyAARAoLCgQI5wcBEgMgAEQKDAoFCOcHAQISAyAHOAoNCgYI5wcBAgASAyAHOAoOCgcI5wcBAgABEgMgCDcKDAoFCOcHAQcSAyA7QwoICgEIEgMiAC8KCwoECOcHAhIDIgAvCgwKBQjnBwICEgMiByYKDQoGCOcHAgIAEgMiByYKDgoHCOcHAgIAARIDIgglCgwKBQjnBwIDEgMiKS4KCAoBCBIDIwAlCgsKBAjnBwMSAyMAJQoMCgUI5wcDAhIDIwccCg0KBgjnBwMCABIDIwccCg4KBwjnBwMCAAESAyMIGwoMCgUI5wcDAxIDIx8kCggKAQgSAyQAKAoLCgQI5wcEEgMkACgKDAoFCOcHBAISAyQHHwoNCgYI5wcEAgASAyQHHwoOCgcI5wcEAgABEgMkCB4KDAoFCOcHBAMSAyQiJwpyCgIGABIEJwArARpmIEhhbmRsZUtleXZhbFNlcnZpY2UgaXMgaW1wbGVtZW50ZWQgYnkgYmFja2VuZHMgdGhhdCB3YW50cyB0byBoYW5kbGUgcmVxdWVzdC10aW1lICdrZXl2YWwnIGluc3RhbmNlcy4KCgoKAwYAARIDJwgbCmwKBAYAAgASAykESRpfIEhhbmRsZUtleXZhbCBpcyBjYWxsZWQgYnkgTWl4ZXIgYXQgcmVxdWVzdC10aW1lIHRvIGRlbGl2ZXIgJ2tleXZhbCcgaW5zdGFuY2VzIHRvIHRoZSBiYWNrZW5kLgoKDAoFBgACAAESAykIFAoMCgUGAAIAAhIDKRUoCgwKBQYAAgADEgMpM0cKNgoCBAASBC4APQEaKiBSZXF1ZXN0IG1lc3NhZ2UgZm9yIEhhbmRsZUtleXZhbCBtZXRob2QuCgoKCgMEAAESAy4IGwohCgQEAAIAEgMxBB0aFCAna2V5dmFsJyBpbnN0YW5jZS4KCg0KBQQAAgAEEgQxBC4dCgwKBQQAAgAGEgMxBA8KDAoFBAACAAESAzEQGAoMCgUEAAIAAxIDMRscCrkECgQEAAIBEgM5BCsaqwQgQWRhcHRlciBzcGVjaWZpYyBoYW5kbGVyIGNvbmZpZ3VyYXRpb24uCgogTm90ZTogQmFja2VuZHMgY2FuIGFsc28gaW1wbGVtZW50IFtJbmZyYXN0cnVjdHVyZUJhY2tlbmRdW2h0dHBzOi8vaXN0aW8uaW8vZG9jcy9yZWZlcmVuY2UvY29uZmlnL21peGVyL2lzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMS5odG1sI0luZnJhc3RydWN0dXJlQmFja2VuZF0KIHNlcnZpY2UgYW5kIHRoZXJlZm9yZSBvcHQgdG8gcmVjZWl2ZSBoYW5kbGVyIGNvbmZpZ3VyYXRpb24gZHVyaW5nIHNlc3Npb24gY3JlYXRpb24gdGhyb3VnaCBbSW5mcmFzdHJ1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"
+---
diff --git a/mash/eks/samples/httpbin/policy/keyval.yaml b/mash/eks/samples/httpbin/policy/keyval.yaml
new file mode 100644 (file)
index 0000000..5d8c3f3
--- /dev/null
@@ -0,0 +1,15 @@
+# this config is created through command
+# mixgen adapter -c $GOPATH/src/istio.io/istio/mixer/test/keyval/config.proto_descriptor -o $GOPATH/src/istio.io/istio/mixer/test/keyval -s=false -n keyval -t keyval
+apiVersion: "config.istio.io/v1alpha2"
+kind: adapter
+metadata:
+  name: keyval
+  namespace: istio-system
+spec:
+  description: example
+  session_based: false
+  templates:
+    - keyval
+  config: CsgCCh5taXhlci90ZXN0L2tleXZhbC9jb25maWcucHJvdG8SBmtleXZhbCJzCgZQYXJhbXMSLwoFdGFibGUYASADKAsyGS5rZXl2YWwuUGFyYW1zLlRhYmxlRW50cnlSBXRhYmxlGjgKClRhYmxlRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSFAoFdmFsdWUYAiABKAlSBXZhbHVlOgI4AUqgAQoGEgQAAAgBCggKAQwSAwAAEgoICgECEgMCCA4KIAoCBAASBAUACAEaFCBBZGFwdGVyIHBhcmFtZXRlcnMKCgoKAwQAARIDBQgOChsKBAQAAgASAwcCIBoOIExvb2t1cCB0YWJsZQoKDQoFBAACAAQSBAcCBRAKDAoFBAACAAYSAwcCFQoMCgUEAAIAARIDBxYbCgwKBQQAAgADEgMHHh9iBnByb3RvMw==
+---
+
diff --git a/mash/eks/samples/httpbin/sample-client/fortio-deploy.yaml b/mash/eks/samples/httpbin/sample-client/fortio-deploy.yaml
new file mode 100644 (file)
index 0000000..06aef93
--- /dev/null
@@ -0,0 +1,41 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: fortio
+  labels:
+    app: fortio
+spec:
+  ports:
+  - port: 8080
+    name: http
+  selector:
+    app: fortio
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: fortio-deploy
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: fortio
+  template:
+    metadata:
+      annotations:
+        # This annotation causes Envoy to serve cluster.outbound statistics via 15000/stats
+        # in addition to the stats normally served by Istio.  The Circuit Breaking example task
+        # gives an example of inspecting Envoy stats.
+        sidecar.istio.io/statsInclusionPrefixes: cluster.outbound,cluster_manager,listener_manager,http_mixer_filter,tcp_mixer_filter,server,cluster.xds-grpc
+      labels:
+        app: fortio
+    spec:
+      containers:
+      - name: fortio
+        image: fortio/fortio:latest_release
+        imagePullPolicy: Always
+        ports:
+        - containerPort: 8080
+          name: http-fortio
+        - containerPort: 8079
+          name: grpc-ping
diff --git a/mash/eks/samples/https/default.conf b/mash/eks/samples/https/default.conf
new file mode 100644 (file)
index 0000000..4a5b420
--- /dev/null
@@ -0,0 +1,10 @@
+server {
+        listen 443 ssl;
+
+        root /usr/share/nginx/html;
+        index index.html;
+
+        server_name localhost;
+        ssl_certificate /etc/nginx/ssl/tls.crt;
+        ssl_certificate_key /etc/nginx/ssl/tls.key;
+}
diff --git a/mash/eks/samples/https/nginx-app.yaml b/mash/eks/samples/https/nginx-app.yaml
new file mode 100644 (file)
index 0000000..aece09e
--- /dev/null
@@ -0,0 +1,43 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: my-nginx
+  labels:
+    app: nginx
+spec:
+  type: NodePort
+  ports:
+  - port: 443
+    name: https
+  selector:
+    app: nginx
+---
+apiVersion: v1
+kind: ReplicationController
+metadata:
+  name: my-nginx
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: nginx
+    spec:
+      volumes:
+      - name: secret-volume
+        secret:
+          secretName: nginxsecret
+      - name: configmap-volume
+        configMap:
+          name: nginxconfigmap
+      containers:
+      - name: nginxhttps
+        image: ymqytw/nginxhttps:1.5
+        command: ["/home/auto-reload-nginx.sh"]
+        ports:
+        - containerPort: 443
+        volumeMounts:
+        - mountPath: /etc/nginx/ssl
+          name: secret-volume
+        - mountPath: /etc/nginx/conf.d
+          name: configmap-volume
diff --git a/mash/eks/samples/kubernetes-blog/bookinfo-ratings.yaml b/mash/eks/samples/kubernetes-blog/bookinfo-ratings.yaml
new file mode 100644 (file)
index 0000000..f02b76f
--- /dev/null
@@ -0,0 +1,49 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Ratings service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: ratings
+  labels:
+    app: ratings
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: ratings
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: ratings-v1
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        app: ratings
+        version: v1
+    spec:
+      containers:
+      - name: ratings
+        image: docker.io/istio/examples-bookinfo-ratings-v1:0.2.3
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/kubernetes-blog/bookinfo-reviews-v2.yaml b/mash/eks/samples/kubernetes-blog/bookinfo-reviews-v2.yaml
new file mode 100644 (file)
index 0000000..aec51d5
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Reviews service v2
+##################################################################################################
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: reviews-v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: reviews
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: reviews
+        version: v2
+    spec:
+      containers:
+      - name: reviews
+        image: docker.io/istio/examples-bookinfo-reviews-v2:0.2.3
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/kubernetes-blog/bookinfo-v1.yaml b/mash/eks/samples/kubernetes-blog/bookinfo-v1.yaml
new file mode 100644 (file)
index 0000000..4e4e1cd
--- /dev/null
@@ -0,0 +1,131 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Details service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: details
+  labels:
+    app: details
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: details
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: details-v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: details
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: details
+        version: v1
+    spec:
+      containers:
+      - name: details
+        image: istio/examples-bookinfo-details-v1:0.2.3
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
+##################################################################################################
+# Reviews service
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: reviews
+  labels:
+    app: reviews
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: reviews
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: reviews-v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: reviews
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: reviews
+        version: v1
+    spec:
+      containers:
+      - name: reviews
+        image: docker.io/istio/examples-bookinfo-reviews-v1:0.2.3
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
+##################################################################################################
+# Productpage services
+##################################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: productpage
+  labels:
+    app: productpage
+spec:
+  ports:
+  - port: 9080
+    name: http
+  selector:
+    app: productpage
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: productpage-v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: productpage
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: productpage
+        version: v1
+    spec:
+      containers:
+      - name: productpage
+        image: docker.io/istio/examples-bookinfo-productpage-v1:0.2.3
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 9080
+---
diff --git a/mash/eks/samples/operator/cni-on.yaml b/mash/eks/samples/operator/cni-on.yaml
new file mode 100644 (file)
index 0000000..ae850b4
--- /dev/null
@@ -0,0 +1,6 @@
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+spec:
+  components:
+    cni:
+      enabled: true
diff --git a/mash/eks/samples/operator/default-install.yaml b/mash/eks/samples/operator/default-install.yaml
new file mode 100644 (file)
index 0000000..65a4d9b
--- /dev/null
@@ -0,0 +1,8 @@
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+metadata:
+  namespace: istio-system
+  name: istio-operator
+spec:
+  profile: default
+
diff --git a/mash/eks/samples/operator/pilot-advanced-override.yaml b/mash/eks/samples/operator/pilot-advanced-override.yaml
new file mode 100644 (file)
index 0000000..4b57fd8
--- /dev/null
@@ -0,0 +1,19 @@
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+spec:
+  components:
+    pilot:
+      k8s:
+        overlays:
+        - kind: Deployment
+          name: istiod
+          patches:
+          - path: spec.template.spec.containers.[name:discovery].args.[30m]
+            value: "60m" # OVERRIDDEN
+          - path: spec.template.spec.containers.[name:discovery].ports.[containerPort:8080].containerPort
+            value: 8090 # OVERRIDDEN
+        - kind: Service
+          name: istiod
+          patches:
+          - path: spec.ports.[name:grpc-xds].port
+            value: 15099 # OVERRIDDEN
diff --git a/mash/eks/samples/operator/pilot-k8s.yaml b/mash/eks/samples/operator/pilot-k8s.yaml
new file mode 100644 (file)
index 0000000..e96e839
--- /dev/null
@@ -0,0 +1,21 @@
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+spec:
+  components:
+    pilot:
+      k8s:
+        resources:
+          requests:
+            cpu: 1000m # override from default 500m
+            memory: 4096Mi # ... default 2048Mi
+        hpaSpec:
+          maxReplicas: 10 # ... default 5
+          minReplicas: 2  # ... default 1
+        nodeSelector:
+          master: "true"
+        tolerations:
+        - key: dedicated
+          operator: Exists
+          effect: NoSchedule
+        - key: CriticalAddonsOnly
+          operator: Exists
diff --git a/mash/eks/samples/operator/values-global.yaml b/mash/eks/samples/operator/values-global.yaml
new file mode 100644 (file)
index 0000000..8726f27
--- /dev/null
@@ -0,0 +1,7 @@
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+spec:
+  values:
+    global:
+      logging:
+        level: "default:warning" # override from info
diff --git a/mash/eks/samples/operator/values-pilot.yaml b/mash/eks/samples/operator/values-pilot.yaml
new file mode 100644 (file)
index 0000000..bca6c2e
--- /dev/null
@@ -0,0 +1,6 @@
+apiVersion: install.istio.io/v1alpha1
+kind: IstioOperator
+spec:
+  values:
+    pilot:
+      traceSampling: 0.1 # override from 1.0
diff --git a/mash/eks/samples/rawvm/Makefile b/mash/eks/samples/rawvm/Makefile
new file mode 100644 (file)
index 0000000..4cc8cbc
--- /dev/null
@@ -0,0 +1,36 @@
+
+FORTIO_IMAGE:='fortio/fortio:latest'
+VERBOSITY:=2
+NAMESPACE:=fortio
+
+YAMLS:=k8services-istio.yaml k8services.yaml k8cli.yaml
+# Was needed when images were missing (#553)
+#PATCH_HUB:='| sed -e "s!docker.io/istio!gcr.io/istio-io!g"'
+
+deploy: k8services-istio client
+
+client: k8cli.yaml
+       kubectl apply -n $(NAMESPACE) -f $<
+
+k8services-istio: k8services-istio.yaml
+       kubectl apply -n $(NAMESPACE) -f $<
+
+k8services-istio.yaml: k8services.yaml
+       istioctl kube-inject -n $(NAMESPACE) --hub $(PILOT_HUB) --tag $(PILOT_TAG) --verbosity $(VERBOSITY) -f $< $(PATCH_HUB) > $@
+
+k8services: k8services.yaml
+       kubectl apply -n $(NAMESPACE) -f $<
+
+%.yaml: %.yaml.in
+       sed -e "s!FORTIO_IMAGE!$(FORTIO_IMAGE)!g" < $< > $@
+
+dump-images:
+       kubectl get pods --all-namespaces -o jsonpath="{..image}" | \
+               tr -s '[[:space:]]' '\n' | sort | uniq -c
+
+clean:
+       -kubectl delete -n $(NAMESPACE) -f k8services-istio.yaml
+       -kubectl delete -n $(NAMESPACE) -f k8services.yaml
+       $(RM) $(YAMLS)
+
+.PHONY: clean k8services k8services-istio dump-images client deploy
diff --git a/mash/eks/samples/rawvm/README.md b/mash/eks/samples/rawvm/README.md
new file mode 100644 (file)
index 0000000..208af23
--- /dev/null
@@ -0,0 +1,167 @@
+# RawVM in Istio 0.2 demo notes
+
+## MySQL Installation
+
+### Official oracle version
+
+```shell
+wget https://dev.mysql.com/get/mysql-apt-config_0.8.7-1_all.deb
+sudo dpkg -i mysql-apt-config_0.8.7-1_all.deb
+# Select server 5.7 (default), tools and previews not needed/disabled
+sudo apt-get update
+sudo apt-get install mysql-server
+# Clearly this is insecure, don't do that for prod !
+sudo mysql
+   ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
+   # Remote 'root' can read test.*, to avoid
+   # ERROR 1130 (HY000): Host '...' is not allowed to connect to this MySQL server
+   create user 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
+   GRANT SELECT ON test.* TO 'root'@'%';
+# Create tables :
+mysql -u root -h 127.0.0.1 --password=password < ~/github/istio/samples/bookinfo/src/mysql/mysqldb-init.sql
+# And to be able to connect remotely (only needed to test before injection)
+sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
+# comment out:
+#bind-address   = 127.0.0.1
+sudo service mysql restart
+# check it's now binding on *
+$ sudo lsof -i :3306
+COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
+mysqld  29145 mysql   31u  IPv6 168376      0t0  TCP *:mysql (LISTEN)
+# from another host, verify it works:
+ldemailly@benchmark-2:~$ mysql -u root -h instance-1 --password=password test -e "select * from ratings"
+mysql: [Warning] Using a password on the command line interface can be insecure.
++----------+--------+
+| ReviewID | Rating |
++----------+--------+
+|        1 |      5 |
+|        2 |      6 |
++----------+--------+
+# for low volume troubleshooting:
+mysql -u root -h instance-1 --password=password
+  SET global general_log_file='/tmp/mysqlquery.log';
+  SET global general_log = 1;
+# then
+tail -f /tmp/mysqlquery.log
+```
+
+### Or
+
+sudo apt-get mariadb-server
+
+TODO: figure out equivalent of above for mariadb
+
+<https://stackoverflow.com/questions/28068155/access-denied-for-user-rootlocalhost-using-password-yes-after-new-instal>
+
+## Sidecar
+
+See <https://github.com/istio/proxy/tree/master/tools/deb>
+
+## Bookinfo with MySql in k8s
+
+You need 5 nodes in your cluster to add mysql (until we tune the requests)
+
+```bash
+# source istio.VERSION
+wget https://storage.googleapis.com/istio-artifacts/pilot/$PILOT_TAG/artifacts/istioctl/istioctl-osx
+chmod 755 istioctl-osx
+./istioctl-osx kube-inject --hub $PILOT_HUB --tag $PILOT_TAG -f samples/bookinfo/kube/bookinfo.yaml > bookinfo-istio.yaml
+kubectl apply -f bookinfo-istio.yaml
+./istioctl-osx kube-inject --hub $PILOT_HUB --tag $PILOT_TAG -f samples/bookinfo/kube/bookinfo-mysql.yaml > bookinfo-mysql-istio.yaml
+kubectl apply -f bookinfo-mysql-istio.yaml
+./istioctl-osx kube-inject --hub $PILOT_HUB --tag $PILOT_TAG -f samples/bookinfo/kube/bookinfo-ratings-v2.yaml > bookinfo-ratings-v2-istio.yaml
+kubectl apply -f bookinfo-ratings-v2-istio.yaml
+# use it (ratings v2 and mysql)
+kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-mysql.yaml
+# wait a bit / reload product page
+# see mysql in grafana and 5,6 stars
+kubectl port-forward mysqldb-v1-325529163-9x1r0 3306:3306 # use actual mysql pod
+mysql -u root -h 127.0.0.1 --password=password test
+  select * from ratings;
+  update ratings set rating=3 where reviewid=1;
+# see first rating change to 3 stars
+
+# for metrics:
+fortio load -t 1m http://$INGRESS_IP/productpage
+```
+
+## Move MySQL to VM
+
+1. remove the k8s based service
+
+    ```bash
+    kubectl delete svc mysqldb
+    ```
+
+1. observe `product ratings not available` when re-loading the page
+
+1. register the VM instead:
+
+    ```bash
+    ./istioctl-osx register mysqldb 10.138.0.13 3306
+    I0904 11:12:56.785430   34562 register.go:44] Registering for service 'mysqldb' ip '10.138.0.13', ports list [{3306 mysql}]
+    I0904 11:12:56.785536   34562 register.go:49] 0 labels ([]) and 1 annotations ([alpha.istio.io/kubernetes-serviceaccounts=default])
+    W0904 11:12:56.887017   34562 register.go:123] Got 'services "mysqldb" not found' looking up svc 'mysqldb' in namespace 'default', attempting to create it
+    W0904 11:12:56.938721   34562 register.go:139] Got 'endpoints "mysqldb" not found' looking up endpoints for 'mysqldb' in namespace 'default', attempting to create them
+    I0904 11:12:57.055643   34562 register.go:180] No pre existing exact matching ports list found, created new subset {[{10.138.0.13  <nil> nil}] [] [{mysql 3306 }]}
+    I0904 11:12:57.090739   34562 register.go:191] Successfully updated mysqldb, now with 1 endpoints
+    ```
+
+1. check the registration:
+
+    ```
+    kubectl get svc mysqldb -o yaml
+    apiVersion: v1
+    kind: Service
+    metadata:
+      annotations:
+        alpha.istio.io/kubernetes-serviceaccounts: default
+      creationTimestamp: 2017-09-04T18:12:56Z
+      name: mysqldb
+      namespace: default
+      resourceVersion: "464459"
+      selfLink: /api/v1/namespaces/default/services/mysqldb
+      uid: ad746e4c-919c-11e7-9a62-42010a8a004e
+    spec:
+      clusterIP: 10.31.253.143
+      ports:
+      - name: mysql
+        port: 3306
+        protocol: TCP
+        targetPort: 3306
+      sessionAffinity: None
+      type: ClusterIP
+    status:
+      loadBalancer: {}
+    ```
+
+## Build debian packages
+
+Prereq:
+
+ps: for docker - remember to "docker ps" and it should work/not error out and not require sudo, if it doesn't work add your username to /etc/group docker
+
+For gcloud (<https://cloud.google.com/sdk/docs/quickstart-debian-ubuntu>):
+
+```shell
+export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
+echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
+curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
+sudo apt-get update && sudo apt-get install google-cloud-sdk
+gcloud init
+sudo apt-get install kubectl
+gcloud container clusters get-credentials demo-1 --zone us-west1-b --project istio-demo-0-2
+```
+
+Note to install rbac yaml you need:
+
+```bash
+kubectl create clusterrolebinding my-admin-access --clusterrole cluster-admin --user USERNAME
+```
+
+Then:
+
+```bash
+git clone https://github.com/istio/proxy.git -b rawvm-demo-0-2-2
+tools/deb/test/build_all.sh
+```
diff --git a/mash/eks/samples/security/psp/sidecar-psp.yaml b/mash/eks/samples/security/psp/sidecar-psp.yaml
new file mode 100644 (file)
index 0000000..f9612d6
--- /dev/null
@@ -0,0 +1,46 @@
+apiVersion: policy/v1beta1
+kind: PodSecurityPolicy
+metadata:
+  name: istio-sidecar
+spec:
+  # Allow the istio sidecar injector to work
+  allowedCapabilities:
+    - NET_ADMIN
+    - NET_RAW
+  seLinux:
+    rule: RunAsAny
+  supplementalGroups:
+    rule: RunAsAny
+  runAsUser:
+    rule: RunAsAny
+  fsGroup:
+    rule: RunAsAny
+  volumes:
+    - '*'
+---
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: istio-sidecar-psp
+rules:
+  - apiGroups:
+      - extensions
+    resources:
+      - podsecuritypolicies
+    resourceNames:
+      - istio-sidecar
+    verbs:
+      - use
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: istio-sidecar-psp
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: istio-sidecar-psp
+subjects:
+  - apiGroup: rbac.authorization.k8s.io
+    kind: Group
+    name: system:serviceaccounts
diff --git a/mash/eks/samples/sleep/README.md b/mash/eks/samples/sleep/README.md
new file mode 100644 (file)
index 0000000..3fe8215
--- /dev/null
@@ -0,0 +1,37 @@
+# Simple sleep service
+
+This sample consists of a simple service that does nothing but sleep.
+It's a ubuntu container with curl installed that can be used as a request source for invoking other services
+to experiment with Istio networking.
+
+To use it:
+
+1. Install Istio by following the [istio install instructions](https://istio.io/docs/setup/).
+
+1. Start the sleep service:
+
+    If you have [automatic sidecar injection](https://istio.io/docs/setup/additional-setup/sidecar-injection/#automatic-sidecar-injection) enabled:
+
+    ```bash
+    kubectl apply -f sleep.yaml
+    ```
+
+    Otherwise manually inject the sidecars before applying:
+
+    ```bash
+    kubectl apply -f <(istioctl kube-inject -f sleep.yaml)
+    ```
+
+1. Start some other services, for example, the [Bookinfo sample](https://istio.io/docs/examples/bookinfo/).
+
+    Now you can `kubectl exec` into the sleep service to experiment with Istio networking.
+    For example, the following commands can be used to call the Bookinfo `ratings` service:
+
+    ```bash
+    export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
+    kubectl exec -it $SLEEP_POD -c sleep curl http://ratings.default.svc.cluster.local:9080/ratings/1
+    {"id":1,"ratings":{"Reviewer1":5,"Reviewer2":4}}
+    ```
+
+You can also use the sleep service to test accessing services outside of the mesh.
+See [configuring egress](https://istio.io/docs/tasks/traffic-management/egress/) for details.
diff --git a/mash/eks/samples/sleep/policy/sni-serviceaccount.yaml b/mash/eks/samples/sleep/policy/sni-serviceaccount.yaml
new file mode 100644 (file)
index 0000000..7e77f49
--- /dev/null
@@ -0,0 +1,55 @@
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requested-server-name
+  namespace: istio-system
+spec:
+  compiledTemplate: listentry
+  params:
+    value: connection.requested_server_name
+---
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: us-wikipedia-checker
+  namespace: istio-system
+spec:
+  compiledAdapter: listchecker
+  params:
+    overrides: ["en.wikipedia.org", "es.wikipedia.org"]
+    blacklist: false
+---
+# Rule to check access to *.wikipedia.org
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: check-us-wikipedia-access
+  namespace: istio-system
+spec:
+  match: source.labels["app"] == "istio-egressgateway-with-sni-proxy" && destination.labels["app"] == "" && source.principal == "cluster.local/ns/default/sa/sleep-us"
+  actions:
+  - handler: us-wikipedia-checker
+    instances: [ requested-server-name ]
+---
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: canada-wikipedia-checker
+  namespace: istio-system
+spec:
+  compiledAdapter: listchecker
+  params:
+    overrides: ["en.wikipedia.org", "fr.wikipedia.org"]
+    blacklist: false
+---
+# Rule to check access to *.wikipedia.org
+apiVersion: "config.istio.io/v1alpha2"
+kind: rule
+metadata:
+  name: check-canada-wikipedia-access
+  namespace: istio-system
+spec:
+  match: source.labels["app"] == "istio-egressgateway-with-sni-proxy" && destination.labels["app"] == "" && source.principal == "cluster.local/ns/default/sa/sleep-canada"
+  actions:
+  - handler: canada-wikipedia-checker
+    instances: [ requested-server-name ]
diff --git a/mash/eks/samples/sleep/policy/sni-wikipedia.yaml b/mash/eks/samples/sleep/policy/sni-wikipedia.yaml
new file mode 100644 (file)
index 0000000..43fe491
--- /dev/null
@@ -0,0 +1,32 @@
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: wikipedia-checker
+  namespace: istio-system
+spec:
+  compiledAdapter: listchecker
+  params:
+    overrides: ["en.wikipedia.org"]  # overrides provide a static list
+    blacklist: true
+---
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: requested-server-name
+  namespace: istio-system
+spec:
+  compiledTemplate: listentry
+  params:
+    value: connection.requested_server_name
+---
+# Rule to check access to *.wikipedia.org
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: check-wikipedia-access
+  namespace: istio-system
+spec:
+  match: source.labels["app"] == "istio-egressgateway-with-sni-proxy" && destination.labels["app"] == ""
+  actions:
+  - handler: wikipedia-checker
+    instances: [ requested-server-name ]
diff --git a/mash/eks/samples/sleep/sleep-vault.yaml b/mash/eks/samples/sleep/sleep-vault.yaml
new file mode 100644 (file)
index 0000000..b82fb14
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright 2019 Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Sleep service
+##################################################################################################
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: sleep
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: sleep
+  labels:
+    app: sleep
+spec:
+  ports:
+  - port: 80
+    name: http
+  selector:
+    app: sleep
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: sleep
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: sleep
+  template:
+    metadata:
+      labels:
+        app: sleep
+    spec:
+      serviceAccountName: vault-citadel-sa
+      containers:
+      - name: sleep
+        image: pstauffer/curl
+        command: ["/bin/sleep", "3650d"]
+        imagePullPolicy: IfNotPresent
+---
diff --git a/mash/eks/samples/sleep/sleep.yaml b/mash/eks/samples/sleep/sleep.yaml
new file mode 100644 (file)
index 0000000..1df565a
--- /dev/null
@@ -0,0 +1,64 @@
+# Copyright Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+##################################################################################################
+# Sleep service
+##################################################################################################
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: sleep
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: sleep
+  labels:
+    app: sleep
+spec:
+  ports:
+  - port: 80
+    name: http
+  selector:
+    app: sleep
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: sleep
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: sleep
+  template:
+    metadata:
+      labels:
+        app: sleep
+    spec:
+      serviceAccountName: sleep
+      containers:
+      - name: sleep
+        image: governmentpaas/curl-ssl
+        command: ["/bin/sleep", "3650d"]
+        imagePullPolicy: IfNotPresent
+        volumeMounts:
+        - mountPath: /etc/sleep/tls
+          name: secret-volume
+      volumes:
+      - name: secret-volume
+        secret:
+          secretName: sleep-secret
+          optional: true
+---
diff --git a/mash/eks/samples/sleep/telemetry/sni-logging.yaml b/mash/eks/samples/sleep/telemetry/sni-logging.yaml
new file mode 100644 (file)
index 0000000..cf1c89a
--- /dev/null
@@ -0,0 +1,45 @@
+# Log entry for egress access
+apiVersion: config.istio.io/v1alpha2
+kind: instance
+metadata:
+  name: egress-access
+  namespace: istio-system
+spec:
+  compiledTemplate: logentry
+  params:
+    severity: '"info"'
+    timestamp: context.time | timestamp("2017-01-01T00:00:00Z")
+    variables:
+      connectionEvent: connection.event | ""
+      source: source.labels["app"] | "unknown"
+      sourceNamespace: source.namespace | "unknown"
+      sourceWorkload: source.workload.name | ""
+      sourcePrincipal: source.principal | "unknown"
+      requestedServerName: connection.requested_server_name | "unknown"
+      destinationApp: destination.labels["app"] | ""
+    monitored_resource_type: '"UNSPECIFIED"'
+---
+# Handler for info egress access entries
+apiVersion: config.istio.io/v1alpha2
+kind: handler
+metadata:
+  name: egress-access-logger
+  namespace: istio-system
+spec:
+  compiledAdapter: stdio
+  params:
+    severity_levels:
+      info: 0 # output log level as info
+    outputAsJson: true
+---
+# Rule to handle access to *.wikipedia.org
+apiVersion: config.istio.io/v1alpha2
+kind: rule
+metadata:
+  name: handle-wikipedia-access
+  namespace: istio-system
+spec:
+  match: source.labels["app"] == "istio-egressgateway-with-sni-proxy" && destination.labels["app"] == "" && connection.event == "open"
+  actions:
+  - handler: egress-access-logger
+    instances: [ egress-access ]
diff --git a/mash/eks/samples/tcp-echo/README.md b/mash/eks/samples/tcp-echo/README.md
new file mode 100644 (file)
index 0000000..5705658
--- /dev/null
@@ -0,0 +1,38 @@
+# TCP Echo Service
+
+This sample runs [TCP Echo Server](src/) as an Istio service. TCP Echo Server
+allows you to connect to it over TCP and echoes back data sent to it along with
+a preconfigured prefix.
+
+## Usage
+
+To run the TCP Echo Service sample:
+
+1. Install Istio by following the [istio install instructions](https://istio.io/docs/setup/kubernetes/quick-start.html).
+
+1. Start the `tcp-echo-server` service inside the Istio service mesh:
+
+    ```console
+    $ kubectl apply -f <(istioctl kube-inject -f tcp-echo.yaml)
+    service/tcp-echo created
+    deployment.extensions/tcp-echo created
+    ```
+
+1. Test by running the `nc` command from a `busybox` container from within the cluster.
+
+    ```console
+    $ kubectl run -i --rm --restart=Never dummy --image=busybox -- sh -c "echo world | nc tcp-echo 9000"
+    hello world
+    pod "dummy" deleted
+    ```
+
+    As you observe, sending _world_ on a TCP connection to the server results in
+    the server prepending _hello_ and echoing back with _hello world_.
+
+1. To clean up, execute the following command:
+
+    ```console
+    $ kubectl delete -f tcp-echo.yaml
+    service "tcp-echo" deleted
+    deployment.extensions "tcp-echo" deleted
+    ```
diff --git a/mash/eks/samples/tcp-echo/tcp-echo-20-v2.yaml b/mash/eks/samples/tcp-echo/tcp-echo-20-v2.yaml
new file mode 100644 (file)
index 0000000..f69ab11
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright 2018 Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: tcp-echo
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - tcp-echo-gateway
+  tcp:
+  - match:
+    - port: 31400
+    route:
+    - destination:
+        host: tcp-echo
+        port:
+          number: 9000
+        subset: v1
+      weight: 80
+    - destination:
+        host: tcp-echo
+        port:
+          number: 9000
+        subset: v2
+      weight: 20
diff --git a/mash/eks/samples/tcp-echo/tcp-echo-all-v1.yaml b/mash/eks/samples/tcp-echo/tcp-echo-all-v1.yaml
new file mode 100644 (file)
index 0000000..3c302c5
--- /dev/null
@@ -0,0 +1,61 @@
+# Copyright 2018 Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: tcp-echo-gateway
+spec:
+  selector:
+    istio: ingressgateway
+  servers:
+  - port:
+      number: 31400
+      name: tcp
+      protocol: TCP
+    hosts:
+    - "*"
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: DestinationRule
+metadata:
+  name: tcp-echo-destination
+spec:
+  host: tcp-echo
+  subsets:
+  - name: v1
+    labels:
+      version: v1
+  - name: v2
+    labels:
+      version: v2
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: tcp-echo
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - tcp-echo-gateway
+  tcp:
+  - match:
+    - port: 31400
+    route:
+    - destination:
+        host: tcp-echo
+        port:
+          number: 9000
+        subset: v1
diff --git a/mash/eks/samples/tcp-echo/tcp-echo-services.yaml b/mash/eks/samples/tcp-echo/tcp-echo-services.yaml
new file mode 100644 (file)
index 0000000..6316809
--- /dev/null
@@ -0,0 +1,79 @@
+# Copyright 2018 Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: tcp-echo
+  labels:
+    app: tcp-echo
+spec:
+  ports:
+  - name: tcp
+    port: 9000
+  - name: tcp-other
+    port: 9001
+  # Port 9002 is omitted intentionally for testing the pass through filter chain.
+  selector:
+    app: tcp-echo
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: tcp-echo-v1
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: tcp-echo
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: tcp-echo
+        version: v1
+    spec:
+      containers:
+      - name: tcp-echo
+        image: docker.io/istio/tcp-echo-server:1.2
+        imagePullPolicy: IfNotPresent
+        args: [ "9000,9001,9002", "one" ]
+        ports:
+        - containerPort: 9000
+        - containerPort: 9001
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: tcp-echo-v2
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: tcp-echo
+      version: v2
+  template:
+    metadata:
+      labels:
+        app: tcp-echo
+        version: v2
+    spec:
+      containers:
+      - name: tcp-echo
+        image: docker.io/istio/tcp-echo-server:1.2
+        imagePullPolicy: IfNotPresent
+        args: [ "9000,9001,9002", "two" ]
+        ports:
+        - containerPort: 9000
+        - containerPort: 9001
diff --git a/mash/eks/samples/tcp-echo/tcp-echo.yaml b/mash/eks/samples/tcp-echo/tcp-echo.yaml
new file mode 100644 (file)
index 0000000..fc0e8ca
--- /dev/null
@@ -0,0 +1,57 @@
+# Copyright 2018 Istio Authors
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+################################################################################
+# tcp-echo service
+################################################################################
+apiVersion: v1
+kind: Service
+metadata:
+  name: tcp-echo
+  labels:
+    app: tcp-echo
+spec:
+  ports:
+  - name: tcp
+    port: 9000
+  - name: tcp-other
+    port: 9001
+  # Port 9002 is omitted intentionally for testing the pass through filter chain.
+  selector:
+    app: tcp-echo
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: tcp-echo
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: tcp-echo
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: tcp-echo
+        version: v1
+    spec:
+      containers:
+      - name: tcp-echo
+        image: docker.io/istio/tcp-echo-server:1.2
+        imagePullPolicy: IfNotPresent
+        args: [ "9000,9001,9002", "hello" ]
+        ports:
+        - containerPort: 9000
+        - containerPort: 9001
diff --git a/mash/eks/samples/websockets/README.md b/mash/eks/samples/websockets/README.md
new file mode 100644 (file)
index 0000000..26a1f38
--- /dev/null
@@ -0,0 +1,48 @@
+# Tornado - Demo Websockets App
+
+This is a sample application that demonstrates the use of an upgraded websockets connection on an ingress traffic when using Istio `VirtualService`.
+The `app.yaml` creates a Kubernetes `Service` and a `Deployment` that is based on an existing Docker image for [Hiroakis's Tornado Websocket Example](https://github.com/hiroakis/tornado-websocket-example).
+
+__Notice:__ The addition of websockets upgrade support in v1alpha3 routing rules has only been added after the release of `Istio v0.8.0`.
+
+## Prerequisites
+
+Install Istio by following the [Istio Quick Start](https://istio.io/docs/setup/kubernetes/quick-start.html).
+
+## Installation
+
+1. First install the application service:
+
+    - With manual sidecar injection:
+
+    ```command
+    kubectl create -f <(istioctl kube-inject -f samples/websockets/app.yaml)
+    ```
+
+    - With automatic sidecar injection
+
+    ```command
+    kubectl create -f samples/websockets/app.yaml
+    ```
+
+1. Create the Ingress `Gateway` and `VirtualService` that enables the upgrade to Websocket for incoming traffic:
+
+    ```command
+    kubectl create -f samples/websockets/route.yaml
+    ```
+
+## Test
+
+- [Find your ingress gateway IP](https://istio.io/docs/tasks/traffic-management/ingress/#determining-the-ingress-ip-and-ports)
+
+- Access <http://$GATEWAY_IP/> with your browser
+
+- The `WebSocket status` should show a green `open` status which means  that a websocket connection to the server has been established.
+To see the websocket in action see the instructions in the _REST API examples_ section of the demo app webpage for updating the server-side data and getting the updated data through the open websocket to the table in the webpage (without refreshing).
+
+## Cleanup
+
+```command
+kubectl delete -f samples/websockets/route.yaml
+kubectl delete -f samples/websockets/app.yaml
+```
diff --git a/mash/eks/samples/websockets/app.yaml b/mash/eks/samples/websockets/app.yaml
new file mode 100644 (file)
index 0000000..f307f64
--- /dev/null
@@ -0,0 +1,36 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: tornado
+  labels:
+    app: tornado
+spec:
+  ports:
+  - port: 8888
+    name: http
+  selector:
+    app: tornado
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: tornado
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: tornado
+      version: v1
+  template:
+    metadata:
+      labels:
+        app: tornado
+        version: v1
+    spec:
+      containers:
+      - name: tornado
+        image: hiroakis/tornado-websocket-example
+        imagePullPolicy: IfNotPresent
+        ports:
+        - containerPort: 8888
+---
diff --git a/mash/eks/samples/websockets/route.yaml b/mash/eks/samples/websockets/route.yaml
new file mode 100644 (file)
index 0000000..ef580b2
--- /dev/null
@@ -0,0 +1,32 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: Gateway
+metadata:
+  name: tornado-gateway
+spec:
+  selector:
+    istio: ingressgateway
+  servers:
+  - port:
+      number: 80
+      name: http
+      protocol: HTTP
+    hosts:
+    - "*"
+---
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: tornado
+spec:
+  hosts:
+  - "*"
+  gateways:
+  - tornado-gateway
+  http:
+  - match:
+    - uri:
+        prefix: /
+    route:
+    - destination:
+        host: tornado
+      weight: 100