-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: validate the subordinate and check reference when deleting and adding… #8219
Changes from 4 commits
5d10f41
734b43f
4f13eed
f0f6ff9
9168493
cc276f7
7db5790
34f79d2
4dde2e9
cba2083
94cdf53
b6cc11e
bb5a2a5
f04b2c5
475007e
527110c
9f08dbb
02709ab
4ecd49f
3c7d4d3
dee8669
5aec5cb
1ae67e6
9f56771
71c0f89
2fc55c9
e1894f8
63f4d7b
775fff0
f322e4f
b5dba07
d69ce76
f6d98e2
a64bb1e
2854be0
ed245b5
c15e3e6
49609a7
3205a75
0cbd892
573578d
09e34e7
8ab326c
9b1533d
63ff87f
11315d8
23d4ace
5f4c836
aafaaf2
be47504
9289dd7
3f85069
d9f3a0a
dbd0e02
1517c85
cd17fcc
401ba10
2c0a1b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -16,6 +16,8 @@ | |||||||||||||||||||||||
-- | ||||||||||||||||||||||||
local core = require("apisix.core") | ||||||||||||||||||||||||
local utils = require("apisix.admin.utils") | ||||||||||||||||||||||||
local config_util = require("apisix.core.config_util") | ||||||||||||||||||||||||
local routes = require("apisix.stream.router.ip_port").routes | ||||||||||||||||||||||||
local stream_route_checker = require("apisix.stream.router.ip_port").stream_route_checker | ||||||||||||||||||||||||
local tostring = tostring | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
@@ -25,6 +27,51 @@ local _M = { | |||||||||||||||||||||||
need_v3_filter = true, | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
local function check_router_refer(items, key) | ||||||||||||||||||||||||
local refer_list = {} | ||||||||||||||||||||||||
for _, item in config_util.iterate_values(items) do | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||
if item.value == nil then | ||||||||||||||||||||||||
goto CONTINUE | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
local route = item.value | ||||||||||||||||||||||||
if route.protocol and route.protocol.superior_id then | ||||||||||||||||||||||||
local data | ||||||||||||||||||||||||
local setkey="/stream_routes/"..route.protocol.superior_id.."/refer" | ||||||||||||||||||||||||
local res, err = core.etcd.get(setkey,false) | ||||||||||||||||||||||||
if res then | ||||||||||||||||||||||||
if #res.body.node.value == 0 then | ||||||||||||||||||||||||
local v = core.json.decode("{}") | ||||||||||||||||||||||||
local r_id = item["key"] | ||||||||||||||||||||||||
v[r_id]=1 | ||||||||||||||||||||||||
data = core.json.encode(v) | ||||||||||||||||||||||||
else | ||||||||||||||||||||||||
local v = core.json.decode(res.body.node.value) | ||||||||||||||||||||||||
local r_id = item["key"] | ||||||||||||||||||||||||
v[r_id]=1 | ||||||||||||||||||||||||
data = core.json.encode(v) | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
local setres, err = core.etcd.set(setkey, data) | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should avoid writing this data to etcd. You set here, I don't see where we delete key. so There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The keys stream_routes_refer/super_ids will be update rather than grow . /apisix/stream_routes_refer/12 it meas the stream_route 22 and 23 have protocol.superior_id 12; if the stream_routes rule no change ,the value no change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so at what point do we delete Anyway, I don't think it's a good solution to write this relationship to etcd. Can we refer to the logic for removing the upstream? apisix/apisix/admin/upstreams.lua Lines 146 to 156 in a62d33f
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for your suggestion I changed the implementation. |
||||||||||||||||||||||||
if not setres then | ||||||||||||||||||||||||
core.log.error("failed to put stream route[", key, "]: ", err) | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
::CONTINUE:: | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
local referkey = key .. "/refer" | ||||||||||||||||||||||||
local rescheck, err = core.etcd.get(referkey,false) | ||||||||||||||||||||||||
if rescheck then | ||||||||||||||||||||||||
if rescheck.body.node ~= nil then | ||||||||||||||||||||||||
local refer_values=core.json.decode(rescheck.body.node.value) | ||||||||||||||||||||||||
for v,_ in pairs(refer_values) do | ||||||||||||||||||||||||
table.insert(refer_list,v) | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
return refer_list | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
local function check_conf(id, conf, need_id) | ||||||||||||||||||||||||
if not conf then | ||||||||||||||||||||||||
|
@@ -142,14 +189,23 @@ function _M.delete(id) | |||||||||||||||||||||||
return 400, {error_msg = "missing stream route id"} | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
local items,_ = routes() | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||
local key = "/stream_routes/" .. id | ||||||||||||||||||||||||
-- core.log.info("key: ", key) | ||||||||||||||||||||||||
local refer_list=check_router_refer(items,key) | ||||||||||||||||||||||||
local warn_message | ||||||||||||||||||||||||
if #refer_list >0 then | ||||||||||||||||||||||||
warn_message = key.." is refered by "..table.concat(refer_list,";;") | ||||||||||||||||||||||||
else | ||||||||||||||||||||||||
warn_message = key.." is refered by None" | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
local res, err = core.etcd.delete(key) | ||||||||||||||||||||||||
if not res then | ||||||||||||||||||||||||
core.log.error("failed to delete stream route[", key, "]: ", err) | ||||||||||||||||||||||||
return 503, {error_msg = err} | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
res.body["refer"]=warn_message | ||||||||||||||||||||||||
return res.status, res.body | ||||||||||||||||||||||||
end | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -447,6 +447,7 @@ http { | |
|
||
init_worker_by_lua_block { | ||
apisix.http_init_worker() | ||
apisix.stream_init_worker() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't need this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to explain my code design : |
||
} | ||
|
||
exit_worker_by_lua_block { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,23 +63,45 @@ local create_router | |
do | ||
local sni_to_items = {} | ||
local tls_routes = {} | ||
local routeid_to_protocols = {} | ||
|
||
function create_router(items) | ||
local tls_routes_idx = 1 | ||
local other_routes_idx = 1 | ||
core.table.clear(tls_routes) | ||
core.table.clear(other_routes) | ||
core.table.clear(sni_to_items) | ||
|
||
core.table.clear(routeid_to_protocols) | ||
for _, item in config_util.iterate_values(items) do | ||
if item.value == nil then | ||
goto CONTINUE | ||
end | ||
local route = item.value | ||
if route.protocol then | ||
routeid_to_protocols[item.key]=route.protocol.name | ||
else | ||
routeid_to_protocols[item.key]="No-Protocol" | ||
end | ||
::CONTINUE:: | ||
end | ||
|
||
for _, item in config_util.iterate_values(items) do | ||
if item.value == nil then | ||
goto CONTINUE | ||
end | ||
local route = item.value | ||
if route.protocol and route.protocol.superior_id then | ||
-- subordinate route won't be matched in the entry | ||
-- TODO: check the subordinate relationship in the Admin API | ||
local key="/apisix/stream_routes/"..route.protocol.superior_id | ||
if routeid_to_protocols[key] == nil then | ||
core.log.warn("There is not exist stream_route: "..key) | ||
elseif routeid_to_protocols[key] == "No-Protocol" then | ||
core.log.warn("The stream_route: "..key.." may lacks procotol configuration") | ||
elseif routeid_to_protocols[key] == route.protocol.name then | ||
goto CONTINUE | ||
else | ||
core.log.warn("RPC procotol is different in stream_route:"..item.key.." and "..key) | ||
end | ||
goto CONTINUE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems we don't need to modify here? I see that the test cases don't cover the changes here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, no action here, just warn logging。In order to remind users, do you think it's ok to keep this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to check this when adding the stream route and return it if it is wrong. In addition, two for loops are used here, which is even less efficient. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a logic that checking this when adding the stream route , there are two situations to judge: So I would add a logic that Validate if the protocol matches the subordinate only if the stream route with superior id exists。Do you think it's ok? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I have a suggestion that in this PR we only finish checking refer when deleting the stream route. You can open a new issue and PR to do what you said. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep it simple and clear enough in this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
end | ||
|
||
|
@@ -146,7 +168,7 @@ do | |
if router_ver ~= user_routes.conf_version then | ||
local err = create_router(user_routes.values) | ||
if err then | ||
return false, "failed to create router: " .. err | ||
return false, "failed to create router: " .. err | ||
end | ||
|
||
router_ver = user_routes.conf_version | ||
|
@@ -236,6 +258,7 @@ function _M.stream_init_worker(filter) | |
checker = stream_route_checker, | ||
filter = filter, | ||
}) | ||
|
||
|
||
if not user_routes then | ||
error("failed to create etcd instance for fetching /stream_routes : " | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.