Skip to content

Commit

Permalink
feat: Adds retry mechanism on failure and debugging support
Browse files Browse the repository at this point in the history
- Added max_attempts and failed_attempts_backoff_timeout fields to schema
- Updated plugin.properties to include EmmyLua Debugger version
- Introduced launch configuration for EmmyLua Debugger in VSCode
- Enhanced changelog with new features and improvements
- Modified Dockerfile to install EmmyLua Debugger
- Added custom Busted script for improved testing with EmmyLua Debugger
  • Loading branch information
dol committed Jan 3, 2025
1 parent c9245b8 commit 4ac39d6
Show file tree
Hide file tree
Showing 13 changed files with 556 additions and 96 deletions.
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// 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": [
{
"type": "emmylua_new",
"request": "launch",
"name": "EmmyLua New Debug",
"host": "localhost",
"port": 9966,
"ext": [
".lua",
".lua.txt",
".lua.bytes"
],
"ideConnectDebugger": true,
}
]
}
4 changes: 3 additions & 1 deletion BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

## Features

- [ ] Add retry attempts
- [x] Add retry attempts
- [ ] Add caching capability

## Improvements

- [ ] Add live tests to the OpenFGA server addition to the mock server.
- [ ] Add an example that uses Consumer in conjunction with the Basic Authentication plugin.
- [ ] Add build, test, and deploy pipeline (GitHub Actions) to the project
- [ ] Add GitHub action to perform a smoke test
- [ ] Add GitHub action to publish .rock when a version was tagged. Use LUAROCKS_API_KEY secret.

## Cleanup

Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Initial implementation of plugin
- Added GitHub action build for linting and unit testing
- Added function to handle unexpected errors and exit the plugin
- Added function to make FGA requests with retry logic
- Added unit tests to mock HTTP requests and return different responses based on call count
- Added support for EMMY Debugger with configurable host and port

### Changed

- Extracted `kong.response.exit(500, "An unexpected error occurred")` to its own function
- Extracted the code inside the `repeat ... until` loop into its own function
- Modified `make_fga_request` to return a boolean indicating allow/deny

### Fixed

### Removed
Expand Down
32 changes: 26 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,31 @@ DOCKER_NO_CACHE :=

BUILDKIT_PROGRESS :=

# Busted runtime profile
BUSTED_RUN_PROFILE := default
BUSTED_FILTER :=

# Busted exclude tags
BUSTED_EXCLUDE_TAGS := postgres
BUSTED_NO_KEEP_GOING := false
BUSTED_COVERAGE := false
BUSTED_EMMY_DEBUGGER := false

BUSTED_EMMY_DEBUGGER_ENABLED_ARGS =

BUSTED_ARGS = --config-file $(DOCKER_MOUNT_IN_CONTAINER)/.busted --run '$(BUSTED_RUN_PROFILE)' --exclude-tags='$(BUSTED_EXCLUDE_TAGS)' --filter '$(BUSTED_FILTER)'
ifdef BUSTED_NO_KEEP_GOING
ifneq ($(BUSTED_NO_KEEP_GOING), false)
BUSTED_ARGS += --no-keep-going
endif

ifneq ($(BUSTED_COVERAGE), false)
BUSTED_ARGS += --coverage
endif

ifneq ($(BUSTED_EMMY_DEBUGGER), false)
BUSTED_EMMY_DEBUGGER_ENABLED_ARGS = -e BUSTED_EMMY_DEBUGGER='/usr/local/lib/lua/5.1/emmy_core.so'
endif

KONG_SMOKE_TEST_DEPLOYMENT_PATH := _build/deployment/kong-smoke-test

CONTAINER_CI_KONG_TOOLING_IMAGE_PATH := _build/images/kong-tooling
Expand Down Expand Up @@ -82,10 +92,10 @@ CONTAINER_CI_OPENFGA_MIGRATION := $(DOCKER) run $(DOCKER_RUN_FLAGS) \
migrate --verbose

