This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch next
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/next by this push:
new c8964358f feat: filter fields supported by all objects (#7391)
c8964358f is described below
commit c8964358fff6dc4ce02cc57f2cd2497f6171aa77
Author: tzssangglass <[email protected]>
AuthorDate: Sun Jul 10 20:08:26 2022 +0800
feat: filter fields supported by all objects (#7391)
---
apisix/admin/v3_adapter.lua | 76 ++++++-
t/admin/filter.t | 506 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 576 insertions(+), 6 deletions(-)
diff --git a/apisix/admin/v3_adapter.lua b/apisix/admin/v3_adapter.lua
index f55df73a4..aa9226a83 100644
--- a/apisix/admin/v3_adapter.lua
+++ b/apisix/admin/v3_adapter.lua
@@ -22,6 +22,8 @@ local request = require("apisix.core.request")
local response = require("apisix.core.response")
local table = require("apisix.core.table")
local tonumber = tonumber
+local re_find = ngx.re.find
+local pairs = pairs
local _M = {}
@@ -81,12 +83,7 @@ local function sort(l, r)
end
-function _M.filter(body)
- if not enable_v3() then
- return
- end
-
- local args = request.get_uri_args()
+local function pagination(body, args)
args.page = tonumber(args.page)
args.page_size = tonumber(args.page_size)
if not args.page or not args.page_size then
@@ -122,4 +119,71 @@ function _M.filter(body)
end
+local function filter(body, args)
+ if not args.name and not args.label and not args.uri then
+ return
+ end
+
+ for i = #body.list, 1, -1 do
+ local name_matched = true
+ local label_matched = true
+ local uri_matched = true
+ if args.name then
+ name_matched = false
+ local matched = re_find(body.list[i].value.name, args.name, "jo")
+ if matched then
+ name_matched = true
+ end
+ end
+
+ if args.label then
+ label_matched = false
+ if body.list[i].value.labels then
+ for k, _ in pairs(body.list[i].value.labels) do
+ if k == args.label then
+ label_matched = true
+ break
+ end
+ end
+ end
+ end
+
+ if args.uri then
+ uri_matched = false
+ if body.list[i].value.uri then
+ local matched = re_find(body.list[i].value.uri, args.uri, "jo")
+ if matched then
+ uri_matched = true
+ end
+ end
+
+ if body.list[i].value.uris then
+ for _, uri in pairs(body.list[i].value.uris) do
+ if re_find(uri, args.uri, "jo") then
+ uri_matched = true
+ break
+ end
+ end
+ end
+ end
+
+ if not name_matched or not label_matched or not uri_matched then
+ table.remove(body.list, i)
+ end
+ end
+end
+
+
+function _M.filter(body)
+ if not enable_v3() then
+ return
+ end
+
+ local args = request.get_uri_args()
+
+ pagination(body, args)
+ filter(body, args)
+end
+
+
return _M
diff --git a/t/admin/filter.t b/t/admin/filter.t
index decf463d3..ea2b004f6 100644
--- a/t/admin/filter.t
+++ b/t/admin/filter.t
@@ -246,3 +246,509 @@ passed
}
--- response_body
passed
+
+
+
+=== TEST 6: only search name or labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ for i = 1, 11 do
+ local code, body = t('/apisix/admin/services/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "name": "]] .. i .. [[",
+ "labels": {"]] .. i .. '":"' .. i .. [["}
+ }]]
+ )
+ end
+
+ ngx.sleep(0.5)
+
+ local matched = {1, 10, 11}
+
+ local code, body, res = t('/apisix/admin/services/?name=1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ -- match the name are 1, 10, 11
+ assert(#res.list == 3)
+
+ for _, node in ipairs(res.list) do
+ assert(core.table.array_find(matched,
tonumber(node.value.name)))
+ end
+
+ code, body, res = t('/apisix/admin/services/?label=1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ -- match the label are 1, 10, 11
+ assert(#res.list == 1)
+ assert(res.list[1].value.id == "1")
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 7: services filter
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ for i = 1, 11 do
+ local code, body = t('/apisix/admin/services/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "name": "]] .. i .. [["
+ }]]
+ )
+ end
+
+ ngx.sleep(0.5)
+
+ local code, body, res = t('/apisix/admin/services/?name=1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+
+ -- match the name and label are 1, 10, 11
+ assert(#res.list == 3)
+
+ local matched = {1, 10, 11}
+ for _, node in ipairs(res.list) do
+ assert(core.table.array_find(matched,
tonumber(node.value.name)))
+ end
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 8: routes filter
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ for i = 1, 11 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "name": "]] .. i .. [[",
+ "uri": "]] .. i .. [["
+ }]]
+ )
+ end
+
+ ngx.sleep(0.5)
+
+ local code, body, res = t('/apisix/admin/services/?name=1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+
+ -- match the name and label are 1, 10, 11
+ assert(#res.list == 3)
+
+ local matched = {1, 10, 11}
+ for _, node in ipairs(res.list) do
+ assert(core.table.array_find(matched,
tonumber(node.value.name)))
+ end
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 9: filter with pagination
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local code, body, res =
t('/apisix/admin/services/?name=1&page=1&page_size=10',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+
+ -- match the name and label are 1, 10
+ assert(#res.list == 2)
+
+ local matched = {1, 10}
+ for _, node in ipairs(res.list) do
+ assert(core.table.array_find(matched,
tonumber(node.value.name)))
+ end
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 10: routes filter with uri
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ for i = 1, 11 do
+ local code, body = t('/apisix/admin/routes/' .. i,
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "name": "]] .. i .. [[",
+ "uri": "]] .. i .. [["
+ }]]
+ )
+ end
+
+ ngx.sleep(0.5)
+
+ local code, body, res = t('/apisix/admin/routes/?uri=1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+
+ -- match the name and label are 1, 10, 11
+ assert(#res.list == 3)
+
+ local matched = {1, 10, 11}
+ for _, node in ipairs(res.list) do
+ assert(core.table.array_find(matched,
tonumber(node.value.name)))
+ end
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 11: match labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello",
+ "labels": {
+ "env": "production"
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ code, body = t('/apisix/admin/routes/2',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello2",
+ "labels": {
+ "env2": "production"
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.sleep(0.5)
+
+ -- only match labels' keys
+ local code, body, res = t('/apisix/admin/routes/?label=env',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ assert(#res.list == 1)
+ assert(res.list[1].value.id == "1")
+
+ -- don't match labels' values
+ code, body, res = t('/apisix/admin/routes/?label=production',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ assert(#res.list == 0)
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 12: match uris
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uris": ["/hello", "/world"]
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ code, body = t('/apisix/admin/routes/2',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uris": ["/foo", "/bar"]
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.sleep(0.5)
+
+ local code, body, res = t('/apisix/admin/routes/?uri=world',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ assert(#res.list == 1)
+ assert(res.list[1].value.id == "1")
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 13: match uris & labels
+# uris are same in different routes, filter by labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uris": ["/hello", "/world"],
+ "labels": {
+ "env": "production"
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ code, body = t('/apisix/admin/routes/2',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uris": ["/hello", "/world"],
+ "labels": {
+ "build": "16"
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.sleep(0.5)
+
+ -- only match route 1
+ local code, body, res =
t('/apisix/admin/routes/?uri=world&label=env',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ assert(#res.list == 1)
+ assert(res.list[1].value.id == "1")
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 14: match uri & labels
+# uri is same in different routes, filter by labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello",
+ "labels": {
+ "env": "production"
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ code, body = t('/apisix/admin/routes/2',
+ ngx.HTTP_PUT,
+ [[{
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello",
+ "labels": {
+ "env2": "production"
+ }
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.sleep(0.5)
+
+ local code, body, res =
t('/apisix/admin/routes/?uri=hello&label=env',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ assert(#res.list == 1)
+ assert(res.list[1].value.id == "1")
+
+ ngx.status = code
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed