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 <alins...@apache.org> 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