mirror of
https://gitee.com/iresty/apisix.git
synced 2024-12-03 20:47:35 +08:00
feature: used json schema to check the configuration of limit-count
plugin. (#116)
* feature: used json schema to check the configuration of `limit-count` plugin. * travis: if there was any errors, exist directly.
This commit is contained in:
parent
d4bbd7d3bf
commit
a4634da49e
@ -40,5 +40,5 @@ script:
|
|||||||
- sudo apisix init_etcd
|
- sudo apisix init_etcd
|
||||||
- cd test-nginx && (sudo cpanm . > build.log 2>&1 || (cat build.log && exit 1)) && cd ..
|
- cd test-nginx && (sudo cpanm . > build.log 2>&1 || (cat build.log && exit 1)) && cd ..
|
||||||
- export PATH=$OPENRESTY_PREFIX/nginx/sbin:$OPENRESTY_PREFIX/luajit/bin:$PATH
|
- export PATH=$OPENRESTY_PREFIX/nginx/sbin:$OPENRESTY_PREFIX/luajit/bin:$PATH
|
||||||
- make check
|
- make check || exit 1
|
||||||
- make test
|
- make test
|
||||||
|
33
lua/apisix/admin/plugins.lua
Normal file
33
lua/apisix/admin/plugins.lua
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
local core = require("apisix.core")
|
||||||
|
local local_plugins = require("apisix.plugin").plugins_hash
|
||||||
|
local pairs = pairs
|
||||||
|
|
||||||
|
|
||||||
|
local _M = {
|
||||||
|
version = 0.1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function _M.check_schema(plugins_conf)
|
||||||
|
for name, plugin_conf in pairs(plugins_conf) do
|
||||||
|
core.log.info("check plugin scheme, name: ", name, ", configurations: ",
|
||||||
|
core.json.delay_encode(plugin_conf, true))
|
||||||
|
local plugin_obj = local_plugins[name]
|
||||||
|
if not plugin_obj then
|
||||||
|
return false, "unknow plugin [" .. name .. "]"
|
||||||
|
end
|
||||||
|
|
||||||
|
if plugin_obj.check_schema then
|
||||||
|
local ok, err = plugin_obj.check_schema(plugin_conf)
|
||||||
|
if not ok then
|
||||||
|
return false, "failed to check the configuration of plugin "
|
||||||
|
.. name .. " err: " .. err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return _M
|
@ -1,4 +1,5 @@
|
|||||||
local core = require("apisix.core")
|
local core = require("apisix.core")
|
||||||
|
local schema_plugin = require("apisix.admin.plugins").check_schema
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
|
|
||||||
|
|
||||||
@ -63,6 +64,13 @@ function _M.put(uri_segs, conf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if conf.plugins then
|
||||||
|
local ok, err = schema_plugin(conf.plugins)
|
||||||
|
if not ok then
|
||||||
|
return 400, {error_msg = err}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local key = "/" .. resource .. "/" .. id
|
local key = "/" .. resource .. "/" .. id
|
||||||
local res, err = core.etcd.set(key, conf)
|
local res, err = core.etcd.set(key, conf)
|
||||||
if not res then
|
if not res then
|
||||||
@ -135,6 +143,13 @@ function _M.post(uri_segs, conf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if conf.plugins then
|
||||||
|
local ok, err = schema_plugin(conf.plugins)
|
||||||
|
if not ok then
|
||||||
|
return 400, {error_msg = err}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local key = "/" .. uri_segs[4]
|
local key = "/" .. uri_segs[4]
|
||||||
-- core.log.info("key: ", key)
|
-- core.log.info("key: ", key)
|
||||||
local res, err = core.etcd.push(key, conf)
|
local res, err = core.etcd.push(key, conf)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
local core = require("apisix.core")
|
local core = require("apisix.core")
|
||||||
|
local schema_plugin = require("apisix.admin.plugins").check_schema
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
|
|
||||||
|
|
||||||
@ -46,6 +47,13 @@ function _M.put(uri_segs, conf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if conf.plugins then
|
||||||
|
local ok, err = schema_plugin(conf.plugins)
|
||||||
|
if not ok then
|
||||||
|
return 400, {error_msg = err}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local key = "/services/" .. id
|
local key = "/services/" .. id
|
||||||
core.log.info("key: ", key)
|
core.log.info("key: ", key)
|
||||||
local res, err = core.etcd.set(key, conf)
|
local res, err = core.etcd.set(key, conf)
|
||||||
@ -121,6 +129,13 @@ function _M.post(uri_segs, conf)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if conf.plugins then
|
||||||
|
local ok, err = schema_plugin(conf.plugins)
|
||||||
|
if not ok then
|
||||||
|
return 400, {error_msg = err}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local key = "/services"
|
local key = "/services"
|
||||||
local res, err = core.etcd.push(key, conf)
|
local res, err = core.etcd.push(key, conf)
|
||||||
if not res then
|
if not res then
|
||||||
|
@ -7,13 +7,15 @@ local pcall = pcall
|
|||||||
local ipairs = ipairs
|
local ipairs = ipairs
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local type = type
|
local type = type
|
||||||
local local_supported_plugins = {}
|
local local_plugins = {}
|
||||||
|
local local_plugins_hash = {}
|
||||||
|
|
||||||
|
|
||||||
local _M = {
|
local _M = {
|
||||||
version = 0.1,
|
version = 0.1,
|
||||||
load_times = 0,
|
load_times = 0,
|
||||||
plugins = local_supported_plugins,
|
plugins = local_plugins,
|
||||||
|
plugins_hash = local_plugins_hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -23,7 +25,8 @@ end
|
|||||||
|
|
||||||
|
|
||||||
local function load()
|
local function load()
|
||||||
core.table.clear(local_supported_plugins)
|
core.table.clear(local_plugins)
|
||||||
|
core.table.clear(local_plugins_hash)
|
||||||
|
|
||||||
local plugin_names = core.config.local_conf().plugins
|
local plugin_names = core.config.local_conf().plugins
|
||||||
if not plugin_names then
|
if not plugin_names then
|
||||||
@ -50,7 +53,7 @@ local function load()
|
|||||||
|
|
||||||
else
|
else
|
||||||
plugin.name = name
|
plugin.name = name
|
||||||
insert_tab(local_supported_plugins, plugin)
|
insert_tab(local_plugins, plugin)
|
||||||
end
|
end
|
||||||
|
|
||||||
if plugin.init then
|
if plugin.init then
|
||||||
@ -59,12 +62,16 @@ local function load()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- sort by plugin's priority
|
-- sort by plugin's priority
|
||||||
if #local_supported_plugins > 1 then
|
if #local_plugins > 1 then
|
||||||
sort_tab(local_supported_plugins, sort_plugin)
|
sort_tab(local_plugins, sort_plugin)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, plugin in ipairs(local_plugins) do
|
||||||
|
local_plugins_hash[plugin.name] = plugin
|
||||||
end
|
end
|
||||||
|
|
||||||
_M.load_times = _M.load_times + 1
|
_M.load_times = _M.load_times + 1
|
||||||
return local_supported_plugins
|
return local_plugins
|
||||||
end
|
end
|
||||||
_M.load = load
|
_M.load = load
|
||||||
|
|
||||||
@ -100,13 +107,13 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function _M.filter(user_route, plugins)
|
function _M.filter(user_route, plugins)
|
||||||
plugins = plugins or core.table.new(#local_supported_plugins * 2, 0)
|
plugins = plugins or core.table.new(#local_plugins * 2, 0)
|
||||||
local user_plugin_conf = user_route.value.plugins
|
local user_plugin_conf = user_route.value.plugins
|
||||||
if user_plugin_conf == nil then
|
if user_plugin_conf == nil then
|
||||||
return plugins
|
return plugins
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, plugin_obj in ipairs(local_supported_plugins) do
|
for _, plugin_obj in ipairs(local_plugins) do
|
||||||
local name = plugin_obj.name
|
local name = plugin_obj.name
|
||||||
local plugin_conf = user_plugin_conf[name]
|
local plugin_conf = user_plugin_conf[name]
|
||||||
|
|
||||||
|
@ -9,8 +9,9 @@ local schema = {
|
|||||||
count = {type = "integer", minimum = 0},
|
count = {type = "integer", minimum = 0},
|
||||||
time_window = {type = "integer", minimum = 0},
|
time_window = {type = "integer", minimum = 0},
|
||||||
key = {type = "string", enum = {"remote_addr"}},
|
key = {type = "string", enum = {"remote_addr"}},
|
||||||
rejected_code = {type = "integer", minimum = 200},
|
rejected_code = {type = "integer", minimum = 200, maximum = 600},
|
||||||
},
|
},
|
||||||
|
additionalProperties = false,
|
||||||
required = {"count", "time_window", "key", "rejected_code"}
|
required = {"count", "time_window", "key", "rejected_code"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,3 +113,250 @@ passed
|
|||||||
[404, 200, 404, 200, 503]
|
[404, 200, 404, 200, 503]
|
||||||
--- no_error_log
|
--- no_error_log
|
||||||
[error]
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 6: invalid route: missing key
|
||||||
|
--- config
|
||||||
|
location /t {
|
||||||
|
content_by_lua_block {
|
||||||
|
local t = require("lib.test_admin").test
|
||||||
|
local code, body = t('/apisix/admin/routes/1',
|
||||||
|
ngx.HTTP_PUT,
|
||||||
|
[[{
|
||||||
|
"plugins": {
|
||||||
|
"limit-count": {
|
||||||
|
"count": 2,
|
||||||
|
"time_window": 60,
|
||||||
|
"rejected_code": 503
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"upstream": {
|
||||||
|
"nodes": {
|
||||||
|
"127.0.0.1:1980": 1
|
||||||
|
},
|
||||||
|
"type": "roundrobin"
|
||||||
|
},
|
||||||
|
"uri": "/hello"
|
||||||
|
}]]
|
||||||
|
)
|
||||||
|
|
||||||
|
if code >= 300 then
|
||||||
|
ngx.status = code
|
||||||
|
end
|
||||||
|
ngx.print(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- error_code: 400
|
||||||
|
--- response_body
|
||||||
|
{"error_msg":"failed to check the configuration of plugin limit-count err: invalid \"required\" in docuement at pointer \"#\""}
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 7: invalid route: wrong count
|
||||||
|
--- config
|
||||||
|
location /t {
|
||||||
|
content_by_lua_block {
|
||||||
|
local t = require("lib.test_admin").test
|
||||||
|
local code, body = t('/apisix/admin/routes/1',
|
||||||
|
ngx.HTTP_PUT,
|
||||||
|
[[{
|
||||||
|
"plugins": {
|
||||||
|
"limit-count": {
|
||||||
|
"count": -100,
|
||||||
|
"time_window": 60,
|
||||||
|
"rejected_code": 503,
|
||||||
|
"key": "remote_addr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"upstream": {
|
||||||
|
"nodes": {
|
||||||
|
"127.0.0.1:1980": 1
|
||||||
|
},
|
||||||
|
"type": "roundrobin"
|
||||||
|
},
|
||||||
|
"uri": "/hello"
|
||||||
|
}]]
|
||||||
|
)
|
||||||
|
|
||||||
|
if code >= 300 then
|
||||||
|
ngx.status = code
|
||||||
|
end
|
||||||
|
ngx.print(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- error_code: 400
|
||||||
|
--- response_body
|
||||||
|
{"error_msg":"failed to check the configuration of plugin limit-count err: invalid \"minimum\" in docuement at pointer \"#\/count\""}
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 8: invalid route: wrong count + POST method
|
||||||
|
--- config
|
||||||
|
location /t {
|
||||||
|
content_by_lua_block {
|
||||||
|
local t = require("lib.test_admin").test
|
||||||
|
local code, body = t('/apisix/admin/routes/1',
|
||||||
|
ngx.HTTP_POST,
|
||||||
|
[[{
|
||||||
|
"plugins": {
|
||||||
|
"limit-count": {
|
||||||
|
"count": -100,
|
||||||
|
"time_window": 60,
|
||||||
|
"rejected_code": 503,
|
||||||
|
"key": "remote_addr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"upstream": {
|
||||||
|
"nodes": {
|
||||||
|
"127.0.0.1:1980": 1
|
||||||
|
},
|
||||||
|
"type": "roundrobin"
|
||||||
|
},
|
||||||
|
"uri": "/hello"
|
||||||
|
}]]
|
||||||
|
)
|
||||||
|
|
||||||
|
if code >= 300 then
|
||||||
|
ngx.status = code
|
||||||
|
end
|
||||||
|
ngx.print(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- error_code: 400
|
||||||
|
--- response_body
|
||||||
|
{"error_msg":"failed to check the configuration of plugin limit-count err: invalid \"minimum\" in docuement at pointer \"#\/count\""}
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 9: invalid service: missing key
|
||||||
|
--- config
|
||||||
|
location /t {
|
||||||
|
content_by_lua_block {
|
||||||
|
local t = require("lib.test_admin").test
|
||||||
|
local code, body = t('/apisix/admin/services/1',
|
||||||
|
ngx.HTTP_PUT,
|
||||||
|
[[{
|
||||||
|
"plugins": {
|
||||||
|
"limit-count": {
|
||||||
|
"count": 2,
|
||||||
|
"time_window": 60,
|
||||||
|
"rejected_code": 503
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"upstream": {
|
||||||
|
"nodes": {
|
||||||
|
"127.0.0.1:1980": 1
|
||||||
|
},
|
||||||
|
"type": "roundrobin"
|
||||||
|
}
|
||||||
|
}]]
|
||||||
|
)
|
||||||
|
|
||||||
|
if code >= 300 then
|
||||||
|
ngx.status = code
|
||||||
|
end
|
||||||
|
ngx.print(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- error_code: 400
|
||||||
|
--- response_body
|
||||||
|
{"error_msg":"failed to check the configuration of plugin limit-count err: invalid \"required\" in docuement at pointer \"#\""}
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 10: invalid service: wrong count
|
||||||
|
--- config
|
||||||
|
location /t {
|
||||||
|
content_by_lua_block {
|
||||||
|
local t = require("lib.test_admin").test
|
||||||
|
local code, body = t('/apisix/admin/services/1',
|
||||||
|
ngx.HTTP_PUT,
|
||||||
|
[[{
|
||||||
|
"plugins": {
|
||||||
|
"limit-count": {
|
||||||
|
"count": -100,
|
||||||
|
"time_window": 60,
|
||||||
|
"rejected_code": 503,
|
||||||
|
"key": "remote_addr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"upstream": {
|
||||||
|
"nodes": {
|
||||||
|
"127.0.0.1:1980": 1
|
||||||
|
},
|
||||||
|
"type": "roundrobin"
|
||||||
|
}
|
||||||
|
}]]
|
||||||
|
)
|
||||||
|
|
||||||
|
if code >= 300 then
|
||||||
|
ngx.status = code
|
||||||
|
end
|
||||||
|
ngx.print(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- error_code: 400
|
||||||
|
--- response_body
|
||||||
|
{"error_msg":"failed to check the configuration of plugin limit-count err: invalid \"minimum\" in docuement at pointer \"#\/count\""}
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=== TEST 11: invalid service: wrong count + POST method
|
||||||
|
--- config
|
||||||
|
location /t {
|
||||||
|
content_by_lua_block {
|
||||||
|
local t = require("lib.test_admin").test
|
||||||
|
local code, body = t('/apisix/admin/services/1',
|
||||||
|
ngx.HTTP_POST,
|
||||||
|
[[{
|
||||||
|
"plugins": {
|
||||||
|
"limit-count": {
|
||||||
|
"count": -100,
|
||||||
|
"time_window": 60,
|
||||||
|
"rejected_code": 503,
|
||||||
|
"key": "remote_addr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"upstream": {
|
||||||
|
"nodes": {
|
||||||
|
"127.0.0.1:1980": 1
|
||||||
|
},
|
||||||
|
"type": "roundrobin"
|
||||||
|
}
|
||||||
|
}]]
|
||||||
|
)
|
||||||
|
|
||||||
|
if code >= 300 then
|
||||||
|
ngx.status = code
|
||||||
|
end
|
||||||
|
ngx.print(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--- request
|
||||||
|
GET /t
|
||||||
|
--- error_code: 400
|
||||||
|
--- response_body
|
||||||
|
{"error_msg":"failed to check the configuration of plugin limit-count err: invalid \"minimum\" in docuement at pointer \"#\/count\""}
|
||||||
|
--- no_error_log
|
||||||
|
[error]
|
||||||
|
Loading…
Reference in New Issue
Block a user