Skip to content

Commit

Permalink
feat: allow injecting logic to APISIX's method (#5068)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacewander authored Sep 16, 2021
1 parent 2e6be23 commit f373faf
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 1 deletion.
6 changes: 6 additions & 0 deletions apisix/cli/ngx_tpl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ stream {
init_by_lua_block {
require "resty.core"
{% if lua_module_hook then %}
require "{* lua_module_hook *}"
{% end %}
apisix = require("apisix")
local dns_resolver = { {% for _, dns_addr in ipairs(dns_resolver or {}) do %} "{*dns_addr*}", {% end %} }
local args = {
Expand Down Expand Up @@ -338,6 +341,9 @@ http {
init_by_lua_block {
require "resty.core"
{% if lua_module_hook then %}
require "{* lua_module_hook *}"
{% end %}
apisix = require("apisix")
local dns_resolver = { {% for _, dns_addr in ipairs(dns_resolver or {}) do %} "{*dns_addr*}", {% end %} }
Expand Down
3 changes: 3 additions & 0 deletions apisix/cli/ops.lua
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ local config_schema = {
config_center = {
enum = {"etcd", "yaml"},
},
lua_module_hook = {
pattern = "^[a-zA-Z._-]+$",
},
proxy_protocol = {
type = "object",
properties = {
Expand Down
1 change: 1 addition & 0 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ apisix:
# configurations to load third party code and/or override the builtin one.
extra_lua_path: "" # extend lua_package_path to load third party code
extra_lua_cpath: "" # extend lua_package_cpath to load third party code
#lua_module_hook: "my_project.my_hook" # the hook module which will be used to inject third party code into APISIX

proxy_cache: # Proxy Caching configuration
cache_ttl: 10s # The default caching time if the upstream does not specify the cache time
Expand Down
15 changes: 15 additions & 0 deletions docs/en/latest/plugin-develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@ apisix:
Now using `require "apisix.plugins.3rd-party"` will load your plugin, just like `require "apisix.plugins.jwt-auth"` will load the `jwt-auth` plugin.

Sometimes you may want to override a method instead of a whole file. In this case, you can configure `lua_module_hook` in `conf/config.yaml`
to introduce your hook.

Assumed your configuration is:

```yaml
apisix:
...
extra_lua_path: "/path/to/example/?.lua"
lua_module_hook: "my_hook"
```

The `example/my_hook.lua` will be loaded when APISIX starts, and you can use this hook to replace a method in APISIX.
The example of [my_hook.lua](https://github.com/apache/apisix/blob/master/example/my_hook.lua) can be found under the `example` directory of this project.

## check dependencies

if you have dependencies on external libraries, check the dependent items. if your plugin needs to use shared memory, it
Expand Down
29 changes: 29 additions & 0 deletions example/my_hook.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
local apisix = require("apisix")

local old_http_init = apisix.http_init
apisix.http_init = function (...)
ngx.log(ngx.EMERG, "my hook works in http")
old_http_init(...)
end

local old_stream_init = apisix.stream_init
apisix.stream_init = function (...)
ngx.log(ngx.EMERG, "my hook works in stream")
old_stream_init(...)
end
45 changes: 44 additions & 1 deletion t/cli/test_main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,49 @@ fi

echo "passed: detect invalid extra_lua_path"

# support hooking into APISIX methods
echo '
apisix:
lua_module_hook: "example/my_hook"
' > conf/config.yaml

out=$(make init 2>&1 || true)
if ! echo "$out" | grep 'property "lua_module_hook" validation failed'; then
echo "failed: bad lua_module_hook should be rejected"
exit 1
fi

echo "passed: bad lua_module_hook should be rejected"

echo '
apisix:
extra_lua_path: "\$prefix/example/?.lua"
lua_module_hook: "my_hook"
stream_proxy:
only: false
tcp:
- addr: 9100
' > conf/config.yaml

rm logs/error.log
make init
make run

sleep 0.5
make stop

if ! grep "my hook works in http" logs/error.log > /dev/null; then
echo "failed: hook can take effect"
exit 1
fi

if ! grep "my hook works in stream" logs/error.log > /dev/null; then
echo "failed: hook can take effect"
exit 1
fi

echo "passed: hook can take effect"

# check restart with old nginx.pid exist
echo "-1" > logs/nginx.pid
out=$(./bin/apisix start 2>&1 || true)
Expand All @@ -621,7 +664,7 @@ if echo "$out" | grep "APISIX is running"; then
exit 1
fi

rm logs/nginx.pid
./bin/apisix stop
echo "pass: ignore stale nginx.pid"

# check the keepalive related parameter settings in the upstream
Expand Down

0 comments on commit f373faf

Please sign in to comment.