Skip to content

Commit

Permalink
fix: ref check while deleting proto via Admin API (#4575)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluesgao committed Jul 14, 2021
1 parent 13ec787 commit bfa70e4
Show file tree
Hide file tree
Showing 2 changed files with 225 additions and 11 deletions.
33 changes: 22 additions & 11 deletions apisix/admin/proto.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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()

Expand All @@ -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)
Expand Down
203 changes: 203 additions & 0 deletions t/admin/proto.t
Original file line number Diff line number Diff line change
@@ -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]

0 comments on commit bfa70e4

Please sign in to comment.