From 4e0f4ba05d2374c35376eea062bc4173d9ae8aaa Mon Sep 17 00:00:00 2001
From: savagebidoof <filter.oriol@gmail.com>
Date: Fri, 5 May 2023 01:41:42 +0200
Subject: [PATCH] 03-HTTPRewrite documented

---
 .../{deployment.yaml => Deployment.yaml}      |  15 -
 .../03-HTTPRewrite/README.md                  | 260 +++++++++++++++++-
 .../03-HTTPRewrite/Service.yaml               |  13 +
 .../03-HTTPRewrite/VirtualService.yaml        |  26 ++
 .../03-HTTPRewrite/gateway.yaml               |  22 --
 5 files changed, 297 insertions(+), 39 deletions(-)
 rename 02-Traffic_management/03-HTTPRewrite/{deployment.yaml => Deployment.yaml} (63%)
 create mode 100644 02-Traffic_management/03-HTTPRewrite/Service.yaml
 create mode 100644 02-Traffic_management/03-HTTPRewrite/VirtualService.yaml

diff --git a/02-Traffic_management/03-HTTPRewrite/deployment.yaml b/02-Traffic_management/03-HTTPRewrite/Deployment.yaml
similarity index 63%
rename from 02-Traffic_management/03-HTTPRewrite/deployment.yaml
rename to 02-Traffic_management/03-HTTPRewrite/Deployment.yaml
index 01dd2b0..233fd2c 100755
--- a/02-Traffic_management/03-HTTPRewrite/deployment.yaml
+++ b/02-Traffic_management/03-HTTPRewrite/Deployment.yaml
@@ -1,18 +1,3 @@
-# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld.yaml
-apiVersion: v1
-kind: Service
-metadata:
-  name: helloworld
-  labels:
-    app: helloworld
-    service: helloworld
-spec:
-  ports:
-    - port: 80
-      name: http
-  selector:
-    app: helloworld
----
 apiVersion: apps/v1
 kind: Deployment
 metadata:
