feature: supported PATCH method for admin routes API.

This commit is contained in:
Yuansheng 2019-08-04 12:48:23 +08:00 committed by YuanSheng Wang
parent 1ce988346a
commit 19e09b539f
3 changed files with 156 additions and 9 deletions

View File

@ -16,7 +16,7 @@ local resources = {
}
local _M = {version = 0.1}
local _M = {version = 0.2}
local router
@ -46,7 +46,7 @@ local function run(params)
req_body = data
end
local code, data = resource[method](params.id, req_body)
local code, data = resource[method](params.id, req_body, params.sub_path)
if code then
core.response.exit(code, data)
end
@ -60,25 +60,36 @@ end
local uri_route = {
{
path = [[/apisix/admin/{res:routes|services|upstreams|consumers|ssl}]],
handler = run
handler = run,
method = {"GET", "PUT", "POST", "DELETE"},
},
{
path = [[/apisix/admin/{res:routes|services|upstreams|consumers|ssl}]]
.. [[/{id:[\d\w_]+}]],
handler = run
handler = run,
method = {"GET", "PUT", "POST", "DELETE"},
},
{
path = [[/apisix/admin/schema/{res:plugins}/{id:[\d\w-]+}]],
handler = run
handler = run,
method = {"GET", "PUT", "POST", "DELETE"},
},
{
path = [[/apisix/admin/{res:schema}/]]
.. [[{id:route|service|upstream|consumer|ssl}]],
handler = run
handler = run,
method = {"GET", "PUT", "POST", "DELETE"},
},
{
path = [[/apisix/admin/plugins/list]],
handler = get_plugins_list
handler = get_plugins_list,
method = {"GET", "PUT", "POST", "DELETE"},
},
{
path = [[/apisix/admin/{res:routes|services|upstreams|consumers|ssl}]]
.. [[/{id:[\d\w_]+}/{sub_path:.*}]],
handler = run,
method = {"PATCH"},
},
}
@ -89,7 +100,6 @@ function _M.init_worker()
end
router = route.new(uri_route)
router:compile()
end

View File

@ -4,7 +4,7 @@ local tostring = tostring
local _M = {
version = 0.1,
version = 0.2,
}
@ -146,4 +146,75 @@ function _M.delete(id)
end
function _M.patch(id, conf, sub_path)
if not id then
return 400, {error_msg = "missing route id"}
end
if not sub_path then
return 400, {error_msg = "missing sub-path"}
end
if not conf then
return 400, {error_msg = "missing new configuration"}
end
local key = "/routes"
if id then
key = key .. "/" .. id
end
local res_old, err = core.etcd.get(key)
if not res_old then
core.log.error("failed to delete route[", key, "]: ", err)
return 500, {error_msg = err}
end
if res_old.status ~= 200 then
return res_old.status, res_old.body
end
core.log.info("key: ", key, " old value: ",
core.json.delay_encode(res_old, true))
local node_value = res_old.body.node.value
local sub_value = node_value
local sub_paths = core.utils.split_uri(sub_path)
for i = 1, #sub_paths - 1 do
local sub_name = sub_paths[i]
if sub_value[sub_name] == nil then
sub_value[sub_name] = {}
end
sub_value = sub_value[sub_name]
if type(sub_value) ~= "table" then
return 400, "invalid sub-path: /"
.. core.table.concat(sub_paths, 1, i)
end
end
if type(sub_value) ~= "table" then
return 400, "invalid sub-path: /" .. sub_path
end
local sub_name = sub_paths[#sub_paths]
sub_value[sub_name] = conf
core.log.info("new conf: ", core.json.delay_encode(node_value, true))
local id, err = check_conf(id, node_value, true)
if not id then
return 400, err
end
-- TODO: this is not safe, we need to use compare-set
local res, err = core.etcd.set(key, node_value)
if not res then
core.log.error("failed to set new route[", key, "]: ", err)
return 500, {error_msg = err}
end
return res.status, res.body
end
return _M

View File

@ -970,3 +970,69 @@ GET /t
passed
--- no_error_log
[error]
=== TEST 28: patch route(new methods)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1/methods',
ngx.HTTP_PATCH,
'["GET"]',
[[{
"node": {
"value": {
"methods": [
"GET"
]
},
"key": "/apisix/routes/1"
},
"action": "set"
}]]
)
ngx.status = code
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]
=== TEST 29: patch route(new uri)
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1/uri',
ngx.HTTP_PATCH,
'"/patch_test"',
[[{
"node": {
"value": {
"uri": "/patch_test"
},
"key": "/apisix/routes/1"
},
"action": "set"
}]]
)
ngx.status = code
ngx.say(body)
}
}
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]