This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 3b35a99c3 refactor(admin): refactor resource routes (#8611)
3b35a99c3 is described below
commit 3b35a99c3f400657a53c36c6d037b3f025a37c88
Author: dongjunduo <[email protected]>
AuthorDate: Thu Jan 12 08:55:09 2023 +0800
refactor(admin): refactor resource routes (#8611)
Fixes https://github.com/apache/apisix/issues/8569
---
apisix/admin/init.lua | 9 +-
apisix/admin/resource.lua | 206 ++++++++++++++++++++++++++++++++++++++++++++++
apisix/admin/routes.lua | 181 ++--------------------------------------
3 files changed, 222 insertions(+), 174 deletions(-)
diff --git a/apisix/admin/init.lua b/apisix/admin/init.lua
index 3ed8d362e..15c4ee6cb 100644
--- a/apisix/admin/init.lua
+++ b/apisix/admin/init.lua
@@ -198,8 +198,13 @@ local function run()
end
end
- local code, data = resource[method](seg_id, req_body, seg_sub_path,
- uri_args)
+ local code, data
+ if seg_res == "routes" then
+ code, data = resource[method](resource, seg_id, req_body,
seg_sub_path, uri_args)
+ else
+ code, data = resource[method](seg_id, req_body, seg_sub_path, uri_args)
+ end
+
if code then
if method == "get" and plugin.enable_data_encryption then
if seg_res == "consumers" then
diff --git a/apisix/admin/resource.lua b/apisix/admin/resource.lua
new file mode 100644
index 000000000..c4aa21b35
--- /dev/null
+++ b/apisix/admin/resource.lua
@@ -0,0 +1,206 @@
+--
+-- 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.
+--
+local core = require("apisix.core")
+local utils = require("apisix.admin.utils")
+local setmetatable = setmetatable
+local tostring = tostring
+local type = type
+
+
+local _M = {
+ need_v3_filter = true,
+}
+
+
+local mt = {
+ __index = _M
+}
+
+
+function _M:check_conf(id, conf, need_id)
+ -- check if missing configurations
+ if not conf then
+ return nil, {error_msg = "missing configurations"}
+ end
+
+ -- check id if need id
+ id = id or conf.id
+ if need_id and not id then
+ return nil, {error_msg = "missing ".. self.kind .. " id"}
+ end
+
+ if not need_id and id then
+ return nil, {error_msg = "wrong ".. self.kind .. " id, do not need it"}
+ end
+
+ if need_id and conf.id and tostring(conf.id) ~= tostring(id) then
+ return nil, {error_msg = "wrong ".. self.kind .. " id"}
+ end
+
+ conf.id = id
+
+ core.log.info("schema: ", core.json.delay_encode(self.schema))
+ core.log.info("conf : ", core.json.delay_encode(conf))
+
+ -- check the resource own rules
+ return self.checker(id, conf, need_id, self.schema)
+end
+
+
+function _M:get(id)
+ local key = "/" .. self.name
+ if id then
+ key = key .. "/" .. id
+ end
+
+ local res, err = core.etcd.get(key, not id)
+ if not res then
+ core.log.error("failed to get ", self.kind, "[", key, "] from etcd: ",
err)
+ return 503, {error_msg = err}
+ end
+
+ utils.fix_count(res.body, id)
+ return res.status, res.body
+end
+
+
+function _M:post(id, conf, sub_path, args)
+ local id, err = self:check_conf(id, conf, false)
+ if not id then
+ return 400, err
+ end
+
+ local key = "/" .. self.name
+ utils.inject_timestamp(conf)
+ local res, err = core.etcd.push(key, conf, args.ttl)
+ if not res then
+ core.log.error("failed to post ", self.kind, "[", key, "] to etcd: ",
err)
+ return 503, {error_msg = err}
+ end
+
+ return res.status, res.body
+end
+
+
+function _M:put(id, conf, sub_path, args)
+ local id, err = self:check_conf(id, conf, true)
+ if not id then
+ return 400, err
+ end
+
+ local key = "/" .. self.name .. "/" .. id
+
+ local ok, err = utils.inject_conf_with_prev_conf(self.kind, key, conf)
+ if not ok then
+ return 503, {error_msg = err}
+ end
+
+ local res, err = core.etcd.set(key, conf, args.ttl)
+ if not res then
+ core.log.error("failed to put ", self.kind, "[", key, "] to etcd: ",
err)
+ return 503, {error_msg = err}
+ end
+
+ return res.status, res.body
+end
+
+
+function _M:delete(id)
+ if not id then
+ return 400, {error_msg = "missing " .. self.kind .. " id"}
+ end
+
+ local key = "/" .. self.name .. "/" .. id
+ local res, err = core.etcd.delete(key)
+ if not res then
+ core.log.error("failed to delete ", self.kind, "[", key, "] in etcd:
", err)
+ return 503, {error_msg = err}
+ end
+
+ return res.status, res.body
+end
+
+
+function _M:patch(id, conf, sub_path, args)
+ if not id then
+ return 400, {error_msg = "missing " .. self.kind .. " id"}
+ end
+
+ if conf == nil then
+ return 400, {error_msg = "missing new configuration"}
+ end
+
+ if not sub_path or sub_path == "" then
+ if type(conf) ~= "table" then
+ return 400, {error_msg = "invalid configuration"}
+ end
+ end
+
+ local key = "/" .. self.name
+ 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 get ", self.kind, " [", key, "] in etcd: ",
err)
+ return 503, {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 modified_index = res_old.body.node.modifiedIndex
+
+ 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, {error_msg = err}
+ end
+ utils.inject_timestamp(node_value, nil, true)
+ else
+ node_value = core.table.merge(node_value, conf)
+ utils.inject_timestamp(node_value, nil, conf)
+ end
+
+ core.log.info("new conf: ", core.json.delay_encode(node_value, true))
+
+ local id, err = self:check_conf(id, node_value, true)
+ if not id then
+ return 400, err
+ end
+
+ local res, err = core.etcd.atomic_set(key, node_value, args.ttl,
modified_index)
+ if not res then
+ core.log.error("failed to set new ", self.kind, "[", key, "] to etcd:
", err)
+ return 503, {error_msg = err}
+ end
+
+ return res.status, res.body
+end
+
+
+function _M.new(opt)
+ return setmetatable(opt, mt)
+end
+
+
+return _M
diff --git a/apisix/admin/routes.lua b/apisix/admin/routes.lua
index 4cd36b385..06f27fa0c 100644
--- a/apisix/admin/routes.lua
+++ b/apisix/admin/routes.lua
@@ -17,42 +17,13 @@
local expr = require("resty.expr.v1")
local core = require("apisix.core")
local apisix_upstream = require("apisix.upstream")
+local resource = require("apisix.admin.resource")
local schema_plugin = require("apisix.admin.plugins").check_schema
-local utils = require("apisix.admin.utils")
-local tostring = tostring
local type = type
local loadstring = loadstring
-local _M = {
- version = 0.2,
- need_v3_filter = true,
-}
-
-
-local function check_conf(id, conf, need_id)
- if not conf then
- return nil, {error_msg = "missing configurations"}
- end
-
- id = id or conf.id
- if need_id and not id then
- return nil, {error_msg = "missing route id"}
- end
-
- if not need_id and id then
- return nil, {error_msg = "wrong route id, do not need it"}
- end
-
- if need_id and conf.id and tostring(conf.id) ~= tostring(id) then
- return nil, {error_msg = "wrong route id"}
- end
-
- conf.id = id
-
- core.log.info("schema: ", core.json.delay_encode(core.schema.route))
- core.log.info("conf : ", core.json.delay_encode(conf))
-
+local function check_conf(id, conf, need_id, schema)
if conf.host and conf.hosts then
return nil, {error_msg = "only one of host or hosts is allowed"}
end
@@ -62,7 +33,7 @@ local function check_conf(id, conf, need_id)
.. "allowed"}
end
- local ok, err = core.schema.check(core.schema.route, conf)
+ local ok, err = core.schema.check(schema, conf)
if not ok then
return nil, {error_msg = "invalid configuration: " .. err}
end
@@ -168,143 +139,9 @@ local function check_conf(id, conf, need_id)
end
-function _M.put(id, conf, sub_path, args)
- local id, err = check_conf(id, conf, true)
- if not id then
- return 400, err
- end
-
- local key = "/routes/" .. id
-
- local ok, err = utils.inject_conf_with_prev_conf("route", key, conf)
- if not ok then
- return 503, {error_msg = err}
- end
-
- local res, err = core.etcd.set(key, conf, args.ttl)
- if not res then
- core.log.error("failed to put route[", key, "] to etcd: ", err)
- return 503, {error_msg = err}
- end
-
- return res.status, res.body
-end
-
-
-function _M.get(id)
- local key = "/routes"
- if id then
- key = key .. "/" .. id
- end
-
- local res, err = core.etcd.get(key, not id)
- if not res then
- core.log.error("failed to get route[", key, "] from etcd: ", err)
- return 503, {error_msg = err}
- end
-
- utils.fix_count(res.body, id)
- return res.status, res.body
-end
-
-
-function _M.post(id, conf, sub_path, args)
- local id, err = check_conf(id, conf, false)
- if not id then
- return 400, err
- end
-
- local key = "/routes"
- utils.inject_timestamp(conf)
- local res, err = core.etcd.push(key, conf, args.ttl)
- if not res then
- core.log.error("failed to post route[", key, "] to etcd: ", err)
- return 503, {error_msg = err}
- end
-
- return res.status, res.body
-end
-
-
-function _M.delete(id)
- if not id then
- return 400, {error_msg = "missing route id"}
- end
-
- local key = "/routes/" .. id
- -- core.log.info("key: ", key)
- local res, err = core.etcd.delete(key)
- if not res then
- core.log.error("failed to delete route[", key, "] in etcd: ", err)
- return 503, {error_msg = err}
- end
-
- return res.status, res.body
-end
-
-
-function _M.patch(id, conf, sub_path, args)
- if not id then
- return 400, {error_msg = "missing route id"}
- end
-
- if conf == nil then
- return 400, {error_msg = "missing new configuration"}
- end
-
- if not sub_path or sub_path == "" then
- if type(conf) ~= "table" then
- return 400, {error_msg = "invalid configuration"}
- end
- 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 get route [", key, "] in etcd: ", err)
- return 503, {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 modified_index = res_old.body.node.modifiedIndex
-
- 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
- utils.inject_timestamp(node_value, nil, true)
- else
- node_value = core.table.merge(node_value, conf)
- utils.inject_timestamp(node_value, nil, conf)
- end
-
- 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
-
- local res, err = core.etcd.atomic_set(key, node_value, args.ttl,
modified_index)
- if not res then
- core.log.error("failed to set new route[", key, "] to etcd: ", err)
- return 503, {error_msg = err}
- end
-
- return res.status, res.body
-end
-
-
-return _M
+return resource.new({
+ name = "routes",
+ kind = "route",
+ schema = core.schema.route,
+ checker = check_conf
+})