You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by to...@apache.org on 2021/07/14 11:58:36 UTC

[apisix] branch master updated: fix: ref check while deleting proto via Admin API (#4575)

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

tokers 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 bfa70e4  fix: ref check while deleting proto via Admin API (#4575)
bfa70e4 is described below

commit bfa70e4f86ca13aca588ba9f59cf24f334200b31
Author: clown <bl...@126.com>
AuthorDate: Wed Jul 14 19:58:27 2021 +0800

    fix: ref check while deleting proto via Admin API (#4575)
---
 apisix/admin/proto.lua |  33 +++++---
 t/admin/proto.t        | 203 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 225 insertions(+), 11 deletions(-)

diff --git a/apisix/admin/proto.lua b/apisix/admin/proto.lua
index f7f7a91..687bc4f 100644
--- a/apisix/admin/proto.lua
+++ b/apisix/admin/proto.lua
@@ -117,25 +117,30 @@ function _M.post(id, conf)
     return res.status, res.body
 end
 
-function _M.check_proto_used(plugins, deleting, ptype, pid)
+local function check_proto_used(plugins, deleting, ptype, pid)
 
-    core.log.info("plugins1: ", core.json.delay_encode(plugins, true))
+    --core.log.info("check_proto_used plugins: ", core.json.delay_encode(plugins, true))
+    --core.log.info("check_proto_used deleting: ", deleting)
+    --core.log.info("check_proto_used ptype: ", ptype)
+    --core.log.info("check_proto_used pid: ", pid)
 
     if plugins then
         if type(plugins) == "table" and plugins["grpc-transcode"]
            and plugins["grpc-transcode"].proto_id
            and tostring(plugins["grpc-transcode"].proto_id) == deleting then
-            return 400, {error_msg = "can not delete this proto,"
+            return false, {error_msg = "can not delete this proto,"
                                      .. ptype .. " [" .. pid
                                      .. "] is still using it now"}
         end
     end
+    return true
 end
 
 function _M.delete(id)
     if not id then
         return 400, {error_msg = "missing proto id"}
     end
+    core.log.info("proto delete: ", id)
 
     local routes, routes_ver = get_routes()
 
@@ -144,13 +149,16 @@ function _M.delete(id)
 
     if routes_ver and routes then
         for _, route in ipairs(routes) do
-            if type(route) == "table" and route.value
-               and route.value.plugins then
-                  return _M.check_proto_used(route.value.plugins, id, "route",
-                                             route.value.id)
+            core.log.info("proto delete route item: ", core.json.delay_encode(route, true))
+            if type(route) == "table" and route.value and route.value.plugins then
+                local ret, err = check_proto_used(route.value.plugins, id, "route",route.value.id)
+                if not ret then
+                    return 400, err
+                end
             end
         end
     end
+    core.log.info("proto delete route ref check pass: ", id)
 
     local services, services_ver = get_services()
 
@@ -159,13 +167,16 @@ function _M.delete(id)
 
     if services_ver and services then
         for _, service in ipairs(services) do
-            if type(service) == "table" and service.value
-               and service.value.plugins then
-                  return _M.check_proto_used(service.value.plugins, id,
-                                             "service", service.value.id)
+            if type(service) == "table" and service.value and service.value.plugins then
+                local ret, err = check_proto_used(service.value.plugins, id,
+                                                "service", service.value.id)
+                if not ret then
+                    return 400, err
+                end
             end
         end
     end
+    core.log.info("proto delete service ref check pass: ", id)
 
     local key = "/proto/" .. id
     -- core.log.info("key: ", key)
diff --git a/t/admin/proto.t b/t/admin/proto.t
new file mode 100644
index 0000000..85de3e8
--- /dev/null
+++ b/t/admin/proto.t
@@ -0,0 +1,203 @@
+#
+# 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.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_root_location();
+no_shuffle();
+log_level("info");
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: put proto (id:1)
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local etcd = require("apisix.core.etcd")
+            local code, message = t('/apisix/admin/proto/1',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "content": "syntax = \"proto3\";
+                            package proto;
+                            message HelloRequest{
+                            string name = 1;
+                                }
+
+                            message HelloResponse{
+                            int32 code = 1;
+                            string msg = 2;
+                                }
+                                // The greeting service definition.
+                            service Hello {
+                                    // Sends a greeting
+                            rpc SayHi (HelloRequest) returns (HelloResponse){}
+                                }"
+                }]],
+                [[
+                    {
+                        "action": "set"
+                    }
+                ]]
+                )
+
+            if code ~= 200 then
+                ngx.status = code
+                ngx.say("[put proto] code: ", code, " message: ", message)
+                return
+            end
+
+            ngx.say("[put proto] code: ", code, " message: ", message)
+        }
+    }
+--- request
+GET /t
+--- response_body
+[put proto] code: 200 message: passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 2: delete proto(id:1)
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local etcd = require("apisix.core.etcd")
+            local code, message = t('/apisix/admin/proto/1',
+                 ngx.HTTP_DELETE,
+                 nil,
+                 [[{
+                    "action": "delete"
+                }]]
+                )
+
+            if code ~= 200 then
+                ngx.status = code
+                ngx.say("[delete proto] code: ", code, " message: ", message)
+                return
+            end
+
+            ngx.say("[delete proto] code: ", code, " message: ", message)
+        }
+    }
+--- request
+GET /t
+--- response_body
+[delete proto] code: 200 message: passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 3: put proto (id:2) + route refer proto(proto id 2) + delete proto(proto id 2)
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local etcd = require("apisix.core.etcd")
+            local code, message = t('/apisix/admin/proto/2',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "content": "syntax = \"proto3\";
+                            package proto;
+                            message HelloRequest{
+                            string name = 1;
+                                }
+
+                            message HelloResponse{
+                            int32 code = 1;
+                            string msg = 2;
+                                }
+                                // The greeting service definition.
+                            service Hello {
+                                    // Sends a greeting
+                            rpc SayHi (HelloRequest) returns (HelloResponse){}
+                                }"
+                }]],
+                [[
+                    {
+                        "action": "set"
+                    }
+                ]]
+                )
+
+            if code ~= 200 then
+                ngx.status = code
+                ngx.say("[put proto] code: ", code, " message: ", message)
+                return
+            end
+            ngx.say("[put proto] code: ", code, " message: ", message)
+
+
+            code, message = t('/apisix/admin/routes/2',
+                 ngx.HTTP_PUT,
+                 [[{
+                        "methods": ["GET"],
+                        "plugins": {
+                            "grpc-transcode": {
+                            "disable": false,
+                            "method": "SayHi",
+                            "proto_id": 2,
+                            "service": "proto.Hello"
+                            }
+                        },
+                        "upstream": {
+                            "nodes": {
+                                "127.0.0.1:8080": 1
+                            },
+                            "type": "roundrobin"
+                        },
+                        "uri": "/grpc/sayhi",
+                        "name": "hi-grpc"
+                }]],
+                [[{
+                    "action": "set"
+                }]]
+                )
+
+            if code ~= 200 then
+                ngx.status = code
+                ngx.say("[route refer proto] code: ", code, " message: ", message)
+                return
+            end
+            ngx.say("[route refer proto] code: ", code, " message: ", message)
+
+
+            code, message = t('/apisix/admin/proto/2',
+                 ngx.HTTP_DELETE,
+                 nil,
+                 [[{
+                    "action": "delete"
+                }]]
+                )
+
+            ngx.say("[delete proto] code: ", code)
+        }
+    }
+--- request
+GET /t
+--- response_body
+[put proto] code: 200 message: passed
+[route refer proto] code: 200 message: passed
+[delete proto] code: 400
+--- no_error_log
+[error]