You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/02/24 02:54:55 UTC
[incubator-apisix] branch master updated: feature: Support password
auth for plugin limit-count-redis (#1150)
This is an automated email from the ASF dual-hosted git repository.
membphis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 5b1a47a feature: Support password auth for plugin limit-count-redis (#1150)
5b1a47a is described below
commit 5b1a47a38ec6d76d62132e02448bc1e122d16b90
Author: wonglend <gk...@qq.com>
AuthorDate: Mon Feb 24 10:54:48 2020 +0800
feature: Support password auth for plugin limit-count-redis (#1150)
---
.travis.yml | 6 +-
lua/apisix/plugins/limit-count.lua | 5 +-
.../plugins/limit-count/limit-count-redis.lua | 14 ++
t/plugin/limit-count-redis.t | 234 +++++++++++++++++++++
4 files changed, 256 insertions(+), 3 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index ee84fd8..58ce94f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ matrix:
include:
- os: linux
services:
- - redis-server
+ - docker
env: OSNAME=linux_openresty
- os: osx
env: OSNAME=osx_openresty
@@ -21,7 +21,7 @@ matrix:
- /usr/local/Homebrew
- os: linux
services:
- - redis-server
+ - docker
env: OSNAME=linux_tengine
- os: linux
env: OSNAME=linux_apisix_luarocks
@@ -51,6 +51,8 @@ before_cache:
- brew cleanup
before_install:
+ - docker pull redis:3.0-alpine
+ - docker run --rm -itd -p 6379:6379 --name apisix_redis redis:3.0-alpine
- echo $OSNAME
- $PWD/.travis/${OSNAME}_runner.sh before_install
diff --git a/lua/apisix/plugins/limit-count.lua b/lua/apisix/plugins/limit-count.lua
index 8989d42..c95e3f6 100644
--- a/lua/apisix/plugins/limit-count.lua
+++ b/lua/apisix/plugins/limit-count.lua
@@ -45,6 +45,9 @@ local schema = {
redis_port = {
type = "integer", minimum = 1
},
+ redis_password = {
+ type = "string", minLength = 0
+ },
redis_timeout = {
type = "integer", minimum = 1
},
@@ -122,7 +125,7 @@ function _M.access(conf, ctx)
end
core.log.error("failed to limit req: ", err)
- return 500
+ return 500, {error_msg = "failed to limit count: ", err}
end
core.response.set_header("X-RateLimit-Limit", conf.count,
diff --git a/lua/apisix/plugins/limit-count/limit-count-redis.lua b/lua/apisix/plugins/limit-count/limit-count-redis.lua
index ef86ab1..ab5dbeb 100644
--- a/lua/apisix/plugins/limit-count/limit-count-redis.lua
+++ b/lua/apisix/plugins/limit-count/limit-count-redis.lua
@@ -51,6 +51,20 @@ function _M.incoming(self, key)
return false, err
end
+ local count
+ count, err = red:get_reused_times()
+ if 0 == count then
+ if conf.redis_password and conf.redis_password ~= '' then
+ local ok, err = red:auth(conf.redis_password)
+ if not ok then
+ return nil, err
+ end
+ end
+ elseif err then
+ -- core.log.info(" err: ", err)
+ return nil, err
+ end
+
local limit = self.limit
local window = self.window
local remaining
diff --git a/t/plugin/limit-count-redis.t b/t/plugin/limit-count-redis.t
index 63860ac..559d8a8 100644
--- a/t/plugin/limit-count-redis.t
+++ b/t/plugin/limit-count-redis.t
@@ -209,3 +209,237 @@ passed
[404, 503, 404, 503, 503]
--- no_error_log
[error]
+
+
+
+=== TEST 6: set route, with redis host, port and right password
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ -- set redis password
+ local redis = require "resty.redis"
+
+ local red = redis:new()
+
+ red:set_timeout(1000) -- 1 sec
+
+ local ok, err = red:connect("127.0.0.1", 6379)
+ if not ok then
+ ngx.say("failed to connect: ", err)
+ return
+ end
+
+ -- for get_reused_times works
+ -- local ok, err = red:set_keepalive(10000, 100)
+ -- if not ok then
+ -- ngx.say("failed to set keepalive: ", err)
+ -- return
+ -- end
+
+ local count
+ count, err = red:get_reused_times()
+ if 0 == count then
+ local res, err = red:eval([[
+ local key = 'requirepass'
+ local value = "foobared"
+ -- redis.replicate_commands()
+ local val = redis.pcall('CONFIG', 'SET', key, value)
+ return val
+ ]], 0)
+ --
+ if not res then
+ ngx.say("failed to set: ", err)
+ return
+ end
+ elseif err then
+ -- ngx.say("already set requirepass done: ", err)
+ return
+ end
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "uri": "/hello",
+ "plugins": {
+ "limit-count": {
+ "count": 2,
+ "time_window": 60,
+ "rejected_code": 503,
+ "key": "remote_addr",
+ "policy": "redis",
+ "redis_host": "127.0.0.1",
+ "redis_port": 6379,
+ "redis_timeout": 1001,
+ "redis_password": "foobared"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 7: up the limit
+--- pipelined_requests eval
+["GET /hello", "GET /hello", "GET /hello", "GET /hello"]
+--- error_code eval
+[200, 200, 503, 503]
+--- no_error_log
+[error]
+
+
+
+=== TEST 8: up the limit
+--- pipelined_requests eval
+["GET /hello1", "GET /hello", "GET /hello2", "GET /hello", "GET /hello"]
+--- error_code eval
+[404, 503, 404, 503, 503]
+--- no_error_log
+[error]
+
+
+
+=== TEST 9: set route, with redis host, port and wrong password
+--- 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,
+ "key": "remote_addr",
+ "policy": "redis",
+ "redis_host": "127.0.0.1",
+ "redis_port": 6379,
+ "redis_timeout": 1001,
+ "redis_password": "WRONG_foobared"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello_new"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.print(body)
+ }
+ }
+--- request
+GET /t
+--- error_code eval
+200
+--- no_error_log
+[error]
+
+
+
+=== TEST 10: request for TEST 9
+--- request
+GET /hello_new
+--- error_code eval
+500
+--- response_body
+{"1":"ERR invalid password","error_msg":"failed to limit count: "}
+--- error_log
+failed to limit req: ERR invalid password
+
+
+
+=== TEST 11: multi request for TEST 9
+--- pipelined_requests eval
+["GET /hello_new", "GET /hello1", "GET /hello1", "GET /hello_new"]
+--- error_code eval
+[500, 404, 404, 500]
+
+
+
+=== TEST 12: restore redis password to ''
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ -- set redis password
+ local redis = require "resty.redis"
+
+ local red = redis:new()
+
+ red:set_timeout(1000) -- 1 sec
+
+ local ok, err = red:connect("127.0.0.1", 6379)
+ if not ok then
+ ngx.say("failed to connect: ", err)
+ return
+ end
+
+ -- for get_reused_times works
+ -- local ok, err = red:set_keepalive(10000, 100)
+ -- if not ok then
+ -- ngx.say("failed to set keepalive: ", err)
+ -- return
+ -- end
+
+ local count
+ count, err = red:get_reused_times()
+ if 0 == count then
+ local redis_password = "foobared"
+ if redis_password and redis_password ~= '' then
+ local ok, err = red:auth(redis_password)
+ if not ok then
+ return nil, err
+ end
+ end
+ local res, err = red:eval([[
+ local key = 'requirepass'
+ local value = ''
+ -- redis.replicate_commands()
+ local val = redis.pcall('CONFIG', 'SET', key, value)
+ return val
+ ]], 0)
+ --
+ if not res then
+ ngx.say("failed to set: ", err)
+ return
+ end
+ elseif err then
+ -- ngx.say("already set requirepass done: ", err)
+ return
+ end
+ }
+ }
+--- request
+GET /t
+--- error_code eval
+200
+--- no_error_log
+[error]