Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cdb9c42
fix: Improve results from admin API while GET all plugins
Revolyssup May 31, 2023
75db0b1
fix error
Revolyssup May 31, 2023
b74771d
add test
Revolyssup Jun 1, 2023
2679448
fix lint
Revolyssup Jun 1, 2023
fea340e
fix lint
Revolyssup Jun 1, 2023
186c792
add newline
Revolyssup Jun 2, 2023
113218d
apply suggested changes
Revolyssup Jun 6, 2023
b2f5834
fix lint err
Revolyssup Jun 6, 2023
c9ad2fd
Refactor admin API for /apisix/admin/plugins
Revolyssup Jun 8, 2023
8bec519
fix lint
Revolyssup Jun 26, 2023
8af5454
fix lint
Revolyssup Jun 27, 2023
69790fd
fix lint
Revolyssup Jun 27, 2023
bf1d23d
Add warning log
Revolyssup Jun 27, 2023
fccea25
apply suggestions
Revolyssup Jun 27, 2023
4044a27
apply suggestions
Revolyssup Jun 28, 2023
1b0105e
add log
Revolyssup Jun 28, 2023
0873c32
update doc
Revolyssup Jun 28, 2023
fa254ee
fix merge conflict
Revolyssup Jun 28, 2023
446ad91
commit suggestions
Revolyssup Jun 29, 2023
d80cd68
fix failing CI
Revolyssup Jun 30, 2023
2f1f302
fix failing CI
Revolyssup Jun 30, 2023
dad573b
fix format chinese doc
Revolyssup Jun 30, 2023
edea4a0
Apply suggestions
Revolyssup Jul 6, 2023
a801549
fix ci
Revolyssup Jul 6, 2023
4c405f0
fix lint
Revolyssup Jul 7, 2023
20de18a
fix lint
Revolyssup Jul 10, 2023
e279e3b
follow code convention
Revolyssup Jul 10, 2023
abc0435
Update docs/en/latest/admin-api.md
Revolyssup Jul 16, 2023
cbba4c8
Update apisix/admin/plugins.lua
Revolyssup Jul 16, 2023
4512a1b
apply suggestions from code review
Revolyssup Jul 16, 2023
043f1e1
fix failing tests
Revolyssup Jul 17, 2023
2197c1f
appply suggestions
Revolyssup Jul 18, 2023
b6232d3
fix tests
Revolyssup Jul 18, 2023
babd145
remove mistake on make test
Revolyssup Jul 18, 2023
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
14 changes: 11 additions & 3 deletions apisix/admin/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
--
local require = require
local core = require("apisix.core")
local get_uri_args = ngx.req.get_uri_args
local route = require("apisix.utils.router")
local plugin = require("apisix.plugin")
local v3_adapter = require("apisix.admin.v3_adapter")
Expand Down Expand Up @@ -253,9 +254,16 @@ end

local function get_plugins_list()
set_ctx_and_check_token()

local plugins = resources.plugins.get_plugins_list()
core.response.exit(200, plugins)
local args = get_uri_args()
local subsystem = args["subsystem"]
-- If subsystem is passed then it should be either http or stream.
-- If it is not passed/nil then http will be default.
subsystem = subsystem or "http"
if subsystem == "http" or subsystem == "stream" then
local plugins = resources.plugins.get_plugins_list(subsystem)
core.response.exit(200, plugins)
end
core.response.exit(400,"invalid subsystem passed")
end

-- Handle unsupported request methods for the virtual "reload" plugin
Expand Down
65 changes: 47 additions & 18 deletions apisix/admin/plugins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ local require = require
local core = require("apisix.core")
local check_schema = require("apisix.plugin").check_schema
local ipairs = ipairs
local pcall = pcall
local table_sort = table.sort
local table_insert = table.insert
local get_uri_args = ngx.req.get_uri_args
local plugin_get_all = require("apisix.plugin").get_all
local plugin_get_http = require("apisix.plugin").get
local plugin_get_stream = require("apisix.plugin").get_stream
local encrypt_conf = require("apisix.plugin").encrypt_conf
local pairs = pairs

Expand All @@ -42,7 +43,15 @@ end

function _M.get(name)
local arg = get_uri_args()
if arg and arg["all"] == "true" then
-- If subsystem is passed inside args then it should be oneOf: http / stream.
local subsystem = arg["subsystem"] or "http"
if subsystem ~= "http" and subsystem ~= "stream" then
return 400, {error_msg = "unsupported subsystem: "..subsystem}
end

-- arg all to be deprecated
if (arg and arg["all"] == "true") then
core.log.warn("query parameter \"all\" will be deprecated soon.")
local http_plugins, stream_plugins = plugin_get_all({
version = true,
priority = true,
Expand All @@ -60,16 +69,18 @@ function _M.get(name)
return 200, http_plugins
end

if not name then
return 400, {error_msg = "not found plugin name"}
end
local plugin

local plugin_name = "apisix.plugins." .. name
if subsystem == "http" then
plugin = plugin_get_http(name)
else
plugin = plugin_get_stream(name)
end

local ok, plugin = pcall(require, plugin_name)
if not ok then
core.log.warn("failed to load plugin [", name, "] err: ", plugin)
return 400, {error_msg = "failed to load plugin " .. name}
if not plugin then
local err = "plugin not found in subsystem " .. subsystem
core.log.warn(err)
return 404, {error_msg = err}
end

local json_schema = plugin.schema
Expand All @@ -85,16 +96,34 @@ function _M.get(name)
end


function _M.get_plugins_list()
local plugins = core.config.local_conf().plugins
function _M.get_plugins_list(subsystem)
local http_plugins
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you check the subsystem here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean before defining stream_plugins variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

local stream_plugins
if subsystem == "http" then
http_plugins = core.config.local_conf().plugins
else
stream_plugins = core.config.local_conf().stream_plugins
end

local priorities = {}
local success = {}
for i, name in ipairs(plugins) do
local plugin_name = "apisix.plugins." .. name
local ok, plugin = pcall(require, plugin_name)
if ok and plugin.priority then
priorities[name] = plugin.priority
table_insert(success, name)
if http_plugins then
for i, name in ipairs(http_plugins) do
local plugin = plugin_get_http(name)
if plugin and plugin.priority then
priorities[name] = plugin.priority
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can these two function be used here?

local plugin_get_http = require("apisix.plugin").get
local plugin_get_stream = require("apisix.plugin").get_stream

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those functions are to get the entire plugin loaded with plugin.load(). Here we just need the names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

table_insert(success, name)
end
end
end

if stream_plugins then
for i, name in ipairs(stream_plugins) do
local plugin = plugin_get_stream(name)
if plugin and plugin.priority then
priorities[name] = plugin.priority
table_insert(success, name)
end
end
end

Expand Down
5 changes: 5 additions & 0 deletions apisix/plugin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,11 @@ function _M.get(name)
end


function _M.get_stream(name)
return stream_local_plugins_hash and stream_local_plugins_hash[name]
end


function _M.get_all(attrs)
local http_plugins = {}
local stream_plugins = {}
Expand Down
28 changes: 10 additions & 18 deletions docs/en/latest/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,14 @@ Plugin resource request address: /apisix/admin/plugins/{plugin_name}

The Plugin ({plugin_name}) of the data structure.

### Request Arguments

| Name | Description | Default |
| --------- | ----------------------------- | ------- |
| subsystem | The subsystem of the Plugins. | http |

The plugin can be filtered on subsystem so that the ({plugin_name}) is searched in the subsystem passed through query params.

### Example API usage:

```shell
Expand All @@ -1330,7 +1338,7 @@ curl "http://127.0.0.1:9180/apisix/admin/plugins/list" \
```

```shell
curl "http://127.0.0.1:9180/apisix/admin/plugins/key-auth" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
curl "http://127.0.0.1:9180/apisix/admin/plugins/key-auth?subsystem=http" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
```

```json
Expand All @@ -1339,26 +1347,10 @@ curl "http://127.0.0.1:9180/apisix/admin/plugins/key-auth" -H 'X-API-KEY: ed

:::tip

You can use the `/apisix/admin/plugins?all=true` API to get all properties of all plugins.

Each Plugin has the attributes `name`, `priority`, `type`, `schema`, `consumer_schema` and `version`.

Defaults to only L7 Plugins. If you need to get attributes of L4 / Stream Plugins, use `/apisix/admin/plugins?all=true&subsystem=stream`.
You can use the `/apisix/admin/plugins?all=true` API to get all properties of all plugins. This API will be deprecated soon.

:::

### Request Methods

| Method | Request URI | Request Body | Description |
| ------ | ------------------------------ | ------------ | ---------------------------------------- |
| GET | /apisix/admin/plugins?all=true | NULL | Fetches all attributes from all Plugins. |

### Request Arguments

| Name | Description | Default |
| --------- | ----------------------------- | ------- |
| subsystem | The subsystem of the Plugins. | http |

## Stream Route

Route used in the [Stream Proxy](./stream-proxy.md).
Expand Down
12 changes: 10 additions & 2 deletions docs/zh/latest/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,14 @@ Content-Type: text/plain

Plugin 资源请求地址:/apisix/admin/plugins/{plugin_name}

### 请求参数

| 名称 | 描述 | 默认 |
| --------- | -------------------------------------- | -------- |
| subsystem | 插件子系统。 | http |

可以在子系统上过滤插件,以便在通过查询参数传递的子系统中搜索 ({plugin_name})

### 请求方法 {#plugin-request-methods}

| 名称        | 请求 URI | 请求 body | 描述          |
Expand Down Expand Up @@ -1346,7 +1354,7 @@ Plugin 资源请求地址:/apisix/admin/plugins/{plugin_name}
- 获取指定插件的属性

```shell
curl "http://127.0.0.1:9180/apisix/admin/plugins/key-auth" \
curl "http://127.0.0.1:9180/apisix/admin/plugins/key-auth?subsystem=http" \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
```

Expand All @@ -1358,7 +1366,7 @@ Plugin 资源请求地址:/apisix/admin/plugins/{plugin_name}

你可以使用 `/apisix/admin/plugins?all=true` 接口获取所有插件的所有属性,每个插件包括 `name`,`priority`,`type`,`schema`,`consumer_schema` 和 `version`。

默认情况下,该接口只返回 L7 插件。如果你需要获取 L4 / Stream 插件,需要使用 `/apisix/admin/plugins?all=true&subsystem=stream`。
您可以使用“/apisix/admin/plugins?all=true”获取所有插件的所有属性。这个 API 将很快被弃用

:::

Expand Down
59 changes: 55 additions & 4 deletions t/admin/plugins.t
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,12 @@ ext-plugin-post-resp



=== TEST 2: wrong path
=== TEST 2: invalid plugin
--- request
GET /apisix/admin/plugins
--- error_code: 400
GET /apisix/admin/plugins/asdf
--- error_code: 404
--- response_body
{"error_msg":"not found plugin name"}
{"error_msg":"plugin not found in subsystem http"}



Expand Down Expand Up @@ -412,3 +412,54 @@ plugins:
}
--- response_body
{"batch-requests":"global","error-log-logger":"global","node-status":"global","server-info":"global"}



=== TEST 13: check with wrong plugin subsystem
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

local _, message, _ = t('/apisix/admin/plugins?subsystem=asdf',
ngx.HTTP_GET
)
ngx.say(message)
}
}
--- response_body eval
qr/\{"error_msg":"unsupported subsystem: asdf"\}/



=== TEST 14: check with right plugin in wrong subsystem
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

local _, message, _ = t('/apisix/admin/plugins/http-logger?subsystem=stream',
ngx.HTTP_GET
)
ngx.say(message)
}
}
--- response_body eval
qr/\{"error_msg":"plugin not found in subsystem stream"\}/



=== TEST 15: check with right plugin in right subsystem
--- config
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test

local _, _ , message = t('/apisix/admin/plugins/http-logger?subsystem=http',
ngx.HTTP_GET
)
ngx.say(message)
}
}
--- response_body eval
qr/this is a mark for our injected plugin schema/
2 changes: 1 addition & 1 deletion t/admin/schema.t
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ qr/"required":\["count","time_window"\]/
=== TEST 8: get not exist plugin
--- request
GET /apisix/admin/schema/plugins/no-exist
--- error_code: 400
--- error_code: 404



Expand Down