This is an automated email from the ASF dual-hosted git repository.
bzp2010 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 783660158 fix: missing etcd init_dir and unable to list resource
(#10569)
783660158 is described below
commit 7836601581651061287c4bc7d8ed0c515b3bfb8b
Author: AlinsRan <[email protected]>
AuthorDate: Thu Nov 30 21:41:01 2023 +0800
fix: missing etcd init_dir and unable to list resource (#10569)
---
apisix/core/etcd.lua | 32 +++++++++++++++-----------------
t/admin/routes.t | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
t/core/config_etcd.t | 2 +-
t/core/etcd.t | 28 +++++++++++++++++++++++++++-
4 files changed, 95 insertions(+), 19 deletions(-)
diff --git a/apisix/core/etcd.lua b/apisix/core/etcd.lua
index 5cd103858..a537c8840 100644
--- a/apisix/core/etcd.lua
+++ b/apisix/core/etcd.lua
@@ -154,16 +154,6 @@ local function kvs_to_node(kvs)
end
_M.kvs_to_node = kvs_to_node
-local function kvs_to_nodes(res)
- res.body.node.dir = true
- res.body.node.nodes = setmetatable({}, array_mt)
- for i=2, #res.body.kvs do
- res.body.node.nodes[i-1] = kvs_to_node(res.body.kvs[i])
- end
- return res
-end
-
-
local function not_found(res)
res.body.message = "Key not found"
res.reason = "Not found"
@@ -211,13 +201,22 @@ function _M.get_format(res, real_key, is_dir, formatter)
else
-- In etcd v2, the direct key asked for is `node`, others which under
this dir are `nodes`
-- While in v3, this structure is flatten and all keys related the key
asked for are `kvs`
- res.body.node = kvs_to_node(res.body.kvs[1])
- if not res.body.kvs[1].value then
- -- remove last "/" when necessary
- if string.byte(res.body.node.key, -1) == 47 then
- res.body.node.key = string.sub(res.body.node.key, 1,
#res.body.node.key-1)
+ res.body.node = {
+ key = real_key,
+ dir = true,
+ nodes = setmetatable({}, array_mt)
+ }
+ local kvs = res.body.kvs
+ if #kvs >= 1 and not kvs[1].value then
+ res.body.node.createdIndex = tonumber(kvs[1].create_revision)
+ res.body.node.modifiedIndex = tonumber(kvs[1].mod_revision)
+ for i=2, #kvs do
+ res.body.node.nodes[i-1] = kvs_to_node(kvs[i])
+ end
+ else
+ for i=1, #kvs do
+ res.body.node.nodes[i] = kvs_to_node(kvs[i])
end
- res = kvs_to_nodes(res)
end
end
@@ -316,7 +315,6 @@ function _M.get(key, is_dir)
if not res then
return nil, err
end
-
return _M.get_format(res, key, is_dir)
end
diff --git a/t/admin/routes.t b/t/admin/routes.t
index 17b30dc4c..835d4b390 100644
--- a/t/admin/routes.t
+++ b/t/admin/routes.t
@@ -734,3 +734,55 @@ GET /t
--- error_code: 400
--- response_body_like
{"error_msg":"invalid configuration: property \\"host\\" validation failed:
failed to match pattern .*
+
+
+
+=== TEST 23: removing the init_dir key from etcd can still list all routes
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local json = require("toolkit.json")
+ local etcd = require("apisix.core.etcd")
+
+ local code, body = t('/apisix/admin/routes/del_init_dir_1',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:8080": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/index.html"
+ }]]
+ )
+ assert(code == 200 or code == 201, "failed to add route")
+
+ local code, body = t('/apisix/admin/routes/del_init_dir_2',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:8080": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/index.html"
+ }]]
+ )
+ assert(code == 200 or code == 201, "failed to add route")
+
+ -- remove the init_dir key from etcd
+ assert(etcd.delete("/routes/"))
+
+ -- list all routes and check them
+ local code, body, res = t('/apisix/admin/routes', ngx.HTTP_GET)
+ ngx.status = code
+ ngx.say(res)
+ }
+ }
+--- request
+GET /t
+--- response_body eval
+qr/del_init_dir_1.*del_init_dir_2/
diff --git a/t/core/config_etcd.t b/t/core/config_etcd.t
index d81cf5615..659c15285 100644
--- a/t/core/config_etcd.t
+++ b/t/core/config_etcd.t
@@ -354,7 +354,7 @@ GET /t
--- grep_error_log eval
qr/readdir key: fake res: .+/
--- grep_error_log_out eval
-qr/readdir key: fake res:
\{("value":"bar","key":"foo"|"key":"foo","value":"bar")\}/
+qr/readdir key: fake res:
\[\{("value":"bar","key":"foo"|"key":"foo","value":"bar")\}\]/
--- wait: 1
--- no_error_log
[error]
diff --git a/t/core/etcd.t b/t/core/etcd.t
index 670ada081..d6f5d7085 100644
--- a/t/core/etcd.t
+++ b/t/core/etcd.t
@@ -351,8 +351,10 @@ GET /t
local etcd = require("apisix.core.etcd")
assert(etcd.set("/ab", "ab"))
local res, err = etcd.get("/a", true)
+ assert(err == nil)
+ assert(#res.body.list == 1)
ngx.status = res.status
- ngx.say(res.body.node.value)
+ ngx.say(res.body.list[1].value)
}
}
--- request
@@ -401,3 +403,27 @@ qr/init_by_lua.*: \S+/
qr{init_by_lua.* ab
init_by_lua.* 200
init_by_lua.* 404}
+
+
+
+=== TEST 8: list multiple kv, get prefix
+--- config
+ location /t {
+ content_by_lua_block {
+ local etcd = require("apisix.core.etcd")
+ assert(etcd.set("/ab", "ab"))
+ assert(etcd.set("/abc", "abc"))
+ -- get prefix
+ local res, err = etcd.get("/a", true)
+ assert(err == nil)
+ assert(#res.body.list == 2)
+ ngx.status = res.status
+ ngx.say(res.body.list[1].value)
+ ngx.say(res.body.list[2].value)
+ }
+ }
+--- request
+GET /t
+--- response_body
+ab
+abc