From ee2b362e2812697ed32062162cae878b6149c236 Mon Sep 17 00:00:00 2001 From: Andrei Date: Mon, 23 May 2022 12:25:30 +0300 Subject: [PATCH] Marked custom python plugins as tested and added example/tutorial and required files in order to run the tutorial --- docs/api_definitions.md | 30 ++++---- .../custom_plugin_python.md | 73 +++++++++++++++++++ .../custom_plugin_python.yaml | 15 ++++ .../custom_plugin_python/manifest.json | 17 +++++ .../custom_plugin_python/middleware.py | 8 ++ 5 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 docs/api_definitions/custom_plugin_python/custom_plugin_python.md create mode 100644 docs/api_definitions/custom_plugin_python/custom_plugin_python.yaml create mode 100644 docs/api_definitions/custom_plugin_python/manifest.json create mode 100644 docs/api_definitions/custom_plugin_python/middleware.py diff --git a/docs/api_definitions.md b/docs/api_definitions.md index ffaf67ad8..c5231eefd 100644 --- a/docs/api_definitions.md +++ b/docs/api_definitions.md @@ -63,22 +63,22 @@ An API Definition describes the configuration of an API. It instructs Tyk Gatewa ## Features -| Feature | Supported | Comments | -| ----------- | --------- | --------- | -| API Tagging | ✅ | - | -| [Config Data](./../config/samples/config_data_virtual_endpoint.yaml) | ✅ | - | -| Context Variables | ✅ | - | +| Feature | Supported | Comments | +| ----------- | --------- |------------------------------------------------------------------------| +| API Tagging | ✅ | - | +| [Config Data](./../config/samples/config_data_virtual_endpoint.yaml) | ✅ | - | +| Context Variables | ✅ | - | | [Cross Origin Resource Sharing (CORS)](./../config/samples/httpbin_cors.yaml) | ⚠️ | [See ISSUE #3396 ](https://github.com/TykTechnologies/tyk/issues/3396) | -| Custom Plugins - Go | ⚠️ | Untested | -| [Custom Plugins - gRPC](./../bdd/features/api_http_grpc_plugin.feature) | ✅ | - | -| [Custom Plugins - Javascript](./api_definitions/custom_plugin.md) | ✅ | - | -| Custom Plugins - Lua | ⚠️ | Untested | -| Custom Plugins - Python | ⚠️ | Untested | -| Global Rate Limit | ❌ | Not Implemented | -| [Segment Tags](./../config/samples/httpbin_tagged.yaml) | ✅ | - | -| Tag Headers | ❌ | Not Implemented | -| [Webhooks](./webhooks.md) | ❌ | [WIP #62](https://github.com/TykTechnologies/tyk-operator/issues/62) | -| [Looping](./api_definitions/looping.md) | ⚠️ | Untested | +| Custom Plugins - Go | ⚠️ | Untested | +| [Custom Plugins - gRPC](./../bdd/features/api_http_grpc_plugin.feature) | ✅ | - | +| [Custom Plugins - Javascript](./api_definitions/custom_plugin.md) | ✅ | - | +| Custom Plugins - Lua | ⚠️ | Untested | +| Custom Plugins - Python | ✅️ | - | +| Global Rate Limit | ❌ | Not Implemented | +| [Segment Tags](./../config/samples/httpbin_tagged.yaml) | ✅ | - | +| Tag Headers | ❌ | Not Implemented | +| [Webhooks](./webhooks.md) | ❌ | [WIP #62](https://github.com/TykTechnologies/tyk-operator/issues/62) | +| [Looping](./api_definitions/looping.md) | ⚠️ | Untested | ## APIDefinition - Endpoint Middleware diff --git a/docs/api_definitions/custom_plugin_python/custom_plugin_python.md b/docs/api_definitions/custom_plugin_python/custom_plugin_python.md new file mode 100644 index 000000000..f2f656928 --- /dev/null +++ b/docs/api_definitions/custom_plugin_python/custom_plugin_python.md @@ -0,0 +1,73 @@ +## Custom Plugin example using python + +We assume that you already have a developed python plugin with the associated python file and its manifest in JSON. +If not, you can start from the provided examples ("manifest.json" and "middleware.py"). +Furthermore, in this example, we are going to serve those as a bundle using a small http python server. + + +Firstly to create the said bundle we need to run the following command: + +``` +IMAGETAG=v3.2.1 + +docker run \ + --rm -w "/tmp" -v $(pwd):/tmp \ + --entrypoint "/bin/sh" -it \ + tykio/tyk-gateway:$IMAGETAG \ + -c '/opt/tyk-gateway/tyk bundle build -y' + +``` + +We are setting the shell variable IMAGETAG to be the version of the gateway we intend on loading the python bundle onto. +In this case, we are loading the plugin onto a Tyk gateway v3.2.1. When completed, you should see a bundle.zip in your current directory. + +Now we must serve the bundle, and the easiest way to do so is through a local server using the following command: +``` +python3 -m http.server +``` + +Your bundle should now be accessible locally through the URL http://localhost:8000/bundle.zip, +or through the url http://host.minikube.internal:8000/bundle.zip from within minikube. + +Next we need to ensure that the python custom plugin with bundle features are enabled +in the gateway. Before deploying the tyk stack we need to add these config +variables to the "values.yaml" file: + + +```yaml +extraEnvs: [ + { + "name": "TYK_GW_ENABLEBUNDLEDOWNLOADER", + "value": "true" + }, + { + "name": "TYK_GW_BUNDLEBASEURL", + "value": "http://host.minikube.internal:8000/" + }, + { + "name": "TYK_GW_BUNDLEINSECURESKIPVERIFY", + "value": "true" + }, + { + "name": "TYK_GW_COPROCESSOPTIONS_ENABLECOPROCESS", + "value": "true" + }, + { + "name": "TYK_GW_COPROCESSOPTIONS_PYTHONPATHPREFIX", + "value": "/opt/tyk-gateway" + } + ] +``` + +Next we should install the tyk stack and the operator in the usual way. + +After everything is up and running we need to create an API that actually +makes use of the python plugin. For this we can use the provided yaml manifest +"custom_plugin_python.yaml" via the command (assuming the tyk stack has been deployed inside the tyk namespace): + +``` +kubectl apply -f custom_plugin_python.yaml -n tyk +``` + +After this command is run, any request to the "/httpbin/get" dashboard endpoint +should have a "Testheader" header injected with value "testvalue". \ No newline at end of file diff --git a/docs/api_definitions/custom_plugin_python/custom_plugin_python.yaml b/docs/api_definitions/custom_plugin_python/custom_plugin_python.yaml new file mode 100644 index 000000000..e837ad735 --- /dev/null +++ b/docs/api_definitions/custom_plugin_python/custom_plugin_python.yaml @@ -0,0 +1,15 @@ +apiVersion: tyk.tyk.io/v1alpha1 +kind: ApiDefinition +metadata: + name: httpbin +spec: + name: httpbin + use_keyless: true + protocol: http + active: true + proxy: + target_url: http://httpbin.org + listen_path: /httpbin + strip_listen_path: true + custom_middleware_bundle: "bundle.zip" + diff --git a/docs/api_definitions/custom_plugin_python/manifest.json b/docs/api_definitions/custom_plugin_python/manifest.json new file mode 100644 index 000000000..ee67a48f4 --- /dev/null +++ b/docs/api_definitions/custom_plugin_python/manifest.json @@ -0,0 +1,17 @@ +{ + "file_list": [ + "middleware.py" + ], + "custom_middleware": { + "driver": "python", + "pre": [ + { + "name": "SetHeader", + "path": "/get", + "require_session": false, + "raw_body_only": false + } + ] + } +} + diff --git a/docs/api_definitions/custom_plugin_python/middleware.py b/docs/api_definitions/custom_plugin_python/middleware.py new file mode 100644 index 000000000..c372568fe --- /dev/null +++ b/docs/api_definitions/custom_plugin_python/middleware.py @@ -0,0 +1,8 @@ +from tyk.decorators import * +from gateway import TykGateway as tyk + +@Hook +def SetHeader(request, session, spec): + tyk.log("PreHook is called", "info") + request.add_header("testheader", "testvalue") + return request, session