From bea548628cb84674e8c6cb090be0c6d448e793b5 Mon Sep 17 00:00:00 2001 From: Mohamed Bana Date: Tue, 6 Dec 2022 14:21:14 +0000 Subject: [PATCH] Mocking from schema Gateway (#1003) Summary ======= `curl -v -H 'Accept: application/json' 192.168.49.2/todos` should work. Changes ======= `examples/mocking/gateway/**` --------------------- Example of Gateway mocking taken from [2] and added a deployment manifest. `skaffold.yaml`, `skaffold.sh`, `Makefile` and `.vscode/launch.json` -------------------------------------------------------------------- Tidy up `skaffold.yaml`, `skaffold.sh` and `Makefile`. Add `.vscode/launch.json` that contains debugger configuration for attaching to the manager from within VS Code. References ========== [1]: https://github.com/kubeshop/kusk-gateway/issues/298. [2]: https://pastebin.com/raw/avYFtZpX. --- Signed-off-by: Mohamed Bana --- .vscode/launch.json | 22 ++++++ Makefile | 42 +++++----- .../gateway/mocking-gateway-api-1.yaml | 77 +++++++++++++++++++ .../mocking-gateway-deployments-1.yaml | 35 +++++++++ internal/controllers/parser.go | 2 +- pkg/spec/spec.go | 29 +++++++ skaffold.sh | 9 ++- skaffold.yaml | 5 +- 8 files changed, 194 insertions(+), 27 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 examples/mocking/gateway/mocking-gateway-api-1.yaml create mode 100644 examples/mocking/gateway/mocking-gateway-deployments-1.yaml diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..2fa13cf81 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Skaffold Debug", + "type": "go", + "request": "attach", + "mode": "remote", + "host": "localhost", + "port": 56268, + "substitutePath": [ + { + "from": "${workspaceFolder}", + "to": "/workspace", + }, + ], + } + ] +} diff --git a/Makefile b/Makefile index e8a6b5017..a48b43baf 100644 --- a/Makefile +++ b/Makefile @@ -82,26 +82,26 @@ tail-envoyfleet: ## Tail logs of envoy .PHONY: enable-logging enable-logging: ## Set some particular logger's level kubectl port-forward --namespace default deployments/default 19000:19000 & echo $$! > /tmp/kube-port-forward-logging.pid - sleep 4 - curl -s -X POST "http://localhost:19000/logging?backtrace=trace" - curl -s -X POST "http://localhost:19000/logging?envoy_bug=trace" - curl -s -X POST "http://localhost:19000/logging?assert=trace" - curl -s -X POST "http://localhost:19000/logging?misc=trace" - curl -s -X POST "http://localhost:19000/logging?secret=trace" - curl -s -X POST "http://localhost:19000/logging?filter=trace" - curl -s -X POST "http://localhost:19000/logging?cache_filter=trace" - curl -s -X POST "http://localhost:19000/logging?ext_authz=trace" - curl -s -X POST "http://localhost:19000/logging?jwt=trace" - curl -s -X POST "http://localhost:19000/logging?oauth2=trace" - curl -s -X POST "http://localhost:19000/logging?connection=trace" - curl -s -X POST "http://localhost:19000/logging?conn_handler=trace" - curl -s -X POST "http://localhost:19000/logging?matcher=trace" - curl -s -X POST "http://localhost:19000/logging?router=trace" - @# curl -s -X POST "http://localhost:19000/logging?grpc=trace" - @# curl -s -X POST "http://localhost:19000/logging?http=trace" - @# curl -s -X POST "http://localhost:19000/logging?http2=trace" - @# curl -s -X POST "http://localhost:19000/logging?upstream=trace" - @# curl -s -X POST "http://localhost:19000/logging?admin=trace" + sleep 2 + curl -s -X POST "http://localhost:19000/logging?backtrace=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?envoy_bug=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?assert=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?misc=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?secret=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?filter=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?cache_filter=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?ext_authz=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?jwt=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?oauth2=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?connection=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?conn_handler=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?matcher=trace" >/dev/null 2>&1 + curl -s -X POST "http://localhost:19000/logging?router=trace" >/dev/null 2>&1 + @# curl -s -X POST "http://localhost:19000/logging?grpc=trace" >/dev/null 2>&1 + @# curl -s -X POST "http://localhost:19000/logging?http=trace" >/dev/null 2>&1 + @# curl -s -X POST "http://localhost:19000/logging?http2=trace" >/dev/null 2>&1 + @# curl -s -X POST "http://localhost:19000/logging?upstream=trace" >/dev/null 2>&1 + @# curl -s -X POST "http://localhost:19000/logging?admin=trace" >/dev/null 2>&1 @# bash -c "trap 'pkill -F /tmp/kube-port-forward-logging.pid' SIGINT SIGTERM ERR EXIT" @echo @echo "How to stop port forward to the admin port (19000):" @@ -165,7 +165,7 @@ docker-build: ## Build docker image with the manager. --file ./build/manager/Dockerfile \ . minikube image --profile kgw load kubeshop/kusk-gateway:$(shell git describe --tags $(shell git rev-list --tags --max-count=1)) - + ##@ Deployment ifndef ignore-not-found diff --git a/examples/mocking/gateway/mocking-gateway-api-1.yaml b/examples/mocking/gateway/mocking-gateway-api-1.yaml new file mode 100644 index 000000000..4c54c1919 --- /dev/null +++ b/examples/mocking/gateway/mocking-gateway-api-1.yaml @@ -0,0 +1,77 @@ +apiVersion: gateway.kusk.io/v1alpha1 +kind: API +metadata: + name: mocking-gateway-api-1 +spec: + fleet: + name: default + namespace: default + spec: | + openapi: 3.0.0 + info: + title: mocking-gateway-api-1 + version: 0.1.0 + x-kusk: + cors: + origins: + - "*" + methods: + - POST + - GET + headers: + - Content-Type + credentials: true + max_age: 86200 + upstream: + service: + namespace: default + name: todo-backend + port: 80 + path: + prefix: / + paths: + /todos: + x-kusk: + mocking: + enabled: true + get: + responses: + "200": + description: "ToDos" + content: + application/json: + schema: + type: object + properties: + title: + type: string + description: Description of what to do + completed: + type: boolean + order: + type: integer + format: int32 + url: + type: string + required: + - title + - completed + - order + - url + example: + title: "Mocked JSON title" + completed: true + order: 13 + url: "http://mockedURL.com" + application/xml: + example: + title: "Mocked XML title" + completed: true + order: 13 + url: "http://mockedURL.com" + text/plain: + example: | + title: "Mocked Text title" + completed: true + order: 13 + url: "http://mockedURL.com" diff --git a/examples/mocking/gateway/mocking-gateway-deployments-1.yaml b/examples/mocking/gateway/mocking-gateway-deployments-1.yaml new file mode 100644 index 000000000..dd86e1660 --- /dev/null +++ b/examples/mocking/gateway/mocking-gateway-deployments-1.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: todo-backend +spec: + replicas: 1 + selector: + matchLabels: + app: todo-backend + template: + metadata: + labels: + app: todo-backend + spec: + containers: + - name: todo-backend + image: docker.io/kubeshop/todobackend-backend + env: + - name: PORT + value: "8080" + ports: + - containerPort: 8080 + name: http +--- +apiVersion: v1 +kind: Service +metadata: + name: todo-backend +spec: + selector: + app: todo-backend + ports: + - name: http + port: 80 + targetPort: 8080 diff --git a/internal/controllers/parser.go b/internal/controllers/parser.go index 4871d3993..07c562dcf 100644 --- a/internal/controllers/parser.go +++ b/internal/controllers/parser.go @@ -199,7 +199,7 @@ func UpdateConfigFromAPIOpts( } } - // // Validate and Proxy to the upstream + // Validate and Proxy to the upstream if finalOpts.Validation != nil && finalOpts.Validation.Request != nil && finalOpts.Validation.Request.Enabled != nil && *finalOpts.Validation.Request.Enabled { var ( upstreamHostname string diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 265587546..60847a1b2 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -156,6 +156,35 @@ func GetExampleResponse(mediaType *openapi3.MediaType) interface{} { return mediaType.Example } + // https://github.com/kubeshop/kusk-gateway/issues/298 and https://github.com/kubeshop/kusk-gateway/issues/324 + // + // Certain examples, like the one below, parses this structure + // + // application/json: + // schema: + // type: object + // properties: + // order: + // type: integer + // format: int32 + // completed: + // type: boolean + // required: + // - order + // - completed + // example: + // order: 13 + // completed: true + // + // With the `example` in the `mediaType.Schema.Value.Example` field. + if mediaType.Schema != nil { + if mediaType.Schema.Value != nil { + if mediaType.Schema.Value.Example != nil { + return mediaType.Schema.Value.Example + } + } + } + if mediaType.Examples != nil { for _, example := range mediaType.Examples { if example.Value != nil && example.Value.Value != nil { diff --git a/skaffold.sh b/skaffold.sh index 1a47b4a80..4d1504fef 100755 --- a/skaffold.sh +++ b/skaffold.sh @@ -18,9 +18,13 @@ install_and_configure_skaffold() { sudo curl -L --output /usr/local/bin/skaffold "https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-${ARCH}" sudo chmod +x /usr/local/bin/skaffold echo - skaffold version + echo "skaffold version: $(skaffold version)" } - skaffold version || install_skaffold + if ! command -v skaffold >/dev/null 2>&1; then + install_skaffold + else + echo "skaffold version: $(skaffold version)" + fi echo skaffold config set --global local-cluster true echo @@ -55,6 +59,7 @@ data: - ${INGRESS_RANGE}" # configure metallb ingress address range + mkdir -pv /tmp/skaffold echo "${CONFIG_MAP_METALLB}" >/tmp/skaffold/config-map-metallb.yaml } diff --git a/skaffold.yaml b/skaffold.yaml index 4db4499a8..183864dbe 100644 --- a/skaffold.yaml +++ b/skaffold.yaml @@ -8,7 +8,7 @@ build: sha256: {} artifacts: - image: kubeshop/kusk-gateway - platforms: ["linux/amd64", "linux/arm64"] + platforms: ["linux/amd64"] docker: dockerfile: build/manager/Dockerfile context: . @@ -25,8 +25,7 @@ deploy: command: - /bin/sh - -c - - echo 'sleeping for 2 seconds before applying `config/samples/gateway_v1_envoyfleet.yaml`' - - sleep 2 + - echo 'sleeping for 2 seconds before applying `config/samples/gateway_v1_envoyfleet.yaml`' && sleep 2 --- apiVersion: skaffold/v2beta29 kind: Config