https://github.com/firetail-io/firetail-apisix-go-plugin
https://github.com/firetail-io/firetail-apisix-go-plugin
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/firetail-io/firetail-apisix-go-plugin
- Owner: FireTail-io
- License: lgpl-2.1
- Created: 2024-03-08T18:59:10.000Z (over 1 year ago)
- Default Branch: dev
- Last Pushed: 2024-11-18T11:17:19.000Z (8 months ago)
- Last Synced: 2025-01-17T00:45:59.194Z (6 months ago)
- Language: Go
- Size: 12.6 MB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# FireTail APISIX Plugin
The FireTail APISIX plugin provides realtime validation of your API traffic against an OpenAPI specification.
## Demo Setup
A demo setup using the FireTail APISIX plugin can be found in the [`/demo`](./demo) directory.
Docker compose is used to run:
1. An APISIX container which has been modified to use the FireTail APISIX plugin.
2. An NGINX instance with mocked API responses which can be used to demonstrate request and response validation.Getting it up and running should be as simple as:
```bash
git clone [email protected]:FireTail-io/firetail-apisix-go-plugin.git
cd firetail-apisix-go-plugin/demo
docker compose up
```You can then make a request to the health endpoint to check everything's working:
```bash
curl localhost:9080/health
```To get the demo setup to ship logs to the FireTail SaaS platform, create a copy of [`demo/.env.example`](./demo/.env.example) at `demo/.env` and modify it.
```bash
cp .env.example .env
nano .env
```### Request Validation
To demonstrate request validation, an API endpoint `POST /profile/{username}/comment` is defined in [the demo's OpenAPI specification](./demo/appspec.yml).
The following request conforms to the OpenAPI specification, so should yield a successful response:
```bash
curl -X POST localhost:9080/profile/alice/comment -H "Content-Type: application/json" -d '{"comment": "Hey, Alice!"}'
``````json
{"message":"Success!"}
```If we change the content of the comment to be an integer, instead of a string, it will no longer conform to the OpenAPI specification and should yield an informative error response from the FireTail APISIX plugin:
```bash
curl -X POST localhost:9080/profile/alice/comment -H "Content-Type: application/json" -d '{"comment": 123456789}'
``````json
{"code":400,"title":"something's wrong with your request body","detail":"the request's body did not match your appspec: request body has an error: doesn't match the schema: Error at \"/comment\": field must be set to string or not be present\nSchema:\n {\n \"type\": \"string\"\n }\n\nValue:\n \"number, integer\"\n"}
```### Response Validation
To demonstrate response validation, an API endpoint `GET /profile/{username}` is defined in [the demo's OpenAPI specification](./demo/appspec.yml), and two corresponding responses are defined in [the `nginx.conf` of the NGINX instance being used as a mock backend](./demo/nginx.conf) for this demo:
```
location /profile/alice {
return 200 '{"username":"alice", "friends": 123456789}';
}location /profile/bob {
return 200 '{"username":"bob", "friends": 123456789, "address":"Oh dear, this shouldn\'t be public!"}';
}
```Alice's profile conforms to the OpenAPI specification:
```bash
curl localhost:9080/profile/alice
``````json
{"username":"alice", "friends": 123456789}
```Bob's profile does not conform to the OpenAPI specification. The response from the FireTail APISIX plugin will tell us why:
```bash
curl localhost:9080/profile/bob
``````json
{"code":500,"title":"internal server error","detail":"the response's body did not match your appspec: response body doesn't match the schema: property \"address\" is unsupported\nSchema:\n {\n \"additionalProperties\": false,\n \"properties\": {\n \"friends\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"username\": {\n \"type\": \"string\"\n }\n },\n \"type\": \"object\"\n }\n\nValue:\n {\n \"address\": \"Oh dear, this shouldn't be public!\",\n \"friends\": 123456789,\n \"username\": \"bob\"\n }\n"}{"code":500,"title":"internal server error","detail":"the response's body did not match your appspec: response body doesn't match the schema: property \"address\" is unsupported\nSchema:\n {\n \"additionalProperties\": false,\n \"properties\": {\n \"friends\": {\n \"minimum\": 0,\n \"type\": \"integer\"\n },\n \"username\": {\n \"type\": \"string\"\n }\n },\n \"type\": \"object\"\n }\n\nValue:\n {\n \"address\": \"Oh dear, this shouldn't be public!\",\n \"friends\": 123456789,\n \"username\": \"bob\"\n }\n"}
```## Development Setup
In the root directory, run `make build`
### Running in development mode
In the root directory, run the unix socket with `APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock APISIX_CONF_EXPIRE_TIME=3600 ./go-runner run`
Then in apisix's configuration file `config.yaml` add this:
```
ext-plugin:
path_for_test: /tmp/runner.sock
```and restart apisix `apisix restart`
### Testing
#### Enable both firetail request and response filtering via apisix API:
**NOTE** You will need to run your application at localhost (127.0.0.1) port 1980. If you wish to point it elsewhere, change the "nodes" parameter from example below.
```
curl http://127.0.0.1:9180/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
"uri": "/profile/alice/comment",
"plugins": {
"ext-plugin-pre-req": {
"conf": [
{"name":"firetail", "value":"{\"body\":\"\"}"}
]
},
"ext-plugin-post-resp": {
"conf": [
{"name":"firetail", "value":"{\"body\":\"\"}"}
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'
```