This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new c0c906eb4 feat: limit-count plugin with redis cluster support tls/ssl 
(#8558)
c0c906eb4 is described below

commit c0c906eb4d62886ffa4b0938b017dc4810cfe639
Author: Ashing Zheng <axing...@gmail.com>
AuthorDate: Tue Jan 3 13:35:57 2023 +0800

    feat: limit-count plugin with redis cluster support tls/ssl (#8558)
    
    Fixes https://github.com/apache/apisix/issues/8413
---
 apisix/plugins/limit-count/init.lua                |   6 +
 .../limit-count/limit-count-redis-cluster.lua      |   4 +
 ci/pod/docker-compose.plugin.yml                   |  50 +++++++
 docs/en/latest/plugins/limit-count.md              |   2 +
 docs/zh/latest/plugins/limit-count.md              |   2 +
 t/plugin/limit-count-redis-cluster.t               | 158 +++++++++++++++++++++
 6 files changed, 222 insertions(+)

diff --git a/apisix/plugins/limit-count/init.lua 
b/apisix/plugins/limit-count/init.lua
index c9051d2e1..f14cdb980 100644
--- a/apisix/plugins/limit-count/init.lua
+++ b/apisix/plugins/limit-count/init.lua
@@ -79,6 +79,12 @@ local policy_to_additional_properties = {
             redis_cluster_name = {
                 type = "string",
             },
+            redis_cluster_ssl = {
+                type = "boolean", default = false,
+            },
+            redis_cluster_ssl_verify = {
+                type = "boolean", default = false,
+            },
         },
         required = {"redis_cluster_nodes", "redis_cluster_name"},
     },
diff --git a/apisix/plugins/limit-count/limit-count-redis-cluster.lua 
b/apisix/plugins/limit-count/limit-count-redis-cluster.lua
index 27d4e85fa..453f60ef3 100644
--- a/apisix/plugins/limit-count/limit-count-redis-cluster.lua
+++ b/apisix/plugins/limit-count/limit-count-redis-cluster.lua
@@ -46,6 +46,10 @@ local function new_redis_cluster(conf)
         read_timeout = conf.redis_timeout,
         auth = conf.redis_password,
         dict_name = "plugin-limit-count-redis-cluster-slot-lock",
+        connect_opts = {
+            ssl = conf.redis_cluster_ssl,
+            ssl_verify = conf.redis_cluster_ssl_verify,
+        }
     }
 
     for i, conf_item in ipairs(conf.redis_cluster_nodes) do
diff --git a/ci/pod/docker-compose.plugin.yml b/ci/pod/docker-compose.plugin.yml
index 4b8c2a4c1..8ddeef202 100644
--- a/ci/pod/docker-compose.plugin.yml
+++ b/ci/pod/docker-compose.plugin.yml
@@ -262,6 +262,56 @@ services:
       CONTEXT_MODE: "self-host"
       FUNC_CONTEXT: 
"{\"name\":\"HelloWorld\",\"version\":\"v1.0.0\",\"port\":\"8080\",\"runtime\":\"Knative\"}"
 
