Skip to content
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: support both standard PATCH and sub path PATCH for admin api #1930

Merged
merged 8 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions apisix/admin/global_rules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function _M.delete(id)
end


function _M.patch(id, conf)
function _M.patch(id, conf, sub_path)
if not id then
return 400, {error_msg = "missing global rule id"}
end
Expand All @@ -115,8 +115,10 @@ function _M.patch(id, conf)
return 400, {error_msg = "missing new configuration"}
end

if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
if not sub_path or sub_path == "" then
if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
end
end

local key = "/global_rules/" .. id
Expand All @@ -134,7 +136,15 @@ function _M.patch(id, conf)

local node_value = res_old.body.node.value

node_value = core.table.merge(node_value, conf);
if sub_path and sub_path ~= "" then
local code, err, node_val = core.table.patch(node_value, sub_path, conf)
node_value = node_val
if code then
return code, err
end
else
node_value = core.table.merge(node_value, conf);
end

core.log.info("new conf: ", core.json.delay_encode(node_value, true))

Expand Down
19 changes: 14 additions & 5 deletions apisix/admin/routes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ function _M.delete(id)
end


function _M.patch(id, conf, args)
function _M.patch(id, conf, sub_path, args)
if not id then
return 400, {error_msg = "missing route id"}
end
Expand All @@ -205,8 +205,10 @@ function _M.patch(id, conf, args)
return 400, {error_msg = "missing new configuration"}
end

if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
if not sub_path or sub_path == "" then
if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
end
end

local key = "/routes"
Expand All @@ -226,10 +228,17 @@ function _M.patch(id, conf, args)
core.log.info("key: ", key, " old value: ",
core.json.delay_encode(res_old, true))


local node_value = res_old.body.node.value

node_value = core.table.merge(node_value, conf);
if sub_path and sub_path ~= "" then
local code, err, node_val = core.table.patch(node_value, sub_path, conf)
node_value = node_val
if code then
return code, err
end
else
node_value = core.table.merge(node_value, conf);
end

core.log.info("new conf: ", core.json.delay_encode(node_value, true))

Expand Down
26 changes: 18 additions & 8 deletions apisix/admin/services.lua
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ function _M.delete(id)
end


function _M.patch(id, conf)
function _M.patch(id, conf, sub_path)
if not id then
return 400, {error_msg = "missing service id"}
end
Expand All @@ -186,8 +186,10 @@ function _M.patch(id, conf)
return 400, {error_msg = "missing new configuration"}
end

if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
if not sub_path or sub_path == "" then
if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
end
end

local key = "/services" .. "/" .. id
Expand All @@ -203,19 +205,27 @@ function _M.patch(id, conf)
core.log.info("key: ", key, " old value: ",
core.json.delay_encode(res_old, true))

local new_value = res_old.body.node.value
local node_value = res_old.body.node.value

new_value = core.table.merge(new_value, conf);
if sub_path and sub_path ~= "" then
local code, err, node_val = core.table.patch(node_value, sub_path, conf)
node_value = node_val
if code then
return code, err
end
else
node_value = core.table.merge(node_value, conf);
end

core.log.info("new value ", core.json.delay_encode(new_value, true))
core.log.info("new value ", core.json.delay_encode(node_value, true))

local id, err = check_conf(id, new_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, new_value)
local res, err = core.etcd.set(key, node_value)
if not res then
core.log.error("failed to set new service[", key, "]: ", err)
return 500, {error_msg = err}
Expand Down
18 changes: 14 additions & 4 deletions apisix/admin/upstreams.lua
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ function _M.delete(id)
end


function _M.patch(id, conf)
function _M.patch(id, conf, sub_path)
if not id then
return 400, {error_msg = "missing upstream id"}
end
Expand All @@ -220,8 +220,10 @@ function _M.patch(id, conf)
return 400, {error_msg = "missing new configuration"}
end

if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
if not sub_path or sub_path == "" then
if type(conf) ~= "table" then
return 400, {error_msg = "invalid configuration"}
end
end

local key = "/upstreams" .. "/" .. id
Expand All @@ -239,7 +241,15 @@ function _M.patch(id, conf)

local new_value = res_old.body.node.value

new_value = core.table.merge(new_value, conf);
if sub_path and sub_path ~= "" then
local code, err, node_val = core.table.patch(new_value, sub_path, conf)
new_value = node_val
if code then
return code, err
end
else
new_value = core.table.merge(new_value, conf);
end

core.log.info("new value ", core.json.delay_encode(new_value, true))

Expand Down
41 changes: 40 additions & 1 deletion apisix/core/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ local new_tab = require("table.new")
local nkeys = require("table.nkeys")
local pairs = pairs
local type = type
local ngx_re = require("ngx.re")


local _M = {
Expand Down Expand Up @@ -90,7 +91,11 @@ local function merge(origin, extend)
for k,v in pairs(extend) do
if type(v) == "table" then
if type(origin[k] or false) == "table" then
merge(origin[k] or {}, extend[k] or {})
if _M.nkeys(origin[k]) ~= #origin[k] then
merge(origin[k] or {}, extend[k] or {})
else
origin[k] = v
end
else
origin[k] = v
end
Expand All @@ -105,4 +110,38 @@ local function merge(origin, extend)
end
_M.merge = merge


local function patch(node_value, sub_path, conf)
local sub_value = node_value
local sub_paths = ngx_re.split(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: /"
.. _M.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]
if sub_name and sub_name ~= "" then
sub_value[sub_name] = conf
else
node_value = conf
end

return nil, nil, node_value
end
_M.patch = patch


return _M
Loading