CONTAINER_CI_OPENFGA_RUN := $(DOCKER) run -d $(DOCKER_RUN_FLAGS) \
-p '8080:8080' \
-p '8081:8081' \
-p '3000:3000' \
-p '2112:2112' \
-p 8080:8080 \
-p 8081:8081 \
-p 3000:3000 \
-p 2112:2112 \
-e OPENFGA_DATASTORE_ENGINE=sqlite \
-e OPENFGA_DATASTORE_URI=file:/data/openfga.sqlite \
-e OPENFGA_DATASTORE_MAX_OPEN_CONNS=100 \
Expand Down Expand Up @@ -124,6 +134,7 @@ CONTAINER_CI_KONG_TOOLING_BUILD = DOCKER_BUILDKIT=1 BUILDKIT_PROGRESS=$(BUILDKIT
--build-arg PONGO_KONG_VERSION='$(PONGO_KONG_VERSION)' \
--build-arg PONGO_ARCHIVE='$(PONGO_ARCHIVE)' \
--build-arg STYLUA_VERSION='$(STYLUA_VERSION)' \
--build-arg EMMY_LUA_DEBUGGER_VERSION='$(EMMY_LUA_DEBUGGER_VERSION)' \
.

CONTAINER_CI_KONG_SMOKE_TEST_BUILD = DOCKER_BUILDKIT=1 BUILDKIT_PROGRESS=$(BUILDKIT_PROGRESS) $(DOCKER) build \
Expand All @@ -139,12 +150,20 @@ CONTAINER_CI_KONG_SMOKE_TEST_BUILD = DOCKER_BUILDKIT=1 BUILDKIT_PROGRESS=$(BUILD
.

CONTAINER_CI_KONG_TOOLING_RUN := MSYS_NO_PATHCONV=1 $(DOCKER) run $(DOCKER_RUN_FLAGS) \
-v '$(PWD):$(DOCKER_MOUNT_IN_CONTAINER)' \
-p 9966:9966 \
-e KONG_SPEC_TEST_REDIS_HOST='$(CONTAINER_CI_REDIS_NAME)' \
-e KONG_SPEC_TEST_LIVE_HOSTNAME='$(CONTAINER_CI_OPENFGA_NAME)' \
-e KONG_LICENSE_PATH=$(DOCKER_MOUNT_IN_CONTAINER)/kong-license.json \
-e KONG_DNS_ORDER='LAST,A,SRV' \
-e BUSTED_EMMY_DEBUGGER_HOST='0.0.0.0' \
-e BUSTED_EMMY_DEBUGGER_PORT='9966' \
-e BUSTED_EMMY_DEBUGGER_SOURCE_PATH='/usr/local/share/lua/5.1/kong/plugins:/usr/local/share/lua/5.1/kong/enterprise_edition' \
-e BUSTED_EMMY_DEBUGGER_SOURCE_PATH_MAPPING='$(DOCKER_MOUNT_IN_CONTAINER);$(PWD):/usr/local/share/lua/5.1;$(PWD)/.luarocks:/usr/local/openresty/lualib;$(PWD)/.luarocks' \
$(BUSTED_EMMY_DEBUGGER_ENABLED_ARGS) \
--network='$(CONTAINER_CI_NETWORK_NAME)' \
-v '$(PWD):$(DOCKER_MOUNT_IN_CONTAINER)' \
-v '$(PWD)/_build/debugger/emmy_debugger.lua:/usr/local/share/lua/5.1/kong/tools/emmy_debugger.lua' \
-v '$(PWD)/_build/debugger/busted:/kong/bin/busted' \
'$(CONTAINER_CI_KONG_TOOLING_IMAGE_NAME)'

CONTAINER_CI_KONG_SMOKE_TEST_RUN_SERVER_NAME = kong-plugin-$(KONG_PLUGIN_NAME)-smoke-test
Expand Down Expand Up @@ -308,6 +327,7 @@ lua-language-server-add-kong: container-ci-kong-tooling
-mkdir -p .luarocks
$(CONTAINER_CI_KONG_TOOLING_RUN) cp -rv /usr/local/share/lua/5.1/. $(DOCKER_MOUNT_IN_CONTAINER)/.luarocks
$(CONTAINER_CI_KONG_TOOLING_RUN) cp -rv /kong $(DOCKER_MOUNT_IN_CONTAINER)/.luarocks
$(CONTAINER_CI_KONG_TOOLING_RUN) cp -rv /usr/local/openresty/lualib/. $(DOCKER_MOUNT_IN_CONTAINER)/.luarocks

.PHONY: clean-test-results
clean-test-results:
Expand Down
70 changes: 52 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Below is the example configuration one might use in `declarative_config`:
port: 1234
https: true
https_verify: true
max_attempts: 3
failed_attempts_backoff_timeout: 1000
timeout: 10000
keepalive: 60000
store_id: "your_store_id"
Expand All @@ -72,24 +74,26 @@ Below is the example configuration one might use in `declarative_config`:

## Configuration

| Property | Default value | Description |
| ------------------------------------------------------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `host`<br/>_required_<br/><br/>**Type:** hostname (string) | - | Hostname of the OpenFGA server |
| `port`<br/>_required_<br/><br/>**Type:** port (number) | 8080 | HTTP API port of OpenFGA |
| `https`<br/>_optional_<br/><br/>**Type:** boolean | false | Use HTTPS to connect to OpenFGA |
| `https_verify`<br/>_optional_<br/><br/>**Type:** boolean | false | Verify HTTPS certificate |
| `timeout`<br/>_optional_<br/><br/>**Type:** number | 10000 | The total timeout time in milliseconds for a request and response cycle. |
| `keepalive`<br/>_optional_<br/><br/>**Type:** number | 60000 | The maximal idle timeout in milliseconds for the current connection. See [tcpsock:setkeepalive](https://github.com/openresty/lua-nginx-module#tcpsocksetkeepalive) for more details. |
| `store_id`<br/>_required_<br/><br/>**Type:** string | - | The store ID in OpenFGA |
| `model_id`<br/>_optional_<br/><br/>**Type:** string | - | Optional model ID (version). Latest is used if this is empty |
| `api_token`<br/>_optional_<br/><br/>**Type:** string | - | Optional API token |
| `api_token_issuer`<br/>_optional_<br/><br/>**Type:** string | - | API token issuer |
| `api_audience`<br/>_optional_<br/><br/>**Type:** string | - | API audience |
| `api_client_id`<br/>_optional_<br/><br/>**Type:** string | - | API client ID |
| `api_client_secret`<br/>_optional_<br/><br/>**Type:** string | - | API client secret |
| `api_token_cache`<br/>_optional_<br/><br/>**Type:** number | 600 | API token cache duration in seconds |
| `tuple`<br/>_required_<br/><br/>**Type:** record | - | Tuple key for authorization |
| `contextual_tuples`<br/>_optional_<br/><br/>**Type:** set | {} | Set of contextual tuples for authorization |
| Property | Default value | Description |
| --------------------------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `host`<br/>_required_<br/><br/>**Type:** hostname (string) | - | Hostname of the OpenFGA server |
| `port`<br/>_required_<br/><br/>**Type:** port (number) | 8080 | HTTP API port of OpenFGA |
| `https`<br/>_optional_<br/><br/>**Type:** boolean | false | Use HTTPS to connect to OpenFGA |
| `https_verify`<br/>_optional_<br/><br/>**Type:** boolean | false | Verify HTTPS certificate |
| `max_attempts`<br/>_optional_<br/><br/>**Type:** integer | 3 | The maximum number of attempts to make when querying OpenFGA. This is useful for handling transient errors and retries. |
| `failed_attempts_backoff_timeout`<br/>_optional_<br/><br/>**Type:** integer | 1000 | The backoff timeout in milliseconds between retry attempts when querying OpenFGA. This helps to avoid overwhelming the server with rapid retries. Formula: `failed_attempts_backoff_timeout \* 2 ^ (attempts - 1) / 1000` |
| `timeout`<br/>_optional_<br/><br/>**Type:** number | 10000 | The total timeout time in milliseconds for a request and response cycle. |
| `keepalive`<br/>_optional_<br/><br/>**Type:** number | 60000 | The maximal idle timeout in milliseconds for the current connection. See [tcpsock:setkeepalive](https://github.com/openresty/lua-nginx-module#tcpsocksetkeepalive) for more details. |
| `store_id`<br/>_required_<br/><br/>**Type:** string | - | The store ID in OpenFGA |
| `model_id`<br/>_optional_<br/><br/>**Type:** string | - | Optional model ID (version). Latest is used if this is empty |
| `api_token`<br/>_optional_<br/><br/>**Type:** string | - | Optional API token |
| `api_token_issuer`<br/>_optional_<br/><br/>**Type:** string | - | API token issuer |
| `api_audience`<br/>_optional_<br/><br/>**Type:** string | - | API audience |
| `api_client_id`<br/>_optional_<br/><br/>**Type:** string | - | API client ID |
| `api_client_secret`<br/>_optional_<br/><br/>**Type:** string | - | API client secret |
| `api_token_cache`<br/>_optional_<br/><br/>**Type:** number | 600 | API token cache duration in seconds |
| `tuple`<br/>_required_<br/><br/>**Type:** record | - | Tuple key for authorization |
| `contextual_tuples`<br/>_optional_<br/><br/>**Type:** set | {} | Set of contextual tuples for authorization |

## Plugin version

Expand Down Expand Up @@ -149,6 +153,36 @@ make lint
make test-unit
```

| Runtime configuration | Description |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| BUSTED_NO_KEEP_GOING | When set to `true`, `busted` will stop running tests after the first failure. Default is `false`. |
| BUSTED_COVERAGE | When set to `true`, `busted` will generate a code coverage report. Default is `false`. |
| BUSTED_EMMY_DEBUGGER | When set to `true`, enables the EMMY Lua debugger for `busted` tests. Default is `false`. |

#### Run test with EMMY Debugger

##### Prerequisites

- Install the [EmmyLua](https://marketplace.visualstudio.com/items?itemName=tangzx.emmylua) extension in VS Code

##### Usage

1. Start your tests with debugging enabled:

`make test-unit BUSTED_EMMY_DEBUGGER=true`

2. In VS Code:
- Set breakpoints in your Lua code
- Start the debugger using F5 or the Debug panel
- The debugger will attach to the running tests
3. Debug features available:
- Step through code
- Inspect variables
- View call stack
- Set conditional breakpoints

The debugger will automatically map source files between your local workspace and the container environment using the configured source roots.

### Pack the plugin into a .rock

```sh
Expand Down
Loading

0 comments on commit 4ac39d6

Please sign in to comment.