+  ## RedisCluster Enable TLS
+  redis-node-0:
+    image: docker.io/bitnami/redis-cluster:7.0
+    volumes:
+      - ./t/certs:/certs
+    environment:
+      - 'ALLOW_EMPTY_PASSWORD=yes'
+      - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2'
+      - 'REDIS_TLS_ENABLED=yes'
+      - 'REDIS_TLS_CERT_FILE=/certs/mtls_server.crt'
+      - 'REDIS_TLS_KEY_FILE=/certs/mtls_server.key'
+      - 'REDIS_TLS_CA_FILE=/certs/mtls_ca.crt'
+      - 'REDIS_TLS_AUTH_CLIENTS=no'
+    ports:
+      - '7000:6379'
+
+  redis-node-1:
+    image: docker.io/bitnami/redis-cluster:7.0
+    volumes:
+      - ./t/certs:/certs
+    environment:
+      - 'ALLOW_EMPTY_PASSWORD=yes'
+      - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2'
+      - 'REDIS_TLS_ENABLED=yes'
+      - 'REDIS_TLS_CERT_FILE=/certs/mtls_server.crt'
+      - 'REDIS_TLS_KEY_FILE=/certs/mtls_server.key'
+      - 'REDIS_TLS_CA_FILE=/certs/mtls_ca.crt'
+      - 'REDIS_TLS_AUTH_CLIENTS=no'
+    ports:
+      - '7001:6379'
+
+  redis-node-2:
+    image: docker.io/bitnami/redis-cluster:7.0
+    volumes:
+      - ./t/certs:/certs
+    depends_on:
+      - redis-node-0
+      - redis-node-1
+    environment:
+      - 'ALLOW_EMPTY_PASSWORD=yes'
+      - 'REDIS_CLUSTER_REPLICAS=0'
+      - 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2'
+      - 'REDIS_CLUSTER_CREATOR=yes'
+      - 'REDIS_TLS_ENABLED=yes'
+      - 'REDIS_TLS_CERT_FILE=/certs/mtls_server.crt'
+      - 'REDIS_TLS_KEY_FILE=/certs/mtls_server.key'
+      - 'REDIS_TLS_CA_FILE=/certs/mtls_ca.crt'
+      - 'REDIS_TLS_AUTH_CLIENTS=no'
+    ports:
+      - '7002:6379'
 
 networks:
   apisix_net:
diff --git a/docs/en/latest/plugins/limit-count.md 
b/docs/en/latest/plugins/limit-count.md
index b098dbd32..75c0eeb79 100644
--- a/docs/en/latest/plugins/limit-count.md
+++ b/docs/en/latest/plugins/limit-count.md
@@ -51,6 +51,8 @@ The `limit-count` Plugin limits the number of requests to 
your service by a give
 | redis_timeout           | integer | False                                    
 | 1000          | [1,...]                                | Timeout in 
milliseconds for any command submitted to the Redis server. Used when the 
`policy` attribute is set to `redis` or `redis-cluster`.                        
                                                                                
                                                                                
                             [...]
 | redis_cluster_nodes     | array   | required when `policy` is 
`redis-cluster` |               |                                        | 
Addresses of Redis cluster nodes. Used when the `policy` attribute is set to 
`redis-cluster`.                                                                
                                                                                
                                                                                
                                     [...]
 | redis_cluster_name      | string  | required when `policy` is 
`redis-cluster` |               |                                        | Name 
of the Redis cluster service nodes. Used when the `policy` attribute is set to 
`redis-cluster`.                                                                
                                                                                
                                                                                
                              [...]
+| redis_cluster_ssl      | boolean  |  False |     false         |             
                           | If set to `true`, then uses SSL to connect to 
redis-cluster. Used when the `policy` attribute is set to `redis-cluster`.      
                                                                                
                                                                                
                                                                                
                   [...]
+| redis_cluster_ssl_verify      | boolean  | False |    false      |           
                             | If set to `true`, then verifies the validity of 
the server SSL certificate. Used when the `policy` attribute is set to 
`redis-cluster`.                                                                
                                                                                
                                                                                
                        [...]
 
 ## Enabling the Plugin
 
diff --git a/docs/zh/latest/plugins/limit-count.md 
b/docs/zh/latest/plugins/limit-count.md
index 3055d2267..76f15c2a7 100644
--- a/docs/zh/latest/plugins/limit-count.md
+++ b/docs/zh/latest/plugins/limit-count.md
@@ -52,6 +52,8 @@ description: 本文介绍了 Apache APISIX limit-count 插件的相关操作,
 | redis_timeout       | integer | 否        | 1000          | [1,...]           
                      | 当 `policy` 设置为 `redis` 或 `redis-cluster` 时,Redis 
服务节点的超时时间(以毫秒为单位)。|
 | redis_cluster_nodes | array   | 否        |               |                   
                      | 当使用 `redis-cluster` 限速策略时,Redis 
集群服务节点的地址列表(至少需要两个地址)。**当 `policy` 属性设置为 `redis-cluster` 时必选。**|
 | redis_cluster_name  | string  | 否        |               |                   
                      | 当使用 `redis-cluster` 限速策略时,Redis 集群服务节点的名称。**当 `policy` 