diff --git a/02-Traffic_management/03-HTTPRewrite/README.md b/02-Traffic_management/03-HTTPRewrite/README.md
index 0204f98..edcfc2f 100755
--- a/02-Traffic_management/03-HTTPRewrite/README.md
+++ b/02-Traffic_management/03-HTTPRewrite/README.md
@@ -1,8 +1,260 @@
+---
+gitea: none
+include_toc: true
+---
+
+# Description
+
+Based on the [previous example](../../01-Getting_Started/01-hello_world_1_service_1_deployment), we configure the [VirtualService](#virtualservice) to internally rewrite the destination URL.
+
+This is useful, as if for example we have a rule that targets the traffic with destination path `/helloworld`, when we connect to the backend, the path that the request contains will also be `/helloworld`, and unless the destination service is already build around this and/or is ready to manage traffic with such destination, we will receive a status code 404 meaning that the page destination was not found.
+
+If we internally rewrite such traffic to the root directory (`/`), we can interact with the root path from the destination service without issues, without the need of specifically altering the behavior of the destination service due this architectural requirement.
+
+Additionally, we also configure a second rule that won't have the URL path rewrite configured, as it will allow us to compare the behaviors.  
+
+This example configures:
+
+    Generic Kubernetes resources:
+    - 1 Service
+    - 1 Deployments
+    
+    Istio resources:
+    - 1 Gateway
+    - 1 Virtual Service
+
+
+# Based on
+
+- [01-hello_world_1_service_1_deployment](../../01-Getting_Started/01-hello_world_1_service_1_deployment)
+
+# Configuration
+
+## Service
+
+Creates a service named `helloworld`.
+
+This service listens for the port `80` expecting `HTTP` traffic and will forward the incoming traffic towards the port `80` from the destination pod.
+
+```yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: helloworld
+  labels:
+    app: helloworld
+    service: helloworld
+spec:
+  ports:
+    - port: 80
+      name: http
+  selector:
+    app: helloworld
+```
+
+## Deployment
+
+Deploys a Nginx server that listens for the port `80`.
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: helloworld-nginx
+  labels:
+    app: helloworld
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: helloworld
+  template:
+    metadata:
+      labels:
+        app: helloworld
+    spec:
+      containers:
+        - name: helloworld
+          image: nginx
+          resources:
+            requests:
+              cpu: "100m"
+          imagePullPolicy: IfNotPresent #Always
+          ports:
+            - containerPort: 80
+```
+
+## Gateway
+
+Deploys an Istio gateway that's listening to the port `80` for `HTTP` traffic.
+
+It doesn't filter for any specific host.
+
+The `selector` field is used to "choose" which Istio Load Balancers will have this gateway assigned to.
+
+The Istio `default` profile creates a Load Balancer in the namespace `istio-system` that has the label `istio: ingressgateway` set, allowing us to target that specific Load Balancer and assign this gateway resource to it.
+
+```yaml
+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:
+        - "*"
+```
+
+## VirtualService
+
+The configuration set, targets the [gateway created](#gateway) as well of not limiting the traffic to any specific host.
+
+We configure 2 HTTP rules.
+
+The first rule will match when the requested path is `/helloworld`.
+
+Internally, we will rewrite the URL path, from `/helloworld` to `/`, as otherwise it will result in status code 404 due not containing such destination in the service, since we are using the default Nginx image.
+
+The second rule will math with the path `/norewrite`, and won't have the rewrite URL path setting configured. This rule will be used to compare behaviors.
+
+
+Both rules will connect with the backend service `helloworld.default.svc.cluster.local` with port `80`.
+
+```yaml
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: helloworld-vs
+spec:
+  hosts:
+    - "*"
+  gateways:
+    - helloworld-gateway
+  http:
+    - match:
+        - uri:
+            exact: /helloworld
+      route:
+        - destination:
+            host: helloworld.default.svc.cluster.local
+            port:
+              number: 80
+    - match:
+        - uri:
+            exact: /norewrite
+      route:
+        - destination:
+            host: helloworld.default.svc.cluster.local
+            port:
+              number: 80
+```
+
+# Walkthrough
+
+## Deploy resources
+
+Deploy the resources.
+
+```shell
+kubectl apply -f ./
+```
+```text 
+deployment.apps/helloworld-nginx created
+service/helloworld created
+virtualservice.networking.istio.io/helloworld-vs created
+gateway.networking.istio.io/helloworld-gateway created
+```
+
+## Wait for the pods to be ready
+
+Wait for the Nginx deployment to be up and ready.
+
+```shell
+kubectl get deployment helloworld-nginx -w
+```
+```text 
+NAME               READY   UP-TO-DATE   AVAILABLE   AGE
+helloworld-nginx   1/1     1            1           2m47s
+```
+
+## Test the service
+
+### Get LB IP
+
+To perform the desired tests, we will need to obtain the IP Istio Load Balancer that we selected in the [Gateway section](#gateway).
+
+On my environment, the IP is the `192.168.1.50`.
+
+```shell
+kubectl get svc -l istio=ingressgateway -A
+```
+```text
+NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                                      AGE
+istio-ingressgateway   LoadBalancer   10.97.47.216   192.168.1.50   15021:31316/TCP,80:32012/TCP,443:32486/TCP   39h
+```
+
+### helloworld
+
+Due to rewriting the URL path internally, we are able to connect to the backend root path (`/`) 
+
+```shell
+curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>" 
+```
+```text
+<h1>Welcome to nginx!</h1>
+```
+
+### norewrite
+
+As expected, due the backend service not having a destination path named `/norewrite`, we receive a status code 404 as well of their pertinent service error page.
+
+```shell
+curl 192.168.1.50/helloworld -s | grep "<h1>.*</h1>" 
+```
+```text
+<center><h1>404 Not Found</h1></center>
+```
+
+## Cleanup
+
+Finally, a cleanup from the resources deployed.
+
+```shell
+kubectl delete -f ./
+```
+```text
+deployment.apps "helloworld-nginx" deleted
+service "helloworld" deleted
+virtualservice.networking.istio.io "helloworld-vs" deleted
+gateway.networking.istio.io "helloworld-gateway" deleted
+```
+
+# Links of interest
+
+- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPDirectResponse
+
+- https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPBody
+
+
+
+
+
+
+
+
+
+
+
+
 
 
-# Continues from
 
-- 01-hello_world_1_service_1_deployment
 
 # There were no changes respective to that version
 
@@ -13,6 +265,10 @@ Through rewriting the URI we can point to the root directory from nginx.
         uri: "/"
 ```
 
+
+
+
+
 ## The idea is that this rewrite is handled "internally" by Istio, not by the Client that started the request
 
 
diff --git a/02-Traffic_management/03-HTTPRewrite/Service.yaml b/02-Traffic_management/03-HTTPRewrite/Service.yaml
new file mode 100644
index 0000000..271ce25
--- /dev/null
+++ b/02-Traffic_management/03-HTTPRewrite/Service.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: helloworld
+  labels:
+    app: helloworld
+    service: helloworld
+spec:
+  ports:
+    - port: 80
+      name: http
+  selector:
+    app: helloworld
\ No newline at end of file
diff --git a/02-Traffic_management/03-HTTPRewrite/VirtualService.yaml b/02-Traffic_management/03-HTTPRewrite/VirtualService.yaml
new file mode 100644
index 0000000..9155ab0
--- /dev/null
+++ b/02-Traffic_management/03-HTTPRewrite/VirtualService.yaml
@@ -0,0 +1,26 @@
+apiVersion: networking.istio.io/v1alpha3
+kind: VirtualService
+metadata:
+  name: helloworld-vs
+spec:
+  hosts:
+    - "*"
+  gateways:
+    - helloworld-gateway
+  http:
+    - match:
+        - uri:
+            exact: /helloworld
+      route:
+        - destination:
+            host: helloworld.default.svc.cluster.local
+            port:
+              number: 80
+    - match:
+        - uri:
+            exact: /norewrite
+      route:
+        - destination:
+            host: helloworld.default.svc.cluster.local
+            port:
+              number: 80
diff --git a/02-Traffic_management/03-HTTPRewrite/gateway.yaml b/02-Traffic_management/03-HTTPRewrite/gateway.yaml
index 838bef9..456e384 100755
--- a/02-Traffic_management/03-HTTPRewrite/gateway.yaml
+++ b/02-Traffic_management/03-HTTPRewrite/gateway.yaml
@@ -1,4 +1,3 @@
-# https://github.com/istio/istio/blob/master/samples/helloworld/helloworld-gateway.yaml
 apiVersion: networking.istio.io/v1alpha3
 kind: Gateway
 metadata:
@@ -13,24 +12,3 @@ spec:
         protocol: HTTP
       hosts:
         - "*"
----
-apiVersion: networking.istio.io/v1alpha3
-kind: VirtualService
-metadata:
-  name: helloworld-vs
-spec:
-  hosts:
-    - "*"
-  gateways:
-    - helloworld-gateway
-  http:
-    - match:
-        - uri:
-            exact: /helloworld
-      route:
-        - destination:
-            host: helloworld.default.svc.cluster.local
-            port:
-              number: 80
-      rewrite:
-        uri: "/"
\ No newline at end of file