From b59a5191970fb7a27fcdf31fc9e3cfb67a925a36 Mon Sep 17 00:00:00 2001 From: nic-chen <33000667+nic-chen@users.noreply.github.com> Date: Tue, 9 Jun 2020 08:26:33 +0800 Subject: [PATCH] feat: support resource name for route, service and upstream object. (#1655) --- apisix/balancer.lua | 14 ++++++++++++- apisix/schema_def.lua | 3 +++ doc/admin-api-cn.md | 12 ++++++++--- doc/admin-api.md | 12 ++++++++--- t/admin/routes.t | 42 +++++++++++++++++++++++++++++++++++++++ t/admin/services.t | 46 +++++++++++++++++++++++++++++++++++++++++++ t/admin/upstream.t | 44 ++++++++++++++++++++++++++++++++++++++++- 7 files changed, 165 insertions(+), 8 deletions(-) diff --git a/apisix/balancer.lua b/apisix/balancer.lua index db43af536352..ce89b6129129 100644 --- a/apisix/balancer.lua +++ b/apisix/balancer.lua @@ -14,7 +14,8 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -local healthcheck = require("resty.healthcheck") +local healthcheck +local require = require local roundrobin = require("resty.roundrobin") local discovery = require("apisix.discovery.init").discovery local resty_chash = require("resty.chash") @@ -26,6 +27,7 @@ local str_gsub = string.gsub local pairs = pairs local ipairs = ipairs local tostring = tostring + local set_more_tries = balancer.set_more_tries local get_last_failure = balancer.get_last_failure local set_timeouts = balancer.set_timeouts @@ -82,6 +84,9 @@ end local function create_checker(upstream, healthcheck_parent) + if healthcheck == nil then + healthcheck = require("resty.healthcheck") + end local checker = healthcheck.new({ name = "upstream#" .. healthcheck_parent.key, shm_name = "upstream-healthcheck", @@ -378,5 +383,12 @@ function _M.init_worker() end end +function _M.upstreams() + if not upstreams_etcd then + return nil, nil + end + + return upstreams_etcd.values, upstreams_etcd.conf_version +end return _M diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua index e8d2b75c0bab..0d59e7700bc3 100644 --- a/apisix/schema_def.lua +++ b/apisix/schema_def.lua @@ -327,6 +327,7 @@ local upstream_schema = { description = "enable websocket for request", type = "boolean" }, + name = {type = "string", maxLength = 50}, desc = {type = "string", maxLength = 256}, service_name = {type = "string", maxLength = 50}, id = id_schema @@ -369,6 +370,7 @@ _M.route = { }, uniqueItems = true, }, + name = {type = "string", maxLength = 50}, desc = {type = "string", maxLength = 256}, priority = {type = "integer", default = 0}, @@ -446,6 +448,7 @@ _M.service = { plugins = plugins_schema, upstream = upstream_schema, upstream_id = id_schema, + name = {type = "string", maxLength = 50}, desc = {type = "string", maxLength = 256}, }, anyOf = { diff --git a/doc/admin-api-cn.md b/doc/admin-api-cn.md index d2517d35a7a9..0e80d0e07c96 100644 --- a/doc/admin-api-cn.md +++ b/doc/admin-api-cn.md @@ -59,7 +59,8 @@ |upstream_id|`plugins`、`upstream`/`upstream_id`、`service_id`至少选择一个 |Upstream|启用的 upstream id,详见 [Upstream](architecture-design-cn.md#upstream)|| |service_id|`plugins`、`upstream`/`upstream_id`、`service_id`至少选择一个 |Service|绑定的 Service 配置,详见 [Service](architecture-design-cn.md#service)|| |service_protocol|可选|上游协议类型|只可以是 "grpc", "http" 二选一。|默认 "http",使用gRPC proxy 或gRPC transcode 时,必须用"grpc"| -|desc |可选 |辅助 |标识路由名称、使用场景等。|客户 xxxx| +|name |可选 |辅助 |标识路由名称|route-xxxx| +|desc |可选 |辅助 |标识描述、使用场景等。|客户 xxxx| |host |可选 |匹配规则|当前请求域名,比如 `foo.com`;也支持泛域名,比如 `*.foo.com`。|"foo.com"| |hosts |可选 |匹配规则|列表形态的 `host`,表示允许有多个不同 `host`,匹配其中任意一个即可。|{"foo.com", "*.bar.com"}| |remote_addr|可选 |匹配规则|客户端请求 IP 地址: `192.168.1.101`、`192.168.1.102` 以及 CIDR 格式的支持 `192.168.1.0/24`。特别的,APISIX 也完整支持 IPv6 地址匹配:`::1`,`fe80::1`, `fe80::1/64` 等。|"192.168.1.0/24"| @@ -86,6 +87,7 @@ route 对象 json 配置内容: "hosts": ["a.com","b.com"], # 一组 host 域名, host 与 hosts 只需要有一个非空即可 "plugins": {}, # 指定 route 绑定的插件 "priority": 0, # apisix 支持多种匹配方式,可能会在一次匹配中同时匹配到多条路由,此时优先级高的优先匹配中 + "name": "路由xxx", "desc": "hello world", "remote_addr": "127.0.0.1", # 客户端请求 IP 地址 "remote_addrs": ["127.0.0.1"], # 一组客户端请求 IP 地址, remote_addr 与 remote_addrs 只需要有一个非空即可 @@ -196,7 +198,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13 |plugins |可选 |Plugin|详见 [Plugin](architecture-design-cn.md#plugin) || |upstream | upstream 或 upstream_id 两个选一个 |Upstream|启用的 Upstream 配置,详见 [Upstream](architecture-design-cn.md#upstream)|| |upstream_id| upstream 或 upstream_id 两个选一个 |Upstream|启用的 upstream id,详见 [Upstream](architecture-design-cn.md#upstream)|| -|desc |可选 |辅助 |标识服务名称、使用场景等。|| +|name |可选 |辅助 |标识服务名称。|| +|desc |可选 |辅助 |服务描述、使用场景等。|| serivce 对象 json 配置内容: @@ -206,6 +209,7 @@ serivce 对象 json 配置内容: "plugins": {}, # 指定 service 绑定的插件 "upstream_id": "1", # upstream 对象在 etcd 中的 id ,建议使用此值 "upstream": {}, # upstream 信息对象,不建议使用 + "name": "测试svc", # service 名称 "desc": "hello world", # service 描述 } ``` @@ -353,7 +357,8 @@ APISIX 的 Upstream 除了基本的复杂均衡算法选择外,还支持对上 |timeout |可选|超时时间对象|设置连接、发送消息、接收消息的超时时间|| |enable_websocket |可选 |辅助|是否允许启用 websocket 能力|| |hash_on |可选 |辅助|该参数作为一致性 hash 的入参|| -|desc |可选 |辅助|标识服务名称、使用场景等。|| +|name |可选 |辅助|标识上游服务名称、使用场景等。|| +|desc |可选 |辅助|上游服务描述、使用场景等。|| upstream 对象 json 配置内容: @@ -379,6 +384,7 @@ upstream 对象 json 配置内容: "checks": {}, # 配置健康检查的参数 "hash_on": "", "key": "", + "name": "upstream-xxx", # upstream 名称 "desc": "hello world", # upstream 描述 } ``` diff --git a/doc/admin-api.md b/doc/admin-api.md index fae8e261bb21..a81c473e1a1e 100644 --- a/doc/admin-api.md +++ b/doc/admin-api.md @@ -53,7 +53,8 @@ |Parameter |Required |Type |Description |Example| |---------|---------|----|-----------|----| -|desc |False |Auxiliary |Identifies route names, usage scenarios, and more.|customer xxxx| +|name |False |Auxiliary |Identifies route names.|customer-xxxx| +|desc |False |Auxiliary |route description, usage scenarios, and more.|customer xxxx| |uri |True |Match Rules|In addition to full matching such as `/foo/bar`、`/foo/gloo`, using different [Router](architecture-design.md#router) allows more advanced matching, see [Router](architecture-design.md#router) for more.|"/hello"| |host |False |Match Rules|Currently requesting a domain name, such as `foo.com`; pan-domain names such as `*.foo.com` are also supported.|"foo.com"| |hosts |False |Match Rules|The `host` in the form of a list means that multiple different hosts are allowed, and match any one of them.|{"foo.com", "*.bar.com"}| @@ -83,6 +84,7 @@ Config Example: "hosts": ["a.com","b.com"], # A set of host. Host and hosts only need to be non-empty one. "plugins": {}, # Bound plugin "priority": 0, # If different routes contain the same `uri`, determine which route is matched first based on the attribute` priority`, the default value is 0. + "name": "route-xxx", "desc": "hello world", "remote_addr": "127.0.0.1", # Client IP "remote_addrs": ["127.0.0.1"], # A set of Client IP. Remote_addr and remo-te_addrs only need to be non-empty one. @@ -192,7 +194,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13 |plugins |False |Plugin|See [Plugin](architecture-design.md#plugin) for more || |upstream |False |Upstream|Enabled Upstream configuration, see [Upstream](architecture-design.md#upstream) for more|| |upstream_id|False |Upstream|Enabled upstream id, see [Upstream](architecture-design.md#upstream) for more || -|desc |False |Auxiliary |Identifies route names, usage scenarios, and more.|customer xxxx| +|name |False |Auxiliary |Identifies service names.|customer-xxxx| +|desc |False |Auxiliary |service usage scenarios, and more.|customer xxxx| Config Example: @@ -202,6 +205,7 @@ Config Example: "plugins": {}, # Bound plugin "upstream_id": "1", # upstream id, recommended "upstream": {}, # upstream, not recommended + "name": "service-test", "desc": "hello world", } ``` @@ -345,7 +349,8 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst |retries |optional|Pass the request to the next upstream using the underlying Nginx retry mechanism, the retry mechanism is enabled by default and set the number of retries according to the number of backend nodes. If `retries` option is explicitly set, it will override the default value.| |enable_websocket|optional| enable `websocket`(boolean), default `false`.| |timeout|optional| Set the timeout for connection, sending and receiving messages. | -|desc |optional|Identifies route names, usage scenarios, and more.| +|name |optional|Identifies upstream names| +|desc |optional|upstream usage scenarios, and more.| Config Example: @@ -371,6 +376,7 @@ Config Example: "checks": {}, # Health check parameters "hash_on": "", "key": "", + "name": "upstream-for-test", "desc": "hello world", } ``` diff --git a/t/admin/routes.t b/t/admin/routes.t index ac8078b2160a..32e674f955c5 100644 --- a/t/admin/routes.t +++ b/t/admin/routes.t @@ -1730,3 +1730,45 @@ GET /t passed --- no_error_log [error] + + + +=== TEST 47: set route(id: 1 + name: test name) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "methods": ["GET"], + "upstream": { + "nodes": { + "127.0.0.1:8080": 1 + }, + "type": "roundrobin" + }, + "name": "test name", + "uri": "/index.html" + }]], + [[{ + "node": { + "value": { + "name": "test name" + }, + "key": "/apisix/routes/1" + }, + "action": "set" + }]] + ) + + ngx.status = code + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] diff --git a/t/admin/services.t b/t/admin/services.t index a3aaa59c510d..73ce783b01cd 100644 --- a/t/admin/services.t +++ b/t/admin/services.t @@ -882,3 +882,49 @@ GET /t 200 passed --- no_error_log [error] + + + +=== TEST 26: set service(id: 1 + test service name) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/services/1', + ngx.HTTP_PUT, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:8080": 1 + }, + "type": "roundrobin" + }, + "name": "test service name" + }]], + [[{ + "node": { + "value": { + "upstream": { + "nodes": { + "127.0.0.1:8080": 1 + }, + "type": "roundrobin" + }, + "name": "test service name" + }, + "key": "/apisix/services/1" + }, + "action": "set" + }]] + ) + + ngx.status = code + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] diff --git a/t/admin/upstream.t b/t/admin/upstream.t index 661186d74b58..53a68094f961 100644 --- a/t/admin/upstream.t +++ b/t/admin/upstream.t @@ -1146,7 +1146,7 @@ GET /t -=== TEST 35: type chash, hash_on: consumer, don't need upstream key +=== TEST 35: type chash, hash_on: consumer, do not need upstream key --- config location /t { content_by_lua_block { @@ -1236,3 +1236,45 @@ GET /t {"error_msg":"invalid configuration: property \"hash_on\" validation failed: matches non of the enum values"} --- no_error_log [error] + + + +=== TEST 38: set upstream(id: 1 + name: test name) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/upstreams/1', + ngx.HTTP_PUT, + [[{ + "nodes": { + "127.0.0.1:8080": 1 + }, + "type": "roundrobin", + "name": "test upstream name" + }]], + [[{ + "node": { + "value": { + "nodes": { + "127.0.0.1:8080": 1 + }, + "type": "roundrobin", + "name": "test upstream name" + }, + "key": "/apisix/upstreams/1" + }, + "action": "set" + }]] + ) + + ngx.status = code + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error]