设置为 `redis-cluster` 时必选。**|
+| redis_cluster_ssl  | boolean  | 否        |     false    |                    
                     | 当使用 `redis-cluster` 限速策略时, 如果设置为 true,则使用 SSL 连接到 
`redis-cluster` |
+| redis_cluster_ssl_verify  | boolean  | 否        |     false        |         
                                | 当使用 `redis-cluster` 限速策略时,如果设置为 true,则验证服务器 
SSL 证书的有效性 |
 
 ## 启用插件
 
diff --git a/t/plugin/limit-count-redis-cluster.t 
b/t/plugin/limit-count-redis-cluster.t
index 7f5eb2c1f..7a4798a60 100644
--- a/t/plugin/limit-count-redis-cluster.t
+++ b/t/plugin/limit-count-redis-cluster.t
@@ -384,3 +384,161 @@ GET /hello
 hello world
 --- error_log
 connection refused
+
+
+
+=== TEST 12: set route, use error type for redis_cluster_ssl and 
redis_cluster_ssl_verify
+--- 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-cluster",
+                            "redis_timeout": 1001,
+                            "redis_cluster_nodes": [
+                                "127.0.0.1:7000",
+                                "127.0.0.1:7001"
+                            ],
+                            "redis_cluster_name": "redis-cluster-1",
+                            "redis_cluster_ssl": "true",
+                            "redis_cluster_ssl_verify": "false"
+                        }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    },
+                    "uri": "/hello"
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.print(body)
+        }
+    }
+--- error_code: 400
+--- response_body
+{"error_msg":"failed to check the configuration of plugin limit-count err: 
else clause did not match"}
+
+
+
+=== TEST 13: set route, redis_cluster_ssl_verify is true(will cause ssl 
handshake err), with enable degradation switch
+--- 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,
+                [[{
+                    "uri": "/hello",
+                    "plugins": {
+                        "limit-count": {
+                            "count": 2,
+                            "time_window": 60,
+                            "rejected_code": 503,
+                            "key": "remote_addr",
+                            "policy": "redis-cluster",
+                            "allow_degradation": true,
+                            "redis_timeout": 1001,
+                            "redis_cluster_nodes": [
+                                "127.0.0.1:7000",
+                                "127.0.0.1:7001"
+                            ],
+                            "redis_cluster_name": "redis-cluster-1",
+                            "redis_cluster_ssl": true,
+                            "redis_cluster_ssl_verify": true
+                        }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    }
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 14: enable degradation switch for TEST 13
+--- request
+GET /hello
+--- response_body
+hello world
+--- error_log
+failed to do ssl handshake
+
+
+
+=== TEST 15: set route, with redis_cluster_nodes and redis_cluster_name 
redis_cluster_ssl and redis_cluster_ssl_verify
+--- 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,
+                [[{
+                    "uri": "/hello",
+                    "plugins": {
+                        "limit-count": {
+                            "count": 2,
+                            "time_window": 60,
+                            "rejected_code": 503,
+                            "key": "remote_addr",
+                            "policy": "redis-cluster",
+                            "redis_timeout": 1001,
+                            "redis_cluster_nodes": [
+                                "127.0.0.1:7000",
+                                "127.0.0.1:7001"
+                            ],
+                            "redis_cluster_name": "redis-cluster-1",
+                            "redis_cluster_ssl": true,
+                            "redis_cluster_ssl_verify": false
+                        }
+                    },
+                    "upstream": {
+                        "nodes": {
+                            "127.0.0.1:1980": 1
+                        },
+                        "type": "roundrobin"
+                    }
+                }]]
+                )
+
+            if code >= 300 then
+                ngx.status = code
+            end
+            ngx.say(body)
+        }
+    }
+--- response_body
+passed
+
+
+
+=== TEST 16: up the limit
+--- pipelined_requests eval
+["GET /hello", "GET /hello", "GET /hello", "GET /hello"]
+--- error_code eval
+[200, 200, 503, 503]

Reply via email to