-
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 13 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,15 +16,36 @@ | |||||
-- | ||||||
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 | ||||||
local string = string | ||||||
local table = table | ||||||
|
||||||
|
||||||
local _M = { | ||||||
version = 0.1, | ||||||
need_v3_filter = true, | ||||||
} | ||||||
|
||||||
local function check_router_refer(items, id) | ||||||
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 r_id = string.gsub(item["key"], "/", "_") | ||||||
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. can we replace |
||||||
local route = item.value | ||||||
if route.protocol and route.protocol.superior_id and route.protocol.superior_id == id then | ||||||
table.insert(refer_list,r_id) | ||||||
end | ||||||
::CONTINUE:: | ||||||
end | ||||||
return refer_list | ||||||
end | ||||||
|
||||||
|
||||||
|
||||||
local function check_conf(id, conf, need_id) | ||||||
if not conf then | ||||||
|
@@ -142,8 +163,18 @@ 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 = {} | ||||||
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
we don't need to init |
||||||
if items ~= nil then | ||||||
refer_list=check_router_refer(items,id) | ||||||
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
|
||||||
end | ||||||
if #refer_list >0 then | ||||||
local warn_message = key.." is referred by "..table.concat(refer_list,";;") | ||||||
return 400,warn_message | ||||||
end | ||||||
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. After thinking about it for a while, it seems that the 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 comments about core.tablepool. |
||||||
|
||||||
local res, err = core.etcd.delete(key) | ||||||
if not res then | ||||||
core.log.error("failed to delete stream route[", key, "]: ", err) | ||||||
|
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,46 @@ 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("Different between 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 | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -639,3 +639,86 @@ passed | |
{"error_msg":"property \"faults\" validation failed: wrong type: expected array, got string"} | ||
--- no_error_log | ||
[error] | ||
|
||
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. need three blank lines between test cases 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 |
||
|
||
|
||
=== TEST 17: put reference route + delete | ||
xrpc: | ||
protocols: | ||
- name: pingpong | ||
--- config | ||
location /t { | ||
content_by_lua_block { | ||
local t = require("lib.test_admin").test | ||
local etcd = require("apisix.core.etcd") | ||
local code, body = t('/apisix/admin/stream_routes/12', | ||
ngx.HTTP_PUT, | ||
[[{ | ||
"remote_addr": "127.0.0.1", | ||
"desc": "test-desc", | ||
"upstream": { | ||
"nodes": { | ||
"127.0.0.1:8080": 1 | ||
}, | ||
"type": "roundrobin" | ||
}, | ||
"protocol": { | ||
"name": "pingpong", | ||
"superior_id": "1", | ||
"conf": { | ||
"faults": [{ | ||
"commands": ["get", "ping"], | ||
"delay": 5 | ||
}] | ||
} | ||
"desc": "new route" | ||
}]], | ||
[[{ | ||
"value": { | ||
"remote_addr": "127.0.0.1", | ||
"desc": "test-desc", | ||
"upstream": { | ||
"nodes": { | ||
"127.0.0.1:8080": 1 | ||
}, | ||
"type": "roundrobin" | ||
}, | ||
"protocol": { | ||
"name": "pingpong", | ||
"superior_id": "1", | ||
"conf": { | ||
"faults": [{ | ||
"commands": ["get", "ping"], | ||
"delay": 5 | ||
}] | ||
} | ||
"desc": "new route" | ||
}, | ||
"key": "/apisix/stream_routes/12" | ||
}]] | ||
) | ||
ngx.status = code | ||
ngx.say(body) | ||
local res = assert(etcd.get('/stream_routes/12')) | ||
local create_time = res.body.node.value.create_time | ||
assert(create_time ~= nil, "create_time is nil") | ||
local update_time = res.body.node.value.update_time | ||
assert(update_time ~= nil, "update_time is nil") | ||
if code ~= 200 then | ||
ngx.status = code | ||
ngx.say(message) | ||
return | ||
end | ||
ngx.say("[push] code: ", code, " message: ", message) | ||
local id = string.sub(res.key, #"/apisix/stream_routes/" + 1) | ||
code, message = t('/apisix/admin/stream_routes/' .. id, ngx.HTTP_DELETE) | ||
ngx.say("[delete] code: ", code, " message: ", message) | ||
} | ||
} | ||
--- request | ||
GET /t | ||
--- response_body | ||
[push] code: 200 message: passed | ||
[delete] code: 400 message: /stream_routes/1 is referred by _apisix_stream_routes_12 | ||
--- no_error_log | ||
[error] |
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.