From ba50e79bfbed1427b0dc98a097a6990407c20b6a Mon Sep 17 00:00:00 2001 From: tzssangglass Date: Wed, 9 Feb 2022 18:19:35 +0800 Subject: [PATCH 01/52] doc: add new QQ group (#6274) --- CONTRIBUTING.md | 2 +- README.md | 2 +- docs/zh/latest/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d528a60e3de3f..152d5904a3bb0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -137,5 +137,5 @@ If you have contributed to Apache APISIX, no matter it is a code contribution to ## Do you have questions about the source code? -- **QQ Group**: 578997126(recommended), 552030619 +- **QQ Group**: 781365357(recommended), 578997126, 552030619 - Join in `apisix` channel at [Apache Slack](http://s.apache.org/slack-invite). If the link is not working, find the latest one at [Apache INFRA WIKI](https://cwiki.apache.org/confluence/display/INFRA/Slack+Guest+Invites). diff --git a/README.md b/README.md index 951bbb9138244..27a0d082ab8eb 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ The technical architecture of Apache APISIX: ## Community - Mailing List: Mail to dev-subscribe@apisix.apache.org, follow the reply to subscribe to the mailing list. -- QQ Group - 578997126 +- QQ Group - 781365357 - Slack Workspace - Please [subscribe the mailing list](https://apisix.apache.org/docs/general/subscribe-guide) then ask for invitation link - ![Twitter Follow](https://img.shields.io/twitter/follow/ApacheAPISIX?style=social) - follow and interact with us using hashtag `#ApacheAPISIX` - [bilibili video](https://space.bilibili.com/551921247) diff --git a/docs/zh/latest/README.md b/docs/zh/latest/README.md index 98f33c96f9900..7e446bd78ec68 100644 --- a/docs/zh/latest/README.md +++ b/docs/zh/latest/README.md @@ -39,7 +39,7 @@ Apache APISIX 的技术架构如下图所示: ## 社区 - 邮件列表 - 发送任意内容到 dev-subscribe@apisix.apache.org 后,根据回复以订阅邮件列表。 -- QQ 群 - 578997126 +- QQ 群 - 781365357 - Slack - 请 [订阅邮件列表](https://apisix.apache.org/docs/general/subscribe-guide) 后发送邮件获取邀请链接 - ![Twitter Follow](https://img.shields.io/twitter/follow/ApacheAPISIX?style=social) - 使用标签 `#ApacheAPISIX` 关注我们并与我们互动。 - [哔哩哔哩](https://space.bilibili.com/551921247) From fec47142eb1e98f387686a2f172920a9fd5cbb90 Mon Sep 17 00:00:00 2001 From: Felix Bartels <1257835+fbartels@users.noreply.github.com> Date: Wed, 9 Feb 2022 12:52:56 +0100 Subject: [PATCH 02/52] =?UTF-8?q?feat(oidc):=20make=20it=20possible=20to?= =?UTF-8?q?=20validate=20tokens=20against=20provider=20host=E2=80=A6=20(#5?= =?UTF-8?q?449)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: starsz --- apisix/plugins/openid-connect.lua | 7 +- docs/en/latest/plugins/openid-connect.md | 15 +- t/plugin/openid-connect.t | 178 +++++++++++++++++++++++ 3 files changed, 192 insertions(+), 8 deletions(-) diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index 1c8d78c1c3baf..9214d472298dd 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -179,8 +179,8 @@ local function introspect(ctx, conf) -- If we get here, token was found in request. - if conf.public_key then - -- Validate token against public key. + if conf.public_key or conf.use_jwks then + -- Validate token against public key or jwks document of the oidc provider. -- TODO: In the called method, the openidc module will try to extract -- the token by itself again -- from a request header or session cookie. -- It is inefficient that we also need to extract it (just from headers) @@ -196,6 +196,8 @@ local function introspect(ctx, conf) end -- Token successfully validated. + local method = (conf.public_key and "public_key") or (conf.use_jwks and "jwks") + core.log.debug("token validate successfully by ", method) return res, err, token, nil else -- Validate token against introspection endpoint. @@ -210,6 +212,7 @@ local function introspect(ctx, conf) -- Token successfully validated and response from the introspection -- endpoint contains the userinfo. + core.log.debug("token validate successfully by introspection") return res, err, token, res end end diff --git a/docs/en/latest/plugins/openid-connect.md b/docs/en/latest/plugins/openid-connect.md index 17e7cb5d6ec7c..3c5dff9d2180b 100644 --- a/docs/en/latest/plugins/openid-connect.md +++ b/docs/en/latest/plugins/openid-connect.md @@ -23,12 +23,14 @@ title: openid-connect ## Summary -- [**Name**](#name) -- [**Attributes**](#attributes) -- [**Modes of operation**](#modes-of-operation) - - [**Token Introspection**](#token-introspection) - - [**Introspecting with public key**](#introspecting-with-public-key) -- [**Troubleshooting**](#troubleshooting) +- [Summary](#summary) +- [Name](#name) +- [Attributes](#attributes) +- [Modes of operation](#modes-of-operation) + - [Token Introspection](#token-introspection) + - [Introspecting with public key](#introspecting-with-public-key) + - [Authentication through OIDC Relying Party flow](#authentication-through-oidc-relying-party-flow) +- [Troubleshooting](#troubleshooting) ## Name @@ -51,6 +53,7 @@ The OAuth 2 / Open ID Connect(OIDC) plugin provides authentication and introspec | introspection_endpoint | string | optional | | | URL of the token verification endpoint of the identity server | | introspection_endpoint_auth_method | string | optional | "client_secret_basic" | | Authentication method name for token introspection | | public_key | string | optional | | | The public key to verify the token | +| use_jwks | boolean | optional | | | Use the jwks endpoint of the identity server to verify the token | | token_signing_alg_values_expected | string | optional | | | Algorithm used to sign the token | | set_access_token_header | boolean | optional | true | | Whether to ensure the access token is set in a request header. | | access_token_in_authorization_header | boolean | optional | false | | If set to `true`, ensure that the access token is set in the `Authorization` header, otherwise use the `X-Access-Token` header. | diff --git a/t/plugin/openid-connect.t b/t/plugin/openid-connect.t index 79a6aa210b651..eae3dcea7fb53 100644 --- a/t/plugin/openid-connect.t +++ b/t/plugin/openid-connect.t @@ -16,6 +16,7 @@ # use t::APISIX 'no_plan'; +log_level('debug'); repeat_each(1); no_long_string(); no_root_location(); @@ -1426,6 +1427,10 @@ passed GET /t --- response_body true +--- grep_error_log eval +qr/token validate successfully by \w+/ +--- grep_error_log_out +token validate successfully by introspection --- no_error_log [error] @@ -1487,3 +1492,176 @@ GET /t {"access_token_in_authorization_header":false,"bearer_only":false,"client_id":"kbyuFDidLLm280LIwVFiazOqjO3ty8KH","client_secret":"60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa","discovery":"http://127.0.0.1:1980/.well-known/openid-configuration","introspection_endpoint_auth_method":"client_secret_basic","logout_path":"/logout","realm":"apisix","scope":"openid","set_access_token_header":true,"set_id_token_header":true,"set_userinfo_header":true,"ssl_verify":false,"timeout":3} --- no_error_log [error] + + + +=== TEST 25: Update plugin with ID provider jwks endpoint for token verification. +--- 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, + [[{ + "plugins": { + "openid-connect": { + "client_id": "course_management", + "client_secret": "d1ec69e9-55d2-4109-a3ea-befa071579d5", + "discovery": "http://127.0.0.1:8090/auth/realms/University/.well-known/openid-configuration", + "redirect_uri": "http://localhost:3000", + "ssl_verify": false, + "timeout": 10, + "bearer_only": true, + "use_jwks": true, + "realm": "University", + "introspection_endpoint_auth_method": "client_secret_post", + "introspection_endpoint": "http://127.0.0.1:8090/auth/realms/University/protocol/openid-connect/token/introspect" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]], + [[{ + "node": { + "value": { + "plugins": { + "openid-connect": { + "client_id": "course_management", + "client_secret": "d1ec69e9-55d2-4109-a3ea-befa071579d5", + "discovery": "http://127.0.0.1:8090/auth/realms/University/.well-known/openid-configuration", + "redirect_uri": "http://localhost:3000", + "ssl_verify": false, + "timeout": 10, + "bearer_only": true, + "use_jwks": true, + "realm": "University", + "introspection_endpoint_auth_method": "client_secret_post", + "introspection_endpoint": "http://127.0.0.1:8090/auth/realms/University/protocol/openid-connect/token/introspect" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }, + "key": "/apisix/routes/1" + }, + "action": "set" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 26: Obtain valid token and access route with it. +--- config + location /t { + content_by_lua_block { + -- Obtain valid access token from Keycloak using known username and password. + local json_decode = require("toolkit.json").decode + local http = require "resty.http" + local httpc = http.new() + local uri = "http://127.0.0.1:8090/auth/realms/University/protocol/openid-connect/token" + local res, err = httpc:request_uri(uri, { + method = "POST", + body = "grant_type=password&client_id=course_management&client_secret=d1ec69e9-55d2-4109-a3ea-befa071579d5&username=teacher@gmail.com&password=123456", + headers = { + ["Content-Type"] = "application/x-www-form-urlencoded" + } + }) + + -- Check response from keycloak and fail quickly if there's no response. + if not res then + ngx.say(err) + return + end + + -- Check if response code was ok. + if res.status == 200 then + -- Get access token from JSON response body. + local body = json_decode(res.body) + local accessToken = body["access_token"] + + -- Access route using access token. Should work. + uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello" + local res, err = httpc:request_uri(uri, { + method = "GET", + headers = { + ["Authorization"] = "Bearer " .. body["access_token"] + } + }) + + if res.status == 200 then + -- Route accessed successfully. + ngx.say(true) + else + -- Couldn't access route. + ngx.say(false) + end + else + -- Response from Keycloak not ok. + ngx.say(false) + end + } + } +--- request +GET /t +--- response_body +true +--- grep_error_log eval +qr/token validate successfully by \w+/ +--- grep_error_log_out +token validate successfully by jwks +--- no_error_log +[error] + + + +=== TEST 27: Access route with an invalid token. +--- config + location /t { + content_by_lua_block { + -- Access route using a fake access token. + local http = require "resty.http" + local httpc = http.new() + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello" + local res, err = httpc:request_uri(uri, { + method = "GET", + headers = { + ["Authorization"] = "Bearer " .. "fake access token", + } + }) + + if res.status == 200 then + ngx.say(true) + else + ngx.say(false) + end + } + } +--- request +GET /t +--- response_body +false +--- error_log +OIDC introspection failed: invalid jwt: invalid jwt string From 6558ba519c304324b84a6364ac4f5fd6be79ffa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Wed, 9 Feb 2022 19:53:19 +0800 Subject: [PATCH 03/52] feat(grpc-transcode): support .pb file (#6264) --- apisix/plugins/grpc-transcode/proto.lua | 70 +++++++++-- apisix/plugins/grpc-transcode/util.lua | 13 +- docs/en/latest/plugins/grpc-transcode.md | 63 +++++++++- docs/zh/latest/plugins/grpc-transcode.md | 63 +++++++++- rockspec/apisix-master-0.rockspec | 2 +- t/grpc_server_example | 2 +- t/plugin/grpc-transcode2.t | 152 +++++++++++++++++++++++ 7 files changed, 343 insertions(+), 22 deletions(-) diff --git a/apisix/plugins/grpc-transcode/proto.lua b/apisix/plugins/grpc-transcode/proto.lua index de19be26bb974..e997b55ef877d 100644 --- a/apisix/plugins/grpc-transcode/proto.lua +++ b/apisix/plugins/grpc-transcode/proto.lua @@ -14,25 +14,23 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -local core = require("apisix.core") -local config_util = require("apisix.core.config_util") -local pb = require("pb") -local protoc = require("protoc") -local pcall = pcall -local ipairs = ipairs -local protos +local core = require("apisix.core") +local config_util = require("apisix.core.config_util") +local pb = require("pb") +local protoc = require("protoc") +local pcall = pcall +local ipairs = ipairs +local decode_base64 = ngx.decode_base64 +local protos local lrucache_proto = core.lrucache.new({ ttl = 300, count = 100 }) local proto_fake_file = "filename for loaded" -local function compile_proto(content) - -- clear pb state - pb.state(nil) - +local function compile_proto_text(content) protoc.reload() local _p = protoc.new() -- the loaded proto won't appears in _p.loaded without a file name after lua-protobuf=0.3.2, @@ -50,8 +48,6 @@ local function compile_proto(content) end local compiled = _p.loaded - -- fetch pb state - compiled.pb_state = pb.state(nil) local index = {} for _, s in ipairs(compiled[proto_fake_file].service or {}) do @@ -69,6 +65,54 @@ local function compile_proto(content) end +local function compile_proto_bin(content) + content = decode_base64(content) + if not content then + return nil + end + + -- pb.load doesn't return err + local ok = pb.load(content) + if not ok then + return nil + end + + local index = {} + for name, _, methods in pb.services() do + local method_index = {} + for _, m in ipairs(methods) do + method_index[m.name] = m + end + -- remove the prefix '.' + index[name:sub(2)] = method_index + end + + local compiled = {} + compiled[proto_fake_file] = {} + compiled[proto_fake_file].index = index + + return compiled +end + + +local function compile_proto(content) + -- clear pb state + pb.state(nil) + + local compiled, err = compile_proto_text(content) + if not compiled then + compiled = compile_proto_bin(content) + if not compiled then + return nil, err + end + end + + -- fetch pb state + compiled.pb_state = pb.state(nil) + return compiled +end + + local _M = { version = 0.1, compile_proto = compile_proto, diff --git a/apisix/plugins/grpc-transcode/util.lua b/apisix/plugins/grpc-transcode/util.lua index 18c9f7808a16e..2a7bfb648e940 100644 --- a/apisix/plugins/grpc-transcode/util.lua +++ b/apisix/plugins/grpc-transcode/util.lua @@ -27,23 +27,26 @@ local type = type local _M = {version = 0.1} -function _M.find_method(protos, service, method) - local loaded = protos[proto_fake_file] - if not loaded or type(loaded) ~= "table" then +function _M.find_method(proto, service, method) + local loaded = proto[proto_fake_file] + if type(loaded) ~= "table" then + core.log.error("compiled proto not found") return nil end - if not loaded.index[service] or type(loaded.index[service]) ~= "table" then + if type(loaded.index[service]) ~= "table" then + core.log.error("compiled proto service not found") return nil end local res = loaded.index[service][method] if not res then + core.log.error("compiled proto method not found") return nil end -- restore pb state - pb.state(protos.pb_state) + pb.state(proto.pb_state) return res end diff --git a/docs/en/latest/plugins/grpc-transcode.md b/docs/en/latest/plugins/grpc-transcode.md index 2f576ef8d7f72..206169ecaa6fc 100644 --- a/docs/en/latest/plugins/grpc-transcode.md +++ b/docs/en/latest/plugins/grpc-transcode.md @@ -29,7 +29,7 @@ HTTP(s) -> APISIX -> gRPC server #### Attributes -* `content`: `.proto` file's content. +* `content`: `.proto` or `.pb` file's content. #### Add a proto @@ -52,6 +52,67 @@ curl http://127.0.0.1:9080/apisix/admin/proto/1 -H 'X-API-KEY: edd1c9f034335f136 }' ``` +If your `.proto` file contains imports, or you want to combine multiple `.proto` files into a proto, +you can use `.pb` file to create the proto. + +Assumed we have a `.proto` called `proto/helloworld.proto`, which imports another proto file: + +```proto +syntax = "proto3"; + +package helloworld; +import "proto/import.proto"; +... +``` + +First of all, let's create a `.pb` file from `.proto` files: + +```shell +protoc --include_imports --descriptor_set_out=proto.pb proto/helloworld.proto +``` + +The output binary file `proto.pb` will contain both `helloworld.proto` and `import.proto`. + +Then we can submit the content of `proto.pb` as the `content` field of the proto. + +As the content is binary, we need to encode it in base64 first. Here we use a Python script to do it: + +```python +#!/usr/bin/env python +# coding: utf-8 +# save this file as upload_pb.py +import base64 +import sys +# sudo pip install requests +import requests + +if len(sys.argv) <= 1: + print("bad argument") + sys.exit(1) +with open(sys.argv[1], 'rb') as f: + content = base64.b64encode(f.read()) +id = sys.argv[2] +api_key = "edd1c9f034335f136f87ad84b625c8f1" # Change it + +reqParam = { + "content": content, +} +resp = requests.put("http://127.0.0.1:9080/apisix/admin/proto/" + id, json=reqParam, headers={ + "X-API-KEY": api_key, +}) +print(resp.status_code) +print(resp.text) +``` + +Create proto: + +```bash +chmod +x ./upload_pb.pb +./upload_pb.py proto.pb 1 +# 200 +# {"node":{"value":{"create_time":1643879753,"update_time":1643883085,"content":"CmgKEnByb3RvL2ltcG9ydC5wcm90bxIDcGtnIhoKBFVzZXISEgoEbmFtZRgBIAEoCVIEbmFtZSIeCghSZXNwb25zZRISCgRib2R5GAEgASgJUgRib2R5QglaBy4vcHJvdG9iBnByb3RvMwq9AQoPcHJvdG8vc3JjLnByb3RvEgpoZWxsb3dvcmxkGhJwcm90by9pbXBvcnQucHJvdG8iPAoHUmVxdWVzdBIdCgR1c2VyGAEgASgLMgkucGtnLlVzZXJSBHVzZXISEgoEYm9keRgCIAEoCVIEYm9keTI5CgpUZXN0SW1wb3J0EisKA1J1bhITLmhlbGxvd29ybGQuUmVxdWVzdBoNLnBrZy5SZXNwb25zZSIAQglaBy4vcHJvdG9iBnByb3RvMw=="},"key":"\/apisix\/proto\/1"},"action":"set"} +``` + ## Attribute List | Name | Type | Requirement | Default | Valid | Description | diff --git a/docs/zh/latest/plugins/grpc-transcode.md b/docs/zh/latest/plugins/grpc-transcode.md index d031943784d5c..842072ee200ca 100644 --- a/docs/zh/latest/plugins/grpc-transcode.md +++ b/docs/zh/latest/plugins/grpc-transcode.md @@ -27,7 +27,7 @@ HTTP(s) -> APISIX -> gRPC server ### 参数 -* `content`: `.proto` 文件的内容 +* `content`: `.proto` 或 `.pb` 文件的内容 ### 添加proto @@ -50,6 +50,67 @@ curl http://127.0.0.1:9080/apisix/admin/proto/1 -H 'X-API-KEY: edd1c9f034335f136 }' ``` +如果你的 `.proto` 文件包含 import,或者你想把多个 `.proto` 文件合并成一个 proto。 +你可以使用 `.pb` 文件来创建 proto。 + +假设我们有一个 `.proto` 叫 `proto/helloworld.proto`,它导入了另一个 proto 文件: + +```proto +syntax = "proto3"; + +package helloworld; +import "proto/import.proto"; +... +``` + +首先,让我们从 `.proto`文件创建一个`.pb`文件。 + +```shell +protoc --include_imports --descriptor_set_out=proto.pb proto/helloworld.proto +``` + +输出的二进制文件 `proto.pb` 将同时包含 `helloworld.proto` 和 `import.proto`。 + +然后我们可以将 `proto.pb` 的内容作为 proto 的 `content` 字段提交。 + +由于内容是二进制的,我们需要先对其进行 base64 编码。这里我们用一个 Python 脚本来做。 + +```python +#!/usr/bin/env python +# coding: utf-8 +# save this file as upload_pb.py +import base64 +import sys +# sudo pip install requests +import requests + +if len(sys.argv) <= 1: + print("bad argument") + sys.exit(1) +with open(sys.argv[1], 'rb') as f: + content = base64.b64encode(f.read()) +id = sys.argv[2] +api_key = "edd1c9f034335f136f87ad84b625c8f1" # Change it + +reqParam = { + "content": content, +} +resp = requests.put("http://127.0.0.1:9080/apisix/admin/proto/" + id, json=reqParam, headers={ + "X-API-KEY": api_key, +}) +print(resp.status_code) +print(resp.text) +``` + +创建proto: + +```bash +chmod +x ./upload_pb.pb +./upload_pb.py proto.pb 1 +# 200 +# {"node":{"value":{"create_time":1643879753,"update_time":1643883085,"content":"CmgKEnByb3RvL2ltcG9ydC5wcm90bxIDcGtnIhoKBFVzZXISEgoEbmFtZRgBIAEoCVIEbmFtZSIeCghSZXNwb25zZRISCgRib2R5GAEgASgJUgRib2R5QglaBy4vcHJvdG9iBnByb3RvMwq9AQoPcHJvdG8vc3JjLnByb3RvEgpoZWxsb3dvcmxkGhJwcm90by9pbXBvcnQucHJvdG8iPAoHUmVxdWVzdBIdCgR1c2VyGAEgASgLMgkucGtnLlVzZXJSBHVzZXISEgoEYm9keRgCIAEoCVIEYm9keTI5CgpUZXN0SW1wb3J0EisKA1J1bhITLmhlbGxvd29ybGQuUmVxdWVzdBoNLnBrZy5SZXNwb25zZSIAQglaBy4vcHJvdG9iBnByb3RvMw=="},"key":"\/apisix\/proto\/1"},"action":"set"} +``` + ## 参数列表 | 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index 3bc8121701b55..a6f3411af588e 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -46,7 +46,7 @@ dependencies = { "lua-resty-session = 2.24", "opentracing-openresty = 0.1", "lua-resty-radixtree = 2.8.1", - "lua-protobuf = 0.3.3", + "api7-lua-protobuf = 0.1.0", "lua-resty-openidc = 1.7.2-1", "luafilesystem = 1.7.0-2", "api7-lua-tinyyaml = 0.4.2", diff --git a/t/grpc_server_example b/t/grpc_server_example index f7ee318f701e0..5e74be697f241 160000 --- a/t/grpc_server_example +++ b/t/grpc_server_example @@ -1 +1 @@ -Subproject commit f7ee318f701e04bf21bf000baab539f5a8bc7eaa +Subproject commit 5e74be697f24151648be1712fce0ab2fdd0ec964 diff --git a/t/plugin/grpc-transcode2.t b/t/plugin/grpc-transcode2.t index 7a48077fc933b..93b84b2097b00 100644 --- a/t/plugin/grpc-transcode2.t +++ b/t/plugin/grpc-transcode2.t @@ -230,3 +230,155 @@ location /t { {"message":"Hello world, name: John"} --- error_log failed to encode request data to protobuf + + + +=== TEST 6: set binary rule +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin") + local json = require("toolkit.json") + + local content = t.read_file("t/grpc_server_example/proto.pb") + local data = {content = ngx.encode_base64(content)} + local code, body = t.test('/apisix/admin/proto/1', + ngx.HTTP_PUT, + json.encode(data) + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + local code, body = t.test('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/grpctest", + "plugins": { + "grpc-transcode": { + "proto_id": "1", + "service": "helloworld.TestImport", + "method": "Run" + } + }, + "upstream": { + "scheme": "grpc", + "type": "roundrobin", + "nodes": { + "127.0.0.1:50051": 1 + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 7: hit route +--- request +POST /grpctest +{"body":"world","user":{"name":"Hello"}} +--- more_headers +Content-Type: application/json +--- response_body chomp +{"body":"Hello world"} + + + +=== TEST 8: service/method not found +--- 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, + [[{ + "uri": "/service_not_found", + "plugins": { + "grpc-transcode": { + "proto_id": "1", + "service": "helloworld.TestImportx", + "method": "Run" + } + }, + "upstream": { + "scheme": "grpc", + "type": "roundrobin", + "nodes": { + "127.0.0.1:50051": 1 + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + local code, body = t('/apisix/admin/routes/2', + ngx.HTTP_PUT, + [[{ + "uri": "/method_not_found", + "plugins": { + "grpc-transcode": { + "proto_id": "1", + "service": "helloworld.TestImport", + "method": "Runx" + } + }, + "upstream": { + "scheme": "grpc", + "type": "roundrobin", + "nodes": { + "127.0.0.1:50051": 1 + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 9: hit route +--- request +POST /service_not_found +{"body":"world","user":{"name":"Hello"}} +--- more_headers +Content-Type: application/json +--- error_log +Undefined service method +--- error_code: 503 + + + +=== TEST 10: hit route +--- request +POST /method_not_found +{"body":"world","user":{"name":"Hello"}} +--- more_headers +Content-Type: application/json +--- error_log +Undefined service method +--- error_code: 503 From 03324ee6f9940020a129f18c11c337e6bd40660f Mon Sep 17 00:00:00 2001 From: Nic Date: Wed, 9 Feb 2022 19:53:51 +0800 Subject: [PATCH 04/52] fix(config_etcd): skip resync_delay while etcd watch timeout (#6259) --- apisix/core/config_etcd.lua | 5 ++++- t/core/etcd-sync.t | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apisix/core/config_etcd.lua b/apisix/core/config_etcd.lua index fa2b09e90dc64..dc7fc3838ab7c 100644 --- a/apisix/core/config_etcd.lua +++ b/apisix/core/config_etcd.lua @@ -579,7 +579,10 @@ local function _automatic_fetch(premature, self) end end - ngx_sleep(self.resync_delay + rand() * 0.5 * self.resync_delay) + -- etcd watch timeout is an expected error, so there is no need for resync_delay + if err ~= "timeout" then + ngx_sleep(self.resync_delay + rand() * 0.5 * self.resync_delay) + end elseif not ok then -- no error. reentry the sync with different state ngx_sleep(0.05) diff --git a/t/core/etcd-sync.t b/t/core/etcd-sync.t index 42a4c72dc3429..a1e674218f91c 100644 --- a/t/core/etcd-sync.t +++ b/t/core/etcd-sync.t @@ -27,7 +27,6 @@ __DATA__ etcd: host: - "http://127.0.0.1:2379" - resync_delay: 0.5 # resync after timeout --- config location /t { content_by_lua_block { From e9e53e8152b92c2daa16a27e411ebf318534b4a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Wed, 9 Feb 2022 19:54:38 +0800 Subject: [PATCH 05/52] refactor: mv the var mqtt_client_id to plugin level (#6241) --- apisix/core/ctx.lua | 5 ----- apisix/stream/plugins/mqtt-proxy.lua | 5 +++++ docs/en/latest/apisix-variable.md | 26 +++++++++++++------------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/apisix/core/ctx.lua b/apisix/core/ctx.lua index a954e750d0961..af8672d9101c5 100644 --- a/apisix/core/ctx.lua +++ b/apisix/core/ctx.lua @@ -148,7 +148,6 @@ do balancer_ip = true, balancer_port = true, consumer_name = true, - mqtt_client_id = true, route_id = true, route_name = true, service_id = true, @@ -254,10 +253,6 @@ function _M.register_var(name, getter) error("the getter of registered var should be a function") end - if apisix_var_names[name] then - error(name .. " is registered") - end - apisix_var_names[name] = getter end diff --git a/apisix/stream/plugins/mqtt-proxy.lua b/apisix/stream/plugins/mqtt-proxy.lua index 3a285890cea4c..2c421dcc2c49a 100644 --- a/apisix/stream/plugins/mqtt-proxy.lua +++ b/apisix/stream/plugins/mqtt-proxy.lua @@ -23,6 +23,11 @@ local str_byte = string.byte local str_sub = string.sub +core.ctx.register_var("mqtt_client_id", function(ctx) + return ctx.mqtt_client_id +end) + + local schema = { type = "object", properties = { diff --git a/docs/en/latest/apisix-variable.md b/docs/en/latest/apisix-variable.md index 9591010e3670e..d6254b82048ba 100644 --- a/docs/en/latest/apisix-variable.md +++ b/docs/en/latest/apisix-variable.md @@ -26,18 +26,18 @@ additional variables. List in alphabetical order: -| Variable Name | Description | Example | -|------------------|-------------------------| --------- | -| balancer_ip | the IP of picked upstream server | 1.1.1.1 | -| balancer_port | the port of picked upstream server | 80 | -| consumer_name | username of `consumer` | | -| graphql_name | the [operation name](https://graphql.org/learn/queries/#operation-name) of GraphQL | HeroComparison | -| graphql_operation | the operation type of GraphQL | mutation | -| graphql_root_fields | the top level fields of GraphQL | ["hero"] | -| mqtt_client_id | the client id in MQTT protocol | | -| route_id | id of `route` | | -| route_name | name of `route` | | -| service_id | id of `service` | | -| service_name | name of `service` | | +| Variable Name | Origin | Description | Example | +|------------------|---------|--------------------| --------- | +| balancer_ip | core | the IP of picked upstream server | 1.1.1.1 | +| balancer_port | core | the port of picked upstream server | 80 | +| consumer_name | core | username of `consumer` | | +| graphql_name | core | the [operation name](https://graphql.org/learn/queries/#operation-name) of GraphQL | HeroComparison | +| graphql_operation | core | the operation type of GraphQL | mutation | +| graphql_root_fields | core | the top level fields of GraphQL | ["hero"] | +| mqtt_client_id | mqtt-proxy | the client id in MQTT protocol | | +| route_id | core | id of `route` | | +| route_name | core | name of `route` | | +| service_id | core | id of `service` | | +| service_name | core | name of `service` | | You can also [register your own variable](./plugin-develop.md#register-custom-variable). From defafb1e426c4ffe4aa740c9bb9ad26992fa2c2e Mon Sep 17 00:00:00 2001 From: leslie <59061168+leslie-tsang@users.noreply.github.com> Date: Wed, 9 Feb 2022 19:55:30 +0800 Subject: [PATCH 06/52] fix(nacos): add complex password support for nacos `host_pattern` match rule (#6261) --- apisix/discovery/nacos/schema.lua | 2 +- t/discovery/nacos2.t | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apisix/discovery/nacos/schema.lua b/apisix/discovery/nacos/schema.lua index 9816d0789d270..40c1ba77cc106 100644 --- a/apisix/discovery/nacos/schema.lua +++ b/apisix/discovery/nacos/schema.lua @@ -14,7 +14,7 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -local host_pattern = [[^http(s)?:\/\/[a-zA-Z0-9-_.:\@%]+$]] +local host_pattern = [[^http(s)?:\/\/([a-zA-Z0-9-_.]+:.+\@)?[a-zA-Z0-9-_.:]+$]] local prefix_pattern = [[^[\/a-zA-Z0-9-_.]+$]] diff --git a/t/discovery/nacos2.t b/t/discovery/nacos2.t index ac16b7ff0bc20..b5b1c134c093b 100644 --- a/t/discovery/nacos2.t +++ b/t/discovery/nacos2.t @@ -21,6 +21,10 @@ workers(3); add_block_preprocessor(sub { my ($block) = @_; + if (!$block->request) { + $block->set_value("request", "GET /t"); + } + if ((!defined $block->error_log) && (!defined $block->no_error_log)) { $block->set_value("no_error_log", "[error]"); } @@ -82,3 +86,29 @@ GET /hello qr/server [1-2]/ --- error_log err:status = 502 + + + +=== TEST 2: test complex host +--- extra_yaml_config +discovery: + nacos: + host: + - "http://nacos:nacos#!&[]()*@127.0.0.1:8858" + fetch_interval: 1 +--- apisix_yaml +routes: + - + uri: /hello + upstream: + service_name: APISIX-NACOS-DEMO + discovery_type: nacos + type: roundrobin + +#END +--- request +GET /hello +--- timeout: 10 +--- error_code_like: ^(?:50\d)$ +--- error_log +nacos login fail From 04a4cf18d083d4940ad88bdc87b255dd18cfaab3 Mon Sep 17 00:00:00 2001 From: John Chever Date: Thu, 10 Feb 2022 09:44:01 +0800 Subject: [PATCH 07/52] docs: added installation mode for LTS version (#6269) --- docs/en/latest/how-to-build.md | 6 +++++- docs/zh/latest/how-to-build.md | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/en/latest/how-to-build.md b/docs/en/latest/how-to-build.md index 2eb830b5445dc..e02f362d61f7c 100644 --- a/docs/en/latest/how-to-build.md +++ b/docs/en/latest/how-to-build.md @@ -23,7 +23,7 @@ title: How to build Apache APISIX ## Step 1: Install Apache APISIX -You can install Apache APISIX via RPM Repository, Docker, Helm Chart, and source release package. Please choose one from the following options. +You can install Apache APISIX via RPM Repository, Docker, Helm Chart, source release package, and source release package ( LTS version ). Please choose one from the following options. ### Installation via RPM Repository(CentOS 7) @@ -128,6 +128,10 @@ Please refer to: [Installing Apache APISIX with Helm Chart](https://github.com/a Attention please, this operation will totally **remove** the related files. +### LTS version Installation via Source Release Package + +The current LTS VERSION of Apache APISIX is `2.10.3`. Set `APISIX VERSION` in [install by source package](# Install by source package) to `2.10.3` and follow the other steps. + ## Step 2: Install ETCD This step is required if you have installed only Apache APISIX via RPM, Docker or source code but not ETCD. diff --git a/docs/zh/latest/how-to-build.md b/docs/zh/latest/how-to-build.md index 10a0f39905ff1..5fe544e3c6d67 100644 --- a/docs/zh/latest/how-to-build.md +++ b/docs/zh/latest/how-to-build.md @@ -23,7 +23,7 @@ title: 如何构建 Apache APISIX ## 步骤1:安装 Apache APISIX -你可以通过 RPM 仓库、Docker、Helm Chart、源码包等多种方式来安装 Apache APISIX。请在以下选项中选择其中一种执行。 +你可以通过 RPM 仓库、Docker、Helm Chart、源码包、源码包(LTS 版本)等多种方式来安装 Apache APISIX。请在以下选项中选择其中一种执行。 ### 通过 RPM 仓库安装(CentOS 7) @@ -128,6 +128,10 @@ $ sudo yum install ./apisix/*.rpm 请注意,该操作将完整**删除**相关文件。 +### 通过源码包安装 LTS 版本 + +目前 Apache APISIX 的 LTS 版本为 `2.10.3`,将“[通过源码包安装](#通过源码包安装)”中的 `APISIX_VERSION` 设置成 `2.10.3` ,其他步骤按顺序进行即可。 + ## 步骤2:安装 ETCD 如果你只通过 RPM、Docker 或源代码安装了 Apache APISIX,而没有安装 ETCD,则需要这一步。 From 862c604a4a85244de2f143aeca71db9046ef5433 Mon Sep 17 00:00:00 2001 From: biubiue Date: Thu, 10 Feb 2022 09:57:31 +0800 Subject: [PATCH 08/52] docs: add forward-auth zh document (#6267) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 罗泽轩 --- docs/zh/latest/config.json | 3 +- docs/zh/latest/plugins/forward-auth.md | 140 +++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 docs/zh/latest/plugins/forward-auth.md diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index a56d1777478fb..c6f2ac94bf668 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -66,7 +66,8 @@ "plugins/basic-auth", "plugins/openid-connect", "plugins/hmac-auth", - "plugins/authz-casbin" + "plugins/authz-casbin", + "plugins/forward-auth" ] }, { diff --git a/docs/zh/latest/plugins/forward-auth.md b/docs/zh/latest/plugins/forward-auth.md new file mode 100644 index 0000000000000..8cd7bb619d257 --- /dev/null +++ b/docs/zh/latest/plugins/forward-auth.md @@ -0,0 +1,140 @@ +--- +title: forward-auth +--- + + + +## 目录 + +- [**名字**](#名字) +- [**属性**](#属性) +- [**数据定义**](#数据定义) +- [**示例**](#示例) +- [**测试插件**](#测试插件) +- [**禁用插件**](#禁用插件) + +## 名字 + +`forward-auth` 插件使用的是经典外部认证。在认证失败的时候,我们可以实现自定义错误或者重定向到认证页面。 + +Forward Auth 巧妙地将认证和授权逻辑移到了一个专门的外部服务中,网关将用户的请求转发给认证服务并阻塞原始请求,并在认证服务以非 2xx 状态响应时替换结果。 + +## 属性 + +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| -- | -- | -- | -- | -- | -- | +| host | string | 必须 | | | 设置 `authorization` 服务的地址 (eg. https://localhost:9188) | +| ssl_verify | boolean | 可选 | true | | 是否验证证书 | +| request_headers | array[string] | 可选 | | | 设置需要由 `client` 转发到 `authorization` 服务的请求头。未设置时,只有 Apache APISIX 的(X-Forwarded-XXX)会被转发到 `authorization` 服务。 | +| upstream_headers | array[string] | 可选 | | | 认证通过时,设置 `authorization` 服务转发至 `upstream` 的请求头。如果不设置则不转发任何请求头。 +| client_headers | array[string] | 可选 | | | 认证失败时,由 `authorization` 服务向 `client` 发送的响应头。如果不设置则不转发任何响应头。 | +| timeout | integer | 可选 | 3000ms | [1, 60000]ms | `authorization` 服务请求超时时间 | +| keepalive | boolean | 可选 | true | | HTTP 长连接 | +| keepalive_timeout | integer | 可选 | 60000ms | [1000, ...]ms | 长连接空闲时间 | +| keepalive_pool | integer | 可选 | 5 | [1, ...]ms | 连接池大小 | + +## 数据定义 + +request_headers 属性中转发到 `authorization` 服务中的 Apache APISIX 内容清单 +| Scheme | HTTP Method | Host | URI | Source IP | +| -- | -- | -- | -- | -- | +| X-Forwarded-Proto | X-Forwarded-Method | X-Forwarded-Host | X-Forwarded-Uri | X-Forwarded-For | + +## 示例 + +首先, 你需要设置一个认证服务。这里使用的是 Apache APISIX 无服务器插件模拟的示例。 + +```shell +curl -X PUT 'http://127.0.0.1:9080/apisix/admin/routes/auth' \ + -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \ + -H 'Content-Type: application/json' \ + -d '{ + "uri": "/auth", + "plugins": { + "serverless-pre-function": { + "phase": "rewrite", + "functions": [ + "return function (conf, ctx) local core = require(\"apisix.core\"); local authorization = core.request.header(ctx, \"Authorization\"); if authorization == \"123\" then core.response.exit(200); elseif authorization == \"321\" then core.response.set_header(\"X-User-ID\", \"i-am-user\"); core.response.exit(200); else core.response.set_header(\"Location\", \"http://example.com/auth\"); core.response.exit(403); end end" + ] + } + } +}' +``` + +下一步, 我们创建一个测试路由。 + +```shell +curl -X PUT http://127.0.0.1:9080/apisix/admin/routes/1 + -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' + -d '{ + "uri": "/headers", + "plugins": { + "forward-auth": { + "host": "http://127.0.0.1:9080/auth", + "request_headers": ["Authorization"], + "upstream_headers": ["X-User-ID"], + "client_headers": ["Location"] + } + }, + "upstream": { + "nodes": { + "httpbin.org:80": 1 + }, + "type": "roundrobin" + } +}' +``` + +我们可以进行下面三个测试: + +1. **request_headers** 从 `client` 转发请求头到 `authorization` 服务 + +```shell +curl http://127.0.0.1:9080/headers -H 'Authorization: 123' +{ + "headers": { + "Authorization": "123", + "Next": "More-headers" + } +} +``` + +2. **upstream_headers** 转发 `authorization` 服务响应头到 `upstream` + +```shell +curl http://127.0.0.1:9080/headers -H 'Authorization: 321' +{ + "headers": { + "Authorization": "321", + "X-User-ID": "i-am-user", + "Next": "More-headers" + } +} +``` + +3. **client_headers** 当授权失败时转发 `authorization` 服务响应头到 `client` + +```shell +curl -i http://127.0.0.1:9080/headers +HTTP/1.1 403 Forbidden +Location: http://example.com/auth +``` + +最后,你可以通过在路由中移除的方式禁用 `forward-auth` 插件。 From 92bbde92c324c496937d487206e581a52f7cef7a Mon Sep 17 00:00:00 2001 From: 123liubao <87936714+123liubao@users.noreply.github.com> Date: Thu, 10 Feb 2022 10:00:37 +0800 Subject: [PATCH 09/52] docs: correct the 'article' to 'documentation' in Getting started. (#6275) --- docs/en/latest/getting-started.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en/latest/getting-started.md b/docs/en/latest/getting-started.md index cd30bfe966d2b..3ee4b461ec128 100644 --- a/docs/en/latest/getting-started.md +++ b/docs/en/latest/getting-started.md @@ -23,13 +23,13 @@ title: Getting Started ## Summary -This article is a quick start guide for Apache APISIX. The Quick Start is divided into the following three steps: +This documentation is a quick start guide for Apache APISIX. The Quick Start is divided into the following three steps: 1. Install Apache APISIX via [Docker Compose](https://docs.docker.com/compose/). 1. Create a route and bind it with a Upstream. 1. Use `curl` command to verify that the results returned after binding are as expected. -In addition, this article provides some advanced operations on how to use Apache APISIX, including adding authentication, prefixing Route, using the APISIX Dashboard, and troubleshooting. +In addition, this documentation provides some advanced operations on how to use Apache APISIX, including adding authentication, prefixing Route, using the APISIX Dashboard, and troubleshooting. We will use the following `echo` endpoint as an example, which will return the parameters we passed. @@ -134,7 +134,7 @@ Now we have a running instance of Apache APISIX! Next, let's create a Route. ### How it works -Apache APISIX provides users with a powerful [Admin API](./admin-api.md) and [APISIX Dashboard](https://github.com/apache/apisix-dashboard). In this article, we use the Admin API to walk you through the procedures of creating a Route. +Apache APISIX provides users with a powerful [Admin API](./admin-api.md) and [APISIX Dashboard](https://github.com/apache/apisix-dashboard). In this documentation, we use the Admin API to walk you through the procedures of creating a Route. We can create a [Route](./architecture-design/route.md) and connect it to an Upstream service(also known as the [Upstream](./architecture-design/upstream.md)). When a `Request` arrives at Apache APISIX, Apache APISIX knows which Upstream the request should be forwarded to. From 06c51935aa207eef8ef75df24172e8656085c3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Thu, 10 Feb 2022 11:24:41 +0800 Subject: [PATCH 10/52] ci: enforce request review on the final state (#6277) --- .asf.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.asf.yaml b/.asf.yaml index cc4b6b86f1135..51a6b731ba51e 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -45,6 +45,7 @@ github: protected_branches: master: required_pull_request_reviews: + dismiss_stale_reviews: true require_code_owner_reviews: true required_approving_review_count: 2 release/2.12: From 50d6465fd7b6288f517fd5c408a3171ace7882dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Feb 2022 11:41:51 +0800 Subject: [PATCH 11/52] build(deps): bump actions/setup-go from 2.1.5 to 2.2.0 (#6279) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/chaos.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e5891e5da765..530cc48e15a15 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,7 +40,7 @@ jobs: submodules: recursive - name: Setup Go - uses: actions/setup-go@v2.1.5 + uses: actions/setup-go@v2.2.0 with: go-version: "1.15" diff --git a/.github/workflows/chaos.yml b/.github/workflows/chaos.yml index d4dafac44c40f..e26a4e90319d6 100644 --- a/.github/workflows/chaos.yml +++ b/.github/workflows/chaos.yml @@ -21,7 +21,7 @@ jobs: submodules: recursive - name: Setup go - uses: actions/setup-go@v2.1.5 + uses: actions/setup-go@v2.2.0 with: go-version: "1.16" From 2dd9a4664498b404a89408894ec533cbd70af2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Sun, 13 Feb 2022 19:59:17 +0800 Subject: [PATCH 12/52] docs: upgrade helm chart for new version if need (#6299) --- MAINTAIN.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/MAINTAIN.md b/MAINTAIN.md index 6997be9d5c7da..afabfee2e8feb 100644 --- a/MAINTAIN.md +++ b/MAINTAIN.md @@ -34,12 +34,13 @@ via `VERSION=x.y.z make release-src` 7. Move the vote artifact to Apache's apisix repo 8. Register the release info in https://reporter.apache.org/addrelease.html?apisix 9. Create a [GitHub release](https://github.com/apache/apisix/releases/tag/2.10.2) from the minor branch -10. Update [APISIX's website](https://github.com/apache/apisix-website/commit/f9104bdca50015722ab6e3714bbcd2d17e5c5bb3) +10. Update [APISIX's website](https://github.com/apache/apisix-website/commit/f9104bdca50015722ab6e3714bbcd2d17e5c5bb3) if the version number is the largest 11. Update APISIX rpm package > Go to [apisix-build-tools](https://github.com/api7/apisix-build-tools) repository and create a new tag named `apisix-${x.y.z}` to automatically submit the package to yum repo 12. Update [APISIX docker](https://github.com/apache/apisix-docker/commit/829d45559c303bea7edde5bebe9fcf4938071601) in [APISIX docker repository](https://github.com/apache/apisix-docker), and create new branch from master, named as `release/apisix-${version}`, e.g. `release/apisix-2.10.2` -13. Send the [ANNOUNCE email](https://lists.apache.org/thread.html/ree7b06e6eac854fd42ba4f302079661a172f514a92aca2ef2f1aa7bb%40%3Cdev.apisix.apache.org%3E) to dev@apisix.apache.org & announce@apache.org +13. Update [APISIX helm chart](https://github.com/apache/apisix-helm-chart/pull/234) if the version number is the largest +14. Send the [ANNOUNCE email](https://lists.apache.org/thread.html/ree7b06e6eac854fd42ba4f302079661a172f514a92aca2ef2f1aa7bb%40%3Cdev.apisix.apache.org%3E) to dev@apisix.apache.org & announce@apache.org ### Release minor version @@ -57,4 +58,5 @@ via `VERSION=x.y.z make release-src` 10. Update APISIX rpm package. > Go to [apisix-build-tools](https://github.com/api7/apisix-build-tools) repository and create a new tag named `apisix-${x.y.z}` to automatically submit the rpm package to yum repo 11. Update [APISIX docker](https://github.com/apache/apisix-docker/commit/829d45559c303bea7edde5bebe9fcf4938071601) in [APISIX docker repository](https://github.com/apache/apisix-docker), and create new branch from master, named as `release/apisix-${version}`, e.g. `release/apisix-2.10.2` -12. Send the [ANNOUNCE email](https://lists.apache.org/thread/4s4msqwl1tq13p9dnv3hx7skbgpkozw1) to dev@apisix.apache.org & announce@apache.org +12. Update [APISIX helm chart](https://github.com/apache/apisix-helm-chart/pull/234) +13. Send the [ANNOUNCE email](https://lists.apache.org/thread/4s4msqwl1tq13p9dnv3hx7skbgpkozw1) to dev@apisix.apache.org & announce@apache.org From 8be6aabc4555eb6326e63624264fe93e05ed0561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Sun, 13 Feb 2022 20:00:25 +0800 Subject: [PATCH 13/52] chore: upgrade lua-resty-dns-client to the latest (#6295) --- rockspec/apisix-master-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index a6f3411af588e..ae451c57995f1 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -32,7 +32,7 @@ description = { dependencies = { "lua-resty-ctxdump = 0.1-0", - "lua-resty-dns-client = 5.2.3", + "lua-resty-dns-client = 6.0.2", "lua-resty-template = 2.0", "lua-resty-etcd = 1.6.0", "api7-lua-resty-http = 0.2.0", From 5c0896a9896cf9918913ea256573ec8a7947c28b Mon Sep 17 00:00:00 2001 From: homeward <97138894+hf400159@users.noreply.github.com> Date: Sun, 13 Feb 2022 20:01:06 +0800 Subject: [PATCH 14/52] docs: added cpanm installation commands and remove $ sign (#6284) --- docs/en/latest/how-to-build.md | 78 +++++++++++++++++----------------- docs/zh/latest/how-to-build.md | 76 +++++++++++++++++---------------- 2 files changed, 79 insertions(+), 75 deletions(-) diff --git a/docs/en/latest/how-to-build.md b/docs/en/latest/how-to-build.md index e02f362d61f7c..12a73e97c1b1d 100644 --- a/docs/en/latest/how-to-build.md +++ b/docs/en/latest/how-to-build.md @@ -32,26 +32,26 @@ This installation method is suitable for CentOS 7. If the official OpenResty repository is not installed yet, the following command will help you automatically install both the repositories of OpenResty and Apache APISIX. ```shell -$ sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm +sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm ``` If the official OpenResty repository is installed, the following command will help you automatically install the repositories of Apache APISIX. ```shell -$ sudo yum-config-manager --add-repo https://repos.apiseven.com/packages/centos/apache-apisix.repo +sudo yum-config-manager --add-repo https://repos.apiseven.com/packages/centos/apache-apisix.repo ``` Please run the following commands to install the repository and Apache APISIX. ```shell # View the information of the latest apisix package -$ sudo yum info -y apisix +sudo yum info -y apisix # Will show the existing apisix packages -$ sudo yum --showduplicates list apisix +sudo yum --showduplicates list apisix # Will install the latest apisix package -$ sudo yum install apisix +sudo yum install apisix ``` ### Installation via RPM Offline Package(CentOS 7) @@ -59,16 +59,16 @@ $ sudo yum install apisix Download APISIX offline RPM package to `./apisix` folder ```shell -$ sudo mkdir -p apisix -$ sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm -$ sudo yum clean all && yum makecache -$ sudo yum install -y --downloadonly --downloaddir=./apisix apisix +sudo mkdir -p apisix +sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm +sudo yum clean all && yum makecache +sudo yum install -y --downloadonly --downloaddir=./apisix apisix ``` Copy `./apisix` folder to the target host, run the following command to install Apache APISIX. ```shell -$ sudo yum install ./apisix/*.rpm +sudo yum install ./apisix/*.rpm ``` ### Installation via Docker @@ -84,14 +84,14 @@ Please refer to: [Installing Apache APISIX with Helm Chart](https://github.com/a 1. Create a directory named `apisix-2.12.0`. ```shell - $ APISIX_VERSION='2.12.0' - $ mkdir apisix-${APISIX_VERSION} + APISIX_VERSION='2.12.0' + mkdir apisix-${APISIX_VERSION} ``` 2. Download Apache APISIX Release source package. ```shell - $ wget https://downloads.apache.org/apisix/${APISIX_VERSION}/apache-apisix-${APISIX_VERSION}-src.tgz + wget https://downloads.apache.org/apisix/${APISIX_VERSION}/apache-apisix-${APISIX_VERSION}-src.tgz ``` You can also download the Apache APISIX Release source package from the Apache APISIX website. The [Apache APISIX Official Website - Download Page](https://apisix.apache.org/downloads/) also provides source packages for Apache APISIX, APISIX Dashboard and APISIX Ingress Controller. @@ -99,18 +99,18 @@ Please refer to: [Installing Apache APISIX with Helm Chart](https://github.com/a 3. Unzip the Apache APISIX Release source package. ```shell - $ tar zxvf apache-apisix-${APISIX_VERSION}-src.tgz -C apisix-${APISIX_VERSION} + tar zxvf apache-apisix-${APISIX_VERSION}-src.tgz -C apisix-${APISIX_VERSION} ``` 4. Install the runtime dependent Lua libraries. ```shell # Switch to the apisix-${APISIX_VERSION} directory - $ cd apisix-${APISIX_VERSION} + cd apisix-${APISIX_VERSION} # Create dependencies - $ make deps + make deps # Install apisix command - $ make install + make install ``` - 4.1 `make deps` install `lualdap` failed, error like: `Could not find header file for LDAP` @@ -121,9 +121,9 @@ Please refer to: [Installing Apache APISIX with Helm Chart](https://github.com/a ```shell # Uninstall apisix command - $ make uninstall + make uninstall # Purge dependencies - $ make undeps + make undeps ``` Attention please, this operation will totally **remove** the related files. @@ -139,12 +139,12 @@ This step is required if you have installed only Apache APISIX via RPM, Docker o You can install ETCD via Docker or binary etc. The following command installs ETCD via binary. ```shell -$ ETCD_VERSION='3.4.13' -$ wget https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz -$ tar -xvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz && \ - cd etcd-v${ETCD_VERSION}-linux-amd64 && \ - sudo cp -a etcd etcdctl /usr/bin/ -$ nohup etcd & +ETCD_VERSION='3.4.13' +wget https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz +tar -xvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz && \ + cd etcd-v${ETCD_VERSION}-linux-amd64 && \ + sudo cp -a etcd etcdctl /usr/bin/ +nohup etcd >/tmp/etcd.log 2>&1 & ``` ## Step 3: Manage Apache APISIX Server @@ -157,7 +157,7 @@ Run the following command to initialize the NGINX configuration file and etcd. ```shell # initialize NGINX config file and etcd -$ apisix init +apisix init ``` ### Test configuration file @@ -166,7 +166,7 @@ Run the following command to test the configuration file. APISIX will generate ` ```shell # generate `nginx.conf` from `config.yaml` and test it -$ apisix test +apisix test ``` ### Start Apache APISIX @@ -175,7 +175,7 @@ Run the following command to start Apache APISIX. ```shell # start Apache APISIX server -$ apisix start +apisix start ``` ### Stop Apache APISIX @@ -188,14 +188,14 @@ The command to perform a graceful shutdown is shown below. ```shell # stop Apache APISIX server gracefully -$ apisix quit +apisix quit ``` The command to perform a forced shutdown is shown below. ```shell # stop Apache APISIX server immediately -$ apisix stop +apisix stop ``` ### View Other Operations @@ -204,23 +204,25 @@ Run the `apisix help` command to see the returned results and get commands and d ```shell # more actions find by `help` -$ apisix help +apisix help ``` ## Step 4: Run Test Cases 1. Install `cpanminus`, the package manager for `perl`. +Please refer to: [Installing package manager `cpanminus`](https://metacpan.org/pod/App::cpanminus#INSTALLATION). + 2. Then install the test-nginx dependencies via `cpanm`: ```shell - $ sudo cpanm --notest Test::Nginx IPC::Run > build.log 2>&1 || (cat build.log && exit 1) + sudo cpanm --notest Test::Nginx IPC::Run > build.log 2>&1 || (cat build.log && exit 1) ``` 3. Run the `git clone` command to clone the latest source code locally, please use the version we forked out: ```shell - $ git clone https://github.com/iresty/test-nginx.git + git clone https://github.com/iresty/test-nginx.git ``` 4. Here are two ways of running tests: @@ -262,7 +264,7 @@ Ensure that OpenResty is set to the default NGINX, and export the path as follow Run the specified test case using the following command. ```shell -$ prove -Itest-nginx/lib -r t/plugin/openid-connect.t +prove -Itest-nginx/lib -r t/plugin/openid-connect.t ``` For more details on the test cases, see the [testing framework](https://github.com/apache/apisix/blob/master/docs/en/latest/internal/testing-framework.md). @@ -286,7 +288,7 @@ apisix: When we need to access the Admin API, we can use the key above, as shown below. ```shell -$ curl http://127.0.0.1:9080/apisix/admin/routes?api_key=abcdefghabcdefgh -i +curl http://127.0.0.1:9080/apisix/admin/routes?api_key=abcdefghabcdefgh -i ``` The status code 200 in the returned result indicates that the access was successful, as shown below. @@ -302,7 +304,7 @@ Content-Type: text/plain At this point, if the key you enter does not match the value of `apisix.admin_key` in `conf/config.yaml`, for example, we know that the correct key is `abcdefghabcdefgh`, but we enter an incorrect key, such as `wrong-key`, as shown below. ```shell -$ curl http://127.0.0.1:9080/apisix/admin/routes?api_key=wrong-key -i +curl http://127.0.0.1:9080/apisix/admin/routes?api_key=wrong-key -i ``` The status code `401` in the returned result indicates that the access failed because the `key` entered was incorrect and did not pass authentication, triggering an `Unauthorized` error, as shown below. @@ -326,8 +328,8 @@ You can refer to the source of [api7/apisix-build-tools](https://github.com/api7 If you are using CentOS 7 and you installed Apache APISIX via the RPM package in step 2, the configuration file is already in place automatically and you can run the following command directly. ```shell -$ systemctl start apisix -$ systemctl stop apisix +systemctl start apisix +systemctl stop apisix ``` If you installed Apache APISIX by other methods, you can refer to the [configuration file template](https://github.com/api7/apisix-build-tools/blob/master/usr/lib/systemd/system/apisix.service) for modification and put it in the `/usr/lib/systemd/system/apisix.service` path. diff --git a/docs/zh/latest/how-to-build.md b/docs/zh/latest/how-to-build.md index 5fe544e3c6d67..9823906361240 100644 --- a/docs/zh/latest/how-to-build.md +++ b/docs/zh/latest/how-to-build.md @@ -32,26 +32,26 @@ title: 如何构建 Apache APISIX 如果尚未安装 OpenResty 的官方 RPM 仓库,请使用以下命令自动安装 OpenResty 和 Apache APISIX 的 RPM 仓库。 ```shell -$ sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm +sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm ``` 如果已安装 OpenResty 的官方 RPM 仓库,请使用以下命令自动安装 Apache APISIX 的 RPM 仓库。 ```shell -$ sudo yum-config-manager --add-repo https://repos.apiseven.com/packages/centos/apache-apisix.repo +sudo yum-config-manager --add-repo https://repos.apiseven.com/packages/centos/apache-apisix.repo ``` 请运行以下命令安装 Apache APISIX。 ```shell # 查看仓库中最新的 apisix 软件包的信息 -$ sudo yum info -y apisix +sudo yum info -y apisix # 显示仓库中现有的 apisix 软件包 -$ sudo yum --showduplicates list apisix +sudo yum --showduplicates list apisix # 安装最新的 apisix 软件包 -$ sudo yum install apisix +sudo yum install apisix ``` ### 通过 RPM 包离线安装(CentOS 7) @@ -59,16 +59,16 @@ $ sudo yum install apisix 下载 APISIX 离线 RPM 包到 `./apisix` 文件夹 ```shell -$ sudo mkdir -p apisix -$ sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm -$ sudo yum clean all && yum makecache -$ sudo yum install -y --downloadonly --downloaddir=./apisix apisix +sudo mkdir -p apisix +sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm +sudo yum clean all && yum makecache +sudo yum install -y --downloadonly --downloaddir=./apisix apisix ``` 拷贝 `./apisix` 文件夹到目标主机,使用以下命令安装 Apache APISIX。 ```shell -$ sudo yum install ./apisix/*.rpm +sudo yum install ./apisix/*.rpm ``` ### 通过 Docker 安装 @@ -84,14 +84,14 @@ $ sudo yum install ./apisix/*.rpm 1. 创建一个名为 `apisix-2.12.0` 的目录。 ```shell - $ APISIX_VERSION='2.12.0' - $ mkdir apisix-${APISIX_VERSION} + APISIX_VERSION='2.12.0' + mkdir apisix-${APISIX_VERSION} ``` 2. 下载 Apache APISIX Release 源码包: ```shell - $ wget https://downloads.apache.org/apisix/${APISIX_VERSION}/apache-apisix-${APISIX_VERSION}-src.tgz + wget https://downloads.apache.org/apisix/${APISIX_VERSION}/apache-apisix-${APISIX_VERSION}-src.tgz ``` 您也可以通过 Apache APISIX 官网下载 Apache APISIX Release 源码包。 Apache APISIX 官网也提供了 Apache APISIX、APISIX Dashboard 和 APISIX Ingress Controller 的源码包,详情请参考 [Apache APISIX 官网-下载页](https://apisix.apache.org/zh/downloads)。 @@ -99,18 +99,18 @@ $ sudo yum install ./apisix/*.rpm 3. 解压 Apache APISIX Release 源码包: ```shell - $ tar zxvf apache-apisix-${APISIX_VERSION}-src.tgz -C apisix-${APISIX_VERSION} + tar zxvf apache-apisix-${APISIX_VERSION}-src.tgz -C apisix-${APISIX_VERSION} ``` 4. 安装运行时依赖的 Lua 库: ```shell # 切换到 apisix-${APISIX_VERSION} 目录 - $ cd apisix-${APISIX_VERSION} + cd apisix-${APISIX_VERSION} # 安装依赖 - $ LUAROCKS_SERVER=https://luarocks.cn make deps + LUAROCKS_SERVER=https://luarocks.cn make deps # 安装 apisix 命令 - $ make install + make install ``` - 4.1 `make deps` 安装 `lualdap` 失败, 错误信息如: `Could not find header file for LDAP` @@ -121,9 +121,9 @@ $ sudo yum install ./apisix/*.rpm ```shell # 卸载 apisix 命令 - $ make uninstall + make uninstall # 卸载依赖 - $ make undeps + make undeps ``` 请注意,该操作将完整**删除**相关文件。 @@ -140,11 +140,11 @@ $ sudo yum install ./apisix/*.rpm ```shell ETCD_VERSION='3.4.13' -$ wget https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz -$ tar -xvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz && \ - cd etcd-v${ETCD_VERSION}-linux-amd64 && \ - sudo cp -a etcd etcdctl /usr/bin/ -$ nohup etcd & +wget https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz +tar -xvf etcd-v${ETCD_VERSION}-linux-amd64.tar.gz && \ + cd etcd-v${ETCD_VERSION}-linux-amd64 && \ + sudo cp -a etcd etcdctl /usr/bin/ +nohup etcd >/tmp/etcd.log 2>&1 & ``` ## 步骤3:管理 Apache APISIX 服务 @@ -157,7 +157,7 @@ $ nohup etcd & ```shell # initialize NGINX config file and etcd -$ apisix init +apisix init ``` ### 测试配置文件 @@ -166,7 +166,7 @@ $ apisix init ```shell # generate `nginx.conf` from `config.yaml` and test it -$ apisix test +apisix test ``` ### 启动 Apache APISIX @@ -175,7 +175,7 @@ $ apisix test ```shell # start Apache APISIX server -$ apisix start +apisix start ``` ### 停止运行 Apache APISIX @@ -186,14 +186,14 @@ $ apisix start ```shell # stop Apache APISIX server gracefully -$ apisix quit +apisix quit ``` 执行强制停机的命令如下所示: ```shell # stop Apache APISIX server immediately -$ apisix stop +apisix stop ``` ### 查看其他操作 @@ -202,23 +202,25 @@ $ apisix stop ```shell # more actions find by `help` -$ apisix help +apisix help ``` ## 步骤4:运行测试案例 1. 安装 `perl` 的包管理器 `cpanminus`。 +详情请参考:[安装包管理器 `cpanmius`](https://metacpan.org/pod/App::cpanminus#INSTALLATION)。 + 2. 然后通过 `cpanm` 来安装 test-nginx 的依赖: ```shell - $ sudo cpanm --notest Test::Nginx IPC::Run > build.log 2>&1 || (cat build.log && exit 1) + sudo cpanm --notest Test::Nginx IPC::Run > build.log 2>&1 || (cat build.log && exit 1) ``` 3. 运行 `git clone` 命令,将最新的源码克隆到本地,请使用我们 fork 出来的版本: ```shell - $ git clone https://github.com/iresty/test-nginx.git + git clone https://github.com/iresty/test-nginx.git ``` 4. 有两种方法运行测试: @@ -260,7 +262,7 @@ $ apisix help 使用以下命令运行指定的测试用例: ```shell -$ prove -Itest-nginx/lib -r t/plugin/openid-connect.t +prove -Itest-nginx/lib -r t/plugin/openid-connect.t ``` 关于测试用例的更多细节,参见 [测试框架](https://github.com/apache/apisix/blob/master/docs/en/latest/internal/testing-framework.md) @@ -284,7 +286,7 @@ apisix: 当我们需要访问 Admin API 时,就可以使用上面记录的 key 了,如下所示: ```shell -$ curl http://127.0.0.1:9080/apisix/admin/routes?api_key=abcdefghabcdefgh -i +curl http://127.0.0.1:9080/apisix/admin/routes?api_key=abcdefghabcdefgh -i ``` 返回结果中的状态码 200 说明访问成功,如下所示: @@ -300,7 +302,7 @@ Content-Type: text/plain 在这个时候,如果您输入的 key 与 `conf/config.yaml` 中 `apisix.admin_key` 的值不匹配,例如,我们已知正确的 key 是 `abcdefghabcdefgh`,但是我们选择输入一个错误的 key,例如 `wrong-key`,如下所示: ```shell -$ curl http://127.0.0.1:9080/apisix/admin/routes?api_key=wrong-key -i +curl http://127.0.0.1:9080/apisix/admin/routes?api_key=wrong-key -i ``` 返回结果中的状态码 `401` 说明访问失败,原因是输入的 `key` 有误,未通过认证,触发 `Unauthorized` 错误,如下所示: @@ -324,8 +326,8 @@ Content-Type: text/html 如果您使用的操作系统是 CentOS 7,且在步骤 2 中通过 RPM 包安装 Apache APISIX,配置文件已经自动安装到位,你可以直接运行以下命令: ```shell -$ systemctl start apisix -$ systemctl stop apisix +systemctl start apisix +systemctl stop apisix ``` 如果通过其他方法安装,可以参考 [配置文件模板](https://github.com/api7/apisix-build-tools/blob/master/usr/lib/systemd/system/apisix.service) 进行修改,并将其放置在 `/usr/lib/systemd/system/apisix.service` 路径下。 From e33d73379e8f3e65c7d951d5602707b7b4bb05c0 Mon Sep 17 00:00:00 2001 From: biubiue Date: Sun, 13 Feb 2022 20:01:53 +0800 Subject: [PATCH 15/52] docs: update forward-auth zh document (#6287) --- docs/zh/latest/plugins/forward-auth.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/zh/latest/plugins/forward-auth.md b/docs/zh/latest/plugins/forward-auth.md index 8cd7bb619d257..91874809d52a5 100644 --- a/docs/zh/latest/plugins/forward-auth.md +++ b/docs/zh/latest/plugins/forward-auth.md @@ -27,8 +27,6 @@ title: forward-auth - [**属性**](#属性) - [**数据定义**](#数据定义) - [**示例**](#示例) -- [**测试插件**](#测试插件) -- [**禁用插件**](#禁用插件) ## 名字 @@ -47,8 +45,8 @@ Forward Auth 巧妙地将认证和授权逻辑移到了一个专门的外部服 | client_headers | array[string] | 可选 | | | 认证失败时,由 `authorization` 服务向 `client` 发送的响应头。如果不设置则不转发任何响应头。 | | timeout | integer | 可选 | 3000ms | [1, 60000]ms | `authorization` 服务请求超时时间 | | keepalive | boolean | 可选 | true | | HTTP 长连接 | -| keepalive_timeout | integer | 可选 | 60000ms | [1000, ...]ms | 长连接空闲时间 | -| keepalive_pool | integer | 可选 | 5 | [1, ...]ms | 连接池大小 | +| keepalive_timeout | integer | 可选 | 60000ms | [1000, ...]ms | 长连接超时时间 | +| keepalive_pool | integer | 可选 | 5 | [1, ...]ms | 长连接池大小 | ## 数据定义 From ebe91aa64c4fd26a03ea1ebddc089c577f4e730b Mon Sep 17 00:00:00 2001 From: kwanhur Date: Sun, 13 Feb 2022 20:39:13 +0800 Subject: [PATCH 16/52] build: correct "surported" to "supported" in install-dependencies.sh (#6305) --- utils/install-dependencies.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/install-dependencies.sh b/utils/install-dependencies.sh index 36623268e0830..0dd431cb8371e 100755 --- a/utils/install-dependencies.sh +++ b/utils/install-dependencies.sh @@ -133,7 +133,7 @@ function main() { elif [[ "${OS_NAME}" == "darwin" ]]; then install_dependencies_on_mac_osx else - echo "Non-surported distribution" + echo "Non-supported distribution" fi return fi From 537a8da24d723caa5c85561d36b3b931ce1f1410 Mon Sep 17 00:00:00 2001 From: Jintao Zhang Date: Sun, 13 Feb 2022 22:12:39 +0800 Subject: [PATCH 17/52] docs: clearer description for Prometheus plugin (#6280) --- docs/en/latest/plugins/prometheus.md | 2 +- docs/zh/latest/plugins/prometheus.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/latest/plugins/prometheus.md b/docs/en/latest/plugins/prometheus.md index 36f022c022286..f4d55693ca407 100644 --- a/docs/en/latest/plugins/prometheus.md +++ b/docs/en/latest/plugins/prometheus.md @@ -54,7 +54,7 @@ plugin_attr: enable_export_server: false ``` -You may need to use [public-api](public-api.md) plugin to expose it. +And expose it by using [public-api](public-api.md) plugin. ## How to enable it diff --git a/docs/zh/latest/plugins/prometheus.md b/docs/zh/latest/plugins/prometheus.md index bf8e4cfc8d742..033e0b0e71c8a 100644 --- a/docs/zh/latest/plugins/prometheus.md +++ b/docs/zh/latest/plugins/prometheus.md @@ -54,7 +54,7 @@ plugin_attr: enable_export_server: false ``` -同时,您还需要使用 [public-api](../../../en/latest/plugins/public-api.md) 插件来暴露它。 +并使用 [public-api](../../../en/latest/plugins/public-api.md) 插件来暴露它。 ## 如何开启插件 From 3f965c4309352d61e4b09e545f67bd66cd3e9b7e Mon Sep 17 00:00:00 2001 From: kwanhur Date: Mon, 14 Feb 2022 15:00:41 +0800 Subject: [PATCH 18/52] build(install-deps): noops installed apisix-repo (#6308) --- utils/install-dependencies.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/install-dependencies.sh b/utils/install-dependencies.sh index 0dd431cb8371e..e692f0df6235e 100755 --- a/utils/install-dependencies.sh +++ b/utils/install-dependencies.sh @@ -49,7 +49,8 @@ function install_dependencies_with_yum() { local common_dep="curl git gcc openresty-openssl111-devel unzip pcre pcre-devel openldap-devel" if [ "${1}" == "centos" ]; then # add APISIX source - sudo yum install -y https://repos.apiseven.com/packages/centos/apache-apisix-repo-1.0-1.noarch.rpm + local apisix_pkg=apache-apisix-repo-1.0-1.noarch + rpm -q --quiet ${apisix_pkg} || sudo yum install -y https://repos.apiseven.com/packages/centos/${apisix_pkg}.rpm # install apisix-base and some compilation tools # shellcheck disable=SC2086 From 605141cba33beccf71100fdea03c8e9608d4852f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E9=A9=AC=E9=AA=9D?= Date: Mon, 14 Feb 2022 15:43:18 +0800 Subject: [PATCH 19/52] fix(traffic-split): failed to match rule when the first rule failed (#6292) Co-authored-by: tangzhenhuang --- apisix/plugins/traffic-split.lua | 1 + t/plugin/traffic-split5.t | 106 +++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/apisix/plugins/traffic-split.lua b/apisix/plugins/traffic-split.lua index 028cc97f55384..9ba0997f6f08e 100644 --- a/apisix/plugins/traffic-split.lua +++ b/apisix/plugins/traffic-split.lua @@ -238,6 +238,7 @@ function _M.access(conf, ctx) for _, rule in ipairs(conf.rules) do if not rule.match then + match_passed = true weighted_upstreams = rule.weighted_upstreams break end diff --git a/t/plugin/traffic-split5.t b/t/plugin/traffic-split5.t index 9e01ac8f69d80..aee660baa6b41 100644 --- a/t/plugin/traffic-split5.t +++ b/t/plugin/traffic-split5.t @@ -311,3 +311,109 @@ passed } --- response_body 1970, 1970, 1971, 1972, 1972, 1973 + + + +=== TEST 5: set upstream(multiple rules, the first rule has the match attribute and the second rule does not) and add route +--- config + location /t { + content_by_lua_block { + local json = require("toolkit.json") + local t = require("lib.test_admin").test + local data = { + uri = "/hello", + plugins = { + ["traffic-split"] = { + rules = { + { + match = { { + vars = { { "arg_id", "==", "1" } } + } }, + weighted_upstreams = { + { + upstream = { + name = "upstream_A", + type = "roundrobin", + nodes = { + ["127.0.0.1:1970"] = 1 + } + }, + weight = 1 + } + } + }, + { + weighted_upstreams = { + { + upstream = { + name = "upstream_B", + type = "roundrobin", + nodes = { + ["127.0.0.1:1971"] = 1 + } + }, + weight = 1 + }, + { + weight = 1 + } + } + } + } + } + }, + upstream = { + type = "roundrobin", + nodes = { + ["127.0.0.1:1972"] = 1 + } + } + } + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + json.encode(data) + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 6: first rule match failed and the second rule match success +--- config + location /t { + content_by_lua_block { + local http = require "resty.http" + local httpc = http.new() + + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello?id=1" + local ports = {} + local res, err + for i = 1, 2 do + res, err = httpc:request_uri(uri) + local port = tonumber(res.body) + ports[i] = port + end + + local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello?id=2" + for i = 3, 4 do + res, err = httpc:request_uri(uri) + local port = tonumber(res.body) + ports[i] = port + end + table.sort(ports) + + ngx.say(table.concat(ports, ", ")) + } + } +--- response_body +1970, 1970, 1971, 1972 From b16c86e24377d19215286c57bff0813a2cfd6c8c Mon Sep 17 00:00:00 2001 From: Soham Banerjee <63705023+soham4abc@users.noreply.github.com> Date: Tue, 15 Feb 2022 06:34:48 +0530 Subject: [PATCH 20/52] fix(redirect-plugin): redirection loop behind a proxy or lb (#6242) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 罗泽轩 Co-authored-by: tzssangglass --- apisix/plugins/redirect.lua | 4 ++- t/plugin/redirect.t | 52 +++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/apisix/plugins/redirect.lua b/apisix/plugins/redirect.lua index f5e5f1dfef6d0..fefe125497886 100644 --- a/apisix/plugins/redirect.lua +++ b/apisix/plugins/redirect.lua @@ -150,7 +150,9 @@ function _M.rewrite(conf, ctx) local uri = conf.uri local regex_uri = conf.regex_uri - if conf.http_to_https and ctx.var.scheme == "http" then + local proxy_proto = core.request.header(ctx, "X-Forwarded-Proto") + local _scheme = proxy_proto or core.request.get_scheme(ctx) + if conf.http_to_https and _scheme == "http" then -- TODO: add test case -- PR: https://github.com/apache/apisix/pull/1958 uri = "https://$host$request_uri" diff --git a/t/plugin/redirect.t b/t/plugin/redirect.t index 3c47e973e7606..2d181398553e7 100644 --- a/t/plugin/redirect.t +++ b/t/plugin/redirect.t @@ -1000,3 +1000,55 @@ Location: /hello?type=string&name=json --- error_code: 302 --- no_error_log [error] + + + +=== TEST 41: enable http_to_https (pass X-Forwarded-Proto) +--- 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, + [[{ + "uri": "/hello", + "host": "foo.com", + "vars": [ + [ + "scheme", + "==", + "http" + ] + ], + "plugins": { + "redirect": { + "http_to_https": true + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 42: enable http_to_https (pass X-Forwarded-Proto) +--- request +GET /hello +--- more_headers +Host: foo.com +X-Forwarded-Proto: http +--- error_code: 301 +--- response_headers +Location: https://foo.com/hello From f206920e9ed03ca0f78fcf01f721bdfff1d40493 Mon Sep 17 00:00:00 2001 From: tzssangglass Date: Tue, 15 Feb 2022 09:05:48 +0800 Subject: [PATCH 21/52] chore: update ngxin-lua-prometheus verison (#6315) --- rockspec/apisix-master-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index ae451c57995f1..4cbee3f28a008 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -50,7 +50,7 @@ dependencies = { "lua-resty-openidc = 1.7.2-1", "luafilesystem = 1.7.0-2", "api7-lua-tinyyaml = 0.4.2", - "nginx-lua-prometheus = 0.20210206", + "nginx-lua-prometheus = 0.20220127", "jsonschema = 0.9.7", "lua-resty-ipmatcher = 0.6.1", "lua-resty-kafka = 0.07", From 0b9a5fbc54f1e8cabeb4450a5ca9dcb1aa5fedea Mon Sep 17 00:00:00 2001 From: Bisakh Date: Tue, 15 Feb 2022 07:12:00 +0530 Subject: [PATCH 22/52] feat(loggly): support HTTP response code to SYSLOG severity mapping (#6228) --- apisix/plugins/loggly.lua | 28 +++++++- docs/en/latest/plugins/loggly.md | 7 +- t/plugin/loggly.t | 112 +++++++++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 2 deletions(-) diff --git a/apisix/plugins/loggly.lua b/apisix/plugins/loggly.lua index d18288850050f..80200394d132c 100644 --- a/apisix/plugins/loggly.lua +++ b/apisix/plugins/loggly.lua @@ -85,6 +85,18 @@ local schema = { type = "boolean", default = true }, + severity_map = { + type = "object", + description = "upstream response code vs syslog severity mapping", + patternProperties = { + ["^[1-5][0-9]{2}$"] = { + description = "keys are HTTP status code, values are severity", + type = "string", + enum = severity_enums + }, + }, + additionalProperties = false + } }, required = {"customer_token"} } @@ -145,6 +157,14 @@ function _M.check_schema(conf, schema_type) if not ok then return nil, err end + + if conf.severity_map then + local cache = {} + for k, v in pairs(conf.severity_map) do + cache[k] = severity[v:upper()] + end + conf._severity_cache = cache + end return log_util.check_log_schema(conf) end @@ -184,9 +204,15 @@ local function generate_log_message(conf, ctx) core.table.insert(taglist, "tag=\"" .. conf.tags[i] .. "\"") end end + + local message_severity = severity[conf.severity:upper()] + if conf._severity_cache and conf._severity_cache[tostring(ngx.status)] then + message_severity = conf._severity_cache[tostring(ngx.status)] + end + local message = { -- facility LOG_USER - random user level message - "<".. tostring(8 + severity[conf.severity:upper()]) .. ">1",-- 1 + "<".. tostring(8 + message_severity) .. ">1",-- 1 timestamp, -- timestamp ctx.var.host or "-", -- hostname "apisix", -- appname diff --git a/docs/en/latest/plugins/loggly.md b/docs/en/latest/plugins/loggly.md index 2a700316ba036..6ce36a9fcf200 100644 --- a/docs/en/latest/plugins/loggly.md +++ b/docs/en/latest/plugins/loggly.md @@ -46,7 +46,8 @@ For more info on Batch-Processor in Apache APISIX please refer to: | Name | Type | Requirement | Default | Description | | ----------------------- | ---- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | customer_token | string | required || A unique identifier is used when sending log data to Loggly to ensure that the logs are sent to the right organization account. | -| severity | string (enum) | optional | INFO | Log event severity level (choose between: "DEBUG", "INFO", "NOTICE", "WARNING", "ERR", "CRIT", "ALERT", "EMEGR" ) [case insensitive] | +| severity | string (enum) | optional | INFO | Syslog log event severity level (choose between: "DEBUG", "INFO", "NOTICE", "WARNING", "ERR", "CRIT", "ALERT", "EMEGR" ) [case insensitive] | +| severity_map | object | optional | nil | A sophisticated way of mapping upstream HTTP response code to SYSLOG severity. A set of key value pairs where keys are HTTP response code and values are one of the 8 SYSLOG severity keywords ("alert", "err" ...) Eg. {"410": "CRIT"} | | tags | array | optional | | To aid in segmentation & filtering. They are metadata you can set and they will be included with any event that is transmitted to Loggly. | | include_req_body | boolean | optional | false | Whether to include the request body. false: indicates that the requested body is not included; true: indicates that the requested body is included. Note: if the request body is too big to be kept in the memory, it can't be logged due to Nginx's limitation. | | include_resp_body| boolean | optional | false | Whether to include the response body. The response body is included if and only if it is `true`. | @@ -83,6 +84,10 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13 "customer_token":"0e6fe4bf-376e-40f4-b25f-1d55cb29f5a2", "tags":["apisix", "testroute"], "severity":"info", + "severity_map":{ + "503": "err", + "410": "alert" + }, "buffer_duration":60, "max_retry_count":0, "retry_delay":1, diff --git a/t/plugin/loggly.t b/t/plugin/loggly.t index d36c7917131fe..09e54ebe80706 100644 --- a/t/plugin/loggly.t +++ b/t/plugin/loggly.t @@ -54,6 +54,22 @@ _EOC_ ngx.say("ok") } } + + location /loggly/503 { + content_by_lua_block { + ngx.status = 503 + ngx.say("service temporarily unavailable") + ngx.exit(ngx.OK) + } + } + + location /loggly/410 { + content_by_lua_block { + ngx.status = 410 + ngx.say("expired link") + ngx.exit(ngx.OK) + } + } } _EOC_ @@ -572,3 +588,99 @@ opentracing --- error_log loggly body: {"route_id":"1"} loggly tags: "apisix" + + + +=== TEST 13: test setup for collecting syslog with severity based on http response code +--- 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, + [[{ + "plugins": { + "loggly": { + "customer_token" : "tok", + "batch_max_size": 1, + "severity_map": { + "503": "ERR", + "410": "ALERT" + } + } + }, + "upstream": { + "nodes": { + "127.0.0.1:10420": 1 + }, + "type": "roundrobin" + }, + "uri": "/loggly/*" + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say("fail") + return + end + ngx.say(body) + + local code, body = t('/apisix/admin/plugin_metadata/loggly', + ngx.HTTP_PUT, + [[{ + "host":"127.0.0.1", + "port": 8126, + "log_format":{ + "route_id": "$route_id" + } + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say("fail") + return + end + ngx.say(body) + } + } +--- response_body +passed +passed + + + +=== TEST 14: syslog PRIVAL 9 for type severity level ALERT +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body, _ = t("/loggly/410", "GET") + ngx.print(body) + } + } +--- response_body +expired link +--- grep_error_log eval +qr/message received: [ -~]+/ +--- grep_error_log_out eval +qr/message received: <9>1 [\d\-T:.]+Z [\d.]+ apisix [\d]+ - \[tok\@41058 tag="apisix"] \{"route_id":"1"\}/ + + + +=== TEST 15: syslog PRIVAL 11 for type severity level ERR +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body, _ = t("/loggly/503", "GET") + ngx.print(body) + } + } +--- response_body +service temporarily unavailable +--- grep_error_log eval +qr/message received: [ -~]+/ +--- grep_error_log_out eval +qr/message received: <11>1 [\d\-T:.]+Z [\d.]+ apisix [\d]+ - \[tok\@41058 tag="apisix"] \{"route_id":"1"\}/ From b06a2a645ca7f4211be923531b37991c8a0e337e Mon Sep 17 00:00:00 2001 From: mango <35127166+mangoGoForward@users.noreply.github.com> Date: Tue, 15 Feb 2022 11:32:29 +0800 Subject: [PATCH 23/52] test(core): fix test cases in `t/core/utils.t` (#6316) --- t/core/utils.t | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/t/core/utils.t b/t/core/utils.t index 477b275c0388e..e6c4735d3b01a 100644 --- a/t/core/utils.t +++ b/t/core/utils.t @@ -81,9 +81,10 @@ GET /t local core = require("apisix.core") local resolvers = {"8.8.8.8"} core.utils.set_resolver(resolvers) - local ip_info, err = core.utils.dns_parse("github.com") + local domain = "github.com" + local ip_info, err = core.utils.dns_parse(domain) if not ip_info then - core.log.error("failed to parse domain: ", host, ", error: ",err) + core.log.error("failed to parse domain: ", domain, ", error: ",err) end ngx.say(require("toolkit.json").encode(ip_info)) } @@ -102,9 +103,10 @@ qr/"address":.+,"name":"github.com"/ location /t { content_by_lua_block { local core = require("apisix.core") - local ip_info, err = core.utils.dns_parse("github.com") + local domain = "github.com" + local ip_info, err = core.utils.dns_parse(domain) if not ip_info then - core.log.error("failed to parse domain: ", host, ", error: ",err) + core.log.error("failed to parse domain: ", domain, ", error: ",err) end core.log.info("ip_info: ", require("toolkit.json").encode(ip_info)) ngx.say("resolvers: ", require("toolkit.json").encode(core.utils.get_resolver())) @@ -257,9 +259,10 @@ res:JohnDavid location /t { content_by_lua_block { local core = require("apisix.core") - local ip_info, err = core.utils.dns_parse("test.com") + local domain = "test.com" + local ip_info, err = core.utils.dns_parse(domain) if not ip_info then - core.log.error("failed to parse domain: ", host, ", error: ",err) + core.log.error("failed to parse domain: ", domain, ", error: ",err) return end ngx.say("ip_info: ", require("toolkit.json").encode(ip_info)) @@ -283,9 +286,10 @@ apisix: location /t { content_by_lua_block { local core = require("apisix.core") - local ip_info, err = core.utils.dns_parse("apisix") + local domain = "apisix" + local ip_info, err = core.utils.dns_parse(domain) if not ip_info then - core.log.error("failed to parse domain: ", host, ", error: ",err) + core.log.error("failed to parse domain: ", domain, ", error: ",err) return end ngx.say("ip_info: ", require("toolkit.json").encode(ip_info)) @@ -309,9 +313,10 @@ apisix: location /t { content_by_lua_block { local core = require("apisix.core") - local ip_info, err = core.utils.dns_parse("apisix") + local domain = "apisix" + local ip_info, err = core.utils.dns_parse(domain) if not ip_info then - core.log.error("failed to parse domain: ", host, ", error: ",err) + core.log.error("failed to parse domain: ", domain, ", error: ",err) return end ngx.say("ip_info: ", require("toolkit.json").encode(ip_info)) From bcf13cd4aeec93a684123c84a19434975bce1c3b Mon Sep 17 00:00:00 2001 From: Gaoll Date: Tue, 15 Feb 2022 19:54:52 +0800 Subject: [PATCH 24/52] fix(proxy-rewrite): when conf.headers are missing,conf.method can make effect (#6300) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 高亮亮 --- apisix/plugins/proxy-rewrite.lua | 24 +++++++-------- t/plugin/proxy-rewrite3.t | 53 ++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/apisix/plugins/proxy-rewrite.lua b/apisix/plugins/proxy-rewrite.lua index eff3c2a256b90..c1d7ec4f5d549 100644 --- a/apisix/plugins/proxy-rewrite.lua +++ b/apisix/plugins/proxy-rewrite.lua @@ -195,22 +195,20 @@ function _M.rewrite(conf, ctx) ctx.var.upstream_uri = upstream_uri end - if not conf.headers then - return - end - - if not conf.headers_arr then - conf.headers_arr = {} + if conf.headers then + if not conf.headers_arr then + conf.headers_arr = {} - for field, value in pairs(conf.headers) do - core.table.insert_tail(conf.headers_arr, field, value) + for field, value in pairs(conf.headers) do + core.table.insert_tail(conf.headers_arr, field, value) + end end - end - local field_cnt = #conf.headers_arr - for i = 1, field_cnt, 2 do - core.request.set_header(ctx, conf.headers_arr[i], - core.utils.resolve_var(conf.headers_arr[i+1], ctx.var)) + local field_cnt = #conf.headers_arr + for i = 1, field_cnt, 2 do + core.request.set_header(ctx, conf.headers_arr[i], + core.utils.resolve_var(conf.headers_arr[i+1], ctx.var)) + end end if conf.method then diff --git a/t/plugin/proxy-rewrite3.t b/t/plugin/proxy-rewrite3.t index 31364d08ecf3b..f98de527fa3fb 100644 --- a/t/plugin/proxy-rewrite3.t +++ b/t/plugin/proxy-rewrite3.t @@ -79,7 +79,7 @@ passed === TEST 2: hit route(upstream uri: should be /hello) --- request GET /hello ---- grep_error_log_out +--- error_log plugin_proxy_rewrite get method: POST @@ -125,7 +125,7 @@ passed === TEST 4: hit route(upstream uri: should be /hello) --- request GET /hello ---- grep_error_log_out +--- error_log plugin_proxy_rewrite get method: GET @@ -151,3 +151,52 @@ plugin_proxy_rewrite get method: GET --- response_body property "method" validation failed: matches none of the enum values done + + + +=== TEST 6: set route(rewrite method with headers) +--- 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"], + "plugins": { + "proxy-rewrite": { + "uri": "/plugin_proxy_rewrite", + "method": "POST", + "scheme": "http", + "host": "apisix.iresty.com", + "headers":{ + "x-api-version":"v1" + } + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 7: hit route(with header) +--- request +GET /hello +--- error_log +plugin_proxy_rewrite get method: POST From d0a7a7005032dfe839ac953b62ea6016b60acb74 Mon Sep 17 00:00:00 2001 From: leslie <59061168+leslie-tsang@users.noreply.github.com> Date: Wed, 16 Feb 2022 10:25:40 +0800 Subject: [PATCH 25/52] feat: compresses the redis lua script in limit-count (#6281) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 罗泽轩 --- apisix/core/string.lua | 12 ++++++++++++ .../limit-count/limit-count-redis-cluster.lua | 4 ++-- apisix/plugins/limit-count/limit-count-redis.lua | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/apisix/core/string.lua b/apisix/core/string.lua index 920a4388e146a..ed7fef8dd88a1 100644 --- a/apisix/core/string.lua +++ b/apisix/core/string.lua @@ -21,6 +21,7 @@ local str_find = string.find local ffi = require("ffi") local C = ffi.C local ffi_cast = ffi.cast +local ngx = ngx ffi.cdef[[ @@ -78,4 +79,15 @@ function _M.rfind_char(s, ch, idx) end +-- reduce network consumption by compressing string indentation +-- this method should be used with caution +-- it will remove the spaces at the beginning of each line +-- and remove the spaces after `,` character +function _M.compress_script(s) + s = ngx.re.gsub(s, [[^\s+]], "", "mjo") + s = ngx.re.gsub(s, [[,\s+]], ",", "mjo") + return s +end + + return _M diff --git a/apisix/plugins/limit-count/limit-count-redis-cluster.lua b/apisix/plugins/limit-count/limit-count-redis-cluster.lua index 935adee3ffbff..27d4e85faa4eb 100644 --- a/apisix/plugins/limit-count/limit-count-redis-cluster.lua +++ b/apisix/plugins/limit-count/limit-count-redis-cluster.lua @@ -29,13 +29,13 @@ local mt = { } -local script = [=[ +local script = core.string.compress_script([=[ if redis.call('ttl', KEYS[1]) < 0 then redis.call('set', KEYS[1], ARGV[1] - 1, 'EX', ARGV[2]) return ARGV[1] - 1 end return redis.call('incrby', KEYS[1], -1) -]=] +]=]) local function new_redis_cluster(conf) diff --git a/apisix/plugins/limit-count/limit-count-redis.lua b/apisix/plugins/limit-count/limit-count-redis.lua index 5cd2286e6eb48..d5c4648248bc6 100644 --- a/apisix/plugins/limit-count/limit-count-redis.lua +++ b/apisix/plugins/limit-count/limit-count-redis.lua @@ -29,13 +29,13 @@ local mt = { } -local script = [=[ +local script = core.string.compress_script([=[ if redis.call('ttl', KEYS[1]) < 0 then redis.call('set', KEYS[1], ARGV[1] - 1, 'EX', ARGV[2]) return ARGV[1] - 1 end return redis.call('incrby', KEYS[1], -1) -]=] +]=]) function _M.new(plugin_name, limit, window, conf) From d8b9b709a8064ec1893df4b8acdc91f97962dc85 Mon Sep 17 00:00:00 2001 From: tzssangglass Date: Wed, 16 Feb 2022 10:40:45 +0800 Subject: [PATCH 26/52] ci: support for generating flame graph (#6136) --- .github/workflows/build.yml | 4 +- .github/workflows/performance.yml | 62 ++++++++++++++++ ci/performance_test.sh | 117 ++++++++++++++++++++++++++++++ t/perf/test_http.py | 14 +++- 4 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/performance.yml create mode 100755 ci/performance_test.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 530cc48e15a15..943b6867cb42a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,8 +100,8 @@ jobs: - name: Linux Install run: | - sudo --preserve-env=OPENRESTY_VERSION \ - ./ci/${{ matrix.os_name }}_runner.sh do_install + sudo --preserve-env=OPENRESTY_VERSION \ + ./ci/${{ matrix.os_name }}_runner.sh do_install - name: Linux Script run: sudo ./ci/${{ matrix.os_name }}_runner.sh script diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml new file mode 100644 index 0000000000000..cff94835a602b --- /dev/null +++ b/.github/workflows/performance.yml @@ -0,0 +1,62 @@ +name: Performance Test + +on: + pull_request: + branches: [master, 'release/**'] + paths-ignore: + - 'docs/**' + - '**/*.md' + +jobs: + performance: + if: github.event_name == 'pull_request' || github.event.label.name == 'performance' + runs-on: ubuntu-18.04 + timeout-minutes: 45 + + steps: + - name: Check out code + uses: actions/checkout@v2.4.0 + with: + submodules: recursive + + - name: Cache deps + uses: actions/cache@v2.1.7 + env: + cache-name: cache-deps + with: + path: deps + key: ${{ runner.os }}-${{ env.cache-name }}-${{ matrix.os_name }}-${{ hashFiles('rockspec/apisix-master-0.rockspec') }} + + - name: Install Dependencies + run: sudo ./ci/performance_test.sh install_dependencies + + - name: Install wrk2 + run: sudo ./ci/performance_test.sh install_wrk2 + + - name: Install SystemTap Tools + run: sudo ./ci/performance_test.sh install_stap_tools + + - name: Perf Test + run: ./ci/performance_test.sh run_performance_test + + - name: Upload Performance Test Result + uses: actions/upload-artifact@v2 + with: + name: perf.txt + path: | + output/performance.txt + retention-days: 3 + + - name: Upload flamegrpah + uses: actions/upload-artifact@v2 + with: + name: flamegraph.svg + path: | + output/flamegraph.svg + retention-days: 3 + +# you can view the generated flamegraph by +# 1. open https://github.com/apache/apisix/actions +# 2. click the "Performance Test" button +# 3. choose the workflows that belong to your commits +# we need a way to have this address automatically appear in the comments of the PR running this workflow. diff --git a/ci/performance_test.sh b/ci/performance_test.sh new file mode 100755 index 0000000000000..695db94bd1cc4 --- /dev/null +++ b/ci/performance_test.sh @@ -0,0 +1,117 @@ +#!/usr/bin/env bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +. ./ci/common.sh + +set -ex + +install_dependencies() { + apt-get -y update --fix-missing + apt-get -y install lua5.1 liblua5.1-0-dev libldap2-dev + export_or_prefix + export OPENRESTY_VERSION=source + ./utils/linux-install-openresty.sh + bash utils/install-dependencies.sh install_luarocks + make deps +} + +install_wrk2() { + cd .. + git clone https://github.com/giltene/wrk2 + cd wrk2 || true + make + ln -s $PWD/wrk /usr/bin + cd .. +} + +install_stap_tools() { + # install ddeb source repo + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622 + + codename=$(lsb_release -c | awk '{print $2}') + sudo tee /etc/apt/sources.list.d/ddebs.list << EOF + deb http://ddebs.ubuntu.com/ ${codename} main restricted universe multiverse + deb http://ddebs.ubuntu.com/ ${codename}-updates main restricted universe multiverse + deb http://ddebs.ubuntu.com/ ${codename}-proposed main restricted universe multiverse +EOF + + sudo apt-get update + sudo apt-get install linux-image-$(uname -r)-dbgsym + sudo apt install elfutils libdw-dev + sudo apt-get install -y python3-setuptools python3-wheel + + # install systemtap + cd /usr/local/ + wget http://sourceware.org/systemtap/ftp/releases/systemtap-4.6.tar.gz + tar -zxf systemtap-4.6.tar.gz + mv systemtap-4.6 systemtap + cd systemtap + ./configure && make all && sudo make install && stap --version + cd .. + + # see https://github.com/openresty/stapxx/pull/48 + git clone https://github.com/api7/stapxx.git -b luajit-gc64 + git clone https://github.com/openresty/openresty-systemtap-toolkit.git + git clone https://github.com/brendangregg/FlameGraph.git +} + + +run_performance_test() { + sudo chmod -R 777 ./ + ulimit -n 10240 + + pip3 install -r t/perf/requirements.txt --user + + #openresty-debug + export OPENRESTY_PREFIX="/usr/local/openresty-debug" + export PATH=$OPENRESTY_PREFIX/nginx/sbin:$OPENRESTY_PREFIX/bin:$OPENRESTY_PREFIX/luajit/bin:$PATH + + mkdir output + python3 ./t/perf/test_http.py >$PWD/output/performance.txt 2>&1 & + + sleep 1 + + # stapxx + export STAP_PLUS_HOME=/usr/local/stapxx + export PATH=/usr/local/stapxx:/usr/local/stapxx/samples:$PATH + # openresty-systemtap-toolkit + export PATH=/usr/local/openresty-systemtap-toolkit:$PATH + # FlameGraph + export PATH=/usr/local/FlameGraph:$PATH + + sudo env PATH=$PATH /usr/local/stapxx/samples/lj-lua-stacks.sxx --arg time=30 --skip-badvars -x $(pgrep -P $(cat logs/nginx.pid) -n -f worker) > /tmp/tmp.bt + sudo env PATH=$PATH /usr/local/openresty-systemtap-toolkit/fix-lua-bt /tmp/tmp.bt > /tmp/flame.bt + sudo env PATH=$PATH /usr/local/FlameGraph/stackcollapse-stap.pl /tmp/flame.bt > /tmp/flame.cbt + sudo env PATH=$PATH /usr/local/FlameGraph/flamegraph.pl /tmp/flame.cbt > $PWD/output/flamegraph.svg +} + +case_opt=$1 +case $case_opt in + (install_dependencies) + install_dependencies + ;; + (install_wrk2) + install_wrk2 + ;; + (install_stap_tools) + install_stap_tools + ;; + (run_performance_test) + run_performance_test + ;; +esac diff --git a/t/perf/test_http.py b/t/perf/test_http.py index 29f1690c174c6..135f24d067a14 100755 --- a/t/perf/test_http.py +++ b/t/perf/test_http.py @@ -91,6 +91,16 @@ def create_conf(): "type": "roundrobin" }] + # expose public api + routes.append({ + "uri": "/gen_token", + "plugins": { + "public-api": { + "uri": "/apisix/plugin/jwt/sign" + } + }, + }) + conf = {} conf["routes"] = routes conf["consumers"] = consumers @@ -128,7 +138,7 @@ def create_env(): class TestHTTP(unittest.TestCase): def setUp(self): - self.duration = os.environ.get("APISIX_PERF_DURATION", "30") + self.duration = os.environ.get("APISIX_PERF_DURATION", "300") self.n_client = os.environ.get("APISIX_PERF_CLIENT", "100") self.n_thread = os.environ.get("APISIX_PERF_THREAD", "2") self.qps = os.environ.get("APISIX_PERF_QPS", "8000") @@ -143,7 +153,7 @@ def test_perf(self): conn = http.client.HTTPConnection("127.0.0.1", port=9080) for i in range(RULE_SIZE): i = str(i) - conn.request("GET", "/apisix/plugin/jwt/sign?key=user-key-" + i) + conn.request("GET", "/gen_token?key=user-key-" + i) response = conn.getresponse() if response.status >= 300: print("failed to sign, got: %s" % response.read()) From 84eced65a9097d4d93037aacb4d215d48d9923b1 Mon Sep 17 00:00:00 2001 From: Nic Date: Wed, 16 Feb 2022 15:20:28 +0800 Subject: [PATCH 27/52] change(prometheus): replace wrong apisix_nginx_http_current_connections{state="total"} label (#6327) Co-authored-by: Alex Zhang --- apisix/plugins/prometheus/exporter.lua | 12 +++++++++--- docs/assets/other/json/apisix-grafana-dashboard.json | 4 ++-- docs/en/latest/plugins/prometheus.md | 4 +++- docs/zh/latest/plugins/prometheus.md | 4 +++- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/apisix/plugins/prometheus/exporter.lua b/apisix/plugins/prometheus/exporter.lua index a3cc86d289135..30534d567fd18 100644 --- a/apisix/plugins/prometheus/exporter.lua +++ b/apisix/plugins/prometheus/exporter.lua @@ -87,6 +87,9 @@ function _M.init() "Number of HTTP connections", {"state"}) + metrics.requests = prometheus:gauge("http_requests_total", + "The total number of client requests since APISIX started") + metrics.etcd_reachable = prometheus:gauge("etcd_reachable", "Config server etcd reachable from APISIX, 0 is unreachable") @@ -199,9 +202,12 @@ local function nginx_status() break end - label_values[1] = name - metrics.connections:set(val[0], label_values) - + if name == "total" then + metrics.requests:set(val[0]) + else + label_values[1] = name + metrics.connections:set(val[0], label_values) + end end end diff --git a/docs/assets/other/json/apisix-grafana-dashboard.json b/docs/assets/other/json/apisix-grafana-dashboard.json index 217ab9ff1a517..247d9b3bc1520 100644 --- a/docs/assets/other/json/apisix-grafana-dashboard.json +++ b/docs/assets/other/json/apisix-grafana-dashboard.json @@ -148,7 +148,7 @@ "tableColumn": "", "targets": [ { - "expr": "sum(apisix_nginx_http_current_connections{state=\"total\", instance=~\"$instance\"})", + "expr": "sum(apisix_http_requests_total{instance=~\"$instance\"})", "intervalFactor": 2, "legendFormat": "Total", "refId": "A" @@ -157,7 +157,7 @@ "thresholds": "", "timeFrom": null, "timeShift": null, - "title": "Total Connections", + "title": "Total Requests", "type": "singlestat", "valueFontSize": "80%", "valueMaps": [ diff --git a/docs/en/latest/plugins/prometheus.md b/docs/en/latest/plugins/prometheus.md index f4d55693ca407..0bab8234f8760 100644 --- a/docs/en/latest/plugins/prometheus.md +++ b/docs/en/latest/plugins/prometheus.md @@ -234,13 +234,15 @@ apisix_etcd_reachable 1 apisix_http_status{code="200",route="1",matched_uri="/hello",matched_host="",service="",consumer="",node="127.0.0.1"} 4 apisix_http_status{code="200",route="2",matched_uri="/world",matched_host="",service="",consumer="",node="127.0.0.1"} 4 apisix_http_status{code="404",route="",matched_uri="",matched_host="",service="",consumer="",node=""} 1 +# HELP apisix_http_requests_total The total number of client requests +# TYPE apisix_http_requests_total gauge +apisix_http_requests_total 1191780 # HELP apisix_nginx_http_current_connections Number of HTTP connections # TYPE apisix_nginx_http_current_connections gauge apisix_nginx_http_current_connections{state="accepted"} 11994 apisix_nginx_http_current_connections{state="active"} 2 apisix_nginx_http_current_connections{state="handled"} 11994 apisix_nginx_http_current_connections{state="reading"} 0 -apisix_nginx_http_current_connections{state="total"} 1191780 apisix_nginx_http_current_connections{state="waiting"} 1 apisix_nginx_http_current_connections{state="writing"} 1 # HELP apisix_nginx_metric_errors_total Number of nginx-lua-prometheus errors diff --git a/docs/zh/latest/plugins/prometheus.md b/docs/zh/latest/plugins/prometheus.md index 033e0b0e71c8a..855ad37ecdbf0 100644 --- a/docs/zh/latest/plugins/prometheus.md +++ b/docs/zh/latest/plugins/prometheus.md @@ -227,13 +227,15 @@ apisix_etcd_reachable 1 apisix_http_status{code="200",route="1",matched_uri="/hello",matched_host="",service="",consumer="",node="127.0.0.1"} 4 apisix_http_status{code="200",route="2",matched_uri="/world",matched_host="",service="",consumer="",node="127.0.0.1"} 4 apisix_http_status{code="404",route="",matched_uri="",matched_host="",service="",consumer="",node=""} 1 +# HELP apisix_http_requests_total The total number of client requests +# TYPE apisix_http_requests_total gauge +apisix_http_requests_total 1191780 # HELP apisix_nginx_http_current_connections Number of HTTP connections # TYPE apisix_nginx_http_current_connections gauge apisix_nginx_http_current_connections{state="accepted"} 11994 apisix_nginx_http_current_connections{state="active"} 2 apisix_nginx_http_current_connections{state="handled"} 11994 apisix_nginx_http_current_connections{state="reading"} 0 -apisix_nginx_http_current_connections{state="total"} 1191780 apisix_nginx_http_current_connections{state="waiting"} 1 apisix_nginx_http_current_connections{state="writing"} 1 # HELP apisix_nginx_metric_errors_total Number of nginx-lua-prometheus errors From 1407eb94526dfe1a188b716011989a94fe98dcbd Mon Sep 17 00:00:00 2001 From: Daming Date: Wed, 16 Feb 2022 15:21:34 +0800 Subject: [PATCH 28/52] docs: polishing zipkin and opentelemetery plugin's docs (#6302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Peter Zhu Co-authored-by: 罗泽轩 --- docs/assets/images/plugin/jaeger-1.png | Bin 0 -> 349947 bytes docs/assets/images/plugin/jaeger-2.png | Bin 0 -> 317479 bytes docs/en/latest/plugins/opentelemetry.md | 4 +- docs/en/latest/plugins/skywalking.md | 12 +--- docs/en/latest/plugins/zipkin.md | 70 ++++++++++++++++++++---- docs/zh/latest/plugins/opentelemetry.md | 4 +- docs/zh/latest/plugins/zipkin.md | 65 +++++++++++++++++++--- 7 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 docs/assets/images/plugin/jaeger-1.png create mode 100644 docs/assets/images/plugin/jaeger-2.png diff --git a/docs/assets/images/plugin/jaeger-1.png b/docs/assets/images/plugin/jaeger-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b25b4414d326a9eb07c059bad40e3c3c5dd04a5f GIT binary patch literal 349947 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

s?%M{iK^Z0@`9rn&9!Zj zqC_5rQ0k^G!!@R8O38fP>dHWK>hU~knx?H8xpgPoOWL?nvviZbKCADNvYvUdPAvi|F3G697vpPva_@0)gxlqfOK9ezq4oN;B8crH#FCNqFaSp~oTR`d7hhp@S! zEM`L727AS;jHOycYw0;_igXIDR`pth|>y@{6yR);8-Ll-~pNAB2~zH(@BJ+|!0 z{yIowq=5yD$jLL#JDtYX3*?scco4eX(+>0QDj}7>2VI=8!l;GoA-#! zAj!SF3j5H*qL@PR^q$2&?cPE!^KTHq1(g^TK)o^A*Jw{-zHG%9h}a zg@=e_|Bj+Du~QS@r3n~$_#l7MsUHvdz&ckID=Y%q2swV0HKzg&8D%?`lFcJeVnjnN z2?8N1*KMx_UBDd83|) znP2P?iPisGtp4x*T-%?c;K-3c^+SIArrG`L_4?N7sPE6C8?JPH`8;wVkHo{WkoeUw zHrFSjj}9v!@2}t0zIb!Qzq(_XGe0!o=oYv_o9Yq2c)`;{=Bj-~9A|aNNpzW_ zD@-9yf7nwR#Sc%yBcBnWY&30C0b!EIEkWQux$IzHw;C|ou3^T5<17isc&B*zjy)H* zKvQ~csa>0Lqxc6`<)Fcv5>9C4Yj)!;^^wW_@QL=<`|`+_ZI#&O;bvLR6gSHCTdKY~ zD5^=}H2(N7c{z=nJ-0UwCTGss0_b5+=@|$v_M22c(2d#(HhU@^EJvjnSQ}J|zpNkN zpw@n*0r9MNm{aD)4C#){gp+yIbzFeycJn@ful}CHV*ZZZx{_V-_F7U*;ZpCE`~A$M zK`tpQ`YorbRiyuFl_a6?`=D$LVGL+Z^e`$=lp-x1?iY$;MpK!y70mI7>L9aoM{It{ zOX{*3rKkrQvir5K7ikkd|Ag%YXF|Pba9vLxiBoA(j_>XyTL5sTp||hY%^al{K`OPd zTOVLMfv0DbXUwZZo%1(q9F&A`vbYJ(CBh9X=F*v`osnKS@N}590cM4bSD$VnBx*N! zX=W)!pNn@5?B;jMyMv-I4=v_QD_mAQtY0J`7h5${O^zF7Hyp>=Ep7->cuYw&-=JUA z+VT9tyu+PM;NH1sVS5#SwX=afw=PBO=2AQ`xf@&BSed!{Bf+BvI zDJlrkF_HEGeKP1Vze`Db>ZRRpKq4fs&*6L0RSZTSm+rMu41{>qqIA`wi)mJ z7Z$`~JTx>k#MS}bxPc67hKO$-pn-MPa#K-i|4(9nb9U5;&7g>2^E`MP^hB0#=YbX; z?g5YutSg?#IvRVd3Xbsi>CX+>G`xv-UHnXXoIw*duS?44uATbCxvKhX%D7?!s`G#+ z;oRI1V)Kv{ulMd=BW=+Jfhi)Xb69;+{zKc_3+II*CIi=3e2^1&%JwgJPbV=4DQmgEf zq(z1($YW-^OG+_>!g%U_9X*w&npPp4g>}Kt^2Qwg;2ok#xA?Ybd@lN~=w6Y#>4Jpo zwn1iPfL2A+1N#H-7vl-bgB9z5C)kT^F+Zr2+1rL@U{#-$R7JuUSjo$y>pEG%s@~AX zHpW%XRQkuV>c0)QfLTiF9RX6UY&v0#Z?RT8TpL!;T5k1~B#pCG5Wg`hVu(3UTGMW! z-f>LjA<}W2@2Ag?=OR(zs@Cltn-c;GaiXan*sXgsQ_|AV62p;Oj(g2DCDYllD?}2d zsIlah*Vs&MYfRj5gi08RuuPnvw8eh3w~L}f`%gb!SBe|Y@88Zd&9B{47*lk$zDcm| z$EX)JvIuPeEySmw(Z=OUWiisn_yyW%m~^PiEvyP$9ThsO z!kTuQnK6$wGVur@AD_v_BMD|`A!FAoH@A$8f7UtDupRvXAc$GF`&;nW&m_L--QrFb ze;i5U`EaF99P^8~M z+85zjC=&8b3=LO+9NV|8vVaoH9(p$e?!vmfi9M5Ei3!Uhr=y*EHl zrLACX0JNpm)<~`+y)Enab|H`!2Y4D5&4lbT6@$j^psEElI$I{CV!>qeA0*C&uUwu^ zmwe;p*CY_RhI}J!CF^j*|9j~cfXT3|x=q7cRs z8iduo433Z1Ui*`4fnEx$#_`Cpmub-Wa;-1M)t2cKJbfe}(A%pqn$hLu?3X)b12#{> ze{CV3I?!Ku-YxoceQ3d-z)O7uci?h;W?O)X!5ds*It_3-wIByFDI2KqeY!X=mQYC#^yvwcp43LaC_RPw8MzLWO%`I>w8 z`T`BjyyJVmd&1Wh-cUo5`7ErbdU{`m>B)o&D+CR6v3=T-f4qA2x-k$3hR5;7`&rJq zvi7HNNq-bbuFls_P3q~sl;4$d+BvcarHRXN=Dz1N`uL5~453>u?8OPhXYi(ZV>McH zPr^vfWX>s$t75z~+Zk1NovV36ItGoA2HPeox7cbHQRXiY^Cd+F^2q{kFHo#C=rjNKOb$; zX^$}ydLobgUOq`7L5X;ds^3?rgrS8C(}ZumzaCxbD=>BR9Imo((zRWp&=Klx%k0P{ zT`BuMpfNqdP`VHWk1P7A};-JKm14<+Z>+O!YY&Rm9$=Sa)kgkstj{oaC4`|B+NeNq`X zYwxNd|hzJcHt*jh=Xosh?s_AIe#RZ=W&S@2Rbq?tH}SZ&`wK zeea<}h~t0JP_0zM;e~*1*CV`w-U5Sj;;t?2#SAqh(Z`FIQw@c753y;kwcUR14>2Za zr_5qRB;hchGf6ItWOwx|O%H*are1S!KKHu4-FF*@aYW<{(I);;ADBa1>;a3g)fKSD z3zv;WB|TCH(Oq!WD*UlT%{+sP`1%m9MKlPHRnH%1aRUYVj)fevZ`I6T?G&_J;X$K{ zmazZZCY!%C-ylXdf6F&fF4m3tdRt-L0UoSHnznpKy<`7V2B>EKc06mlOp4reQxkd| zV^Y>Gg7uJ7h!d&I@&>ho;mxE(?bMA98IrWdh}@-+vJU!tEsLP9p$B+lY*%>&{zUKd zC5W>K(_%=k5KOf4aB7*>)NCgVRK|7MiT$N4#li}$z6L(m4&q|9LhnY^bXy-XEp}Yp z8S2k7)WKSJZd4iUQL1))wLH+eon(_fz@zZ&W@EN~;}WlD_GTA7!Z?7-f}V#-^Nx90 z{239?J9_*UkHDSy;gqNgyKOrbIX%c*U8#75vB@JUOLUVGzg(kOOpaU24Z$+Hfj-Th zj9pP=%E*!*#GD92JzTrf+>`xVgZ-f23QKP5ev=-1vqPy?MeAGE1P07Mg%N@u5uZ^~ zcB694EaX4CYlcPN2qgPh43FtQ$nJb`;7&lqVU`fO;=Ms;QP18V0~sO1!f*`*w8yqLJ^1gL7W) z42uC9SWR3)=tS@YS1z^h`+~oXXAaGOJ==LW(gbE}xP%)Pv+FX@UHgfQG~pHlW0WWD zYg4H{pC8wDR=imRz>9Gu+^(5JhG6 zdXm$L+RaiB(-qFuAGD=EhW!Mp z2#Owm8L7Y?a^J42post&KCAmIXe1gE$7P*mGEpo9VQA+mRR(=H5ZiHQY4-`gSAW)k z1J1k$rcy0cTeo9lpzDxu0O}0AM!?HLc?`5UHI*kHoC0V$l#pN)3=)FPT!cE$re4n$ z@RGl3&b^ICjh9Ryo~_NKZ(5{vnF&SFVKtkv7fgy<-;ro;uzBBZ1Q4!!?+8*Z1hAN2Y!+4C<;SXG6aVhIL9H-`?L(ohaBb~?{H%zSR&nN2_fTJVb%5?(3 zYFvL=6R+ka&~Y_}vD;^(HK1UM9_9xSZFtHn1S)D$AFHi|;=3}Si zpgDCo>#azsltGp8l@2ZQwSjS{lQ~&ddAdJ!rA!I1wjvzjeLU+HVWr@M@hbZK zK!mlxm3(deO;*D79aSkK#jxS%_$e>V%7xa?M`6zI$IM2q~@^z5pRM69a-B0rFD)X z?WfxUzb&aF6jD$&hFgDLZ&9N%#q2KGOAD!07>N=kX$`HV#YFu16^g?7^U(tFKiWdL zw<#dLvjW{eND5x=%cicbjqK)gYM#n(3G;L`ZHC0ID%|c}Cu^*;3#-5YqYC0;!>7t= zF+onx(See{YtR@}!N!mv=o00#yaW1e>3nEKjSLL3G`I-qBHJLSaB^Jr52K$4{3|8s z>+kDlOu%@Ur=pOM2iU|O!{zJI$-lLtxx?`y3BnzmO`AIrpOpD=wKE8$iA9a~^Iw~^ z^u~ahUP)r-10kXxM&pI*5#iyf6hY-ClkaqNbzQKBG4ktW$c2$W>fsIlISRD+w1r@A z(IFQZ7uLKwc#s~IWdza@nQ%Y*x~`xBdjDpRYmWg2NPw_A9tp{Q zVuRH61_@j)WR+g6dN7+h9n@~te$uIwJQl{+OxEui(KdMgr$}+m3%FnCM0SN0x!9J? zTpuZ?a@Kb`Dgn@9qPRz9ErFlAK6OVw8TJ%Pj(+dn5)e`BS{J~ieOb0sLZlm4&ZU7_ z6mngZyL=}Gaj;sEW%%ZfNV+X6ch9&zBPT0vTgHhUz}Hay9yd3K$P7c;!clmAc!fk# z4_Y-l%@|H+C@`SJ>k>c%wS4)Y{dUr&T0_hhFQXmH{^!kW$ZFeDr8CoTdUP}*>iZ8c zM7nR^IH1Qmr*6dOBCFP+FUuI4CqJeQIsag^kI(bHyV45*Ue53%w)nzIUG378*3W-D zP_lGL&6~eO^ARbb{7F4AgtbO(I6pu7)TN0rzL@8Ns7qVMr+K?z`CItn5l8{<1k59k z6$Kh++KmKDkokLJOFg4Ud`{ZYLKo?ar~`5C1IX)hsn`X@Sh?tdxBhybh)l&Lx}CnI zz4<{8G3USiO2L5?Cyt`8tX?-P@ojM!>307JQlwNR4;T3)B;por8dY^%AV(h7{l3Wp zj>vzIx&E#3<}AD1R3}H|@JOrF_2^Q>x*PK-<5~s=&EgSb;>xZ*-D-}?#OAf>^lD$^ z*wN4ws&ta3JrCaMG?x-8CemqIqDBV$36VbU5av5QWpbkI;x}nNl*P(&{Or zTyowQ{pbaF!X~KY-@Q=m66g$$G_JD`$6!#EV56kvvb(9aw&HrKV zEyJ?fw*Fy3kdzLQE-48?=?;+w=}tkqy9A}Xm5{ER?rx-|yO9P7>E@lB^FGgZpY!Z} zj{E#Sp6j|lEbegIku$|!u??7o*Y+K%pum2=7L zcqu)XWL1%)^!lB5n9il4_ALnS6Sj!gn>6LsE~J*z!`ZkgIfB-~N(4I(KE2M{yzE6shv4$I%q`P4M_w>uFw)4* zh|GAtBNwHFmyuRAN zX8__c+bD#Bi*-Ff!YLk&(J)9G%ileesyCy*^N*5%A3Elh4nQn8Sm(P{wW!_95;u#H z`g`EuZ}t|t7x0brfB+2r>6~M-uy8bTfR>Wv0t$P}raEtPLQ6m~wV7&(t(kC@>yXA|B#ZlrqGBjN~G{MjarZu26f#rrxCpr z{n>qP-2_FLXh)?aEbWg$0v|%C*814$m`i$%r7t#qU>>v%V;@{au3l8=E_keKXxi@x zO_$r8Sl)WXMzIEfob!XPzEXzD9qRcnD=an%JY8;!2o)l(nFZ2&!vV*eG088mTm4eo@-|7`<5>Dj>D1)1YY}rdGRmq5;1=NQF!51 zUCrJS^pggzC~_|?Ojgy-t~>*aPZmirDc|qUdG!R{Y3oRr*?9~1qIK!Yv(hG|Dc8}F zqrke}Y`RHXOS4vdoJRLuiReq@i2dTUE_C*j#X&C{{gUQy^4MSWg-&=sjb^6Xy&e)$ z%FDsn%hS)h7T(y1oD^QOptH$o`c_u7(xUr5qd{%st>~`6r}Q+o`dpZYPXb}4)gfDI z5fPMgn3%=elT*1gHkQKG{MFvLW@eX_7?@fOn(f4od0%ur^y*?v+@LDI2?PsP%;9uq&mmImhWqRU_7;y-D#iy8 z*M;=*HoeVVSzFyc%tiPyEHo!NLtAR;z=c0*kGE|mlK8Asu%tnE+ODQv-3V_8;zI#} zty#;1XD*_S2nis=EF^Qi>cAlINs}61l1_2CWve^=B>ML}mfub>k_?zF2xDsJ=oX$6 zsZ^dbjFqKsebbA*`Gde$DP#!kxoGViUzYsoN(slMK*mo6Oek(qV#ff2qAT$v=Rfkq z&n%+w#0#ot=$4m~)9EU^rgo}8yx4lckuqIiafSZ=Mb}iWId`q2Zy?MMzm{vlC8%~n z)M|L{MXWuX)#a*&S`P0pWbCiYl|@a5ImBE%iWHHGt}J%WM|+WBd@D35BJ5D(`GREMGvuDod^fbZiD+4W0; z5E?c86R{Ow$jHg<70=H_@|ZqAw8rJ#;Xk_KV`D42bAI^@sHflxy`!(6=T1B&0OI|N z2v}HH8{&ONt&64x5C2)<{rt^Xz&pZEZMzd=bG2PYm<*AjwBkZ4Nl`;wpx(pkY%%h1 zwX(6Hk2GvYs-d>mv!730?YYT@H365Ee^ZSovGYOjQhyDnO=(CfeS9yAQD`Jc?(cVw z;-9)@D^AA1N~FWAbzt^8t_+pnqf&P!2`?sBa>6P!Nno94GodvELuFvJo&S1nen!GSbq8U54TX zGj5)*Bqg7|uw=q3Eh~G|gxIa7?LH(UE{>Q*8(WYCmQGV(6(wRDBLIg~o`xkMl>WRO3 zpnwZ;)x7x?cLygMmK4Hc~q0Pe?n03Q$^H0Jxh{EVdEhR zx1j)dBsyh-5dLYOs0KdKOXb)?yV@72wxU$-5DJof1YdXKi2(RVt068JMeS_v>2wxL zgE|*V)AoMfxG&h4YE-EqdV~UK@JMM-gZ}P@_)WI)hmfG9Hm1bqpn@vDnELwq$JUzl z@I$A}Ak>iF%+t}3b*Falr@*}466v)ExsdTm=Rn{}KZAz%F!z*(M_s>ol|4ys;P{W? z;b-e2WgPQkxqJg^~f~4NjIFqB?#MQ=mvyW#kPaTFO0sTOb3d?OY(Y2e7^!KI&d?Y_8>!IZ0Qoq}zKG0S$ z8A%r~Bx?a-VSLAoAC$p9lBERa6x#3}>IVJoWVy)vOs$YK%w&)iB~CCx5nYM>n1skf zfBDS|U3&`F{KDrs_*s>@F6!E2MPYg7!H~Mfz?r1jSR5U?KA^9lJ%xf7l**{m+17LZ z7mn>5WN5epBnlyVCEvJ`?aPzseuR*(7F|^c2neJ_QP_YrU|s?HJ`82quOqHsPBDzyg^V zi|Zd=1HJM0bNIc&7S8{IY7ioDe{=Y`9Ld#NrKZL!hy+|sihG^Oys1M`EoL>u6?ZDu zRyI<9Tlutby!K{{BQ>A7h?9p$lg%$?6kJ(bsR*8~h8N`J;N|-+k}3B?b6q%iVL5>;K7cYOla>YEC20-M@*1KR$l` z+{i+9<6^A?>{g4A6@f*C6(O<6%q~v>{k3Xwzj7InyWE)4D=2OD%cTC?h&a7sMe-n zV31z4(ntzkwz03p|BiH*B8S1Q*s&UD&|Lf12;qjAbL<@!9E`kkg)D6478()~1F(_A z0Ia9G{4(AhC$YmK5O6t2h7xd)!J!h_X`P>+M@C006cqX{+f>vNen$qgfc@Jn5QUo| ze{B|5XgOovsKO`B;-_ei6jW3al9Iv13fv-h8c#MWRIoi-#nM=@u8^3F%!IxU$g#kw zSMtS#T9a zf|KmyJs1nL+7^AM92?Ck>fsjD|pw{DsMut9yw&tC)H-W zc}jB1lTZJWAmV>Pa`#}620nI%|NO1&LyP-$f7{xMLe0TmhLZX5T38h(7djUTG48rE zciT}`5vK3a+m3d~7TnBTG4ro~a$KM*l=kIRRB|>&MMagbHFZ$$Y{ry8cwrHd&Dgy6 z`qp6U?ILxq(z>t|tAZV8B9Ouv(mMtX&n56@itisui;9o@1=wzh?AC${C&k5TK`A&* zJI$N@cgUK8whutfaW7&)QKHrU^EM*e8XKl@%b4?%WEHqVle z5v<>z%9?-c*Az|+YPIPG&XZvGJMr_MeE^&KA%^up@}F|JTveA_j=lnQ7qGK&z_Dmx ze!{ys@;p~^71|;N8PAcJ^J%jAY`%o#?zEU*>*h=C2X1|8J}_s}1%hX0@&DNHpDjr(+ako0^GcjQgaMTkejrHySoj_cW1gt9G8~y+}X$i@2ge2)Gx>^SeVH{_N7L0T2OO&a|3Yj$W)=VKm?^&Me|CUCN4@zSW z=3>o~7OurQWRXW*i!_)N)%F z>d%9t0+P6TC@8If$;zTCF=xRMPR_`nO3FtQtLlehDu=qYJ(iz4J6TtUY(7*kOsMMY zd~k7~$n3aop&AvDdycAbZm}~WuViT0L$%G?^J?t&ZZFDJ?w?sZi&>vLcQUBv^{iqO z#W)~@V2=pbWLh$cDNRVxk@2^{Eg<|$?*5lIM8?Dw(eT&HRY@md2%lglcLtnoyj|yR zzgJe2xcHrX=z6S*LYw0tuG5glOSsTvyCBANWhTT}%}r-ZwT?}mNUq4gR#z>hgo9-! zaX8KI4X70xjy66R%3PNiXn%4sdvoQcT54J)jZ46{w!*e^WqEA~^1#)?98L&%$>f!b zqEyu#yJVsm;?FhqO3Nzbn z*ZP|M{l%L3Laz2LuVa3&`A829vR7B8d^QKVt`(Uwf>q;8^b0m$U#VEoDWzzdz`8K!rV& z78*2pe~M3|Y@TLJN@P0c?WJLxA$?-CyOk&2ESc&s3PJc~GU-L8u292Qb{pZs%PV~P zYX5*>S#N7z9^_ND_w!8C^RG6kWt{$1zF|A9pE@ zSqkF{G;ED524Z5cD zqayhFoIPjQ7}-T1u*r<8K6q|Qn?6(iw*>D!#>s~4S?@3a0}zgv%%)cq^5mPxSm)^!@PD)!%5b$fXguE9p+p&oOIxc$D!at zg)PEtJdu-%EHCNOa8ZdP-KRhn2%@X(&T|+u(XU{J6m)K7p+7xS!U_xB;w2}8BMZ*| z+GQ6gbY@$fBD=@;!Z1T)G&RX~7n!oT#?|nHWJSBc+6otKAYxi{X=KCF zkf8PSHPgCa!?o@qj^-*o?SUWom6fcubtPiy{SiZ&q1m)2KPOdUaN)tAOcT5?eg~Q2 z4dW9H3Syenz6#odm&Q2QL=1Q7@Y+HO2BGbPg{t`g4xt|3N)qWdHIOvhI^BWY12YJB16xu^g;qPn56^ANGd1O+aKL2 zhaVkzBiko0m{mj$AC1$hqA5~T=xPMG%%VIG$)&n2(q?q0rDK#aG+&_ER(Kvc21$aY zjr0$=(T$tSoyRR+Dws|8doDK{sd%~h;gTs$8dKP~MY|Hp5JMp>1Sd#st8^8O6N zyp5^qm1?&6-}lzk-uvQ;{}mJD=aa4??A{980HYSez*qGRjjOkm%uXhwOaby~VLhd_ z_Ol{TS=XGTfh>`-ProxAE3L8aG<#%oz_afk7~%PaZH#DZdZconjS!rhTtA_I)GgZ@ zF)&^@!Dzr&4zUg|Ted6YY6>VNbBw(LE>n+2&`0guUgk@x<}($}8E zT;f2q6wc{D*I#%qzX^H}sleEgdtO?YL|GAW+eOf(h=rauX6|J-yPe8Bo@eF!>9LW>%UH?J7e2g%Kpp0vWT|#$F1H;mVvP?~_kBFo`aeR6Hm!qH^hNsj40m2#OyB`mhQJ#)2GjGjTStc78 z8ExM_3>LGtwk9RKyw=k2m!4kcSADc}@r;3(+esD?5%DMyRGyLZ6vk$n`k@k!Bcl>> zX6&JNtb*jq4LjAXTpH({Q!|nYg=q~n^wV76sQ0o9asJuT`M0hYqsgom^0h&Jj7XA9 zl&BwSEcGg?Bpn%=(svxq?+-Mfdwum<`3+SQymkm=s1_Q*F=Nuy7UxioHQc1-k+3dJd)M#;f!hZK@(KpJ7iUC-!(sR zpxqtL45E1QWI7x2<}pe(C}fG@aXn$bzH82s3k_{BUu~WKeX^vD#)v91G7=_V0&{|& zx)gL|>h7h>%?Xly&%xe7_d?6O4Ah3bdinAte;i@%lTHBYc-E&bcN*Z0n%w1_h6Ro0 z2s-i1qPywTH{ZGxKk#Y?)%E3rErq6_gN;j-ND$6&su0|zLWNYE<8G@;Bj`BcSK#i2 zwgNgTNCjZa)j2f9ETE^FA`8aBR1@h3ymd{{M_!J{R zpYtVgfyj6?Mq}}uAA4VVSD7i#_O(oIwS!{2k&xmxOgyV?yt$j4KDm{f6tuq-?fzz3 zxc|1W46+?hG`CXYjCB0t+WFiAmYD7Y2SH5j3)@ow`B@$}z-Dm*!t!lutZ`w{i}#0w zadxKY+!LNSuQ*!>$Z7MSK$2SM<4s#S*ZRyp)wufwn~V*U_j+KTFNeILJ1zmofyd>J zT=9dwGwrm-2iok6^hYqoHrxcB=AZyX&FhtJi#IG~J5iR0KQ%yOrL>wX==W8eS?~L_ zOnL%e-c-%2t%o`a)j9bk2=}r8WrtC%yi4)Bm$wzC7J%E%8!1@`G;Qv7<4aBLv2l*E zPVN~dUZeDqN?_eAnG!y|haUW?<#8H4XpL6%VY00dSDzWiaBRx^QymEU7QiB~s$Z&o zo%JahixYTWX0;@kyv(qRy{ikLJc?*dzFV{D>Nzu1GVjVeUwmQycUJ3n_s9|=a5owF z>?&0UZdeNy?MCLN37@%OQ{QG!zuk#pYMs>f_*8VRnsI?9j5vjT^|H%n2ef=~#t?YWA$-I;fm)xhGXBYN?eg>{WquH~MHaJ*T`i z7e3_xj@|h4vK6evBY7da5Sr~EoV~C>__)}IdiGk{p7CrsMKU|H$?0G4pAZ)s9jq^O z^7;+4mlqrby$2VLM`0fbVgd2mefd94o-r?!oo|;q@i^ zs>Rhe^>fJpv0zd1_LuAKXMBDO>EwQDl%|%E=)5L-4FIlYZ=p$B3A7rkZFMew*b;$5 z2D_XRj6EX%`gKMGqV@;H?IjqbY_&)2Pe6`#Eby+v&X{%e0_ZSJuASIyJ$9*?Au7-& zC=2gHt`{*GT3P%Jz}~gT3J2Zo>R9g!_%A&oA}S>Jen;M;i)~Nt!cXx|x6M~5gGU1D`{!g9L=gnb#r7Iibw7?JIJWN z9DHb|k<_uiu$Xi8$MJ1C|GYqVzC9UXqkHM#aX8u@6=(OIM5ga^kq<(0&Rc3H0hI`C zCk1VbgpMDa2R^42j{cSzsH6+kr`a1vGq|7W?nfnbGhv_Wxn-jqoKHV2m7IGoXX#FY zHaGbV9scQOe3sX7_;XnmcCz2X9)40i*o;5Ez*c5dLt-X@e&%4?H2-ANmaEYn(kDKX z)hnIIEG7D|Ti*S-dHOs7<(1cD`V5_AcO1w?0eJ!kaU*`+4GXs!hjYBwaA6lir{m&} z-oGNM{F3KSArnkQ>Ns#FH{rNm#j+Yk`;eGvgyrq9P2s0QFNkx?Xge=G02SDxvaJi9w|M{6}GJeyH1PXq#zZ)2F`W zG_Y@e#z{rhnacQBo@S2f1e$VsDk6&RHnBCp;D!f@NQbuT4)& zD=#asUhCv2f9R)e`xMJOp3`BE;q`$oG0GR9l?>&5_7mUNCD4@PQ{p|g=0>PnR^QrV%rz^icD?Q9IYQJkIgnU0V%{{<(Ghs?b_srvoTZPmfnq*(gUTP*g= zo)2z`*RFkRU+(+dev&OW(x#jbdwc%@I_3wMM}Ah^SibN$9V8Y^z#c_b_a6#gBo9Bo zmmiMmEl>hR9+?$DTN1=nw}#Sq}vNXZ=rV7JS>dgC^L(D5^{ZV*w}In%Q$oKLdu4Ixri{@ zb2FdiyGf#*GPb7vNerd|IAEvT7T=Y>zA4G2-STtI%(*b%CYlj|Va9(1 zh1&6OO2or~268(;E+-;zeo%@8LzaF_yFj`cH=!CJx|R2e<~aas{nni>c(UjefSt9Z zVM1UfC1iEvBhN!{(yO0i2~zAq=dI5eUzSv+Yix}`x7UC&j7xC53GJ!``!3}pXDhJh z`%WJm91s}EuxHld5vYaW!O4|bR$5tTHoDcM@LIkl4I)# z)+xMiUyUaW*MZO^7WKqJwfqce`Qf9*TO@T$IjBi;jBbDcDlzKy43q4+s~ckkP1pU^ zq&lXK$3nM*%50`%kQnl_dn}e^BIE$7Vm|wr_rm|#NZ%pa&ZKu3Q1zYret`ZwG55E6 z-Ir2z&Ox*2(tT22~u7C%?Jxx59bOW z<;k@Dz-SHo@B!vhfqxTp?F!m?Yk}L--yaKla8`3#PM>>AQGswiNXDX*dbdJL(EKWYmc3@)}f?M3MP*I^NP=@=ncuWZ;6TXJa#)TvS6lCDKDSYe=81#@XleuVu5C-LNlzi;Mmk zhe1PyZ1}zD8VQOXck|?ToM&YICP``jl^^2x+St8tk;$MfOZ;?~=((BfTc?QAm}l0f{S>`Hv-1*3ss~xc#r#{&Xov?5Q{;`$$P5Zm*Xxg7IH*=jU|8 zTs)VEOz%NuSnqmPV>8Wmu(2;NOxhSh(8U;TjL+6fUgj|rmz};B46&)>l?Gh;)1o0pnlVpB?SercnVWBYRSs2fF~kJ3lrT zb=W&dotF7gLhGEfg_=QR#p>JjWZoB^u49oM$w-wwycN$5*t(osaEaDS_vY&yEu&r- z%p95cGqn&3+NqNU!X59sNBTseRolsBASh7I$y<2k0<^{QzdN zJzvR^AW9BrNO-?d*mF@B)z9eBe7Xa%bv|S_itreA4@vl|m(>^6;x82+Hz)zd)kDk- zbKl7-dWF;O!l=zsbpGc7z^LZ%LF0f&$J*!Zs5b6U6u#$$$qQrd^*C{7r}oFKZ!Kv? z>n&V|dvI?hxl4+D9A$D5HSe2T^2vJt&w71QeZ|HjPpEoeZuU6sw=&3;-;oNlps_ZG z7m)!4tWWb~a%1n7@VYb6tOG9i%S&N6QlDqRNH={JZCsE@O_V)tcu6!>m}QoEBPZfE z*?xbXK{)c!_RG0o$FBG8m)G(!r`_kYc75Gl}op{Lw(_$Gk|}cs|MWv5+CHk zxIAHv2;y>#rZFAwPD`p=sXxt*t{$~ojXSRzA{QrE_bNr--_up8to=9>bdO*L2*oXe zouTF1GDl*o*NR5Ooy2Ie#^QTYP?`Dy{8%NO7%v`&P+m;CvdQTOJl5aiseG#!F!bp8 zi565Q?XZYK2I4Rm+1|M}PaF#is5R1cG@QC72@}rC4~<>F-gQB(BH8oA@jA^SK1K?7!TcKv!N@oHy*Qo zJ#48&Y}_467v)xmDnjhI0r)JEV@lEQ$cxfwIoj#gjY;Y~YP`MeZ#Yq3z{Xszgfji; zl<9Ri)77!A*19-A)L8(|g5_@Utw%gAb_5v(c$++jbpB_clII2SM*ck~O8#8z15O{P zQAl4nk!=3*h`p?Ac_<6Fj}b{L zfOYyQ1tQT%v*^)D=y;SahfSsUWzdL3k~t7JhyVUXA~pX48>M(ATk>G)CIB%HpnI{Q znidCf-T0KB?C7HOfsb#bDrV36HgU|O&B$=rI)^iy)-2~dS>!QFa*Th&yUSClg!y6xh#Jj2eiw)7y8smYlpr6`!Zi1tZGs>cJ0l!a%Wbmz+_ zd*X`+F=DOaB=O06+bdxKj=#|AHH8^|mOUl;*m7=`2%l&ENi|B4a^cMoq!wjd-Ar}D z!ECzyX0$5K{L|nk%QwX|Uu`Lt(x1N=slPM5e>6;qzLTX2-6b>?nW3>_BbvZ_o{1%c$ye4L?j!vbrFKs>Jz zzz>N}cjlxbE-ui&0dO$+K&APyd1?QgRC|JEp5s0xhAb?M_6z<2X~j!1OJLuH&|06l zs&>1ITlI`#CGPG~!VXd?A`P>=^&@mB20nt$mhUx{btPXXZ1vmy(SPXDIg>QB`sH8Q zzj9$PUCn5RIHki9!Sfw%uE%=3U1E75c>wPhgY{YgDVc7b-q?9=V5wB?<*DtNEi=ve zOED?lr8Z^V;aZ=1>6@~Q<^A=16C!byA)a&!v}=6+&YbOM0H+|@0Jk7+Z#%<%_@BBi z{~x`&|JFzk^potND85zNkz{-kL!E>1@JG`yR*qUczP@@c^cLj|8*Ggc=u|fvU`X?J zNSU{*GCx^s);w>0H*h+dB&FGP0c$jVCI6n>!szzZ{!-g=1`MCOzSG3DTqMo|Ils1= z$|%#uP=RiOO`cp+mq(L{^zdo|CynPMS|PZA@ZC>1i$KFqHQ;TavPM zEKUD8)!c|U@34f_-aOB&)|m!MSZ4SHjpW&&HMN&`fP;97A|>NPI_DlfwwTE?fEMJN z9m7oUS-B@z`=!m-3B50>PmE_Ih5nej|I`Yb_WiwXqBpiNx%+agg+oehTkyaw+gF>- z^iDQ_0MZwc=Y!3w;FFS*wb;*ORhsjLE!MeIQMRN?e(zFD;0q@)Y&GQc06<&6%+5~v z4y2oCo4BlOdA4KSG-W*sAKl%W%fo5ca0!#XuW@LfG<^Mt@iYG!-Z`jC zUp8UcG`%zm%A#8m5?HHI`{*B+N9Mogmt3JSGq18nhcG}TyJ?$hkZYEF4qRh1pi^S-Zq|#w0U)(VZXSYfKEs&r=o>_G0G6Pl%2kuE%9?pN-Is2d3KcyVz)fqK? z_lKPiJTZPPZ3safQGx19I&k$^#M0y0F&PA!`1P?I%wpVI9TNhWX zc+AW4)l&=QL2m}hA`PkDvkzf|V%w{ioU5ElYg9;QB<_3@o|RWl!>%7GBA+kFAiZC+ zHD{Y}Yx)|p={{R+y%vT3Ce;8HcGk#L{NrmtMCK0&s0W{4m?|B;KJfdzSA&69x|5!t z<+q+`B=DNqd%@AkV#$_+K&!$eMw|NwkK6nQ1j7KNxPx{o>A3$WQ#IA$(Z&1)fjri!@P}gzO9Ip@Dl3F1T zH)FWL`nQ^PSp9%)rN{zZ*m2MM#tzj7etc8V97g{zum{X1Y-d>jX3k)9)4^)n6HPN@ zJ4Rd;`8;rW{LXD5F+ixOJ8Y|}`0;8$glF3ih0p|?uwr6*hnF;?b&=>-FBDdj)8cQP zGvBltS#MzSHbqrp@1~=5Gp=59(md;;8tN8?PFw9Q{;%BswM8k95Zt&c@nOFO^BJxwm{>Sqo~81&jZ^>W6Ii~7w2gtB-p@Iq&*4KcsLiDY1#ivhUJ;|dkLZdr2XGS&u8v4i=~qW-^Y-+W(D|FwLnPGwdgGw&y%04H6HBoE(BkE2`Z zK_1L`p(WNB_~nF1M#QlL=Ol&IFSi;1S+9X6mt6hOH=dXQoM+KHXCFgBO^n&QGbgKk~?7*(`uuJz$ z=5{Xqn#9G%iF#aH)I+4Z?@)=UK=}Yx#SbdgL$#pj-YruXD{}sEFZO|^BD`AyuX`?=+B=yt3zPItZj`7;l20ETLLT&G3SUNN7$p$^FLnc5SH(YrBBfVi=K zgcX-KucS#S;@;RD90I-4lMzH9`xA2x$LZ`O`Q+TC?GsIE9gjGU=#S{Pw^vTPxqgA8 z0sCjt@cV=fk4nxcfg@ zV9wKZUVfFAP47_r#4p8@Pe-D};|Y+w=M)eGTP|zjAso~Zg4=eW6)s5(eV{G!!H9%Z zOCs0zVxd5JxpfYYt21^vVS#gi-qx?ejl6+^XqxOv+?M7 z`1rNuy6(ua@?c)PTck^?pL^|#rAVX=y!-)w-VsP?>VU9|BJNjw4jTgv zsaFHj`z(s1EP22r$r1+kL_R7JH@gc1owN99_~)-T&dEC)G2AHwHIRq7TRxv}&n>=i z_<|_n48VCsCypl=@$C4*GV(xyu#GS5NMi?}SBR%H;+%FHJ(l)l*jC*jJXReWXm?|! z9NJ{ri$dcA4TN*PDL5h5HZ@-E);UG)rXP(1%aos%mFYPgYV}$U1IkiZH znOyZMi&3GPy-#Wa3E~&BuYI94u&=mm*ZSDQ<-LM+OZ}iN+|g>GMHNHt;vzpjW4+5K z@zgF5=-t3(-4TTf+Z?%OP8SUejf8(**xU^on9mRN%(xcn%kIr1dYnjgqb|4|h7e1+ zDKD19%FE0A;H5qVEsDeXl>>+mVw1hkuvH44Ebl*l8xLLSz70?}XWus^$A&plI-R)+ z1TfaJ*)dXgsVefd_7K-HMtUbFyf8JC&yox%EQ{odeme?KR;a_(c#`SP)K1^Uk1Lbd z@T!v*-JRWOhsr5UW^dA$~2CI|h*vyD%952j5Q#FYl=)aCCr6-j3akC!J>$r)avQ+x!MgH}L{%FYt!I7lmF|lUT{(3Bi z$5oAAXZk?-F06Ko(5aGoTw=CSGj;$okhWbk#X;=&2mIRMe z@#h;LutXd(U!gVWW@XB54jP4pVBlk=p zPPz&D-#+y_ys|p`K4GND$m4l1WkdKLddFTvSHk6q&!PP;@1{T{V!Lt$>5H8K<$T16 zp%-Xrq~xz(3TVGg&=)vTI@oOvQ$m_k&9{gyfDOvbTBJY0@d1ATkax`u=iB-SnTBXFKuQErjAuUkmLZhO<2+IcPG=?>S z&^Ynr8aJL41frXWP$E(kXpcT`vZTjE$u5#l)TcJNKH53|ab$1za5SOOB^otKqr84L z#%vJy(SuXI-K9}Ty^LY{7V-MgE4~hm1cfmS%0z0Ymn|!sQas7qyws4*d0D;pkgqwl zVlE?Yu*ALTIk7vFZNQMJE-)LZkOZ}`5Qn4PIWEM>la?<_)~3}S*B1auwu)?T(@i7$ zXj!j*1zNmcPJRquG5VDy(1FTP0FVMq`1TEbzpXriql@uOZSoQF1kYOX;ne3|P86P? zW4y6-jZRgyZlWb4MgnQR({BVqg~w5qpBh6yt6p%h8TNf-pCZ+e;p;q-92{sV?*2lR zK>aE0Ip&X6ePqA3Yri&e)}a9uO4Q6-vmqN!J|6iIOr=)yw|v0t#}^Z0sWq}=%u?n+ zsFI6q145ZMLI~SdL5gzID0vr?aumy+cx9P0X7z>6%r7lqjB-jK(&ye_0!AU!g*@j* z*Ia2n%H)+4#7F05TQM49c!>K7`<9?~%yw6cr#+i7ySEbbbbqS}``$!-Y8n8BqQQ#M zF51OuI&`b_!S!G8uLQ#$Fp(yAl5kOSbt!taZ&ogCLR#M!F%9R+XH&o9O4Rn(g$*1? z=HqL;0f|k|6`xXXaYu&ApN2tv^EGOQ6?9*U5!GPuL{`cx-KiYqmf9hr^UM~YCO;s! z_Zw%7;cF$QxoG&zEMZ^4N5vZXVH0YTn#s;zO8SbN75VfD zJ3iAUiid8te~RzI%}iY=MA}~$J|T9gR9vaGJww}Tucn=RQ2rU?^AW9B?@8Y<%LE_W z5uW0)-%*x{5bu=Gz-fm2HqldqQom4+h0bugp*AiT?GO;en3Q2StMlkEyyQ@yeJ_vk zp0+J|{Z0<9jHh8}1T8D67Rp;cReA95zbzVn$`umO1#XJuzM<2iRXHE7u>zCo?G31m zH3!X@vwCO{eHBn=0XP@)vBsYIYeE0yPS?`r(l@#tdw? z%KefpW~OmxifK&Ht-hV9Ff~HLd0Lz)5%+QgTbSShh98pS=J1!hR8DEV>POIY%7wwP zWI5H3RA4neY%B1)IV6##Y(d?*05Nu-3w1m4LNUG(U>i;oLD~j=n=TAGY~jy@p%vr1 zl#D4mpL|S$gDR9K3ZH`g6~&t02bW|?pS-bs45C;DaxtdLjYrG?ayHEvw;jj`Ga)AA zatNMh`zBA{m0F}(H|_!OSl=!jwQ7e;$mS>6Bn5tH7j(v&1pPM)Kzx$bc$h-HM9*iF z=vWE?5p36Tkl!ZKd$w7RtIeNf0_5V;8}X-~9Kl5AyQfHhX`--LBunYg8l$oF>hW48 zh{XUij5r-8j8+k%@UDz*mZr-R9G5{T_j+43{WM(HI9D_Hq!y-{!rnuq*4s3 zVumakk$D@;#nC3F`MdQ4Uyj)0X^res9K*|B6M_Qox<(KkV%TQP$`Bo1`tT4!2O@22 z&oh)0|);AYJ%>Htrwp=%0R|UVv8YJzcW4 z`=z=4?q>c~OhB{)P22uQzp~AKH_M)ydkDmfw;1$bpn@D7N`MaTi zdfETqN&JVi^s-?9ngd4@KLOFNaLw;#sle+cp0F=hu{Dt0X!te0$8n599|Rp1aiMOJ zj|SQWThH|OI~BV0br-;!@~6UFu?+HIBH0ss$Nj@;{U1N1>_f+}E~SGEzlfVaY&t|w zY<6hyloWpG8$6Ztmm$!EEwyt88d^pzXwdKqT3!c78in=BUM#=jXzcOh&y+gbZ~2OZ z%kY#~**pD?e264Wo;O!-i+HEf?)jnZMXuXOwt)9n(EHmX+T*4zqv2~0MWX% zWQKLW->twuxcdI_&v2oX;U{hic}ia^C-s8-jn?`;QMj*E%Y6(1`n?2yfCXrL87eJ4 zAjpG>H0Q*Cdx2Q&34=zR!GB@v93{m{v$9ld`3q5`dtNpqvS;uM&}1O>y)%|k+XDEK zN8?aPn^SFT+8%bG2b&+9gyG+bB% z??JCB=;%8!#L07_ApIXa@kd;rg9RPKxg?}q4Th@(xwz`324do9cA3>6)Bsk_1d395 z6lj^Vc>5X*j&UFE3*PhMMu?tRxA`ocJok^(`%@ob27M)~r+Zt{y>`(+KfJU#Q@5~VQrKU{k zmuNf-9Rp%Ym}5C|>9Y^`F7;RL^qU+>Xzn<=k+C%mz%#! z9gwTK*Hgdfj{A8U;de&e0|d<92L075uU13_y6?OHFo|$=o&H3Q8eBbuUtqWtXarfH zCumAa!~W%^q4m9o%}d*1zw-2_7s&~S{u=)xFMR!r*srL7H845*5fc8t7zFv5_4q%- zzB=n-VXym@@ZV1pzhe#?;6wZGEdI_$|E0xm%<*4Z{FfHLQQ)_$|MJCuY4IBce!KcF zU;IC&1!UFP^E=A#G!^Q~=DtrXK@Crl$bLaReM343It`Xin)RE%ULvPLNBUWX_!T1z zJo6korB&3UVG93eQ#;>}9{_NU>lXx;^|bmRrAMi1mPvo%py`MC-R%EF6$LiDtm94? zERP_q8&-63(tn_Rf4bAY15{_&RipKvHQ8UF_nnI%3k>n;iKM` zAE=g+a%YtNmo4r#(0|$De`U&l+2XhD{Qrb4Wa(`&elIM%0;!5k#%R?+jZ}eZSqI4Q zP+y}`DNuWnr`Hb-@#Zf8I6Dbb@ZY*^GN@_MD#YR7(S*X=8 z4cv$N{~u-V9oFQ!?Tao8V1+4&s0gTl2nq-aD4hw&q=Pi+(vjX0B#=Z!MUh3sS2Q|9Sv_DBsjoK6}*-D1;*Wj%>Jm0Od8b5C34Y8Tvo|lzw#G zuK+%aR0a10QL6?Y2gS%p{B+??<*2nJ>wiG$r_7YYuO7J}KlK1_ZNFBV6#74X5X#AC zj`tT?Jo{F9rvg!Q5;{9dEEZZZs&j%}QBpVQ?SK3`1}dk2W1s%(A>RJL-d5>y^YN5N zp3X#on7Zj==BuyT@^&Cu0exj41CX>8dq<{9RnGzf(7v+(DT}!>kjmv5JU%F0e`heo zf=0Pmq7^TaTLqQ=PygiqT3LaO>Pe*eiMun|S!t*)A4PyFyI>aX@E=){y_*%Tqqh;8 zDa9T*eWlLeV(a`UYY5S{1i&bFYdlVcDp5vk=!E?l=X{;=rMmo%&z^FDm7Yxjm0(Lx z&&eV|#;25;`PMl<%c<2wF-te^R!ULJ&UUNkTEwO>mB^1K&-St^t&!{Iqgsx0BFLNL zc{9-Z`4~ysO7&1>>1=&H!TMxxnv7MVq&`0k))i56mJJge4W&)4#1#sC^UVWoH0bu# zEJa-gmB6?~3L)c@a8mYY@P2|QZu>JmNmBHsBd|)Hl&EAKBZ(b2FJ6^UYLTyl{&FcE z3hkX&Dn~vZNf5P8sVqzpTXa~bBW4Iu3PTpPUa=Cb1!rZ+C_4FV3$=?|nwVP7!G&w^ z6p}mK;rFOlAooGM1`V`p={NZgH-0zWY8*3QPe>#|#wSFy=G1ZqcU@?`{Q)~(YP2@Q- z2MFaI-`YUs*Y*#2`eJ^^IFwD~TD=!~sH_1Gai7og?AjBY!OM9!dy(g1?)E>G8|--U zfxRc>kLKId2tA?kx;&UurFRCD|SoRj9Up@VjbA&WSELsS(R z19NYYky}}g&U#JD+4^HfS{8h;PRidOu5I*RceE719&ilHk6)K|`zC3td5RHCR}voo z`SoajEji}TF*F||q}Bw`PD1@`x(KZ_Y0D*Kj<7M6is9`^-u?>n(AqYXN&$AnNZ_E7puX z7a*{G<)5Yf|Ksa;tHP%(BzUm%OUNN!E;nWSdlEIv9)l_|cL3<~2Q6In!d@@v$490X zX{J{KTaT>D#>@_%FG4&_yt4qdsumE`m#C4-Tj@>Kkj>mt*}#RMd_ZB9sfP9L`6+`5 zsaBvJjGMN?puu~+LZyI)fV-+O0z_0XZ}fBO3Q$sc^Vj=xPxrbFObPwgd}BXlyQ)~qd-S$b(^KAteNx00e|}mpvi2of+F>R{cjQQE zccUHL6~wjTp12EJ@SBvS?;phOHt*2J*2v$HK}aJNW=CIGb@@LwCxS(p^)nK zD3wq>KBOS-)Wr7{RJW4KTUMlr;#KgBb({2{OnB>_71+e3TY6P7U*xvPfFW{*?f)m` z^Ub+?1_(WCbdy7O+`eV4Up$nIlMx<|d3rf`kD@KEUL7S%e`VR?R;zs@2#x&qpzTUS z#|0@*%gP%Hb!f%wd|Pxn1vkBxrDIUHs%8dY0r>42Rn+>zh|6aJ=)z5b0@dIx_#P^p$ zRoJXNN^U!t(Bjg4!(S)ley&8OV*;SkZSK(p+(*52XfMP@Ey^a?JYK})lNHP%x$yMO z#v){_sG=?w`)GfatW@PDR-o9jNxn`TqYrEFR*hyq z%^QHV(aJ!3$u7A%{Zf)k_@*b6HxC9Br}C}fiz_BeO#0~%blOy-JIbeO=Gq#v)W-w&6J%Iqkm zwymks)T)p=t$Qxt;NNlZomZMFw%^IURO_ z4k1)xoNIcFyv?;kTcbB0Duiv+#5+McH^pd319`%X{2|x84>^Q0?9wu?|dL z6RO>HKt5<;rQjCp(7eHSM5{)1`y-lWHuS#xu*}ta+j2kITmO**tm|9HDNAEQ{L#MM zJf4R;i=&FcO$*-b(q40q5r<0|!F3AwhUM*#{849I5@&Y~cb9d=1v75=_1pq?a+(P+ z`^C?)_V<3+TeZ~FOKksF=UH$X5bTszp==-$t2%*be{brqwECr&LlA%Y`S_O>X~eF8>!Z6jVqQ;iD^OTN%5Hl) zPWR1W<*eU^(=g_sZ?aVfuPgJ87a=ynT+K3c;EOL7lfcmw?!+qgQZb*?1Ek+Dt*5zv2?P+xbrLag|!RB6K^ezq|%rhLCnj)5Md< zctSC~07;K6Dw#{Gig+r9Ajx7|sl3<5rR+Y7)>UxmD~(J0bE?yic0z>#xgX`_6!F=W z5@miZA7QLOBJj*lTC?jp@pD`yq|iCIP&n@;pmRnu(8o{wJ$8RG z8NRg>MU6j;O(^w9#VcgFb&Zr z8?%X({O=)*3g2_`jPi{0H$2d}#UQ_OT^aPify^t=QURFYS>GX4hvf}^j+OS*g(qH@ zcB}w;JhM@G&|HHNCT+P@sD-vw>>HsO`XSO|eI8u>G%|JCFVR&J|9RBVCBtGD&IlT+ z+nkt5k#@gAaB$!ObXBLy=6Z!PZV1{GRH;M8I+;D{o)<3wmydM7h5?YbR$A*dFYCnP zqylKXL{k6(z|XiK?87Qx6|W^3Kfi3kDgUsWCSe}VmeIg#I%)H2k;&-k)SwLJhPas_ zix#>*OV-!sU;PGm^ba5M=e??2?d4NmQ_b(w{Dz(gpXH-CS+?rb17?UI1E_^rks_ zZq~Ofm2i8xKtB+v)GyJBH7|!&S;%taKe;}ZQlH!E)VgC9C?tY6rCFeMa~xTnJnqs_ zE$e~sjO*AV#tBOYEuA*I9@spXq&Pq8Ra;vdnCn}=HF8TUqzFi=Yu0=G1=+GDYH6{5 zMf9h7mK{`SCl^hxxTU&HHLv!dHwTIJG=Gxvn43;{3l<(*!ce#a3V#{Ndp zKNr$&8rUydvMi1M5W8fjkO)hXli@`vyO^ca1EM0~@v6v;z!2yrd0gK;TYXE$^@ZgV z?=li8m;@|gVI0`ggJ)=d89=#(V;rK#$Tn zvPF~rR*ph-`~Ku`XhmT}H6wX4(~#f2e$sSt+fPE?>G(PI<=}P8%^1nPtU(`gdj;D< zb#0lJ=X9LTcNCCgK0QP|?z{eYxk7l;e#g>#dQ2UQ=Nz=HaOzuzbV;#+pB-t$=ZD6<{!MgnwaI(>gW51K#1Dqcrvg-Z`uoiJ9jcuX_g$= z#(U(7*sl64yvbiEytsTYt{?5(aJVY*pB;sr5vOIi*ttS}hOwJ^9qz}AX*$e56j=DkeMrUN>oGTcbI?=f>ZXIq zl0jA0!85tnqEy2!e3Hq3mm7pXKd_z-kxU1#f@Gez&NFu`ucwFD%a^?A&Y*fviHi}M zj=JJLsnySsUxTn;Efh@AcO(5n=AmCHBMO1J@)@jjuR(1tRp3iXmRJw-VS*UM%ug$6+Yo`jGL@-ml*(woVYw31F=1M2WtY)R`+$SG z!q{1})Ap49&tUVf5$A8O-biv8xC8?>D{uqQb3Bj61%BjEq!21yw5q}q3QbE>h;zOg z!PrT&M_VEb;-5GaP46>~2-YcOMZBA7{lxj&*58vrisz(tH;nVU;qU601$knu|HW$$U~_Xgh@T4blthZndMegcc{2FSe6*e^M`G3}%>a}mq_x*TKvJ_NH6pLaOD(E) z=kKSkLTGU+<9WK-X1?TN-kYs{3V}stgJ7{9e#;%ybyR2;q3~H3#L%0+PXa-I94-*cc$lwXlPCzuWVchK1tG!3WuViWtrW_zPfgfs zb#Xyp-i%q6&i2M%7)#t=wnP*$@hj3gqMs7r^4JSP#Fi&ilY?1112 zOgLS+8nxDf>40^O2!joECccY3Cmm9U#Vw8b59`e^+R1aCiL}*n;qgBE9K%1~MiyPR zg7)&^8jSQl7u^@Y)fb!-peV?f%w`eUX!C~VaJbGa-A=4>@kcwWc5*HT*PbUH8}j~y z(!ANno#oCT+a`}fYyaL(Y1z_0b?ZPGuMX@iS0GDD%gyJjMA>y)iRJL#$H)Ut0!5^vDG@e{aCExvE(8G89^PFLd~kXq+ijiLzg3_ zyn=tVJ>Gqa`JQ7IJbDgJ>96HJh_Kj1YBVnW+^@dl=gJpqbuy8Z24i!znPyg`>KG?4 zKQp@~uqhV-U>f~i&6MFqk??l51!(?e+6RT4sedu#1&gL~QzNcZ+BWIA^ z!b9M5l>?6wA04!4hgitNk%i};n%5iRAFf(rS$RCEX@R@hqk-=Utp{16{_*m02NI(u zQyWvofsf$L#TARO3T{p3EKb3ofAx`#95h(##jR_(Ylp3Wj`Fh5?p!A^EPt^}OdjMO z+JxmO^3x6Z29>LI&zauw)J5c`{ zM-ch&gH-lR<5@9xz=NqKPjrs@9OgMzK#$PqAWrQ8y)MWbTAe7gUH6(V^^LtV`iM4o zl=E=t(}#O~j3U!G4&jcVf~@yNwi~%xTy|)nxy;_=vU&A=Fc7|DviccFy_nS$N^|@@ z?LIm_T#imXc^Lrs-OHQzKH;i|6~Q}gEE=2-S!FjeU1?#wTKM?AE^hCLH8K`8oX}+B zFo_48pRTiw>*?Hlec929*LBAwwx0K832(O70|BH*ZHLw;Wc1~C-{BAhB)I2RnA&2Um-F+TUx?%hzb3361yg2eAC)x^jOL!MJudr8)5IOCh=44vy^8U#zH(ihnD* zPNF+73#NY%qcBB4!VDFH5V>q;qXE3{pcTfTXWW_g@l^X`mijY{YT!C4ZlRq?Sy z5OJ=2<&9C4;u!G(y#69+@?ygA9@VJpXYKr-PY1Hjm&F>^f~CX#+Y5X$f&cdhR>FpD*AU3VX?GU=;{iQ1qKo7Sq5+fYV% zYMf90bik=1gYndRMw8zv3XA%j)-$+4=h*ekoYHa}*#yBGO@xVh+rC6-j(BQtu+cGvmy$45T?o(Onj>-7Kpo`W_w{=m)HZ?vyP}0k0O~`v4eWLJj|F-t7OI7F0rkbyfQ27QUXZZ~ zEW^I;sDEh-UuE&kpC{{Rl13uL&;-|7Sm9xH4>a+KxM-02_=NHIYyr<{(QBJ3AI z9n#1n+Kr8o(p2VbX{E($`1Rd?GZgNgofzD!&lNF2IQCIiE>k!QuGU-j-_*0aTV^QzN9sZqk1EA4SAmxlP^9!Bzn+En)em0S z<3^2cz#}{>od1no@Lj-p`j28yS4%TnC@AhiEK)a8-~WV|O9r$q4YE}TUQ2fA`g|F6 z>(Tuo*-rB=zIPB!MMCqw$MNAV>{;LMP{iyNF2Sz{1dNgsFaN)0#4{_}%8WZO99%qa z+pC;Lite7|hGVS3Qp6Dgnp?cp1HdPLX~=9?GrV9c3kV|-d)H8?RhFjasqH{8qs;Vm z0Hl`PQ~%B6I9*|qP9?x!PBaA&?6%ai^6y=0(p?`ibn0?_DtxTpE2)*)z=#^a?A8P^ zy(2VH@wpZGW9SY#3!l9=a?ele3ss?h&SO5EVrD#8bwG-1%x#Z8YPkquKvU&}9vZ5) z9os3l;?G;x(am#F5$nIYmHoRRdEexAJySpQdf%A+PmR^lc@=$pCIYk|pu}T53`B!fy`1*9S&uA?BrpOwDwbE%5%-^4r|Yk$bIgar7Nar2!xSQBFv@>2=ir&#Q2{3R zzW+=u%6z@dnkJGf*3kjr6{w`%%R29oAzhX4s;h@InDnu5Dq&c>xn3uUQ(UJv%aN0FBPo;zNpB zRta1;&gw}pXLp(nnC|L|JZyZJcnt${AaYCZ75{EZ%Wca?n_lh?+-5E^2A%bHA1G>I z#8^z~PC*q){r_F8i9y_Jx+$y@d%*y%!Sm!`{MBeD-uq?t2e!{PDGk+B#Ii~lO?vCy zeH&MPo?qpzP9ckzr_1v`@c^cMc%0z@;N?_1%bEfkR>0Cf!iJu#1ECNtI&Ur&9q#@- zFYbED=w}B23A&_uBZD5Ll?qvglIK)-9WHUZ=)Zy&8^L?@ULKd+|;5B(%+L|nZj6#U5dgshoO zP%a1rAIZSdH^flb@>WF)GZO<=x$Otzl1?*POVkX;v5+3gfa$U|+Eh&0@e}s!0hDXt z04UTNVMS^g)`9a_L9?$Z3}aLf{o{#0>k!%oXE+q&48E&Hc9lu0 z`OXf)8)bbf%^x~D3P28-;DK|yu!?DdiS+|~JPPxIya4%Jn0T0#qA&33r)UoEQncct z8VY-C)5)qP?uJeY{FSudeB=LQ0eG`UBA*+)|9SwP4dTkt7ddQ*IUH^|WS1kaa4b6* zp6qJPI1EeknZ34KQ+3sK<83$rvSNr>i}_r=zy@pGI>M0Y<^MQv(0kk~NC+TTXOjs? znzWM@|HZejSAFu{e)n$J>hpOvwFscmqqCm1Ci1Os&cD(tmp5p6N_++LWj4;`r|k!l z_{8d(S`R7+_1`;+p{$P|2=>}<$zTp=%rV2Q2UT&7Y@!84f{6?w1hJHL{u#S)`m2>i zdpNW6a8h!mzIAtnXVYdL_~)iek|L1Qag>L6zu&&7YbEs$lYuA1r0n}8UcNNWMD*Tj z;Urtl;P{Z7k`**GZ1^$bPq}H6`)5;&PDdUFSid(jNohE4!t$eh8lm$Y=0HX~@#*8@fe+f)8!o!~w3#e{ zQ}g|HMll1vWikEL`o|B`; z*^&HALFPO%*m&%-x3+av7~xEAI>M_u59*@S z;9ffiGBpb9hnQk$shM`Md9d9$^3%Z-v`*k~Kj?R7d)Mw>Buw6&}6;X@liDK5r zu7$0`K5g7~pcufV-$_jZQgh;R7KM&+-tcN5ZkJ++c8FHUx+x)8Q;^bITEE~{kAVft zV=@qT=70-fYKGWcoR_W#1bpxj9~F08DW$ft@FjiguZr&=1Cd6NthvAhYWOVr?W2hR z9C1wIUfZfASHuAj+LqU#cK$yM(R(*{Na74HB4TS%MCe`1ggYgwg?c!%OAQt?I123M z<%;H#%IrHK__FB1*h>X?*k~(4{BYcfgm#FMFu5H>?0h5qW=XUA`xdj7*3q2cw|ko^ zDr?-cNZ;@Upmm(ZkFUq3;7_?%ixw;!8$e&y0xemUDk~$cWoNE+S(lDx zvSXWe=X0+I;s0U9bhZ2(q&-?DMmp0$PX_SGf1h84&>2hn!`tz1PT@iW7ql$z`3J02 ze9tq3Fnu;@BecUr8Pp^IMEo2K$8VOIC++wGbXKwr_gG3JD+m77&eubWdv*c}GpguB z+*KE&m^vq5wH8&8dZ+Amw1b|!u;8L<_*JEbU-+)hjlaI@{-pWz0=R|dQ1&`&8Kq5} z?DRRIblb-4$U!xQT~o|gq1p5qK}2z)#QdR+vntEMeI0$$h_uE?k^g(`DN_RtN#d8BoCx76PQg;ed^ z+(>=}@UUn@yf%u&Q!gR7SxCe{qc`HKd`>()c*1?K=Drqt+pSU0Xf|MOs?H}P*L>V6 zzChSkol^-G!1;u^_2>i6cjOj#NSuSU;Kht>Lx=G}onBU5i<%lYym=-~ct%yXmmMhu z?&SzO#x$+SD=CC9AWKbd)u8!ZYF&77&i9=2f?pin`>pK5yoCC} zd2{5Lo&d?$d#;O(YWELh$P8a*`Q>opH@kR6T(N54(;Y{-vaxi%pBgVe-|--nR7-{` zlji*OgMryCJGb7io^D)2Gzzx##DXT6`x5PeBxj3itIllo2&$f#TD!f!^^Pm zeG$02&mwV$*2OX5-Y6@7UHfP4h56}jKt9;_NFKQfQ4Yu$apa*#+`Z)|6UJ!*ma*!~dAin< zAG1!qtS%+wmj`IF)msHe@(sRfWkjJ%EQfI=;b^lu@Zx5Ela0_FmsB2ozQZZRlY1&% z=eZnyk%iJc02xGrXp)k+4P^oCRcVQDQQ{qzelTF7Xz(Dg3_K^CKQqb*4C%6`@H8O& zN3}KOIJ%>&CGdf2f}n!i+I3(m5gu7)sn3;JK2@cg8lfKFV-OeEbuK6+b66kZ7YlLx-rzi{6Ak7RjmD764D$meIKJ@>B-&j_;_yl}TKwRsJ8j zGjVZWCh{86?S4uRTNhWHeD+wsUCLVWujgrM!^~T&k>&fn}rLJJHQ9nX^RE0&Ydw0K#>s$v|Zs!GcC!V3+ujiu_OFU=! zknE2(lQ^6I@ZZExDc{{m!`{d3vM{dbK8w(9r6b-~m)g)M;4fGY?@!nW3?mJiM@0wo zpd>I|bLXh2iAeLZr0z0D*7!(G@1iSMIm&rS5^s`$&(Ii(Ox(m;Sbt`(e3(Qs;?fGfo6lVON*+w7@zb_*G*)$3bZ`C$xOG&xa6K1(dF~6o)}g95yQFNy6jWvRRp!wKAD~p1IceK+L+?RGl><#w)95)kM=C zz{|2wx5D@?nW!3np%{?8i88j(CxU-iazmCz!*D-T*|d*&%6fR19%dYMFRR~izk5h6 zOZBQ~T>xv$wL>c);mni#(3f?yV#?&-x;JdORpK|X@_L)#N$?Dm{A^}&&q>?g%cXiy z`ZHd1-d5{}`NqjOjf;H1We@crG^G>A(Z7j*1p?#AVzzp*>1MTO8CBt-bjd{Npg_j$j8jC&mgjk%^?>EIF8NGFp&SIN43!60SR#8CMPg*we zJc2YOx80{?^~LvYQ+K-!=%D%q<`m2`j0aj%SfqVxR;H}E+Pj5$8<-RhU#5E2HG%?q zIgpU9+vG;it0DF4iT8SgaiVpP1a$%O_?d=~$^7sGj430D8r=5MR=;wQ4@oc!7y0l` z^R}mTXN*KUj9%u|p~3h3B1%&;+cuq(vamZIh^aHVhcY3ak$aHL(5{M+E_;^*j7PkJ zc-Lc=#K)wl$32VTJXx+#DHDlngcxO6&i!i#`xeK1|I|GF zSNsylHmExL$ZKqZmIi?Z%!XRe^|Q(mr8}>_)2-a3aOZemyw17i{RPIz-Thr}?p~?9 zn9*#|aodpdW6n|TyrtKeqL#xf2xaX;#nszBtr!E`FUx~~$ZU7lhw_?TAtd$D%V*zq zDgjy?{R8Mw(B7?)>_TPDdws5zVr7XVY2evj(yY7qxKEHr{x?6ZxSj6~+){3FX;9M4 zsGZ0qwQxS_c6GFrdxG3Q^5xUHyWjm&|7sv{+J=God`&3J?Odm)cMC=Z6c`U?O?SubHPkByHWeY-O{{u4PeQjq;&r4!;89I zz?Kc)n)#rzbE?zQ=#YJ%N4^b@QIC8(*>&y@`cHTT6E_{m3MBpDtxApT;G5|0Jtmx1 z2Tl9mHJ1GPXA;D5n?=udm&JKXCrZsQCVEB54WEa^&gzzrxk1Tua!y8COO_i&VFMWt zyPb8ZLu*Y%asZrPaFx^+EZkr3iXH;bN!7|^lhP2=zlr8gPW{{YQtloj+~qUQWuMGy z-6lOZm(+!a9dKr6Zy{?zXDx~IT#Kn9yPYOZz|8h_JE-S7iQ+%3#wmZL$)$HJSG&Zt zG^02qWM_}zF(Xb!PPxy2&zAD(l`Nk3g<~P67R|rb#aD!2ihV_hB4Js*|G@12>vH|) zE6tOisIIMp(tzebEp>Hig0Ep2%w0iVnEDB-%GaAZsGrtnVXM;Q=+Y?m-lUUKFDu2= z;P&Jr-$n0*fcknX(?C<^(l36zK6JhO#UFqurnhIRvtRZ_Xldysb05&T?tnVDwXW`< zC+-XO%OCHwlYWJ=&F&8?@rjqZ-Gl&8xc8YtMZ;P2Tb5`fQ2Y*v!D_=VkqTuw&)0HW--g+_&&;(+( zR?gfQsH#{gf^ZOFtgk$bD!3lEe=OsmLq=i|IMQPmX}qCD^dsU zG_0fmkUfC|i@Prg^itwyfiw5+v zay*T!X{>g>f^E!zc^I{(cw{rfZwOi(23ZFahf*F%{6ev4Og>&4PU8?QTZyi~Z5Mf7 zgzXbu$MRHeKjS9Ph!%Nn!I(W(`(D7MygX`>Voc+9B-%~zJH5O`&#O@0u+*{CXVf8U z-1)@QN0SW_qmX5d$R5bHIxZvVzaK&3HGcItFoy9>o6MHYuY50a@2p_>1|fUh-vG2H zh46sw5ieRqu!eR!vhUKX0{B%fB z$E4!VbjRA#F)zRXQVpbF_9Fw|NYkg4fU{I!5l)hF9l0q7^ibOX4wqlpZSnW>e#HI? zMchhTkZn>P%u0d47_&?XA8^@#x`Dmg%akfL5SnSpO#OgkwUDPV8?QDLU zU9`fXax>u;AN(?#&_$1W2l3z)TZUdr{A1m-w{h0dyRkyL5$o_LzJJPFO(-Yg6(pU* zP@ei`Z}#}u6t0SAyWLcsBYZ{Rk-_q%1t;cFN3NTBS~m=q01jzT<`ux8D&+Qf7R3B8 zEBomTD4VQXMdF$gn&^+s~xyQkDTYZ{RF!{tC^>`Ze_)Gg2e^z!THN%dNjvV%; zmqFGvhbgIhV$30t#Yw0erl^v;cTCldAMoFOd*-(0mv8>81e$e0R#QGA-zCY;`B!j8 z{^q&*A}?ss=GG>1o%gd+_b5O73`1WnI?atTev5C$%r+#w=F?l$Lda1ocq(XJs5I8{ zUdkhHUJe0pL;uHda4UFb0m?&$-?zxqkAiwfmW|gSWy0Z%$Z`&)^2{Pf!Rvo;+6vVV zNx)hu3#ts3P)1nav?M8ilr&a7JUyV4A2!MPA`hh>oX7(*i@%7S3JVi4yiG!s`l$2j z==iFzE?ZZq)?5yJqwZvtsm8<=*U-yEAIwOTKeLOlQ}tAFgs!?xmO|IX?3^PvV4<61 zVyYVX=`9{*{Wq(8hHh9QUw!2iwHerYzzbX!y%* zzO>Mx$iF#$ew6(&;xcxNa53u1ghY3StJ#8&!$8&HHP9bQ)Eo}`r}d1LQ1W@T9~%1! zm2bGW9vrW_sFq^CYIJ5i9XKv&rGH9B>BQe~{Kfqc64$~YSxQigtn0}vj&k=N;g!D+Qp@+bkVdi>KH8>8g{-a>9F64<<&+y!rqN1aI9BRir^Z^s$xir zrLnqZ;9kVMpax`MrCk5u*x7C2p15WHqZ^33+ivV;c#aO-a6zc>0fItTDeJWa*Q0=* zFfctgQIO}tQkZwEL`!+D$hoVZkgfN9uid!bhzbcwPE)^Ivae^@rrU|9p#SOT^k zLDnNrn{vS|6tT|+YlO`>34y!UR_`5Z&NEy**=`r(Z4lR1`&dlu(`CvqmmYICW?FFf z+8EV34<=DYlRx3LkC@P*cTi|63mrs#tz%M#I5NFw zO(ncBdwaT zfW%b^#hcmBRz>nk1XR9KJI!o32Po@K+KJPXT*TUNVLF{M4=O_vDeew++S2a7d6Rm9LP-Voh|D=}l85nm6NA6n&%FVY&j`KpOxs>&hefD4MY zUdS_JSpy?Xd6qo=G&DU5bzOndFl@XG{}YZ_ex8BS6!0q zIk(4z7;Rh;Ovb72vd^$*eNxraj>Ob*#GPinCg)RL&5B5^*?kt?5Lcb~Ht!ZYi0&N` zzUGHL3($QK_wJDkU4pcpQDTadMQ)uqTV=KZ5rkaaP*{s!&(IF|nB;VE>0~aF>ZUe8 zdGS=mxlqe1E&DC|ThzyNCC1_MyRb>Jz^-Tc7V?{}2|xxUyMgLZ!VaDfUiFNBJ%;&d zUrj5z8~ETA(ev(m<0{@1LK%B4vquT) z+qX`hRIGY+>vGrRXh9C3m=hb;TLfl}I#ss$sTq|Mml;RHaQmp-A0IO3g4WYWfMe!# z^wX3GyFBgd4=CeS)Xp1uR35^8UnCm*Tiq!3mxLl9hDnaPT zt)e>h&$2x7#0jJ11PyFX%1~b*usYrj&Df2G3vA#0Y^eIpf2BCB4i{>sQY75ZP7dUliI( z;SHw<6l4P|j0|J!~7@h}DzK43QWsGO1 z3Z$iDW!>+oYVRC+&P^xjuxiRgl(=3A#Oo_jDxhSd*`m80u=kR5l%FwOn`m`o#tpr) z-Rhh|uhTV|SZr;TGh?c9eeu==f2@IMyIK~=5Lz1EkML)tyO~K~EgFV4MP6w|Z95^y#JOKBnY^^X?iF&s7%%&exOT$!(W=4Td0R9(v(wV?abA|(*dz@LTq zAUBaNeG(6Pq7VbR<(%E4llIq0>=pQ*3KHJvM0i@)C!cJ&KJAuKCn0BcB{rWoXgb5_kDE2Gc5gG_5{i$#F*LT1Gj;X? zr@~B|X**VO@`tWN+lNpx_5FC3hNreLKvO9*$~OngAzTfb&Ws9CJj?zT4+n zms%sb=*JFYQLAW1tGCY^gV-)FDy;M!b*~9~R>-{YSuS`&Tf$_PhB0sTDiz+bPYF)z zOnkq;Hamt(?}KFh5{o|$U%w}~Az z-~nGi@kly;v@Q3z4eZijMVJ5j%ECK6`c-wE>oVwIG$_iShyU`n?{AnwFwx3hYTh-s zX^7B5PKN@(oeI%I$z`>8;7(hm<2bPLS&p)it^0mOGHjN_YU1^k?$~k394JE2ibJQ${R=%#giN7BF6&EA^>v&+r&|tlzVV z%I#n^x3Roz-ThplN(4B{wXk~3SCiT#VwJHF&b9D&pEyo_yOEW&xo-`AOR&y|Iek0x zN!Gu0ckDA5&&0+2`P@Ktm2e2|X-)L-xmfOt#t&$Nff#qLjB%lH`s5p%=n}1Hhv3*K}s zQPUx)zG;i8r{yZMax$Tc;%fdVc6d+lGj!?#lga5e8&2zABl2c4CZh~Qk(3)n1T;?$ z;DB9U%@>L~>NRbk8ieKzmNuW?NP4)e&#mO<*if8TNUBQzR+F(KdCXqPv!THPL1ChhHIwin1Y>ux=r+#hBWC^*O^ydlYjF75Q z|A>BffUI?N|1=D*E7*|Xmw1evB-17N?jkD(0W~=zEEBe@M z;c3FJlvzHqkqnfdg(R@hFqU-++Rh=_tcu$^HIn8vzB5oSUlp0&3(Mr>s=wLs9xF|p>z^KYV^eiN2=)`(+bh@DVsF)e47eW=|Dg{z%1*W4lLy$y`xaok_iC1HCAG=2+>@px-enkf$K z=sFtc7{&vNxX9Rn+M2BIw^w}MO+5;7VtTo7M|woSPW{Ti2`j4zJ1c z_i_eSz|{jtV4n+Xc;HlJoI1ZD=>k*x-Rh4gW!|zYbQicxJSiw%F9`t}R}b%2S{(>C zD`lh{c2d6P7|@&_B%5VXov#0r{krLW`t2|XNZqcv`3JvuRE=l(x%=kLuPQSPUAo^s zLsI0W|1f{U+Bf?(ZLCteUT0FO52-bJI{DA6jPi$`No#Kd$i=K(0AbRAeNNB8!C!>k zCoeSNkW-8(1g#6pd{mI25&VE_yJt6n+{ew9kZ`)|7b_^mfth%mGey9!d@wmu#5$zaSSRg4Q zg*@*z(VVtYXr9Ykag&W;`!@QhW_RuMlgSSC7dX?K<;z?mTMns)p62Lr3!!K3-Qzoh z<&ND+Vjt4zT$pvk`j_}lhF?;relS@n^k4Ltp4Vskz)nsXi@twa-a_j2#33=X|Qtox_#v@)z&38mUnt+vSep=O8V7w zYmSTV9|`A`91l`5VO-3=dBHY%uc>5YSq>ihP2pz2F4FRp??E6Jni{BOIY zNx^HjH3HqR#H#~;Ke6VQ@XkXXQ!FBcEJ~s`OF0NO$Mmf?)CCa()obAixMqPIrjv0#{Iai!~S9iLomvx^rU4A8R@nltvRPC(b zn}&{>(-c(jQD)j2WIO8EepuBy!9H&m8#F0$wCv$H?6`MDCACtV@2PtGige^7@3mW2 zM~$-r0G0SWI%+p4;-s0@G3oAb4~>B>;fSSy+>+`j{xVRx{C!`0=G&cIAl3D~;yfkc zB@4IM`4Y{34{7COb&gZlz*1;`am}=LwVBQUA*6u$Hrqb*ty$G_ZtrP9O2DOqz>Bkb zr3ssqtf|K$s!ky#t~;zc3u7Ur<)^~oqmEoEi~=%!?t7;)dHAr-SHzlcN2k9G8Z6~D z6YSOG!&;wZeP4YoZe!tIExDDYkyAXodaNpbJ$wYMT8UaLDem$3rd#r)f@LW4Nk6N4 zrNi=>Td#u~dHxQ-1B`-Am4wd&awqEt{UQFIAxEDMuTuZEm_SPbY*td7%QJ&?tXMKu z5O)&Izz^diZA-Wq&jzKh*LmR}TkkDwFTqx>J9y!WJbszB%(J!|?@g{kP!`oyA!M>SL~oP6l4zLY5q^1@2?(wQ^FIhNyWJjzW`Fd69E3%cVYzKEhtaq6Z~Om{nZWsbg)e%;1Zh> zu}1&F&-#-!@cUp{aPamYcr~#8+vNV^kr_p>EmlbwWyhCaS2^M0g+ zXu{;Lci*3EP>8l+2+6*pVdLg(D-cXngB;%LzWw{-c#X=4#Y<2+T*aY{01zRoYPul- z&M!pMKe^z)-95h%*PUIryvw<;S4Ny>xh0&<7zAqtPrmwZEdH|X=sR%)tj8=sbK8<| zHjS4dpwLPO$fay9e^~y5GUk7>90}`q%iUOXEz5})!YN0Ts+=q_5XEGLT`|S)`!_+6 zaGp2aJ7_0evmmJ*_{azWJUgNAt_fyg7>np=CScGLWs6>PZ5NVN*(yB;GAXTNRpgCynmS6xu&)jd+?S;P}sP zY-o(bsyY;z2)p2cQn{?QG7`528#dU^7(`~7ddsy z34`Ark-AyD3;~PWH5{CvPb@DjUftx*~40|8Dblb-kv(mff5{eRA1~3#g0yB@g>27yD&WF+Y8dl|=LW z+W+5Fle?Q8<{VByQjEg!1Nxbu4KKrj%#iILk?jLN`zxWj|Y(}v_3C zU(bi9CyD;q|NTvhVS%70*;9`+>L1G;|NEp<_!$loWE<3urOHJ=16|I`GS#xQf#l1v zy_0sqvv#Uz9+*E!t#y`KATjc1rPaH`tt}B;@v)qNW{ukp?FOI#(WD$XYRq2a*TA?gV`*+am+zQaX9=g2s!6hjL@*vk9=lcnO z7I%Wju8^0CKNrA%`6*$Y;LRjMNZu$=?zIG|#!~kKJH$s&Fr*zqE0PVw9tD7YEwzwC zy2tU(Abb?)AgmR6s%EOPsAN%`=P~I@usP5&j)nQr!OJPR^hZFSco-ZJ$g9aL-u*Wwq~v^ue=griuHU z1J8MZXx{`dK=N<*+Bdu;YJeFv1{0*NJs^%-FJeoCkyL}rQZ&?&uMLnlfN#^}<3lX*DN~)Z?`;t1FM)4~* zijqRk4D&k?Nd5+qmSJ_a3UrKsv3H%-&APc4qla4ghM@9LUcu>wYrsGL2Uv^Sq*-^~NUtDqb&FJ+mQM#w?**|qP#X#q49`(oc#Z3$y}H``PUSOa*% zX`o}kOV1G5DE41g1bsza%pH4Kq=+iU)4y`%3IGC4dmnU#eP$qan9&8|@nGEzgLn80 zb7#M44KZ<_f)WUe_M&T15x1n##7T=eG7Y4XdsC+DJ zypK%zE?dt|T@>OkY-@?flW&V;)@Z=iW46y{{JnFSzl1YiQoNMSOY<;NnAT&v+vWhU znT)@Vq=$5qISBL?3OO!HYTS$g*y^)#U8uJ5uTw=Yf(6^{nzM#D_vPxLfKHwjto8lP zAqJ5eY&Drd#X)%*K}Qb$Jo74tg&ypFc`9&z`ASSQRBRQ|EGyma2vonGZ%i;HLdWMFJ`x!=GWw3w*#Dg|u~5ZkmOu9}^3 zBIKnXLF4zyO(3xC+uO{TR!XsS|rS?Y- zHGXf8Ug?&mD*-L#4|9NxHAbLOV3dR8a zjeQow1|Bb2!c2b>Xzn^}-zj2Td$btG7|4o$cfobUJj4}%PA2C zJ+{SbiXR}}ou2OU%xxN>rGGo5skF ziI<3Ig!p2Dx{M9&G_< zmS<_GAo+(U6+&wX3gMqwC9{BW$5n$gyV(|QN6^FB><1IzVr;jE*+NeW{MOqjesd`e z-(CO$6##p5;D!XP(qymLQVUp^0E|hY(z@i~UT_OOYqMwa^=G205azWz(I62Y0a<*oH%~pb?P|a{?CdN5Ih<1tS#1q;j&sQ!M)dybT z%?7{@XbHh^dLWj&KoJRK;OgV!b7MQi<2jV|LL7Ff`??*0i;l7YO=X=xecp>fF3r5T zWp}G65x3G&IC@1rO`fI-=*%8_-tP9`22H5{&Z5+<-uU5Fw$F#uF3>)LwlT5-<&OcFtOZf+Y)YTW7Rosd#l{7k-x_JUV2;!vWO7TLzC3b6|-g_S8c%*_xwqz4{x8= z9*7%CuSvYTaW@e>I|@TG1TRUUJkIyWSln{!FltGm(zF|AFs#E`l9V1rMx+7!;HGIf z(BRiZm0GRZ`#_a%qFG6rCVWBkO7X+9 zvAUq#9j*c?NT06tAGRNL9E1&bM5 z-IY|&E{@thjtNdo`0y0g^YNh*pnahGJ4N<%Q^gJ5T1J>uU_(Jgu`M+e?w-`|v_I*G z8b3YR3v28$0vyoX*Rb>-%C-n72q9M`VrF{rF&3?E2aQn5l-<% zHJR=Ezy|UU`Mr-9FN?T33}vYE^S`YW&C23UmMVwujXGO)C*6N++~4PhDpgPR!c?$5 z_LE;xNOm^AVGAQwN<%L6rskbo zQ$tBj?yp}!*K;`%h`6p35+)ig?GH3+AaQs1CwwM9@xaozFwN_aJe1k^x?ZoEM(El- z)Z{|GSal{C+h1=Wu>>*7E{I{7+T63yYrLIzr=3-Rx)%Fc{kJq+S+n)FhdWDUDm7X( z(n~wl6V-cT)aN>wqy4<0;UcijndTE-zuc$@BaZl9pb=XEH5GofW@gfdnvY@VDf8n^UsY{RZ<5a_LXoA{f)UHAUhLp%W%2b z65VJ=M8JKNvsVIo>Pcjd__T;m3zU5jbB?4V3?tLOPtZw|!@u^y4+uoR4XNXOl z36%XuyXK)S917VDuw;Fia_Pk(IL!3iS!C_0iItd02E(DSP$9_ef`_+HkJxv%n`yw0 zb*!sru$jFC;ubyQ10n53}g3TZuyq%Uw9{|qL z15=3V%*QZhrO(DQT_US*B#1YvF7unIYOk$r&2{d1ogGeBh!+KLfp)6l8Hg9Nim!j6 z;764{MhIK_e9bNpkNZ+Ay@$fcpY9NRP<@&GiId<&^^K%H<*0&>`B1f+^Agxvvh-3Q z!6EB)>(D(RDVwu9N!Ey9Mp0=XA27IC8HXfVDJksRxEleLVU%y_tTaX2+t?&@E%tNO zFkgn6<>k5524dm1HJ;JIM@Jif$6)ZzCqfG8DJ>C`X6=p z%<0o%D)I&3kON)a)EUV+Nc^Qbgo!h1ZPQ*4d4dD`a z?eT8W!*`4a=-GD)qNYHWHvdz(GYCnAJ}E3lF|t*DBWPpM=5uO`$8Rp4KbyvrnM+-5h zqVGC32<&51mIhGnduaKfLYV!i>1)*96T#=2$^Mktk|WkkT9G+p<;~A>bWL|!BFX~E zD#mx<#>1(P1?Q>;hwKEO8|#;FvC$38Rg10GE^gMeU&Z=^SIYbb+ij&JVj(m;o!mq* zO2Cpz_Sr$Ud?v4PM=?O*kRuiLc_fv?7qAl`FNQ*?akJ`*bKp4M(c<2d0C z6iJVg_7g~gT5>F>0)*5Sxh;qJs(>zsho_99aSHmaL@XjrHu8zY%k%icuIHBcdp>zf zpCi6%VrH+Hst|7lsu2`44H$y6-lcc!0ibY?Cd|5OMF2YWJfG-a6-^nClfxyhUUXIq z5EH)av^tht7&U_|HSD3;IGJ&bNuh7&P>cia-0k|AABtfPk5q_S3O00?g-wUZo4q~ASvk&-4Y8~vCOvvnCE znK<#69N4i%r+oi%>pCI4(hvvzFXfQCIuGPKO678>c2^%Z&OYreF1xaFuA_3bXtD-= z8tgYzVYw^sh7w7f@+YER@uEW%mNCf|%5l0qSM;wO4|OfEcy@YsUo0!8fj$zdcT2JM z!uW8x3*nPpy$Xvf!bOfURa2hF*_z(tS$!|VsRf5)$B#|o72+SW4dfC=!C*4)^J(R% zP@WCMV;K`6v8K^fyesG#L zqraq6G42mDANHbVmV7!1^eErjK21J08x$CumKj9ys20;fMAFY@U~?9#s3L$!?Ldmm zCFoQ+k1exiGT4c5L4rfYH&TiMRb0wr&!>r?S;0|dBX$9FH;;kXU+Ft}p=Pf5yDo)* zg0E1|$lZwvm)Ay+ApWZz1tF3Zu>DD%Z-7Dm+BcX!DFk&itX|5kawqj4?gO2G3>2`q z#BuvS5dF*XeZUGF80fy^B3>RkSZEChl}*C6-W)J2eACKS%okUr60o=|%jltgOS0=4 zV!kU;bX{R>iQq<4P?8}r#4&vyl(8!geLw{dHk zJZ{0FXby(y(Js3qvS|IvXE`F=W`T|#$22N+58V%}I&_7%QwA;b3Gcl==axQ3rD3qL zxV@+&0PmjKm+Orhk1Sm{qw=1!jC>3ZRmt}o$nYR37YkPzM>mz4VZqA43Dan0d*u%P zuSX2C3HG8x20cC{8Jup`d^^Bh3&Z#nW22}PSl=d1=qfjY(xYmi=X9%pQy zKccv*0=x^Id_(ci-Sx*(M?dmQ03q{oV~`45Z%w`uLwsk36#YHgTGq>@^*u)s=wt~S z7RZ87kG_%uV9aJe1;yp|-B2?W&~Y83xSeiz0rnJ+M~r#jCf;LrrQP8DY({fks_g{HqFkI-yDhCeF3M`DLe@LSBdQ=QjL&%nFfuI~@14I~ zCsm1c{haT_2@U3%+XLv_7*0EPmVcls;Z5sHxT*D3&_RGBy393b^p*u`?dfoOCiTc- zadouLN?_q`?~(6r{TgE5quud}*dbykR%D=BrF;#xG>EznI*mB!Qd+wCxAOJm-*Z7* zZjiYxm5qB;QQ+A%rx^?l8pmF=ithN*Q7ng!2mRt=4_9#?lLi!qZx3aKmSiclOSS76 zuF1#DM03~2&Z%&o?YN0vc_&|#u2Ki$E9QwyufAXVxjj5VdSj^ARORygg%~ey)-Y2e zOxQ#(na`Ou7boI&D2C@aMsvsRV_xpDsn7@L_YX!G{j^9S=W}RLjN@q-Vu`;Z?ke(kPrIFnN8> z{i@q?LFB4OeQBiz+x#sprMkzYHzKp;lV%C*J^>_b1$fbAm<%9@zs*3ok$6((Bu|ON z%0qSkiyTz;2n`gFS>?fmwAFJTAEIhLMP$%|C~?p0_Mt8*(f;dasu>_dl-j_uelN0= zjIv}BbOVqnW}W1Ld`u5x)8L#uoc|mHw<6f3!HJOEYv%i_7@%&It1H{?W-o&h%Oc!Q z{XJfI@Xn&P6n>>FlU++5Od;foaV?kT42eOt?n{rcIaRh5Z&7c%K*A^UJKqhVS?n|| zUzDzicgZV458Y2gpuU6fJToV{9z;hm}mE$30L(uYJb$BB9^&G)?K`VyznaO|Oc$w=968&&fT7 z@Tt;8lJMjx{@3{GcT(>2nk$tQj&8M+z>ldpCGfH6;*z>f8>%!CYhT3t0g|DR^a8Nx zFsQ)t=*47mFs>7c=zg8?H$|sFfZPxAk-0eeOF;*x0sc`X7jwJ2@4{YMJe)vy6b?i; z;l;Zk8OfZgVqz0W#czi5j=QrSZ+tND2 zEaf%WwABsLc$ebqC1c@vHHT(Up$aL+LFQS2Dzz&4q2^B_F<$j99~NvwQR$3+u~98H zgyMl9D4jtsX63P~)%kf-gy*nmDZPKajN=YUmzbCPvm$7mM{ET=4jm97N;dwhL9CSq z#FuZ?ft0dlbcUa8O07+Wr zwQJVWDy8W9kUj4z0(MukI@&@Xz(AI5u6i;M`}ss!O#;w0M`zCjf}T(GU~OV3m#_EG z6n;c;BXOBSoL;`IzVJ>m`jeqsgSVa0P zoR>?#_<>OLmp-k98e@YRxKF>0)}=?4USWkg0#(zU&d5s2H025h7Pcig;gDXdPOZXj zT54U4hVE{#Nxq+Yak?^+I9sC;=pIim1;q$=y7FbOr4=0-rxSk0YpLU;!I%r=1u>77PavPB1fH9#QCX*N{lWqUtrIk^Hy11aebjD^fcXIJC9Dvm~Fzy zc)0ZGs4LoW%pEZj#W~$n$LWXLP7vQ|Hrhjb_0BME4zo`)>t57(Z@tftkTFBWu&j3b zyw=Lqk)qSuC#d=`c+3P)Fw3@8B%68q{;v3+}j|tYvQCYBFO5d3YB%TB7R`3?5lq zR_?g{pv(2m<>kzC>F;2QeUC8_0o-YOz8fPlhLcseqg(j2*`i~wAb^$c}!B_xPt{x=X5X|(HP_M=0KvJlJ{9#{!1e2 zZ`lg`$!;&OH^W#Y#b4dwXo)ERi{+pZAdIFML0Q8aUyVNTSDwJyyz>E1oa<+Lefc7r)|E;IIDb!9qtt z!<+TC7x-zee?x!F=fx)I+K*VGhuU@MqRkgJZ8S>Q)bn>s%!h+;OZKp?PWqR>hQ8-4 zLQ9`Ko&L_1pJHB0^ztJshq-DIf_C^?uG4p9N-p_nK&^bf1|oXCNJ`Q?%${aO!DOuO zkY;4;k>zR4acFn#P{Ko$_f5`WYdT?+dmYB+&~n)Pd0`bv;ZGqtFt)A)KI`w~)%w=%+Zcy?_1w4PXKV6NPgE{)5Id{&Lv)WDAQQ~ggs|u{wXZfF z{gRmmw$Le53?SklV`K#{wst(DHYe}+d=!~P{BbVEJ{TlZJm4COBUIxVs>#Jn!eei5 z%6w+Tsi#|{zl!5#5-D|aka>eZfJLV?d+jc@10%8ESTlZ*D8|QBLGwR40PK|~W`0ss z8e##%dBNEf7!TR24;z43_Oib8bqvoYcdtMm-XPq^IIqjzgq#nGwQ{-GW@~UXqyjgl z8_{UbRjd}WQ2BgMs$>gFu21XU)*1m9Iov&GB}hbO&T>*b&6o%~+%b~&sGJTKKH`2G zD?8iry7r5LIuu?p34{;w3xKN#aWTF&+4*7r7vt$q2=8otSrEzX=Iy1CzVi4w7u6ah=xFnZ+g|qvSyJJHDb5 zajvO$+q4zk5)a4>|7`f$xG`9PYMr|k#(H3OC|j!o;i3pLB;lWLU=ilAxmu*LT=$fq zjzy#J1*N?QOJ+FB3f+c)xvrQr-)$x;ldZYk2^`BJL{8L3^vf;FEDgdmlVjs0a;aj1)c*>gH4^-a~z&>9D54_Cn?HLjadFF;gI>dlebGXQch;ucloqexE7Pp0QFagD^pc8sJA}_Mj z$G#?w@BB8%7o!i+$(WQ)>xxiN2XWrqS35G2-!b_&B`Gmh%h~UQLEhMv|kY z=D3vuQZB6I`Y4b2Z1DI^s*3Y;&5yJM@zf_S>-xBI;$34VEWF%h=G(e>A?zTlhx*72 zAcjWm-if%NTU?RkZe^ z(A^MPkLlcSf9xoE#3^D|Ywg{U`w=vxJX?@ePVZ%SvaZde1Ld15?XTZi9PS44dO(l( zMrP8Vxgot)ORB#e$L&-Sp26qwzdKRrtJ_ryVC3tQFWtJn&{D4_(%swffjLPLjQHqZ ziedddxDXS?n=i_ER4DIu&~<}2QVt7N)73Pik|tjwA1ef-3evg4>a8@`pU9tONJ68J zyzvPr%20;}l340$cPkX;$JoGKNc z$r~1cdpl+&n^;l8*1Jx&hX+kITdtE)&=}AtK~MILpssHDF~&cv{1A3^)_WPb~KO%?=4~^q1w9-K0yT-#TnMY&AA~g1@TA0_8=UL(h zMqJaP|#pmROT0D!3H>~U2meHmQvd?T1*q?^co z+P*jGe!vkY{{E{Lp1;g2zX=vQ&8s2IT2agKuXZ0%QXhro5x4MzZXI){YrN=w$hGv5 znL@JjcUE2)mW-aXHvzTgO2_4t>EJ+oSxvhpuYtLS5Tn8y79}*1VqwkqBFR))BRGuW zV_h=UY{cor?-;FJbm}CTU4a^v5)JGhXIF?$NJMhEmYJEJIs)$4m`&`wwJ6`#guD;q zO4GS+6r_;iW1-kY4T+#hQaG5bIY*S71-YXmmI|GzEQUA4Ws*}m$JKA-cBY} z5cc4=WHz0NRMSO%0hQLStz>Hq9k*5j~yb%%;w9ZChOQ}J%z0>)oOCdy=V+} z1;3@GsZPhGzjW$;z|dyN($O_XeU0)qo_P5l;%9k(GRf)Yx3toJ7g;S9s zZPs?I1ij3LQjkgnPGddDZLr{any1FqJ>%d>*) zQK7T5JQT5A z79ixGnQosd#jIhh@93}AUC`IP0~%59Y{5n@DT1nt-QJB;3>{bi=%LnD52w_HAx_cb zkEPpk^{QS*7n^i{R_Khm(;KE`R81Xw4`rf%1?n&|!fIAj_~8>k<;P5rg|Nxo{%>nF zsNMTI6V$m+e^99C-_-#`l$2A&=5b*UAVXy7Rh1eX16BcJ)_e0-k~=eRYz$h2l01DU zib7UR3C>@>ZDaU6URJPNjOK*0E3qe4j(Q1%x6iN2F_+&Miom8zlZ(Ds1lMR|b_*{A zqQ4Q;_xD^Nl9@lGkpaQ$;7o_%cxA|9O=dPLD=v+LqUQa)JvWFC2;n%CK^NFH(jT#TO;^|*W?rlomEYDkOn@gqlloBua;k*6$snA3Dq5S#l zpeTN(?2{vI5uoQ*oRrl1V10ypv|$;Wpkp82p<5eNXeo=N%}#8i=h|JqK)#&#NbONX zp@tjH$`aGzT;qz@4Q*%TfM+1hD1I!lxH^wldux;Wc%0#i@L15(O}tW--M92IpT&2U z4oh*C2tIEmHB|t^+usTs(&CJ6xVeJ*ieu02pvA#?G_&>L8QZPz$mA;D5D(zX4CalC z4rN}XaIWqC$oe&4WnQY*YOC~2u#;oyF+6pJ6TK{>Ly7;rtMDdBDfM#>UDqCv@`eHz zhv0$I8()9@0Fa60vDqF)7zo$u>6mL7`871vK0_Ttty&8&SejS%5&$U^Hyjkrs&};2 z?d1f+0owhIIU6CN#Pb~8AVsUv)xs^eN03F+pZ!o4MA2b(r}4qVSxTD5tBd`U+i`b8 zxAJ4}<)+FzEan%xA8g7d_g~ypNj~`LL;9*3g4}M+thkNcHIX2ZN+ig={iAj!C}28yFMUqM6n-6Aitp1m)$b|5r97mpCdIjB8FLse|<7vt1l zJU-mn+MB|tmEgiw7tiRx63Q_c9w31E3ve~|V&sB=;!WL4Z{cmcT<2|GKW_=|iQxHq zit`li&y+m$E`>`DN?fVyzzFVrHEZ(E;iumpSy{37->kWmJSU*C9gie-sk2|#~b z;`Dl62H&~PXVI<|8uU5VpL_iXcB$AlxYcI8hYM9`7GjH{nZm~Y#x)W;didg^oCnj6 zB#O=Gg-{7@>{ha4C4ai{H0RwxE>DtF7%*x@)<`s$O$Pba|!e3sp0OS{ALRdo=ReNV zccT)NJ3#!)Xywy3e&lMDJ;_Pu;9q(Z|V!eytyqymB-K<|M zj^~0Jj(>FQv}?S&f6R=U@iq^em3YitP}>z5JHWG1k{PZfFkQ{|UXp0A%$JPq z%>m7Ir(-MOh|q$Sb}i_6z#eAc@3M0H9CP`n%i?trPc$M^Y8Ce>_(hW zmZg9&;z#Kd9D%7v0Nq+KxdXCuuou){tztcA0@0w9N)gARUmM z@VU?3NwC``>TPkY{*fcG2taJ)#F@L3&IABC98Hjp{`^&lB8mr0>9=wlqsqTst6HeW5f7YDdgjTCL9bZ4lS z1&2WnG?1>AL$AX7Ql=V;+e|4RA)=9?{B=#Ex8+7s;AJF7_w+eS{M`#}xSjQz`^FFz zsUlOD8WfJ6cL(U^Q8l+~tYbW}sQvuO7)Y%xjn~#T^DA{5UxeWWz@NR=Cs~n*d`M9T zl!YB=tdj{FpoUGP$rLIQ{WH&!EhTGSZ?Kz6x1!NC4)L{1G2!OKRL8(SFNE!oi^Si?lv{W zyXX7qD){4Q_dOuHMX~x64KgJ;*}~6&$Yi;ADzLZEvi7l3>lK>F$2A}BuvKae_gXS& zsZ0s>xbS7_vgqD*o6WQl`jD>2Y1<`L&@^G${|?8A!ah=rxd6LB1L`ztC6WdNoG&bG zOXLYrW}Kz?g{JML$B}SmCc!>cH2Gq{(MClU>hp%3bb@Jb>TW0Eq?eECMQ%cRVVpbhXhF8@f4ITaDIaAF#v543=(xn57ZSa;4AhU%2t zBzCd`o=SC?c;4&bkLPc?epI2*Opulj;DOyJ>^UJT;Xv8~rqkVC20{OG#YzJdFyd|x zy>VOCTPZ*}{-Mv^sgSJ7!?r?XP~FF+#7>UGVAb((0Q29eaV`DcFADj{%4`e}(T6@f zc83+FGfkm2A_N~F?rJgW5T)|`ZUp|2Fu>rU47Z$jg1x59rFe*MV4KXtjY(SKId4h8 zIx_p~uV>A`2j$hw((ukHUJN*4s3}6j)NSqiZaQJ1V&qJr z`A3yU(%1~@x#Mr_-tp&hNh&5;me;`??+n50D&YHrsqA#(p|e)?&UkHqr$V!xk$ibTXP7Xyq_W+LR*1+ zy8D;KBl);^lEPVB24$kNS2~@?AL6DsRanLjn@f93s#l3NWwg9)+U<5F*L%~5^znOv zMS~$#1QStfRz>yan9lkSj1aXIw-Ir=97X#iNBj1+gxR=ez2Ds&+9+)%THgNJR=eCJ zMYOy!&gAE)41v4|-+Y{87TGhYM6D(p2m9oD8xNR9Zr4kWKJaW`slY|3=Flzg5&OLw%?O6yJHlL3EA507HKox%(sxVOie17z0Jh0oN zv+d9P(BX842`2LkNK(j^P-g@)__Yo#zY4F|5;cIy=3}5BkdJBs1p{x{(gc8XTWx$t ztgsFUOYC6r%Q%1ZI)0)rhMgBo^i!0d7iM^4tC}j`XpkssL6w?U9&0TzmG3kPj>^2l zZ?z6xNv1qG-Ws|!l-#Nxv|K#p zOrMT`e4nP2)Jr-wtyT>2qwdsrO|&li?$W1?)5|aQUlL0&y%EF1U#J$8>%PIr2pVGy z_B(1gI}Yw<7G#@`Is#?r@sga}sGx3&Ub!d!8L7_nMA%-6FUN#W(eR0wwp$Wc3<=ui zYH}M~7WG6sC-^^Xi9oS&@JQ*!5?COcYcUo6;wLnGr<~eqYLsvi%SW~zi_Fv|N0AX)&KLsBpDlb zcSS}2z?w>^2`#InYl9mOLL~$ zzOIbtt{o$r8(cI9hw6N3z_fc$vKPTMVrFDQz#6DPDQ@Rxa=5fHhqQmPklBvqPa=D{ ztiM0Uc<+cix#eBObjiZ(N{-;_hu!ZLq1BnCqN5XVxWJu{p{QjF?dOkAywByK`?pkD z8Wk?{lz%!7g&uLspZ53L9&w!reotMOmf+|#pH98%_Ubtr%cy0V-@$Uls7ko3Z0+=W zgyE>@j$HJx(aZ`ewS$?irT>Xj%JHB|r{z{Dv|5x`J$LlTnNdS}A?zNPb}vEk0Ri33 zv7^UTM?IL?{%wNtx$tA2Prc@bAMMZgW%Sk*vzuT0*AI8eyu8lhe%q_rtJVy!@y!M# z-kaUjRe`w+)SqfjcJibnRKJNJLPMl}yVUR3{MQF6HXGTUgv)QSaf+0~z4@008s|>8 z6^|OPFiE4e4KBw+J5Kv?=~!@?UDH^JjYF<#oiEurHYi_9-0#R>`u6=p{deSySe^0d zwqdqHV#rHvVxO?#!*kdSyb*b?tW!2*EOip!)<)gFChFKI@)d^gX#GxrytA$-d{uEV zx#ZKF{}rUY5`n6$9HnBe`{PHS_7Wr%9Nt^Tx|r;BUQeN0+|f z?4Y{yN!OPF+AuABJ^)uAb=7shZ*=eLN`$^@jiB{i6<(+nV90G2l=TxR#|XKbRQP|} zqxHC66CG#1BH;G5W#7(qEM+&&=i7UMfW6chR7D0^TN&-XJ$DCJyo)I3l`=%&Qg2nq zen@AmhOwpfI0Dsgyf{+c-{JVqAh0Z$_Cgvlwf3AWobz;U47asW)P25w){RR_yT1aaO>kMum9zHGSE7Pi6FCbE7ouYjkKZSFDY!yMs*K z)JxT`)3d$-QzFxi-^x`*o+@XuZbUm+^f<9P1g?#9o!m8g)_v?|{fVQ-VXA+*NJG1`C$~XwgRjFRO z8uH2j-cztaQf5t@>CO*fKDp~=rTe^YettZ~{;r5M++EOD^@4bmW+|K`c**aGi#nu4f`#T<0Zc4FxANREz6Z2>i1#X)en z!)Gts&HQWKP>*Ya$r;{l3URKbSG_Z3!$m}6u%)$o35!>2+vRHE48QD2G5X;�#qj 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 b?Z3W!gCI;C@%DU%gU literal 0 HcmV?d00001 diff --git a/docs/assets/images/plugin/jaeger-2.png b/docs/assets/images/plugin/jaeger-2.png new file mode 100644 index 0000000000000000000000000000000000000000..610f75dd5dda85f28e1175df04121a812ea8ad0d GIT binary patch literal 317479 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 literal 0 HcmV?d00001 diff --git a/docs/en/latest/plugins/opentelemetry.md b/docs/en/latest/plugins/opentelemetry.md index d2610eb021591..5ebc1c22af588 100644 --- a/docs/en/latest/plugins/opentelemetry.md +++ b/docs/en/latest/plugins/opentelemetry.md @@ -74,8 +74,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1 ], "plugins": { "opentelemetry": { - sampler": { - "name": "always_on", + "sampler": { + "name": "always_on" } } }, diff --git a/docs/en/latest/plugins/skywalking.md b/docs/en/latest/plugins/skywalking.md index 6633e2f73577d..c84d597ff3f9f 100644 --- a/docs/en/latest/plugins/skywalking.md +++ b/docs/en/latest/plugins/skywalking.md @@ -113,7 +113,7 @@ plugin_attr: - By default, SkyWalking uses H2 storage, start SkyWalking directly by ```shell - sudo docker run --name skywalking -d -p 1234:1234 -p 11800:11800 -p 12800:12800 --restart always apache/skywalking-oap-server:8.7.0-es6 + sudo docker run --name skywalking -d -p 1234:1234 -p 12800:12800 --restart always apache/skywalking-oap-server:8.7.0-es6 ``` - Of Course, you may want to use Elasticsearch storage instead @@ -133,7 +133,7 @@ plugin_attr: 3. Finally, run SkyWalking OAP server: ```shell - sudo docker run --name skywalking -d -p 1234:1234 -p 11800:11800 -p 12800:12800 --restart always --link elasticsearch:elasticsearch -e SW_STORAGE=elasticsearch -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 apache/skywalking-oap-server:8.7.0-es6 + sudo docker run --name skywalking -d -p 1234:1234 -p 12800:12800 --restart always --link elasticsearch:elasticsearch -e SW_STORAGE=elasticsearch -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 apache/skywalking-oap-server:8.7.0-es6 ``` 2. SkyWalking Web UI: @@ -210,23 +210,15 @@ And then reload APISIX. ## Upstream services(Code With SpringBoot) ```java -package com.lenovo.ai.controller; - import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; -/** - * @author cyxinda - * @create 2020-05-29 14:02 - * @desc skywalking test controller - **/ @RestController public class TestController { @RequestMapping("/uid/{count}") public String getUidList(@PathVariable("count") String countStr, HttpServletRequest request) { - System.out.println("counter:::::-----"+countStr); return "OK"; } } diff --git a/docs/en/latest/plugins/zipkin.md b/docs/en/latest/plugins/zipkin.md index 23aed69922103..218973c1f3b68 100644 --- a/docs/en/latest/plugins/zipkin.md +++ b/docs/en/latest/plugins/zipkin.md @@ -27,14 +27,15 @@ title: Zipkin - [**Attributes**](#attributes) - [**How To Enable**](#how-to-enable) - [**Test Plugin**](#test-plugin) - - [run the Zipkin instance](#run-the-zipkin-instance) + - [Run the Zipkin instance](#run-the-zipkin-instance) + - [Run the Jaeger instance](#run-the-jaeger-instance) - [**Disable Plugin**](#disable-plugin) ## Name -[Zipkin](https://github.com/openzipkin/zipkin) is a OpenTracing plugin. +[Zipkin](https://github.com/openzipkin/zipkin) an open source distributed tracing system. This plugin is supported to collect tracing and report to Zipkin Collector based on [Zipkin API specification](https://zipkin.io/pages/instrumenting.html). -It's also works with `Apache SkyWalking`, which is support Zipkin v1/v2 format. +It's also works with [Apache SkyWalking](https://skywalking.apache.org/docs/main/latest/en/setup/backend/zipkin-trace/#zipkin-receiver) and [Jaeger](https://www.jaegertracing.io/docs/1.31/getting-started/#migrating-from-zipkin), which are support Zipkin [v1](https://zipkin.io/zipkin-api/zipkin-api.yaml)/[v2](https://zipkin.io/zipkin-api/zipkin2-api.yaml) format. And of course, it can integrate other tracing systems adapted to Zipkin v1/v2 format as well. ## Attributes @@ -100,31 +101,78 @@ You also can complete the above operation through the web interface, first add a ## Test Plugin -### run the Zipkin instance +### Run the Zipkin instance e.g. using docker: ``` -sudo docker run -d -p 9411:9411 openzipkin/zipkin +docker run -d -p 9411:9411 openzipkin/zipkin ``` Here is a test example: ```shell -$ curl http://127.0.0.1:9080/index.html +curl http://127.0.0.1:9080/index.html HTTP/1.1 200 OK ... ``` -Then you can use a browser to access the webUI of Zipkin: +Then you can use a browser to access `http://127.0.0.1:9411/zipkin`, the webUI of Zipkin: + +![zipkin web-ui](../../../assets/images/plugin/zipkin-1.jpg) + +![zipkin web-ui list view](../../../assets/images/plugin/zipkin-2.jpg) + +### Run the Jaeger instance + +Besides Zipkin, this plugin supports reporting the traces to Jaeger as well. Here is a sample run on docker. +Run Jaeger backend on docker first: ``` -http://127.0.0.1:9411/zipkin +docker run -d --name jaeger \ + -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ + -p 16686:16686 \ + -p 9411:9411 \ + jaegertracing/all-in-one:1.31 ``` -![zipkin web-ui](../../../assets/images/plugin/zipkin-1.jpg) +Create a route with Zipkin plugin like Zipkin's example: -![zipkin web-ui list view](../../../assets/images/plugin/zipkin-2.jpg) +``` +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "methods": ["GET"], + "uri": "/index.html", + "plugins": { + "zipkin": { + "endpoint": "http://127.0.0.1:9411/api/v2/spans", + "sample_ratio": 1, + "service_name": "APISIX-IN-SG", + "server_addr": "192.168.3.50" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } +}' +``` + +Access the service: + +```shell +curl http://127.0.0.1:9080/index.html +HTTP/1.1 200 OK +... +``` + +Then you can access `http://127.0.0.1:16686`, the WebUI of Jaeger, to view traceson browser: + +![jaeger web-ui](../../../assets/images/plugin/jaeger-1.png) + +![jaeger web-ui trace](../../../assets/images/plugin/jaeger-2.png) ## Disable Plugin @@ -133,7 +181,7 @@ When you want to disable the zipkin plugin, it is very simple, no need to restart the service, it will take effect immediately: ```shell -$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", diff --git a/docs/zh/latest/plugins/opentelemetry.md b/docs/zh/latest/plugins/opentelemetry.md index fbf784e3095e4..54bb9f1b0e662 100644 --- a/docs/zh/latest/plugins/opentelemetry.md +++ b/docs/zh/latest/plugins/opentelemetry.md @@ -74,8 +74,8 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1 ], "plugins": { "opentelemetry": { - sampler": { - "name": "always_on", + "sampler": { + "name": "always_on" } } }, diff --git a/docs/zh/latest/plugins/zipkin.md b/docs/zh/latest/plugins/zipkin.md index c9db9c0a7dd41..c42c7349fd9d4 100644 --- a/docs/zh/latest/plugins/zipkin.md +++ b/docs/zh/latest/plugins/zipkin.md @@ -31,9 +31,9 @@ title: zipkin ## 名字 -`zipkin`(https://github.com/openzipkin/zipkin) 是一个开源的服务跟踪插件。 +[Zipkin](https://github.com/openzipkin/zipkin) 是开源的分布调用链追踪系统。该插件基于[Zipkin API规范](https://zipkin.io/pages/instrumenting.html),支持收集跟踪信息,并上报 Zipkin Collector。 -它还可以在 “Apache SkyWalking” 上运行,支持 Zipkin v1/v2 格式。 +> 它还能够与适配了 Zipkin [v1](https://zipkin.io/zipkin-api/zipkin-api.yaml)/[v2](https://zipkin.io/zipkin-api/zipkin2-api.yaml) 的 [Apache SkyWalking](https://skywalking.apache.org/docs/main/latest/en/setup/backend/zipkin-trace/#zipkin-receiver) 和 [Jaeger](https://www.jaegertracing.io/docs/1.31/getting-started/#migrating-from-zipkin)。当然,它也能够与其它支持 Zipkin v1/v2 数据格式的调用链追踪系统集成。 ## 属性 @@ -104,33 +104,80 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1 e.g. 用 docker: ``` -sudo docker run -d -p 9411:9411 openzipkin/zipkin +docker run -d -p 9411:9411 openzipkin/zipkin ``` 测试示例: ```shell -$ curl http://127.0.0.1:9080/index.html +curl http://127.0.0.1:9080/index.html HTTP/1.1 200 OK ... ``` -打开浏览器,访问 Zipkin 的 web 页面: +在浏览器访问`http://127.0.0.1:9411/zipkin`,在 Zipkin WebUI 上查询 traces: + +![zipkin web-ui](../../../assets/images/plugin/zipkin-1.jpg) + +![zipkin web-ui list view](../../../assets/images/plugin/zipkin-2.jpg) + +### Run the Jaeger instance + +除了对接 Zipkin,该插件也支持将 traces 上报到 Jaeger。下面运行在`docker`环境上的示例: +首先,运行 Jaeger 后端服务: ``` -http://127.0.0.1:9411/zipkin +docker run -d --name jaeger \ + -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ + -p 16686:16686 \ + -p 9411:9411 \ + jaegertracing/all-in-one:1.31 ``` -![zipkin web-ui](../../../assets/images/plugin/zipkin-1.jpg) +创建路由,并且配置 Zipkin: -![zipkin web-ui list view](../../../assets/images/plugin/zipkin-2.jpg) +``` +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "methods": ["GET"], + "uri": "/index.html", + "plugins": { + "zipkin": { + "endpoint": "http://127.0.0.1:9411/api/v2/spans", + "sample_ratio": 1, + "service_name": "APISIX-IN-SG", + "server_addr": "192.168.3.50" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } +}' +``` + +访问服务: + +```shell +curl http://127.0.0.1:9080/index.html +HTTP/1.1 200 OK +... +``` + +然后在浏览器中打开`http://127.0.0.1:16686`,在 Jaeger WebUI 上查询 traces: + +![jaeger web-ui](../../../assets/images/plugin/jaeger-1.png) + +![jaeger web-ui trace](../../../assets/images/plugin/jaeger-2.png) ## 禁用插件 当你想去掉插件的时候,很简单,在插件的配置中把对应的 json 配置删除即可,无须重启服务,即刻生效: ```shell -$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", From f0273becc72a8a70bfe80665b4337169cbe23b61 Mon Sep 17 00:00:00 2001 From: Nicolas Frankel Date: Wed, 16 Feb 2022 09:18:23 +0100 Subject: [PATCH 29/52] feat: Add feature request template (#6338) --- .github/ISSUE_TEMPLATE/feature_request.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000000..0eec9a3c0993f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,19 @@ +name: "Feature request" +description: Ask for a new feature or an improvement of an existing one +title: "feat: As a User, I want to ... so that ..." +body: + - type: markdown + attributes: + value: | + The more information you fill in, the better we can help you. + + - Please use English on public channel. + - Encourage using words rather than pictures to describe your demand. + - Encourage pre-searching with keywords in the issue. + - type: textarea + id: description + attributes: + label: Issue description + description: Provide a clear and concise description of what you want. + validations: + required: true From 1cdbf81be39ec2f70cc9fd334b11f2a07f725223 Mon Sep 17 00:00:00 2001 From: tzssangglass Date: Wed, 16 Feb 2022 16:50:08 +0800 Subject: [PATCH 30/52] ci: fix flamegraph CI trigger condition (#6339) --- .github/workflows/performance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index cff94835a602b..5c59f07ed4606 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -9,7 +9,7 @@ on: jobs: performance: - if: github.event_name == 'pull_request' || github.event.label.name == 'performance' + if: github.event_name == 'pull_request' && github.event.label.name == 'performance' runs-on: ubuntu-18.04 timeout-minutes: 45 From a933c0bda43c275f7cd832511c85b8322c506d80 Mon Sep 17 00:00:00 2001 From: Zhendong Qi <88528414+zhendongcmss@users.noreply.github.com> Date: Wed, 16 Feb 2022 21:01:49 +0800 Subject: [PATCH 31/52] feat: clickhouse logger (#6215) Co-authored-by: qizhendong --- apisix/plugins/clickhouse-logger.lua | 179 ++++++++++++++++ conf/config-default.yaml | 1 + docs/en/latest/config.json | 1 + docs/en/latest/plugins/clickhouse-logger.md | 148 +++++++++++++ docs/zh/latest/config.json | 1 + docs/zh/latest/plugins/clickhouse-logger.md | 146 +++++++++++++ t/admin/plugins.t | 1 + t/debug/debug-mode.t | 1 + t/plugin/clickhouse-logger.t | 221 ++++++++++++++++++++ 9 files changed, 699 insertions(+) create mode 100644 apisix/plugins/clickhouse-logger.lua create mode 100644 docs/en/latest/plugins/clickhouse-logger.md create mode 100644 docs/zh/latest/plugins/clickhouse-logger.md create mode 100644 t/plugin/clickhouse-logger.t diff --git a/apisix/plugins/clickhouse-logger.lua b/apisix/plugins/clickhouse-logger.lua new file mode 100644 index 0000000000000..f7b734645334f --- /dev/null +++ b/apisix/plugins/clickhouse-logger.lua @@ -0,0 +1,179 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +local bp_manager_mod = require("apisix.utils.batch-processor-manager") +local log_util = require("apisix.utils.log-util") +local core = require("apisix.core") +local http = require("resty.http") +local url = require("net.url") +local plugin = require("apisix.plugin") + +local ngx = ngx +local tostring = tostring + +local plugin_name = "clickhouse-logger" +local batch_processor_manager = bp_manager_mod.new(plugin_name) + +local schema = { + type = "object", + properties = { + endpoint_addr = core.schema.uri_def, + user = {type = "string", default = ""}, + password = {type = "string", default = ""}, + database = {type = "string", default = ""}, + logtable = {type = "string", default = ""}, + timeout = {type = "integer", minimum = 1, default = 3}, + name = {type = "string", default = "clickhouse logger"}, + ssl_verify = {type = "boolean", default = true}, + }, + required = {"endpoint_addr", "user", "password", "database", "logtable"} +} + + +local metadata_schema = { + type = "object", + properties = { + log_format = log_util.metadata_schema_log_format, + }, +} + + +local _M = { + version = 0.1, + priority = 398, + name = plugin_name, + schema = batch_processor_manager:wrap_schema(schema), + metadata_schema = metadata_schema, +} + + +function _M.check_schema(conf, schema_type) + if schema_type == core.schema.TYPE_METADATA then + return core.schema.check(metadata_schema, conf) + end + return core.schema.check(schema, conf) +end + + +local function send_http_data(conf, log_message) + local err_msg + local res = true + local url_decoded = url.parse(conf.endpoint_addr) + local host = url_decoded.host + local port = url_decoded.port + + core.log.info("sending a batch logs to ", conf.endpoint_addr) + + if not port then + if url_decoded.scheme == "https" then + port = 443 + else + port = 80 + end + end + + local httpc = http.new() + httpc:set_timeout(conf.timeout * 1000) + local ok, err = httpc:connect(host, port) + + if not ok then + return false, "failed to connect to host[" .. host .. "] port[" + .. tostring(port) .. "] " .. err + end + + if url_decoded.scheme == "https" then + ok, err = httpc:ssl_handshake(true, host, conf.ssl_verify) + if not ok then + return false, "failed to perform SSL with host[" .. host .. "] " + .. "port[" .. tostring(port) .. "] " .. err + end + end + + local httpc_res, httpc_err = httpc:request({ + method = "POST", + path = url_decoded.path, + query = url_decoded.query, + body = "INSERT INTO " .. conf.logtable .." FORMAT JSONEachRow " .. log_message, + headers = { + ["Host"] = url_decoded.host, + ["Content-Type"] = "application/json", + ["X-ClickHouse-User"] = conf.user, + ["X-ClickHouse-Key"] = conf.password, + ["X-ClickHouse-Database"] = conf.database + } + }) + + if not httpc_res then + return false, "error while sending data to [" .. host .. "] port[" + .. tostring(port) .. "] " .. httpc_err + end + + -- some error occurred in the server + if httpc_res.status >= 400 then + res = false + err_msg = "server returned status code[" .. httpc_res.status .. "] host[" + .. host .. "] port[" .. tostring(port) .. "] " + .. "body[" .. httpc_res:read_body() .. "]" + end + + return res, err_msg +end + + +function _M.log(conf, ctx) + local metadata = plugin.plugin_metadata(plugin_name) + core.log.info("metadata: ", core.json.delay_encode(metadata)) + local entry + + if metadata and metadata.value.log_format + and core.table.nkeys(metadata.value.log_format) > 0 + then + entry = log_util.get_custom_format_log(ctx, metadata.value.log_format) + else + entry = log_util.get_full_log(ngx, conf) + end + + if batch_processor_manager:add_entry(conf, entry) then + return + end + + -- Generate a function to be executed by the batch processor + local func = function(entries, batch_max_size) + local data, err + + if batch_max_size == 1 then + data, err = core.json.encode(entries[1]) -- encode as single {} + else + local log_table = {} + for i = 1, #entries do + core.table.insert(log_table, core.json.encode(entries[i])) + end + data = core.table.concat(log_table, " ") -- assemble multi items as string "{} {}" + end + + if not data then + return false, 'error occurred while encoding the data: ' .. err + end + + return send_http_data(conf, data) + end + + batch_processor_manager:add_entry_to_new_processor(conf, entry, ctx, func) +end + + +return _M diff --git a/conf/config-default.yaml b/conf/config-default.yaml index e2897abab2820..6a8362ab73990 100644 --- a/conf/config-default.yaml +++ b/conf/config-default.yaml @@ -382,6 +382,7 @@ plugins: # plugin list (sorted by priority) - syslog # priority: 401 - udp-logger # priority: 400 - file-logger # priority: 399 + - clickhouse-logger # priority: 398 #- log-rotate # priority: 100 # <- recommend to use priority (0, 100) for your custom plugins - example-plugin # priority: 0 diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json index 0977cdc9b255a..e0c070e080032 100644 --- a/docs/en/latest/config.json +++ b/docs/en/latest/config.json @@ -125,6 +125,7 @@ "plugins/kafka-logger", "plugins/rocketmq-logger", "plugins/udp-logger", + "plugins/clickhouse-logger", "plugins/syslog", "plugins/log-rotate", "plugins/error-log-logger", diff --git a/docs/en/latest/plugins/clickhouse-logger.md b/docs/en/latest/plugins/clickhouse-logger.md new file mode 100644 index 0000000000000..4bec548b97668 --- /dev/null +++ b/docs/en/latest/plugins/clickhouse-logger.md @@ -0,0 +1,148 @@ +--- +title: clickhouse-logger +--- + + + +## Summary + +- [**Name**](#name) +- [**Attributes**](#attributes) +- [**How To Enable**](#how-to-enable) +- [**Test Plugin**](#test-plugin) +- [**Metadata**](#metadata) +- [**Disable Plugin**](#disable-plugin) + +## Name + +`clickhouse-logger` is a plugin which push Log data requests to clickhouse. + +## Attributes + +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| ---------------- | ------- | ------ | ------------- | ------- | ------------------------------------------------ | +| endpoint_addr | string | required | | | The `clickhouse` endpoint. | +| database | string | required | | | The DB name to store log. | +| logtable | string | required | | | The table name. | +| user | string | required | | | clickhouse user. | +| password | string | required | | | clickhouse password. | +| timeout | integer | optional | 3 | [1,...] | Time to keep the connection alive after sending a request. | +| name | string | optional | "clickhouse logger" | | A unique identifier to identity the logger. | +| batch_max_size | integer | optional | 100 | [1,...] | Set the maximum number of logs sent in each batch. When the number of logs reaches the set maximum, all logs will be automatically pushed to the clickhouse. | +| max_retry_count | integer | optional | 0 | [0,...] | Maximum number of retries before removing from the processing pipe line. | +| retry_delay | integer | optional | 1 | [0,...] | Number of seconds the process execution should be delayed if the execution fails. | +| ssl_verify | boolean | optional | true | [true,false] | verify ssl. | + +## How To Enable + +The following is an example of how to enable the `clickhouse-logger` for a specific route. + +```shell +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "plugins": { + "clickhouse-logger": { + "user": "default", + "password": "a", + "database": "default", + "logtable": "test", + "endpoint_addr": "http://127.0.0.1:8123" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "uri": "/hello" +}' +``` + +## Test Plugin + +> success: + +```shell +$ curl -i http://127.0.0.1:9080/hello +HTTP/1.1 200 OK +... +hello, world +``` + +## Metadata + +| Name | Type | Requirement | Default | Valid | Description | +| ---------------- | ------- | ----------- | ------------- | ------- | ---------------------------------------------------------------------------------------- | +| log_format | object | optional | {"host": "$host", "@timestamp": "$time_iso8601", "client_ip": "$remote_addr"} | | Log format declared as key value pair in JSON format. Only string is supported in the `value` part. If the value starts with `$`, it means to get [APISIX variable](../apisix-variable.md) or [Nginx variable](http://nginx.org/en/docs/varindex.html). | + + Note that **the metadata configuration is applied in global scope**, which means it will take effect on all Route or Service which use clickhouse-logger plugin. + +### Example + +```shell +curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/clickhouse-logger -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "log_format": { + "host": "$host", + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr" + } +}' +``` + +create clickhouse log table + +```sql +CREATE TABLE default.test ( + `host` String, + `client_ip` String, + `route_id` String, + `@timestamp` String, + PRIMARY KEY(`@timestamp`) +) ENGINE = MergeTree() +``` + +On clickhouse run `select * from default.test;`, will got below row: + +``` +┌─host──────┬─client_ip─┬─route_id─┬─@timestamp────────────────┐ +│ 127.0.0.1 │ 127.0.0.1 │ 1 │ 2022-01-17T10:03:10+08:00 │ +└───────────┴───────────┴──────────┴───────────────────────────┘ +``` + +## Disable Plugin + +Remove the corresponding json configuration in the plugin configuration to disable the `clickhouse-logger`. +APISIX plugins are hot-reloaded, therefore no need to restart APISIX. + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/hello", + "plugins": {}, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } +}' +``` diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index c6f2ac94bf668..74ffac34e84c2 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -120,6 +120,7 @@ "plugins/kafka-logger", "plugins/rocketmq-logger", "plugins/udp-logger", + "plugins/clickhouse-logger", "plugins/syslog", "plugins/log-rotate", "plugins/error-log-logger", diff --git a/docs/zh/latest/plugins/clickhouse-logger.md b/docs/zh/latest/plugins/clickhouse-logger.md new file mode 100644 index 0000000000000..8aa6d9b779aaa --- /dev/null +++ b/docs/zh/latest/plugins/clickhouse-logger.md @@ -0,0 +1,146 @@ +--- +title: clickhouse-logger +--- + + + +## 目录 + +- [**定义**](#定义) +- [**属性列表**](#属性列表) +- [**如何开启**](#如何开启) +- [**测试插件**](#测试插件) +- [**插件元数据设置**](#插件元数据设置) +- [**禁用插件**](#禁用插件) + +## 定义 + +`clickhouse-logger` 是一个插件,可将Log数据请求推送到clickhouse服务器。 + +## 属性列表 + +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| ---------------- | ------- | ------ | ------------- | ------- | ------------------------------------------------ | +| endpoint_addr | string | 必须 | | | `clickhouse` 服务器的 endpoint。 | +| database | string | 必须 | | | 使用的数据库。 | +| logtable | string | 必须 | | | 写入的表名 。 | +| user | string | 必须 | | | clickhouse的用户。 | +| password | string | 必须 | | | clickhouse的密码 。 | +| timeout | integer | 可选 | 3 | [1,...] | 发送请求后保持连接活动的时间。 | +| name | string | 可选 | "clickhouse logger" | | 标识 logger 的唯一标识符。 | +| batch_max_size | integer | 可选 | 100 | [1,...] | 设置每批发送日志的最大条数,当日志条数达到设置的最大值时,会自动推送全部日志到 `clickhouse` 。 | +| max_retry_count | integer | 可选 | 0 | [0,...] | 从处理管道中移除之前的最大重试次数。 | +| retry_delay | integer | 可选 | 1 | [0,...] | 如果执行失败,则应延迟执行流程的秒数。 | +| ssl_verify | boolean | 可选 | true | [true,false] | 验证证书。 | + +## 如何开启 + +这是有关如何为特定路由启用 `clickhouse-logger` 插件的示例。 + +```shell +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "plugins": { + "clickhouse-logger": { + "user": "default", + "password": "a", + "database": "default", + "logtable": "test", + "endpoint_addr": "http://127.0.0.1:8123" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "uri": "/hello" +}' +``` + +## 测试插件 + +> 成功: + +```shell +$ curl -i http://127.0.0.1:9080/hello +HTTP/1.1 200 OK +... +hello, world +``` + +## 插件元数据设置 + +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| ---------------- | ------- | ------ | ------------- | ------- | ------------------------------------------------ | +| log_format | object | 可选 | {"host": "$host", "@timestamp": "$time_iso8601", "client_ip": "$remote_addr"} | | 以 JSON 格式的键值对来声明日志格式。对于值部分,仅支持字符串。如果是以 `$` 开头,则表明是要获取 [APISIX 变量](../../../en/latest/apisix-variable.md)或 [Nginx 内置变量](http://nginx.org/en/docs/varindex.html)。特别的,**该设置是全局生效的**,意味着指定 log_format 后,将对所有绑定 http-logger 的 Route 或 Service 生效。 | + +### 设置日志格式示例 + +```shell +curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/clickhouse-logger -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "log_format": { + "host": "$host", + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr" + } +}' +``` + +创建clickhouse log table + +```sql +CREATE TABLE default.test ( + `host` String, + `client_ip` String, + `route_id` String, + `@timestamp` String, + PRIMARY KEY(`@timestamp`) +) ENGINE = MergeTree() +``` + +在clickhouse上执行`select * from default.test;`,将得到类似下面的数据: + +``` +┌─host──────┬─client_ip─┬─route_id─┬─@timestamp────────────────┐ +│ 127.0.0.1 │ 127.0.0.1 │ 1 │ 2022-01-17T10:03:10+08:00 │ +└───────────┴───────────┴──────────┴───────────────────────────┘ +``` + +## 禁用插件 + +在插件配置中删除相应的 json 配置以禁用 clickhouse-logger。APISIX 插件是热重载的,因此无需重新启动 APISIX: + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "methods": ["GET"], + "uri": "/hello", + "plugins": {}, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } +}' +``` diff --git a/t/admin/plugins.t b/t/admin/plugins.t index f7435ccd9482e..68b5721f6d16c 100644 --- a/t/admin/plugins.t +++ b/t/admin/plugins.t @@ -117,6 +117,7 @@ rocketmq-logger syslog udp-logger file-logger +clickhouse-logger example-plugin aws-lambda azure-functions diff --git a/t/debug/debug-mode.t b/t/debug/debug-mode.t index 579068e5b90db..f5b6e359b50ab 100644 --- a/t/debug/debug-mode.t +++ b/t/debug/debug-mode.t @@ -83,6 +83,7 @@ loaded plugin and sort by priority: 403 name: kafka-logger loaded plugin and sort by priority: 402 name: rocketmq-logger loaded plugin and sort by priority: 401 name: syslog loaded plugin and sort by priority: 400 name: udp-logger +loaded plugin and sort by priority: 398 name: clickhouse-logger loaded plugin and sort by priority: 0 name: example-plugin loaded plugin and sort by priority: -2000 name: serverless-post-function loaded plugin and sort by priority: -3000 name: ext-plugin-post-req diff --git a/t/plugin/clickhouse-logger.t b/t/plugin/clickhouse-logger.t new file mode 100644 index 0000000000000..69e1a6f67d987 --- /dev/null +++ b/t/plugin/clickhouse-logger.t @@ -0,0 +1,221 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use t::APISIX 'no_plan'; + +log_level("info"); +repeat_each(1); +no_long_string(); +no_root_location(); + +add_block_preprocessor(sub { + my ($block) = @_; + + if ((!defined $block->error_log) && (!defined $block->no_error_log)) { + $block->set_value("no_error_log", "[error]"); + } + + if (!defined $block->request) { + $block->set_value("request", "GET /t"); + } + + my $http_config = $block->http_config // <<_EOC_; + server { + listen 10420; + location /clickhouse-logger/test { + content_by_lua_block { + ngx.req.read_body() + local data = ngx.req.get_body_data() + local headers = ngx.req.get_headers() + ngx.log(ngx.WARN, "clickhouse body: ", data) + for k, v in pairs(headers) do + ngx.log(ngx.WARN, "clickhouse headers: " .. k .. ":" .. v) + end + ngx.say("ok") + } + } + } +_EOC_ + + $block->set_value("http_config", $http_config); +}); + +run_tests(); + +__DATA__ + +=== TEST 1: Full configuration verification +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.clickhouse-logger") + local ok, err = plugin.check_schema({timeout = 3, + retry_delay = 1, + batch_max_size = 500, + user = "default", + password = "a", + database = "default", + logtable = "t", + endpoint_addr = "http://127.0.0.1:10420/clickhouse-logger/test", + max_retry_count = 1, + name = "clickhouse logger", + ssl_verify = false + }) + + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +passed + + + +=== TEST 2: Basic configuration verification +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.clickhouse-logger") + local ok, err = plugin.check_schema({user = "default", + password = "a", + database = "default", + logtable = "t", + endpoint_addr = "http://127.0.0.1:10420/clickhouse-logger/test" + }) + + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +passed + + + +=== TEST 3: auth configure undefined +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.clickhouse-logger") + local ok, err = plugin.check_schema({user = "default", + password = "a", + database = "default", + logtable = "t" + }) + + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +property "endpoint_addr" is required + + + +=== TEST 4: add plugin on routes +--- 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, + [[{ + "plugins": { + "clickhouse-logger": { + "user": "default", + "password": "a", + "database": "default", + "logtable": "t", + "endpoint_addr": "http://127.0.0.1:10420/clickhouse-logger/test", + "batch_max_size":1, + "inactive_timeout":1 + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/opentracing" + }]], + [[{ + "action":"set", + "node":{ + "value":{ + "uri":"/opentracing", + "upstream":{ + "scheme":"http", + "nodes":{ + "127.0.0.1:1982":1 + } + }, + "plugins":{ + "clickhouse-logger":{ + "batch_max_size":1, + "max_retry_count":0, + "retry_delay":1, + "ssl_verify":true, + "endpoint_addr":"http://127.0.0.1:10420/clickhouse-logger/test", + "password":"a", + "buffer_duration":60, + "timeout":3, + "user":"default", + "name":"clickhouse-logger", + "database":"default", + "logtable":"t", + "inactive_timeout":1 + } + }, + "id":"1" + }, + "key":"/apisix/routes/1" + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 5: access local server +--- request +GET /opentracing +--- response_body +opentracing +--- error_log +clickhouse body: INSERT INTO t FORMAT JSONEachRow +clickhouse headers: x-clickhouse-key:a +clickhouse headers: x-clickhouse-user:default +clickhouse headers: x-clickhouse-database:default +--- wait: 5 From 06f709594df56ee5ce18e9ec0f79a0484a1a3bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Wed, 16 Feb 2022 21:40:14 +0800 Subject: [PATCH 32/52] test: remove duplicate --- no_error_log & --- request sections (#6317) --- t/admin/plugins.t | 32 ++++-------------------------- t/admin/upstream2.t | 4 ---- t/core/ctx2.t | 4 ---- t/misc/patch.t | 4 ---- t/node/plugin-configs.t | 4 ---- t/plugin/batch-requests2.t | 6 ------ t/plugin/ext-plugin/conf_token.t | 2 -- t/plugin/ext-plugin/sanity.t | 10 +--------- t/plugin/jwt-auth-vault.t | 2 -- t/plugin/jwt-auth.t | 4 ---- t/plugin/ldap-auth.t | 6 ------ t/plugin/limit-conn2.t | 16 --------------- t/plugin/plugin.t | 2 -- t/plugin/prometheus3.t | 2 -- t/plugin/rocketmq-logger.t | 26 ------------------------ t/plugin/traffic-split2.t | 34 -------------------------------- t/plugin/traffic-split5.t | 12 ----------- 17 files changed, 5 insertions(+), 165 deletions(-) diff --git a/t/admin/plugins.t b/t/admin/plugins.t index 68b5721f6d16c..e6e29d2f618bc 100644 --- a/t/admin/plugins.t +++ b/t/admin/plugins.t @@ -29,6 +29,10 @@ add_block_preprocessor(sub { $block->set_value("request", "GET /t"); } + if (!defined $block->error_log && !defined $block->no_error_log) { + $block->set_value("no_error_log", "[error]"); + } + $block; }); @@ -37,7 +41,6 @@ run_tests; __DATA__ === TEST 1: get plugins' name ---- request --- config location /t { content_by_lua_block { @@ -56,8 +59,6 @@ __DATA__ end } } ---- request -GET /t --- response_body real-ip @@ -125,9 +126,6 @@ openwhisk serverless-post-function ext-plugin-post-req ---- no_error_log -[error] - === TEST 2: wrong path @@ -136,8 +134,6 @@ GET /apisix/admin/plugins --- error_code: 400 --- response_body {"error_msg":"not found plugin name"} ---- no_error_log -[error] @@ -157,8 +153,6 @@ GET /apisix/admin/plugins ngx.status = code } } ---- no_error_log -[error] @@ -181,8 +175,6 @@ plugins: ngx.status = code } } ---- no_error_log -[error] @@ -202,8 +194,6 @@ plugins: ngx.status = code } } ---- no_error_log -[error] @@ -223,8 +213,6 @@ plugins: ngx.status = code } } ---- no_error_log -[error] @@ -244,8 +232,6 @@ plugins: ngx.status = code } } ---- no_error_log -[error] @@ -276,8 +262,6 @@ plugins: } --- response_body eval qr/\{"metadata_schema":\{"properties":\{"ikey":\{"minimum":0,"type":"number"\},"skey":\{"type":"string"\}\},"required":\["ikey","skey"\],"type":"object"\},"priority":0,"schema":\{"\$comment":"this is a mark for our injected plugin schema","properties":\{"disable":\{"type":"boolean"\},"i":\{"minimum":0,"type":"number"\},"ip":\{"type":"string"\},"port":\{"type":"integer"\},"s":\{"type":"string"\},"t":\{"minItems":1,"type":"array"\}\},"required":\["i"\],"type":"object"\},"version":0.1\}/ ---- no_error_log -[error] @@ -317,8 +301,6 @@ qr/\{"metadata_schema":\{"properties":\{"ikey":\{"minimum":0,"type":"number"\}," } --- response_body eval qr/\[\{"name":"wolf-rbac","priority":2555\},\{"name":"ldap-auth","priority":2540\},\{"name":"hmac-auth","priority":2530\},\{"name":"basic-auth","priority":2520\},\{"name":"jwt-auth","priority":2510\},\{"name":"key-auth","priority":2500\}\]/ ---- no_error_log -[error] @@ -351,8 +333,6 @@ qr/\[\{"name":"wolf-rbac","priority":2555\},\{"name":"ldap-auth","priority":2540 } --- response_body eval qr/\{"properties":\{"password":\{"type":"string"\},"username":\{"type":"string"\}\},"required":\["username","password"\],"title":"work with consumer object","type":"object"\}/ ---- no_error_log -[error] @@ -383,8 +363,6 @@ qr/\{"properties":\{"password":\{"type":"string"\},"username":\{"type":"string"\ } --- response_body {"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"burst":{"minimum":0,"type":"integer"},"conn":{"exclusiveMinimum":0,"type":"integer"},"default_conn_delay":{"exclusiveMinimum":0,"type":"number"},"disable":{"type":"boolean"},"key":{"type":"string"},"key_type":{"default":"var","enum":["var","var_combination"],"type":"string"},"only_use_default_delay":{"default":false,"type":"boolean"}},"required":["conn","burst","default_conn_delay","key"],"type":"object"},"version":0.1} ---- no_error_log -[error] @@ -427,5 +405,3 @@ plugins: } --- response_body {"batch-requests":"global","error-log-logger":"global","node-status":"global","server-info":"global"} ---- no_error_log -[error] diff --git a/t/admin/upstream2.t b/t/admin/upstream2.t index e7b867035ad1c..7f22d11490523 100644 --- a/t/admin/upstream2.t +++ b/t/admin/upstream2.t @@ -286,10 +286,6 @@ no valid upstream node ngx.print(body) } } ---- request -GET /t --- error_code: 400 --- response_body_like eval qr/{"error_msg":"invalid configuration: property \\\"timeout\\\" validation failed: property \\\"(connect|send|read)\\\" validation failed: expected 0 to be greater than 0"}/ ---- no_error_log -[error] diff --git a/t/core/ctx2.t b/t/core/ctx2.t index 5922e7c7bf83c..47c0a47430c66 100644 --- a/t/core/ctx2.t +++ b/t/core/ctx2.t @@ -274,12 +274,8 @@ GET /hello ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] diff --git a/t/misc/patch.t b/t/misc/patch.t index a735126df3db9..deee50c18816f 100644 --- a/t/misc/patch.t +++ b/t/misc/patch.t @@ -147,8 +147,6 @@ apisix: ngx.say("ok") } } ---- request -GET /t --- response_body ok @@ -181,8 +179,6 @@ apisix: --- stream_request eval m --- stream_response: ok ---- no_error_log -[error] diff --git a/t/node/plugin-configs.t b/t/node/plugin-configs.t index 16e3178095a00..770392276a779 100644 --- a/t/node/plugin-configs.t +++ b/t/node/plugin-configs.t @@ -154,8 +154,6 @@ conf_version: \d+#2 } } ---- request -GET /t --- error_code: 403 @@ -176,8 +174,6 @@ GET /t assert(core.etcd.delete("/plugin_configs/1")) } } ---- request -GET /t --- error_log property "block_rules" validation failed diff --git a/t/plugin/batch-requests2.t b/t/plugin/batch-requests2.t index 135f7fc2c0c55..1cc3178e4aee2 100644 --- a/t/plugin/batch-requests2.t +++ b/t/plugin/batch-requests2.t @@ -65,8 +65,6 @@ __DATA__ ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -109,8 +107,6 @@ plugin_attr: } } --- error_code: 404 ---- no_error_log -[error] @@ -135,8 +131,6 @@ plugin_attr: ngx.say(body) } } ---- request -GET /t --- response_body passed diff --git a/t/plugin/ext-plugin/conf_token.t b/t/plugin/ext-plugin/conf_token.t index 58a8b13725285..0c659c5c99a98 100644 --- a/t/plugin/ext-plugin/conf_token.t +++ b/t/plugin/ext-plugin/conf_token.t @@ -139,5 +139,3 @@ done qr/fetch token from shared dict, token: 233/ --- grep_error_log_out eval qr/(fetch token from shared dict, token: 233){1,}/ ---- no_error_log -[error] diff --git a/t/plugin/ext-plugin/sanity.t b/t/plugin/ext-plugin/sanity.t index 690ef1902d673..a665f1cf8424d 100644 --- a/t/plugin/ext-plugin/sanity.t +++ b/t/plugin/ext-plugin/sanity.t @@ -115,8 +115,8 @@ hello world --- error_log get conf token: 233 --- no_error_log -[error] flush conf token lrucache +[error] --- grep_error_log eval qr/(sending|receiving) rpc type: \d data length:/ --- grep_error_log_out @@ -271,8 +271,6 @@ receiving rpc type: 1 data length: --- error_log flush conf token lrucache flush conf token in shared dict ---- no_error_log -[error] @@ -334,8 +332,6 @@ hello world } --- error_log eval qr/get conf token: 233 conf: \[(\{"value":"bar","name":"foo"\}|\{"name":"foo","value":"bar"\}),(\{"value":"dog","name":"cat"\}|\{"name":"cat","value":"dog"\})\]/ ---- no_error_log -[error] @@ -384,8 +380,6 @@ hello world --- error_log refresh cache and try again flush conf token in shared dict ---- no_error_log -[error] @@ -549,8 +543,6 @@ hello world } --- error_log eval qr/get conf token: 233 conf: \[(\{"value":"bar","name":"foo"\}|\{"name":"foo","value":"bar"\}),(\{"value":"dog","name":"cat"\}|\{"name":"cat","value":"dog"\})\]/ ---- no_error_log -[error] diff --git a/t/plugin/jwt-auth-vault.t b/t/plugin/jwt-auth-vault.t index 8220663510caf..bcb7817c5748c 100644 --- a/t/plugin/jwt-auth-vault.t +++ b/t/plugin/jwt-auth-vault.t @@ -178,8 +178,6 @@ passed ngx.say(body) } } ---- request -GET /t --- response_body passed diff --git a/t/plugin/jwt-auth.t b/t/plugin/jwt-auth.t index 25ba22800c173..c5ec543192f5d 100644 --- a/t/plugin/jwt-auth.t +++ b/t/plugin/jwt-auth.t @@ -1160,8 +1160,6 @@ hello world === TEST 46: test for unsupported algorithm ---- request -PATCH /apisix/plugin/jwt/sign?key=user-key --- config location /t { content_by_lua_block { @@ -1177,8 +1175,6 @@ PATCH /apisix/plugin/jwt/sign?key=user-key ngx.say(require("toolkit.json").encode(conf)) } } ---- request -GET /t --- response_body_like eval qr/property "algorithm" validation failed/ diff --git a/t/plugin/ldap-auth.t b/t/plugin/ldap-auth.t index 1480323199145..f5963aa979067 100644 --- a/t/plugin/ldap-auth.t +++ b/t/plugin/ldap-auth.t @@ -168,8 +168,6 @@ Authorization: Bad_header Zm9vOmZvbwo= --- error_code: 401 --- response_body {"message":"Invalid authorization header format"} ---- no_error_log -[error] @@ -181,8 +179,6 @@ Authorization: Basic aca_a --- error_code: 401 --- response_body {"message":"Failed to decode authentication header: aca_a"} ---- no_error_log -[error] @@ -194,8 +190,6 @@ Authorization: Basic Zm9v --- error_code: 401 --- response_body {"message":"Split authorization err: invalid decoded data: foo"} ---- no_error_log -[error] diff --git a/t/plugin/limit-conn2.t b/t/plugin/limit-conn2.t index 75375aaed8bfb..b1cc12230ee5d 100644 --- a/t/plugin/limit-conn2.t +++ b/t/plugin/limit-conn2.t @@ -400,12 +400,8 @@ request latency is nil ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -430,13 +426,9 @@ passed ngx.say(json.encode(ress)) } } ---- request -GET /t --- timeout: 10s --- response_body [200,200] ---- no_error_log -[error] @@ -450,8 +442,6 @@ GET /test_concurrency 503 503 503 ---- no_error_log -[error] --- error_log The value of the configured key is empty, use client IP instead @@ -491,12 +481,8 @@ The value of the configured key is empty, use client IP instead ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -510,7 +496,5 @@ GET /test_concurrency 503 503 503 ---- no_error_log -[error] --- error_log The value of the configured key is empty, use client IP instead diff --git a/t/plugin/plugin.t b/t/plugin/plugin.t index c5a6c13768da7..009a511879496 100644 --- a/t/plugin/plugin.t +++ b/t/plugin/plugin.t @@ -146,8 +146,6 @@ passed ngx.print(res) } } ---- request -GET /t --- response_body hello world diff --git a/t/plugin/prometheus3.t b/t/plugin/prometheus3.t index 550dc71f1ee09..0d2db21d509a3 100644 --- a/t/plugin/prometheus3.t +++ b/t/plugin/prometheus3.t @@ -177,8 +177,6 @@ plugins: - error-log-logger - prometheus - http-logger ---- request -GET /t --- config location /t { content_by_lua_block { diff --git a/t/plugin/rocketmq-logger.t b/t/plugin/rocketmq-logger.t index 79b90136b4385..1355d3dfee461 100644 --- a/t/plugin/rocketmq-logger.t +++ b/t/plugin/rocketmq-logger.t @@ -54,8 +54,6 @@ __DATA__ ngx.say("done") } } ---- request -GET /t --- response_body done @@ -73,8 +71,6 @@ done ngx.say("done") } } ---- request -GET /t --- response_body property "nameserver_list" is required done @@ -100,8 +96,6 @@ done ngx.say("done") } } ---- request -GET /t --- response_body property "timeout" validation failed: wrong type: expected integer, got string done @@ -164,8 +158,6 @@ done ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -241,8 +233,6 @@ hello world local res, err = httpc:request_uri(uri, {method = "GET"}) } } ---- request -GET /t --- error_log failed to send data to rocketmq topic [error] @@ -284,8 +274,6 @@ failed to send data to rocketmq topic ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -343,8 +331,6 @@ abcdef ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -399,8 +385,6 @@ connection: close ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -473,8 +457,6 @@ qr/send data to rocketmq: \{.*"upstream":"127.0.0.1:1980"/ ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -522,8 +504,6 @@ hello world ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -574,8 +554,6 @@ qr/send data to rocketmq: \{.*"upstream":"127.0.0.1:1980"/ ngx.say(body) } } ---- request -GET /t --- response_body passed @@ -617,8 +595,6 @@ passed ngx.sleep(0.5) } } ---- request -GET /t --- timeout: 5s --- ignore_response @@ -664,8 +640,6 @@ qr/queue: 2/] ngx.sleep(0.5) } } ---- request -GET /t --- timeout: 5s --- ignore_response diff --git a/t/plugin/traffic-split2.t b/t/plugin/traffic-split2.t index 58c98b5b1c537..5a4afc5b8fda9 100644 --- a/t/plugin/traffic-split2.t +++ b/t/plugin/traffic-split2.t @@ -152,12 +152,8 @@ GET /server_port?name=jack&age=18 ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -170,8 +166,6 @@ host: 127.0.0.1 uri: /uri host: 127.0.0.1 x-real-ip: 127.0.0.1 ---- no_error_log -[error] @@ -219,12 +213,8 @@ x-real-ip: 127.0.0.1 ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -235,8 +225,6 @@ GET /uri?name=jack uri: /uri host: test.com x-real-ip: 127.0.0.1 ---- no_error_log -[error] @@ -287,12 +275,8 @@ x-real-ip: 127.0.0.1 ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -305,8 +289,6 @@ host: 127.0.0.1 uri: /uri host: localhost x-real-ip: 127.0.0.1 ---- no_error_log -[error] @@ -358,8 +340,6 @@ x-real-ip: 127.0.0.1 } --- response_body passed ---- no_error_log -[error] @@ -467,8 +447,6 @@ chash_key: "hello" } --- response_body passed ---- no_error_log -[error] @@ -492,8 +470,6 @@ location /t { } --- response_body eval qr/1980, 1981, 1982, 1980, 1981, 1982, 1980, 1981, 1982/ ---- no_error_log -[error] @@ -561,8 +537,6 @@ qr/1980, 1981, 1982, 1980, 1981, 1982, 1980, 1981, 1982/ } --- response_body passed ---- no_error_log -[error] @@ -585,8 +559,6 @@ location /t { } --- response_body eval qr/1980, 1980, 1980, 1980, 1981, 1981, 1982, 1982/ ---- no_error_log -[error] @@ -677,12 +649,8 @@ qr/1980, 1980, 1980, 1980, 1981, 1981, 1982, 1982/ ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -706,8 +674,6 @@ location /t { } --- response_body eval qr/1980, 1981, 1982, 1980, 1981, 1982, 1980, 1981, 1982/ ---- no_error_log -[error] diff --git a/t/plugin/traffic-split5.t b/t/plugin/traffic-split5.t index aee660baa6b41..5e2b80ac363ec 100644 --- a/t/plugin/traffic-split5.t +++ b/t/plugin/traffic-split5.t @@ -154,12 +154,8 @@ __DATA__ ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -272,12 +268,8 @@ passed ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] @@ -379,12 +371,8 @@ passed ngx.say(body) } } ---- request -GET /t --- response_body passed ---- no_error_log -[error] From f37fc0eb77abbf7fdf98ea40ce706d75e5582a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=B2=BB=E5=9B=BD?= Date: Wed, 16 Feb 2022 21:47:10 +0800 Subject: [PATCH 33/52] fix(hmac-auth): hmac-auth plugin sort array param (#6314) --- apisix/plugins/hmac-auth.lua | 9 ++++++ t/plugin/hmac-auth3.t | 61 ++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/apisix/plugins/hmac-auth.lua b/apisix/plugins/hmac-auth.lua index 73cb947d3c032..9a63db977ad22 100644 --- a/apisix/plugins/hmac-auth.lua +++ b/apisix/plugins/hmac-auth.lua @@ -244,7 +244,16 @@ local function generate_signature(ctx, secret_key, params) -- whether to encode the uri parameters if type(param) == "table" then + local vals = {} for _, val in pairs(param) do + if type(val) == "boolean" then + val = "" + end + core.table.insert(vals, val) + end + core.table.sort(vals) + + for _, val in pairs(vals) do core.table.insert(query_tab, encode_or_not(key) .. "=" .. encode_or_not(val)) end else diff --git a/t/plugin/hmac-auth3.t b/t/plugin/hmac-auth3.t index bc66dc6569f1b..d90dcbcdb4d31 100644 --- a/t/plugin/hmac-auth3.t +++ b/t/plugin/hmac-auth3.t @@ -532,3 +532,64 @@ plugin_attr: } --- response_body passed + + + +=== TEST 10: Test sort table param. +--- config + location /t { + content_by_lua_block { + local ngx_time = ngx.time + local ngx_http_time = ngx.http_time + local core = require("apisix.core") + local t = require("lib.test_admin") + local hmac = require("resty.hmac") + local ngx_encode_base64 = ngx.encode_base64 + + local secret_key = "my-secret-key" + local timestamp = ngx_time() + local gmt = ngx_http_time(timestamp) + local access_key = "my-access-key" + local custom_header_a = "asld$%dfasf" + local custom_header_b = "23879fmsldfk" + local body = "{\"name\": \"world\"}" + + local signing_string = { + "POST", + "/hello", + "a=&a=1&a=2&a1a=123&c=&name=123", + access_key, + gmt, + "x-custom-header-a:" .. custom_header_a, + "x-custom-header-b:" .. custom_header_b + } + signing_string = core.table.concat(signing_string, "\n") .. "\n" + core.log.info("signing_string:", signing_string) + + local signature = hmac:new(secret_key, hmac.ALGOS.SHA256):final(signing_string) + local body_digest = hmac:new(secret_key, hmac.ALGOS.SHA256):final(body) + + core.log.info("signature:", ngx_encode_base64(signature)) + local headers = {} + headers["X-HMAC-SIGNATURE"] = ngx_encode_base64(signature) + headers["X-HMAC-ALGORITHM"] = "hmac-sha256" + headers["Date"] = gmt + headers["X-HMAC-DIGEST"] = ngx_encode_base64(body_digest) + headers["X-HMAC-ACCESS-KEY"] = access_key + headers["X-HMAC-SIGNED-HEADERS"] = "x-custom-header-a;x-custom-header-b" + headers["x-custom-header-a"] = custom_header_a + headers["x-custom-header-b"] = custom_header_b + + local code, body = t.test('/hello?c=&a1a=123&name=123&a&a=2&a=1', + ngx.HTTP_POST, + body, + nil, + headers + ) + + ngx.status = code + ngx.say(body) + } + } +--- response_body +passed From e4658fc236af345c9009c0feba4b8754dfbbebcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Fri, 18 Feb 2022 10:42:02 +0800 Subject: [PATCH 34/52] feat(wasm): support getting request body (#6325) Co-authored-by: leslie <59061168+leslie-tsang@users.noreply.github.com> --- .github/workflows/build.yml | 4 +- apisix/cli/ngx_tpl.lua | 4 + apisix/wasm.lua | 26 +++++- ci/centos7-ci.sh | 2 +- docs/en/latest/wasm.md | 1 + t/APISIX.pm | 8 ++ t/plugin/grpc-web/go.mod | 5 +- t/plugin/grpc-web/go.sum | 8 +- t/wasm/go.mod | 4 +- t/wasm/go.sum | 11 +-- t/wasm/request-body.t | 152 ++++++++++++++++++++++++++++++++++++ t/wasm/request-body/main.go | 99 +++++++++++++++++++++++ 12 files changed, 301 insertions(+), 23 deletions(-) create mode 100644 t/wasm/request-body.t create mode 100644 t/wasm/request-body/main.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 943b6867cb42a..43e80b1b4c4d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,7 +42,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2.2.0 with: - go-version: "1.15" + go-version: "1.17" - name: Cache deps uses: actions/cache@v2.1.7 @@ -79,7 +79,7 @@ jobs: run: sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl libpcre3 libpcre3-dev libldap2-dev - name: Build wasm code - if: startsWith(matrix.os_name, 'linux_openresty') + if: matrix.os_name == 'linux_openresty' run: | export TINYGO_VER=0.20.0 wget https://github.com/tinygo-org/tinygo/releases/download/v${TINYGO_VER}/tinygo_${TINYGO_VER}_amd64.deb 2>/dev/null diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua index 6ef7e8e7f23cb..10642537b621a 100644 --- a/apisix/cli/ngx_tpl.lua +++ b/apisix/cli/ngx_tpl.lua @@ -587,6 +587,10 @@ http { set $ctx_ref ''; set $from_error_page ''; + {% if wasm then %} + set $wasm_process_req_body ''; + {% end %} + # http server location configuration snippet starts {% if http_server_location_configuration_snippet then %} {* http_server_location_configuration_snippet *} diff --git a/apisix/wasm.lua b/apisix/wasm.lua index 7a6e81c4b813b..415e7fd6715fb 100644 --- a/apisix/wasm.lua +++ b/apisix/wasm.lua @@ -63,30 +63,48 @@ end local function http_request_wrapper(self, conf, ctx) + local name = self.name local plugin_ctx, err = fetch_plugin_ctx(conf, ctx, self.plugin) if not plugin_ctx then - core.log.error("failed to fetch wasm plugin ctx: ", err) + core.log.error(name, ": failed to fetch wasm plugin ctx: ", err) return 503 end local ok, err = wasm.on_http_request_headers(plugin_ctx) if not ok then - core.log.error("failed to run wasm plugin: ", err) + core.log.error(name, ": failed to run wasm plugin: ", err) return 503 end + + -- $wasm_process_req_body is predefined in ngx_tpl.lua + local handle_body = ctx.var.wasm_process_req_body + if handle_body ~= '' then + local body, err = core.request.get_body() + if err ~= nil then + core.log.error(name, ": failed to get request body: ", err) + return 503 + end + + local ok, err = wasm.on_http_request_body(plugin_ctx, body, true) + if not ok then + core.log.error(name, ": failed to run wasm plugin: ", err) + return 503 + end + end end local function header_filter_wrapper(self, conf, ctx) + local name = self.name local plugin_ctx, err = fetch_plugin_ctx(conf, ctx, self.plugin) if not plugin_ctx then - core.log.error("failed to fetch wasm plugin ctx: ", err) + core.log.error(name, ": failed to fetch wasm plugin ctx: ", err) return 503 end local ok, err = wasm.on_http_response_headers(plugin_ctx) if not ok then - core.log.error("failed to run wasm plugin: ", err) + core.log.error(name, ": failed to run wasm plugin: ", err) return 503 end end diff --git a/ci/centos7-ci.sh b/ci/centos7-ci.sh index 7c74eba9742e4..304dde6d925a3 100755 --- a/ci/centos7-ci.sh +++ b/ci/centos7-ci.sh @@ -50,7 +50,7 @@ install_dependencies() { # add go1.15 binary to the path mkdir build-cache # centos-7 ci runs on a docker container with the centos image on top of ubuntu host. Go is required inside the container. - cd build-cache/ && wget https://golang.org/dl/go1.15.linux-amd64.tar.gz && tar -xf go1.15.linux-amd64.tar.gz + cd build-cache/ && wget https://golang.org/dl/go1.17.linux-amd64.tar.gz && tar -xf go1.17.linux-amd64.tar.gz export PATH=$PATH:$(pwd)/go/bin cd .. # install and start grpc_server_example diff --git a/docs/en/latest/wasm.md b/docs/en/latest/wasm.md index dc66454a94514..4d115e336e992 100644 --- a/docs/en/latest/wasm.md +++ b/docs/en/latest/wasm.md @@ -101,6 +101,7 @@ Here is the mapping between Proxy WASM callbacks and APISIX's phases: * `proxy_on_configure`: run once there is not PluginContext for the new configuration. For example, when the first request hits the route which has WASM plugin configured. * `proxy_on_http_request_headers`: run in the access/rewrite phase, depends on the configuration of `http_request_phase`. +* `proxy_on_http_request_body`: run in the same phase of `proxy_on_http_request_headers`. To run this callback, we need to set property `wasm_process_req_body` to non-empty value in `proxy_on_http_request_headers`. See `t/wasm/request-body/main.go` as an example. * `proxy_on_http_response_headers`: run in the header_filter phase. ## Example diff --git a/t/APISIX.pm b/t/APISIX.pm index 6050bd2acf5c4..268ae7eb85676 100644 --- a/t/APISIX.pm +++ b/t/APISIX.pm @@ -217,6 +217,13 @@ if ($version =~ m/\/apisix-nginx-module/) { _EOC_ } +my $a6_ngx_vars = ""; +if ($version =~ m/\/apisix-nginx-module/) { + $a6_ngx_vars = <<_EOC_; + set \$wasm_process_req_body ''; +_EOC_ +} + add_block_preprocessor(sub { my ($block) = @_; my $wait_etcd_sync = $block->wait_etcd_sync // 0.1; @@ -714,6 +721,7 @@ _EOC_ set \$upstream_cache_key ''; set \$upstream_cache_bypass ''; set \$upstream_no_cache ''; + $a6_ngx_vars proxy_cache \$upstream_cache_zone; proxy_cache_valid any 10s; diff --git a/t/plugin/grpc-web/go.mod b/t/plugin/grpc-web/go.mod index cece5f1ddd736..85c7a597b8401 100644 --- a/t/plugin/grpc-web/go.mod +++ b/t/plugin/grpc-web/go.mod @@ -4,10 +4,9 @@ go 1.16 require ( github.com/golang/protobuf v1.4.3 - github.com/satori/go.uuid v1.2.0 // indirect - golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect + github.com/satori/go.uuid v1.2.0 + golang.org/x/net v0.0.0-20200822124328-c89045814202 golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect - golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/grpc v1.43.0 ) diff --git a/t/plugin/grpc-web/go.sum b/t/plugin/grpc-web/go.sum index 626dadfd33c91..bb6c12b5635b7 100644 --- a/t/plugin/grpc-web/go.sum +++ b/t/plugin/grpc-web/go.sum @@ -64,8 +64,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -75,12 +73,9 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -117,6 +112,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/t/wasm/go.mod b/t/wasm/go.mod index 3f9de8af9c553..f82b7e9a0aa54 100644 --- a/t/wasm/go.mod +++ b/t/wasm/go.mod @@ -1,9 +1,9 @@ module github.com/api7/wasm-nginx-module -go 1.15 +go 1.17 require ( - github.com/tetratelabs/proxy-wasm-go-sdk v0.14.1-0.20210819090022-1e4e69881a31 + github.com/tetratelabs/proxy-wasm-go-sdk v0.16.0 github.com/valyala/fastjson v1.6.3 ) diff --git a/t/wasm/go.sum b/t/wasm/go.sum index 97ddff755a285..835b676307a41 100644 --- a/t/wasm/go.sum +++ b/t/wasm/go.sum @@ -1,15 +1,16 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tetratelabs/proxy-wasm-go-sdk v0.14.1-0.20210819090022-1e4e69881a31 h1:V3GXN5nayOdIU3NypbxVegGFCVGm78qOA8Q7wkeudy8= -github.com/tetratelabs/proxy-wasm-go-sdk v0.14.1-0.20210819090022-1e4e69881a31/go.mod h1:qZ+4i6e2wHlhnhgpH0VG4QFzqd2BEvQbQFU0npt2e2k= +github.com/tetratelabs/proxy-wasm-go-sdk v0.16.0 h1:6xhDLV4DD2+q3Rs4CDh7cqo69rQ50XgCusv/58D44o4= +github.com/tetratelabs/proxy-wasm-go-sdk v0.16.0/go.mod h1:8CxNZJ+9yDEvNnAog384fC8j1tKNF0tTZevGjOuY9ds= github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/t/wasm/request-body.t b/t/wasm/request-body.t new file mode 100644 index 0000000000000..96d3217526277 --- /dev/null +++ b/t/wasm/request-body.t @@ -0,0 +1,152 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use t::APISIX; + +my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx'; +my $version = eval { `$nginx_binary -V 2>&1` }; + +if ($version !~ m/\/apisix-nginx-module/) { + plan(skip_all => "apisix-nginx-module not installed"); +} else { + plan('no_plan'); +} + +add_block_preprocessor(sub { + my ($block) = @_; + + if ((!defined $block->error_log) && (!defined $block->no_error_log)) { + $block->set_value("no_error_log", "[error]"); + } + + if (!defined $block->request) { + $block->set_value("request", "GET /t"); + } + + my $extra_yaml_config = <<_EOC_; +wasm: + plugins: + - name: wasm-request-body + priority: 7997 + file: t/wasm/request-body/main.go.wasm +_EOC_ + $block->set_value("extra_yaml_config", $extra_yaml_config); +}); + +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- 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, + [[{ + "uri": "/hello", + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "plugins": { + "wasm-request-body": { + "conf": "{\"processReqBody\":true, \"start\":1, \"size\":3}" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 2: hit +--- request +POST /hello +hello +--- grep_error_log eval +qr/request get body: \w+/ +--- grep_error_log_out +request get body: ell + + + +=== TEST 3: no body +--- request +POST /hello +--- error_log +error status returned by host: not found + + + +=== TEST 4: do not process body +--- 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, + [[{ + "uri": "/hello", + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + }, + "plugins": { + "wasm-request-body": { + "conf": "{\"processReqBody\":false, \"start\":1, \"size\":3}" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 5: hit +--- request +POST /hello +hello +--- grep_error_log eval +qr/request get body: \w+/ +--- grep_error_log_out diff --git a/t/wasm/request-body/main.go b/t/wasm/request-body/main.go new file mode 100644 index 0000000000000..7895fe900e593 --- /dev/null +++ b/t/wasm/request-body/main.go @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm" + "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types" + "github.com/valyala/fastjson" +) + +func main() { + proxywasm.SetVMContext(&vmContext{}) +} + +type vmContext struct { + types.DefaultVMContext +} + +func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext { + return &pluginContext{contextID: contextID} +} + +type pluginContext struct { + types.DefaultPluginContext + contextID uint32 + start int + size int + processReqBody bool +} + +func (ctx *pluginContext) OnPluginStart(pluginConfigurationSize int) types.OnPluginStartStatus { + data, err := proxywasm.GetPluginConfiguration() + if err != nil { + proxywasm.LogCriticalf("error reading plugin configuration: %v", err) + return types.OnPluginStartStatusFailed + } + + var conf *fastjson.Value + var p fastjson.Parser + conf, err = p.ParseBytes(data) + if err != nil { + proxywasm.LogErrorf("error decoding plugin configuration: %v", err) + return types.OnPluginStartStatusFailed + } + + ctx.start = conf.GetInt("start") + ctx.size = conf.GetInt("size") + ctx.processReqBody = conf.GetBool("processReqBody") + return types.OnPluginStartStatusOK +} + +func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext { + return &httpContext{pluginCtx: ctx, contextID: contextID} +} + +type httpContext struct { + types.DefaultHttpContext + pluginCtx *pluginContext + contextID uint32 +} + +func (ctx *httpContext) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action { + if ctx.pluginCtx.processReqBody { + proxywasm.SetProperty([]string{"wasm_process_req_body"}, []byte("true")) + } + + return types.ActionContinue +} + +func (ctx *httpContext) OnHttpRequestBody(bodySize int, endOfStream bool) types.Action { + size := ctx.pluginCtx.size + if size == 0 { + size = bodySize + } + + body, err := proxywasm.GetHttpRequestBody(ctx.pluginCtx.start, size) + if err != nil { + proxywasm.LogErrorf("failed to get body: %v", err) + return types.ActionContinue + } + + proxywasm.LogWarnf("request get body: %v", string(body)) + return types.ActionContinue +} From deb3a56eae10087db7a85d877be14523b834fefc Mon Sep 17 00:00:00 2001 From: tyltr Date: Fri, 18 Feb 2022 10:42:47 +0800 Subject: [PATCH 35/52] feat: support for configuring the number of etcd health check retries (#6322) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tzssangglass Co-authored-by: 罗泽轩 --- apisix/cli/etcd.lua | 4 +++- conf/config-default.yaml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apisix/cli/etcd.lua b/apisix/cli/etcd.lua index 53c41468cf90c..9edfbcd51876e 100644 --- a/apisix/cli/etcd.lua +++ b/apisix/cli/etcd.lua @@ -196,7 +196,9 @@ function _M.init(env, args) local res, err local retry_time = 0 - while retry_time < 2 do + + local health_check_retry = tonumber(yaml_conf.etcd.health_check_retry) or 2 + while retry_time < health_check_retry do res, err = request(version_url, yaml_conf) -- In case of failure, request returns nil followed by an error message. -- Else the first return value is the response body diff --git a/conf/config-default.yaml b/conf/config-default.yaml index 6a8362ab73990..c49272e054ab6 100644 --- a/conf/config-default.yaml +++ b/conf/config-default.yaml @@ -274,6 +274,7 @@ etcd: timeout: 30 # 30 seconds #resync_delay: 5 # when sync failed and a rest is needed, resync after the configured seconds plus 50% random jitter #health_check_timeout: 10 # etcd retry the unhealthy nodes after the configured seconds + health_check_retry: 2 # etcd retry time that only affects the health check, default 2 #user: root # root username for etcd #password: 5tHkHhYkjr6cQY # root password for etcd tls: From 00b7b0198f167c1e1a69d0c976b4a1dd231f48ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=85=E8=BF=9B=E8=B6=85?= Date: Fri, 18 Feb 2022 11:09:26 +0800 Subject: [PATCH 36/52] feat(graphql): support http get and post json request (#6343) --- apisix/core/ctx.lua | 59 +++++++++++++++++++++++++++++++++++++-- t/router/graphql.t | 67 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/apisix/core/ctx.lua b/apisix/core/ctx.lua index af8672d9101c5..fc1d3f86310d1 100644 --- a/apisix/core/ctx.lua +++ b/apisix/core/ctx.lua @@ -18,6 +18,7 @@ local core_str = require("apisix.core.string") local core_tab = require("apisix.core.table") local request = require("apisix.core.request") local log = require("apisix.core.log") +local json = require("apisix.core.json") local config_local = require("apisix.core.config_local") local tablepool = require("tablepool") local get_var = require("resty.ngxvar").fetch @@ -36,7 +37,52 @@ local pcall = pcall local _M = {version = 0.2} -local GRAPHQL_DEFAULT_MAX_SIZE = 1048576 -- 1MiB +local GRAPHQL_DEFAULT_MAX_SIZE = 1048576 -- 1MiB +local GRAPHQL_REQ_DATA_KEY = "query" +local GRAPHQL_REQ_METHOD_HTTP_GET = "GET" +local GRAPHQL_REQ_METHOD_HTTP_POST = "POST" +local GRAPHQL_REQ_MIME_JSON = "application/json" + + +local fetch_graphql_data = { + [GRAPHQL_REQ_METHOD_HTTP_GET] = function(ctx, max_size) + local body = request.get_uri_args(ctx)[GRAPHQL_REQ_DATA_KEY] + if not body then + return nil, "failed to read graphql data, args[" .. + GRAPHQL_REQ_DATA_KEY .. "] is nil" + end + + if type(body) == "table" then + body = body[1] + end + + return body + end, + + [GRAPHQL_REQ_METHOD_HTTP_POST] = function(ctx, max_size) + local body, err = request.get_body(max_size, ctx) + if not body then + return nil, "failed to read graphql data, " .. (err or "request body has zero size") + end + + if request.header(ctx, "Content-Type") == GRAPHQL_REQ_MIME_JSON then + local res + res, err = json.decode(body) + if not res then + return nil, "failed to read graphql data, " .. err + end + + if not res[GRAPHQL_REQ_DATA_KEY] then + return nil, "failed to read graphql data, json body[" .. + GRAPHQL_REQ_DATA_KEY .. "] is nil" + end + + body = res[GRAPHQL_REQ_DATA_KEY] + end + + return body + end +} local function parse_graphql(ctx) @@ -51,9 +97,16 @@ local function parse_graphql(ctx) max_size = size end - local body, err = request.get_body(max_size, ctx) + local method = request.get_method() + local func = fetch_graphql_data[method] + if not func then + return nil, "graphql not support `" .. method .. "` request" + end + + local body + body, err = func(ctx, max_size) if not body then - return nil, "failed to read graphql body: " .. (err or "request body has zero size") + return nil, err end local ok, res = pcall(gq_parse, body) diff --git a/t/router/graphql.t b/t/router/graphql.t index 294e2a14fe5cc..b6936fc554acb 100644 --- a/t/router/graphql.t +++ b/t/router/graphql.t @@ -232,7 +232,7 @@ query { } --- error_code: 404 --- error_log -failed to read graphql body +failed to read graphql data @@ -244,7 +244,7 @@ failed to read graphql body local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, [=[{ - "methods": ["POST"], + "methods": ["POST", "GET"], "upstream": { "nodes": { "127.0.0.1:1980": 1 @@ -283,7 +283,62 @@ hello world -=== TEST 13: multiple root fields +=== TEST 13: test send http post json data +--- request +POST /hello +{"query":"query{owner{name}}"} +--- more_headers +Content-Type: application/json +--- response_body +hello world + + + +=== TEST 14: test send http get query data +--- request +GET /hello?query=query{owner{name}} +--- response_body +hello world + + + +=== TEST 15: test send http get multiple query data success +--- request +GET /hello?query=query{owner{name}}&query=query{repo{name}} +--- response_body +hello world + + + +=== TEST 16: test send http get multiple query data failure +--- request +GET /hello?query=query{repo{name}}&query=query{owner{name}} +--- error_code: 404 + + + +=== TEST 17: no body (HTTP GET) +--- request +GET /hello +--- error_code: 404 +--- error_log +failed to read graphql data, args[query] is nil + + + +=== TEST 18: no body (HTTP POST JSON) +--- request +POST /hello +{} +--- more_headers +Content-Type: application/json +--- error_code: 404 +--- error_log +failed to read graphql data, json body[query] is nil + + + +=== TEST 19: multiple root fields --- request POST /hello query { @@ -299,7 +354,7 @@ hello world -=== TEST 14: root fields mismatch +=== TEST 20: root fields mismatch --- request POST /hello query { @@ -311,9 +366,9 @@ query { -=== TEST 15: no body +=== TEST 21: no body --- request POST /hello --- error_code: 404 --- error_log -failed to read graphql body: request body has zero size +failed to read graphql data, request body has zero size From 9b98f1d13187c58195543bd48cb8b66e33aeab27 Mon Sep 17 00:00:00 2001 From: roketyyang Date: Fri, 18 Feb 2022 11:10:45 +0800 Subject: [PATCH 37/52] fix(opentelemetry): batch_span_processor export zero length spans (#6349) Co-authored-by: roketyyang --- rockspec/apisix-master-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index 4cbee3f28a008..1d654d7cfb238 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -73,7 +73,7 @@ dependencies = { "inspect == 3.1.1", "lualdap = 1.2.6-1", "lua-resty-rocketmq = 0.3.0-0", - "opentelemetry-lua = 0.1-1", + "opentelemetry-lua = 0.1-2", } build = { From 17338b9b6abc016e0492f26bb3c027b797e3f96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Sat, 19 Feb 2022 23:22:24 +0800 Subject: [PATCH 38/52] ci: remove unnecessary tmate action (#6367) --- .github/actions/action-tmate | 1 - .github/workflows/chaos.yml | 6 ------ .gitmodules | 3 --- 3 files changed, 10 deletions(-) delete mode 160000 .github/actions/action-tmate diff --git a/.github/actions/action-tmate b/.github/actions/action-tmate deleted file mode 160000 index 079a16b22b8bc..0000000000000 --- a/.github/actions/action-tmate +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 079a16b22b8bcc5dd231a42d9a5e8e48db564688 diff --git a/.github/workflows/chaos.yml b/.github/workflows/chaos.yml index e26a4e90319d6..87ecf4ee111bc 100644 --- a/.github/workflows/chaos.yml +++ b/.github/workflows/chaos.yml @@ -84,9 +84,3 @@ jobs: - name: Run test working-directory: ./t/chaos run: ginkgo -r --v --progress --trace - - # Debug via SSH if previous steps failed - - name: Set up tmate session - if: ${{ failure() }} - uses: ./.github/actions/action-tmate - timeout-minutes: 15 diff --git a/.gitmodules b/.gitmodules index 12854c44f59af..6ad3766a07a59 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "t/toolkit"] path = t/toolkit url = https://github.com/api7/test-toolkit.git -[submodule ".github/actions/action-tmate"] - path = .github/actions/action-tmate - url = https://github.com/mxschmitt/action-tmate [submodule "t/grpc_server_example"] path = t/grpc_server_example url = https://github.com/api7/grpc_server_example From 682f8ccfe9fa0239ef83735c3398c74a7812890a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Sat, 19 Feb 2022 23:31:47 +0800 Subject: [PATCH 39/52] fix: should not limit the header number (#6379) --- apisix/core/request.lua | 2 +- apisix/plugins/request-validation.lua | 4 ++-- t/core/request.t | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apisix/core/request.lua b/apisix/core/request.lua index c15ac62e2b57e..1bd8aafee0f0b 100644 --- a/apisix/core/request.lua +++ b/apisix/core/request.lua @@ -43,7 +43,7 @@ local function _headers(ctx) end local headers = ctx.headers if not headers then - headers = get_headers() + headers = get_headers(0) ctx.headers = headers end diff --git a/apisix/plugins/request-validation.lua b/apisix/plugins/request-validation.lua index e64a9cec372d1..0b3b0f3e18f33 100644 --- a/apisix/plugins/request-validation.lua +++ b/apisix/plugins/request-validation.lua @@ -66,8 +66,8 @@ function _M.check_schema(conf) end -function _M.rewrite(conf) - local headers = ngx.req.get_headers() +function _M.rewrite(conf, ctx) + local headers = core.request.headers(ctx) if conf.header_schema then local ok, err = core.schema.check(conf.header_schema, headers) diff --git a/t/core/request.t b/t/core/request.t index 7d688c9886eb0..0f0acb414a3b0 100644 --- a/t/core/request.t +++ b/t/core/request.t @@ -422,3 +422,24 @@ the post form is too large: request body in temp file not supported POST /t --- response_body POST + + + +=== TEST 14: get header +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + ngx.say(core.request.header(ngx.ctx, "X-101")) + } + } +--- more_headers eval +my $i = 1; +my $s; +while ($i <= 101) { + $s .= "X-$i:$i\n"; + $i++; +} +$s +--- response_body +101 From e279dfffef30029f050254ceac3154b21a3f419b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Mon, 21 Feb 2022 09:51:52 +0800 Subject: [PATCH 40/52] change(admin): empty nodes should be encoded as array (#6384) --- apisix/core/etcd.lua | 4 +++- apisix/core/json.lua | 1 + docs/en/latest/getting-started.md | 4 ++-- docs/en/latest/internal/testing-framework.md | 2 +- docs/zh/latest/getting-started.md | 4 ++-- t/admin/consumers2.t | 2 +- t/admin/global-rules2.t | 2 +- t/admin/plugin-metadata2.t | 2 +- t/admin/routes3.t | 2 +- t/admin/ssl3.t | 2 +- t/admin/upstream3.t | 2 +- 11 files changed, 15 insertions(+), 12 deletions(-) diff --git a/apisix/core/etcd.lua b/apisix/core/etcd.lua index 793ece52bd2d8..288fac791079d 100644 --- a/apisix/core/etcd.lua +++ b/apisix/core/etcd.lua @@ -15,10 +15,12 @@ -- limitations under the License. -- local fetch_local_conf = require("apisix.core.config_local").local_conf +local array_mt = require("apisix.core.json").array_mt local etcd = require("resty.etcd") local clone_tab = require("table.clone") local health_check = require("resty.etcd.health_check") local ipairs = ipairs +local setmetatable = setmetatable local string = string local tonumber = tonumber local _M = {} @@ -88,7 +90,7 @@ _M.kvs_to_node = kvs_to_node local function kvs_to_nodes(res) res.body.node.dir = true - res.body.node.nodes = {} + 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 diff --git a/apisix/core/json.lua b/apisix/core/json.lua index 2a83d71cc1527..b464dcc0673a6 100644 --- a/apisix/core/json.lua +++ b/apisix/core/json.lua @@ -25,6 +25,7 @@ local cached_tab = {} local _M = { version = 0.1, + array_mt = require("cjson.safe").array_mt, decode = require("cjson.safe").decode, -- This method produces the same encoded string when the input is not changed. -- Different calls with cjson.encode will produce different string because diff --git a/docs/en/latest/getting-started.md b/docs/en/latest/getting-started.md index 3ee4b461ec128..9eb4d63949ffd 100644 --- a/docs/en/latest/getting-started.md +++ b/docs/en/latest/getting-started.md @@ -118,11 +118,11 @@ The following data is returned to indicate that Apache APISIX was successfully s ```json { - "count":1, + "count":0, "action":"get", "node":{ "key":"/apisix/services", - "nodes":{}, + "nodes":[], "dir":true } } diff --git a/docs/en/latest/internal/testing-framework.md b/docs/en/latest/internal/testing-framework.md index f5c4daf7fdedf..c9a11f785c342 100644 --- a/docs/en/latest/internal/testing-framework.md +++ b/docs/en/latest/internal/testing-framework.md @@ -351,7 +351,7 @@ ONLY: --- config ... --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/upstreams","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/upstreams","nodes":[]}} ``` ### Executing Shell Commands diff --git a/docs/zh/latest/getting-started.md b/docs/zh/latest/getting-started.md index 1780d1155afd4..cd5e9320ed9d4 100644 --- a/docs/zh/latest/getting-started.md +++ b/docs/zh/latest/getting-started.md @@ -116,11 +116,11 @@ curl "http://127.0.0.1:9080/apisix/admin/services/" -H 'X-API-KEY: edd1c9f034335 ```json { - "count":1, + "count":0, "action":"get", "node":{ "key":"/apisix/services", - "nodes":{}, + "nodes":[], "dir":true } } diff --git a/t/admin/consumers2.t b/t/admin/consumers2.t index 28bc2fcc31d38..3c296b79339fd 100644 --- a/t/admin/consumers2.t +++ b/t/admin/consumers2.t @@ -150,7 +150,7 @@ __DATA__ } } --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/consumers","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/consumers","nodes":[]}} diff --git a/t/admin/global-rules2.t b/t/admin/global-rules2.t index 3835dcc0f107b..6ff033b52f439 100644 --- a/t/admin/global-rules2.t +++ b/t/admin/global-rules2.t @@ -60,7 +60,7 @@ __DATA__ } } --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/global_rules","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/global_rules","nodes":[]}} diff --git a/t/admin/plugin-metadata2.t b/t/admin/plugin-metadata2.t index def0ba222b682..190b9ae20faf8 100644 --- a/t/admin/plugin-metadata2.t +++ b/t/admin/plugin-metadata2.t @@ -60,4 +60,4 @@ __DATA__ } } --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/plugin_metadata","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/plugin_metadata","nodes":[]}} diff --git a/t/admin/routes3.t b/t/admin/routes3.t index d9eb4f9165f9c..668ff47a7b185 100644 --- a/t/admin/routes3.t +++ b/t/admin/routes3.t @@ -60,7 +60,7 @@ __DATA__ } } --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/routes","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/routes","nodes":[]}} diff --git a/t/admin/ssl3.t b/t/admin/ssl3.t index 4fcce6069d667..cb09b5119223f 100644 --- a/t/admin/ssl3.t +++ b/t/admin/ssl3.t @@ -60,4 +60,4 @@ __DATA__ } } --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/ssl","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/ssl","nodes":[]}} diff --git a/t/admin/upstream3.t b/t/admin/upstream3.t index 9796a05eb499a..070c8b3d23680 100644 --- a/t/admin/upstream3.t +++ b/t/admin/upstream3.t @@ -60,7 +60,7 @@ __DATA__ } } --- response_body -{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/upstreams","nodes":{}}} +{"action":"get","count":0,"node":{"dir":true,"key":"/apisix/upstreams","nodes":[]}} From 51f87773f40c2f6935d2e619f54ec17dc7c41eca Mon Sep 17 00:00:00 2001 From: Daming Date: Mon, 21 Feb 2022 09:52:37 +0800 Subject: [PATCH 41/52] doc: adjust the directory structure of observability's documents (#6391) --- docs/en/latest/config.json | 68 ++++++++++++++++++++++---------------- docs/zh/latest/config.json | 65 +++++++++++++++++++++--------------- 2 files changed, 79 insertions(+), 54 deletions(-) diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json index e0c070e080032..b93a9edeeeb93 100644 --- a/docs/en/latest/config.json +++ b/docs/en/latest/config.json @@ -105,35 +105,47 @@ }, { "type": "category", - "label": "Monitoring", + "label": "Observability", "items": [ - "plugins/prometheus", - "plugins/zipkin", - "plugins/skywalking", - "plugins/opentelemetry", - "plugins/node-status", - "plugins/datadog" - ] - }, - { - "type": "category", - "label": "Loggers", - "items": [ - "plugins/http-logger", - "plugins/skywalking-logger", - "plugins/tcp-logger", - "plugins/kafka-logger", - "plugins/rocketmq-logger", - "plugins/udp-logger", - "plugins/clickhouse-logger", - "plugins/syslog", - "plugins/log-rotate", - "plugins/error-log-logger", - "plugins/sls-logger", - "plugins/google-cloud-logging", - "plugins/splunk-hec-logging", - "plugins/file-logger", - "plugins/loggly" + { + "type": "category", + "label": "Tracers", + "items": [ + "plugins/zipkin", + "plugins/skywalking", + "plugins/opentelemetry" + ] + }, + { + "type": "category", + "label": "Metrics", + "items": [ + "plugins/promethues", + "plugins/node-status", + "plugins/datadog" + ] + }, + { + "type": "category", + "label": "Loggers", + "items": [ + "plugins/http-logger", + "plugins/skywalking-logger", + "plugins/tcp-logger", + "plugins/kafka-logger", + "plugins/rocketmq-logger", + "plugins/udp-logger", + "plugins/clickhouse-logger", + "plugins/syslog", + "plugins/log-rotate", + "plugins/error-log-logger", + "plugins/sls-logger", + "plugins/google-cloud-logging", + "plugins/splunk-hec-logging", + "plugins/file-logger", + "plugins/loggly" + ] + } ] }, { diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index 74ffac34e84c2..a75205653d152 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -101,33 +101,46 @@ }, { "type": "category", - "label": "Monitoring", + "label": "Observability", "items": [ - "plugins/prometheus", - "plugins/zipkin", - "plugins/skywalking", - "plugins/opentelemetry", - "plugins/node-status" - ] - }, - { - "type": "category", - "label": "Loggers", - "items": [ - "plugins/http-logger", - "plugins/skywalking-logger", - "plugins/tcp-logger", - "plugins/kafka-logger", - "plugins/rocketmq-logger", - "plugins/udp-logger", - "plugins/clickhouse-logger", - "plugins/syslog", - "plugins/log-rotate", - "plugins/error-log-logger", - "plugins/sls-logger", - "plugins/google-cloud-logging", - "plugins/splunk-hec-logging", - "plugins/file-logger" + { + "type": "category", + "label": "Tracers", + "items": [ + "plugins/zipkin", + "plugins/skywalking", + "plugins/opentelemetry" + ] + }, + { + "type": "category", + "label": "Metrics", + "items": [ + "plugins/promethues", + "plugins/node-status", + "plugins/datadog" + ] + }, + { + "type": "category", + "label": "Loggers", + "items": [ + "plugins/http-logger", + "plugins/skywalking-logger", + "plugins/tcp-logger", + "plugins/kafka-logger", + "plugins/rocketmq-logger", + "plugins/udp-logger", + "plugins/clickhouse-logger", + "plugins/syslog", + "plugins/log-rotate", + "plugins/error-log-logger", + "plugins/sls-logger", + "plugins/google-cloud-logging", + "plugins/splunk-hec-logging", + "plugins/file-logger" + ] + } ] }, { From b0f71819faf92d21fa52e293e5ea05e79614abc7 Mon Sep 17 00:00:00 2001 From: Hwting <837479851@qq.com> Date: Mon, 21 Feb 2022 09:54:13 +0800 Subject: [PATCH 42/52] docs: polishing skywalking-logger plugin's docs (#6377) --- docs/zh/latest/plugins/skywalking-logger.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/zh/latest/plugins/skywalking-logger.md b/docs/zh/latest/plugins/skywalking-logger.md index 3d863896ac017..fa6e8e913ab40 100644 --- a/docs/zh/latest/plugins/skywalking-logger.md +++ b/docs/zh/latest/plugins/skywalking-logger.md @@ -40,9 +40,11 @@ title: skywalking-logger | 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | | ---------------- | ------- | ------ | ------------- | ------- | ------------------------------------------------ | -| uri | string | 必须 | | | `SkyWalking OAp` 服务器的 URI。 | -| timeout | integer | 可选 | 3 | [1,...] | 发送请求后保持连接活动的时间。 | -| name | string | 可选 | "skywalking logger" | | 标识 logger 的唯一标识符。 | +| endpoint_addr | string | 必须 | | | `SkyWalking OAp` 服务器的 URI。 | +| service_name | string | 可选 |"APISIX" | | `SkyWalking` 服务名称。 | +| service_instance_name | string | 可选 |"APISIX Instance Name"| | `SkyWalking`服务实例名称,将其设置为`$hostname`以直接获取本地主机名。 | +| timeout | integer | 可选 | 3 | [1,...] | 发送请求后保持连接活动的时间。 | +| name | string | 可选 | "skywalking logger" | | 标识 logger 的唯一标识符。 | | batch_max_size | integer | 可选 | 1000 | [1,...] | 设置每批发送日志的最大条数,当日志条数达到设置的最大值时,会自动推送全部日志到 `HTTP/HTTPS` 服务。 | | inactive_timeout | integer | 可选 | 5 | [1,...] | 刷新缓冲区的最大时间(以秒为单位),当达到最大的刷新时间时,无论缓冲区中的日志数量是否达到设置的最大条数,也会自动将全部日志推送到 `HTTP/HTTPS` 服务。 | | buffer_duration | integer | 可选 | 60 | [1,...] | 必须先处理批次中最旧条目的最长期限(以秒为单位)。 | @@ -59,7 +61,7 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13 { "plugins": { "skywalking-logger": { - "uri": "http://127.0.0.1:12800" + "endpoint_addr": "http://127.0.0.1:12800" } }, "upstream": { From 42e84e437fa532f24523f5b38015436e1fcc013f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Mon, 21 Feb 2022 09:54:33 +0800 Subject: [PATCH 43/52] docs(extern-plugin): the implementation of runner (#6336) --- docs/en/latest/config.json | 1 + docs/en/latest/external-plugin.md | 4 ++ docs/en/latest/internal/plugin-runner.md | 78 ++++++++++++++++++++++++ docs/zh/latest/external-plugin.md | 5 ++ 4 files changed, 88 insertions(+) create mode 100644 docs/en/latest/internal/plugin-runner.md diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json index b93a9edeeeb93..2ffbf81f2606f 100644 --- a/docs/en/latest/config.json +++ b/docs/en/latest/config.json @@ -278,6 +278,7 @@ "type": "category", "label": "internal", "items": [ + "internal/plugin-runner", "internal/testing-framework" ] }, diff --git a/docs/en/latest/external-plugin.md b/docs/en/latest/external-plugin.md index 4c620c446a91f..8094f1062ba8c 100644 --- a/docs/en/latest/external-plugin.md +++ b/docs/en/latest/external-plugin.md @@ -47,6 +47,10 @@ run external plugins and return the result back to APISIX. The target external plugins and the execution order are configured in the `ext-plugin-*` plugins. Like other plugins, they can be enabled and reconfigured on the fly. +## How is it implemented + +If you are instested in the implementation of Plugin Runner, please refer to [The Implementation of Plugin Runner](./internal/plugin-runner.md). + ## Supported plugin runners - Java: https://github.com/apache/apisix-java-plugin-runner diff --git a/docs/en/latest/internal/plugin-runner.md b/docs/en/latest/internal/plugin-runner.md new file mode 100644 index 0000000000000..4117187d2ac29 --- /dev/null +++ b/docs/en/latest/internal/plugin-runner.md @@ -0,0 +1,78 @@ +--- +title: The Implementation of Plugin Runner +--- + + + +## Prerequirement + +Each request which runs the extern plugin will trigger an RPC to Plugin Runner over a connection on Unix socket. The data of RPC are serialized with [Flatbuffers](https://github.com/google/flatbuffers). + +Therefore, the Plugin Runner needs to: + +1. handle a connection on Unix socket +2. support Flatbuffers +3. use the proto & generated code in https://github.com/api7/ext-plugin-proto/ + +## Listening to the Path + +APISIX will pass the path of Unix socket as an environment variable `APISIX_LISTEN_ADDRESS` to the Plugin Runner. So the runner needs to read the value and listen to that address during starting. + +## Register Plugins + +The Plugin Runner should be able to load plugins written in the particular language. + +## Handle RPC + +There are two kinds of RPC: PrepareConf & HTTPReqCall + +### Handle PrepareConf + +As people can configure the extern plugin on the side of APISIX, we need a way to sync the plugin configuration to the Plugin Runner. + +When there is a configuration that needs to sync to the Plugin Runner, we will send it via the PrepareConf RPC call. The Plugin Runner should be able to handle the call and store the configuration in a cache, then returns a unique conf token that represents the configuration. + +In the previous design, an idempotent key is sent with the configuration. This field is deprecated and the Plugin Runner can safely ignore it. + +Requests run plugins with particular configuration will bear a particular conf token in the RPC call, and the Plugin Runner is expected to look up actual configuration via the token. + +When the configuration is modified, APISIX will send a new PrepareConf to the Plugin Runner. Currently, there is no way to notify the Plugin Runner that a configuration is removed. Therefore, we introduce another environment variable `APISIX_CONF_EXPIRE_TIME` as the conf cache expire time. The Plugin Runner should be able to cache the conf slightly longer than `APISIX_CONF_EXPIRE_TIME`, and APISIX will send another PrepareConf to refresh the cache if the configuration is still existing after `APISIX_CONF_EXPIRE_TIME` seconds. + +### Handle HTTPReqCall + +Each request which runs the extern plugin will trigger the HTTPReqCall. The HTTPReqCall is almost a serialized version of HTTP request, plus a conf token. The Plugin Runner is expected to tell APISIX what to update by the response of HTTPReqCall RPC call. + +Sometimes the plugin in the Plugin Runner needs to know some information that is not part of the HTTPReqCall request, such as the request start time and the route ID in APISIX. Hence the Plugin Runner needs to reply to an `ExtraInfo` message as the response on the connection which sends the HTTPReqCall request. APISIX will read the `ExtraInfo` message and return the asked information. + +Currently, the information below is passed by `ExtraInfo`: + +* variable value +* request body + +The flow of HTTPReqCall procession is: + +``` +APISIX sends HTTPReqCall +Plugin Runner looks up the plugin configuration by the token in HTTPReqCall +(optional) loop: +    Plugin Runner asks for ExtraInfo +    APISIX replies the ExtraInfo +Plugin Runner replies HTTPReqCall +``` diff --git a/docs/zh/latest/external-plugin.md b/docs/zh/latest/external-plugin.md index e02538ebd1a25..3e8049f8631df 100644 --- a/docs/zh/latest/external-plugin.md +++ b/docs/zh/latest/external-plugin.md @@ -41,6 +41,11 @@ APISIX 支持使用 Lua 语言编写插件,这种类型的插件在 APISIX 内 External Plugin 及其执行顺序在这里 `ext-plugin-*` 配置。与其他插件一样, External Plugin 可以动态启用和重新配置。 +## 它是如何实现的 + +如果你对 Plugin Runner 内部实现感兴趣,请参考这份文档: +[The Implementation of Plugin Runner](../../en/latest/internal/plugin-runner.md) + ## 支持的 Plugin Runner - Java: https://github.com/apache/apisix-java-plugin-runner From 21aa21bbfc5b581f32278afe3725fea63d9ba42a Mon Sep 17 00:00:00 2001 From: Zeping Bai Date: Mon, 21 Feb 2022 17:12:55 +0800 Subject: [PATCH 44/52] docs: fix configuration file typo (#6395) --- docs/en/latest/config.json | 2 +- docs/zh/latest/config.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json index 2ffbf81f2606f..2c029753e08cd 100644 --- a/docs/en/latest/config.json +++ b/docs/en/latest/config.json @@ -120,7 +120,7 @@ "type": "category", "label": "Metrics", "items": [ - "plugins/promethues", + "plugins/prometheus", "plugins/node-status", "plugins/datadog" ] diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index a75205653d152..9c700f72d34d4 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -116,7 +116,7 @@ "type": "category", "label": "Metrics", "items": [ - "plugins/promethues", + "plugins/prometheus", "plugins/node-status", "plugins/datadog" ] From 9bdee14dc77e0076960f2b943822fe7507c5f1d2 Mon Sep 17 00:00:00 2001 From: leslie <59061168+leslie-tsang@users.noreply.github.com> Date: Mon, 21 Feb 2022 17:36:04 +0800 Subject: [PATCH 45/52] fix(request-validation): should not limit the urlencoded post args number (#6396) --- apisix/plugins/request-validation.lua | 4 +- t/plugin/request-validation.t | 56 +++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/apisix/plugins/request-validation.lua b/apisix/plugins/request-validation.lua index 0b3b0f3e18f33..20abffc9277af 100644 --- a/apisix/plugins/request-validation.lua +++ b/apisix/plugins/request-validation.lua @@ -88,7 +88,9 @@ function _M.rewrite(conf, ctx) end if headers["content-type"] == "application/x-www-form-urlencoded" then - req_body, err = ngx.decode_args(body) + -- use 0 to avoid truncated result and keep the behavior as the + -- same as other platforms + req_body, err = ngx.decode_args(body, 0) else -- JSON as default req_body, err = core.json.decode(body) end diff --git a/t/plugin/request-validation.t b/t/plugin/request-validation.t index 92f810896a367..ba42136993a47 100644 --- a/t/plugin/request-validation.t +++ b/t/plugin/request-validation.t @@ -1817,3 +1817,59 @@ qr/object matches none of the required/ --- error_code: 400 --- no_error_log [error] + + + +=== TEST 51: add route for urlencoded post data validation +--- 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, + [[{ + "plugins": { + "request-validation": { + "body_schema": { + "type": "object", + "required": ["required_payload"], + "properties": { + "required_payload": {"type": "string"} + }, + "rejected_msg": "customize reject message" + } + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/echo" + }]]) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 52: test urlencoded post data +--- more_headers +Content-Type: application/x-www-form-urlencoded +--- request eval +"POST /echo +" . "a=b&" x 101 . "required_payload=101-hello" +--- response_body eval +qr/101-hello/ +--- no_error_log +[error] From 1c6b47354ac4bc4f04b21cb626eafaf0d875bafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BD=97=E6=B3=BD=E8=BD=A9?= Date: Tue, 22 Feb 2022 11:30:06 +0800 Subject: [PATCH 46/52] docs(cn): remove datadog from sidebar & fix doc lint conf (#6411) --- .github/workflows/doc-lint.yml | 1 + docs/zh/latest/config.json | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-lint.yml b/.github/workflows/doc-lint.yml index e37f7d4323653..43f604ffbab37 100644 --- a/.github/workflows/doc-lint.yml +++ b/.github/workflows/doc-lint.yml @@ -4,6 +4,7 @@ on: pull_request: branches: [master, 'release/**'] paths: + - 'docs/**' - '**/*.md' jobs: diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index 9c700f72d34d4..a74b92505f5bd 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -117,8 +117,7 @@ "label": "Metrics", "items": [ "plugins/prometheus", - "plugins/node-status", - "plugins/datadog" + "plugins/node-status" ] }, { From ecf08c6dd50c3ea3e7bf3c4723ada5e90bbeae13 Mon Sep 17 00:00:00 2001 From: Zeping Bai Date: Tue, 22 Feb 2022 12:00:20 +0800 Subject: [PATCH 47/52] docs: update public API relative usage (#6318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 琚致远 --- docs/en/latest/plugins/batch-requests.md | 36 ++++++++++++++++-------- docs/en/latest/plugins/jwt-auth.md | 14 +++++++++ docs/en/latest/plugins/node-status.md | 18 +++++++++++- docs/en/latest/plugins/wolf-rbac.md | 16 +++++++++++ docs/zh/latest/plugins/batch-requests.md | 36 ++++++++++++++++-------- docs/zh/latest/plugins/jwt-auth.md | 14 +++++++++ docs/zh/latest/plugins/node-status.md | 12 +++++++- docs/zh/latest/plugins/wolf-rbac.md | 16 +++++++++++ 8 files changed, 136 insertions(+), 26 deletions(-) diff --git a/docs/en/latest/plugins/batch-requests.md b/docs/en/latest/plugins/batch-requests.md index f397765aef5a5..81f0c4e18fb56 100644 --- a/docs/en/latest/plugins/batch-requests.md +++ b/docs/en/latest/plugins/batch-requests.md @@ -118,23 +118,35 @@ Response is `Array` of [HttpResponse](#httpresponse). ## How to specify custom uri -We can change the default uri in the `plugin_attr` section of `conf/config.yaml`. +We have the [public-api](public-api.md) plugin, customizing the uri becomes even easier. We just need to set the `uri` you want when creating the route and change the configuration of the `public-api` plugin. -| Name | Type | Requirement | Default | Description | -| ---------- | ------ |-------------| ---------------------------- | --------------------------------- | -| uri | string | optional | "/apisix/batch-requests" | uri to use with batch-requests plugin | - -Here is an example: - -```yaml -plugin_attr: - batch-requests: - uri: "/api-gw/batch" +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/br -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/batch-requests", + "plugins": { + "public-api": { + "uri": "/apisix/batch-requests" + } + } +}' ``` ## Test Plugin -You can pass your request detail to batch API( `/apisix/batch-requests` ), `apisix` can automatically complete requests via [http pipeline](https://en.wikipedia.org/wiki/HTTP_pipelining). Such as: +First you need to setup the route for the API that batch request, which will use the [public-api](public-api.md) plugin. + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/br -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/batch-requests", + "plugins": { + "public-api": {} + } +}' +``` + +Then, you can pass your request detail to batch API(`/apisix/batch-requests`), APISIX can automatically complete requests via [http pipeline](https://en.wikipedia.org/wiki/HTTP_pipelining). Such as: ```shell curl --location --request POST 'http://127.0.0.1:9080/apisix/batch-requests' \ diff --git a/docs/en/latest/plugins/jwt-auth.md b/docs/en/latest/plugins/jwt-auth.md index e23653e86ab53..cd5b826721979 100644 --- a/docs/en/latest/plugins/jwt-auth.md +++ b/docs/en/latest/plugins/jwt-auth.md @@ -196,6 +196,20 @@ then add jwt-auth plugin in the Consumer page: #### Get the Token in `jwt-auth` Plugin: +First, you need to set up the route for the API that signs the token, which will use the [public-api](public-api.md) plugin. + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/jas -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/plugin/jwt/sign", + "plugins": { + "public-api": {} + } +}' +``` + +Let's get a token. + * without extension payload: ```shell diff --git a/docs/en/latest/plugins/node-status.md b/docs/en/latest/plugins/node-status.md index d70f7389948ff..0636c2b800bc0 100644 --- a/docs/en/latest/plugins/node-status.md +++ b/docs/en/latest/plugins/node-status.md @@ -58,7 +58,17 @@ plugins: # plugin list ...... ``` -After starting `APISIX`, you can get status information through the API `/apisix/status`. +2. Setup the route for the status API, which will use the [public-api](public-api.md) plugin. + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/ns -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/status", + "plugins": { + "public-api": {} + } +}' +``` ## Test Plugin @@ -121,3 +131,9 @@ $ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f "plugins": {} }' ``` + +3. You can also remove the route on `/apisix/status`, no one can access the API. + +```sh +$ curl http://127.0.0.1:9080/apisix/admin/routes/ns -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X DELETE +``` diff --git a/docs/en/latest/plugins/wolf-rbac.md b/docs/en/latest/plugins/wolf-rbac.md index eef6e3afbe446..1b91a7836eaee 100644 --- a/docs/en/latest/plugins/wolf-rbac.md +++ b/docs/en/latest/plugins/wolf-rbac.md @@ -110,6 +110,22 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1 ## Test Plugin +#### Setup routes for public API + +Use the `public-api` plugin to expose the public API. + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/wal -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/plugin/wolf-rbac/login", + "plugins": { + "public-api": {} + } +}' +``` + +You also need to setup the `change_pwd` and `user_info` routes together. + #### Login and get `wolf-rbac` token: The following `appid`, `username`, and `password` must be real ones in the wolf system. diff --git a/docs/zh/latest/plugins/batch-requests.md b/docs/zh/latest/plugins/batch-requests.md index bfb9876ef53e3..13aa04b69a88c 100644 --- a/docs/zh/latest/plugins/batch-requests.md +++ b/docs/zh/latest/plugins/batch-requests.md @@ -122,23 +122,35 @@ curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/batch-requests -H 'X-API ## 如何修改自定义 uri -我们可以在 `conf/config.yaml` 的 `plugin_attr` 配置项中修改默认的 `uri` +我们可以使用 [public-api](../../../en/latest/plugins/public-api.md) 插件轻易的设置自定义 uri。只需要在创建路由时设置需要的 uri 并改变 `public-api` 插件的配置即可。 -| 名称 | 类型 | 必选项 | 默认值 | 描述 | -| --------- | ------ | ------ | ---------------------------- | -------------- | -| uri | string | 可选 |"/apisix/batch-requests" | `batch-requests` 插件的自定义 uri | - -配置示例: - -```yaml -plugin_attr: - batch-requests: - uri: "/api-gw/batch" +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/br -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/batch-requests", + "plugins": { + "public-api": { + "uri": "/apisix/batch-requests" + } + } +}' ``` ## 测试插件 -你可以将要访问的请求信息传到网关的批量请求接口( `/apisix/batch-requests` ),网关会以 [http pipeline](https://en.wikipedia.org/wiki/HTTP_pipelining) 的方式自动帮你完成请求。 +首先,你需要为 batch request 的 API 设置一个路由,它将使用 [public-api](../../../en/latest/plugins/public-api.md) 插件。 + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/br -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/batch-requests", + "plugins": { + "public-api": {} + } +}' +``` + +之后,你就可以将要访问的请求信息传到网关的批量请求接口( `/apisix/batch-requests` )了,网关会以 [http pipeline](https://en.wikipedia.org/wiki/HTTP_pipelining) 的方式自动帮你完成请求。 ```shell curl --location --request POST 'http://127.0.0.1:9080/apisix/batch-requests' \ diff --git a/docs/zh/latest/plugins/jwt-auth.md b/docs/zh/latest/plugins/jwt-auth.md index 2ee30151bf0b8..d3caff81543a3 100644 --- a/docs/zh/latest/plugins/jwt-auth.md +++ b/docs/zh/latest/plugins/jwt-auth.md @@ -123,6 +123,20 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f13 #### 首先进行登录获取 `jwt-auth` token: +首先,你需要为签发 token 的 API 设置一个路由,它将使用 [public-api](../../../en/latest/plugins/public-api.md) 插件。 + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/jas -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/plugin/jwt/sign", + "plugins": { + "public-api": {} + } +}' +``` + +之后,我们就可以调用它获取 token 了。 + * 没有额外的 payload: ```shell diff --git a/docs/zh/latest/plugins/node-status.md b/docs/zh/latest/plugins/node-status.md index 1901ac6b4de04..89782d0153cc1 100644 --- a/docs/zh/latest/plugins/node-status.md +++ b/docs/zh/latest/plugins/node-status.md @@ -56,7 +56,17 @@ plugins: # plugin list ...... ``` -启动 `APISIX` 之后,即可访问该插件提供的接口,获得基本的状态信息。 +2. 为状态 API 配置路由,它将使用 [public-api](../../../en/latest/plugins/public-api.md) 插件。 + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/ns -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/status", + "plugins": { + "public-api": {} + } +}' +``` ## 测试插件 diff --git a/docs/zh/latest/plugins/wolf-rbac.md b/docs/zh/latest/plugins/wolf-rbac.md index 58d07f8af18ab..4e1eededabc97 100644 --- a/docs/zh/latest/plugins/wolf-rbac.md +++ b/docs/zh/latest/plugins/wolf-rbac.md @@ -110,6 +110,22 @@ curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f1 ## 测试插件 +#### 为 API 设置路由 + +我们使用 [public-api](../../../en/latest/plugins/public-api.md) 插件来暴露这些 public API. + +```shell +$ curl http://127.0.0.1:9080/apisix/admin/routes/wal -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/apisix/plugin/wolf-rbac/login", + "plugins": { + "public-api": {} + } +}' +``` + +你也需要为 `change_pwd` 和 `user_info` 两个 API 配置路由。 + #### 首先进行登录获取 `wolf-rbac` token: 下面的 `appid`, `username`, `password` 必须为 wolf 系统中真实存在的. From 462413551e2eca0ed1ced54742d3c961b9dc5f06 Mon Sep 17 00:00:00 2001 From: Gaoll Date: Tue, 22 Feb 2022 14:14:37 +0800 Subject: [PATCH 48/52] docs: add zh proxy-control.md&modify other doc error (#6346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 高亮亮 --- docs/zh/latest/architecture-design/route.md | 2 +- docs/zh/latest/config.json | 1 + docs/zh/latest/plugins/proxy-control.md | 93 +++++++++++++++++++++ docs/zh/latest/plugins/traffic-split.md | 2 +- 4 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 docs/zh/latest/plugins/proxy-control.md diff --git a/docs/zh/latest/architecture-design/route.md b/docs/zh/latest/architecture-design/route.md index 86264f87954d8..161fc0bb92f0d 100644 --- a/docs/zh/latest/architecture-design/route.md +++ b/docs/zh/latest/architecture-design/route.md @@ -23,7 +23,7 @@ title: Route Route 字面意思就是路由,通过定义一些规则来匹配客户端的请求,然后根据匹配结果加载并执行相应的插件,并把请求转发给到指定 Upstream。 -Route 中主要包含三部分内容:匹配规则(比如 uri、host、remote_addr 等),插件配(限流限速等)和上游信息。 +Route 中主要包含三部分内容:匹配规则(比如 uri、host、remote_addr 等),插件配置(限流限速等)和上游信息。 请看下图示例,是一些 Route 规则的实例,当某些属性值相同时,图中用相同颜色标识。 ![路由示例](../../../assets/images/routes-example.png) diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index a74b92505f5bd..cf5a3a154618a 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -96,6 +96,7 @@ "plugins/api-breaker", "plugins/traffic-split", "plugins/request-id", + "plugins/proxy-control", "plugins/client-control" ] }, diff --git a/docs/zh/latest/plugins/proxy-control.md b/docs/zh/latest/plugins/proxy-control.md new file mode 100644 index 0000000000000..454e5f2c7aa5d --- /dev/null +++ b/docs/zh/latest/plugins/proxy-control.md @@ -0,0 +1,93 @@ +--- +title: proxy-control +--- + + + +## 目录 + +- [**名称**](#名称) +- [**属性**](#属性) +- [**如何启用**](#如何启用) +- [**测试插件**](#测试插件) +- [**禁用插件**](#禁用插件) + +## 名称 + +`proxy-control` 能够动态地控制 Nginx 代理的行为。 + +**这个插件需要APISIX在 [APISIX-OpenResty](../how-to-build.md#步骤6:为-Apache-APISIX-构建-OpenResty)上运行。** + +## 属性 + +| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | +| --------- | ------------- | ----------- | ---------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| request_buffering | boolean | 可选 | true | | 动态设置 [`proxy_request_buffering`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering) | + +## 如何启用 + +以下是一个示例,在指定路由中启用插件: + +```shell +curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/upload", + "plugins": { + "proxy-control": { + "request_buffering": false + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } +}' +``` + +## 测试插件 + +使用 `curl` 去测试: + +```shell +curl -i http://127.0.0.1:9080/upload -d @very_big_file +``` + +将不会在 error 日志中找到 "a client request body is buffered to a temporary file" 。 + +## 禁用插件 + +当您要禁用这个插件时,这很简单,您可以在插件配置中删除相应的 json 配置,无需重新启动服务,它将立即生效: + +```shell +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/upload", + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } +}' +``` + +现在就已经移除 `proxy-control` 插件了。其他插件的开启和移除也是同样的方法。 diff --git a/docs/zh/latest/plugins/traffic-split.md b/docs/zh/latest/plugins/traffic-split.md index 8a8ee6593ba2e..59d4f0729c8b2 100644 --- a/docs/zh/latest/plugins/traffic-split.md +++ b/docs/zh/latest/plugins/traffic-split.md @@ -224,7 +224,7 @@ world 1981 ### 蓝绿发布 -通过请求头获取 `match` 规则参数(也可以通过请求参数获取或NGINX变量),在 `match` 规则匹配通过后,表示所有请求都命中到插件配置的 upstream ,否则所以请求只命中 `route` 上配置的 upstream 。 +通过请求头获取 `match` 规则参数(也可以通过请求参数获取 NGINX 变量),在 `match` 规则匹配通过后,表示所有请求都命中到插件配置的 upstream ,否则所有请求只命中 `route` 上配置的 upstream 。 ```shell curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' From 4ec0d6b01510e96bb8139eb654799f902047ece0 Mon Sep 17 00:00:00 2001 From: mango <35127166+mangoGoForward@users.noreply.github.com> Date: Wed, 23 Feb 2022 09:08:29 +0800 Subject: [PATCH 49/52] docs: translate Chinese to English in en clickhouse-logger (#6416) --- docs/en/latest/plugins/clickhouse-logger.md | 26 ++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/en/latest/plugins/clickhouse-logger.md b/docs/en/latest/plugins/clickhouse-logger.md index 4bec548b97668..590da9d5d8f06 100644 --- a/docs/en/latest/plugins/clickhouse-logger.md +++ b/docs/en/latest/plugins/clickhouse-logger.md @@ -36,19 +36,19 @@ title: clickhouse-logger ## Attributes -| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | -| ---------------- | ------- | ------ | ------------- | ------- | ------------------------------------------------ | -| endpoint_addr | string | required | | | The `clickhouse` endpoint. | -| database | string | required | | | The DB name to store log. | -| logtable | string | required | | | The table name. | -| user | string | required | | | clickhouse user. | -| password | string | required | | | clickhouse password. | -| timeout | integer | optional | 3 | [1,...] | Time to keep the connection alive after sending a request. | -| name | string | optional | "clickhouse logger" | | A unique identifier to identity the logger. | -| batch_max_size | integer | optional | 100 | [1,...] | Set the maximum number of logs sent in each batch. When the number of logs reaches the set maximum, all logs will be automatically pushed to the clickhouse. | -| max_retry_count | integer | optional | 0 | [0,...] | Maximum number of retries before removing from the processing pipe line. | -| retry_delay | integer | optional | 1 | [0,...] | Number of seconds the process execution should be delayed if the execution fails. | -| ssl_verify | boolean | optional | true | [true,false] | verify ssl. | +| Name | Type | Requirement | Default | Valid | Description | +|-----------------|---------| ------ | ------------- | ------- | ------------------------------------------------ | +| endpoint_addr | string | required | | | The `clickhouse` endpoint. | +| database | string | required | | | The DB name to store log. | +| logtable | string | required | | | The table name. | +| user | string | required | | | clickhouse user. | +| password | string | required | | | clickhouse password. | +| timeout | integer | optional | 3 | [1,...] | Time to keep the connection alive after sending a request. | +| name | string | optional | "clickhouse logger" | | A unique identifier to identity the logger. | +| batch_max_size | integer | optional | 100 | [1,...] | Set the maximum number of logs sent in each batch. When the number of logs reaches the set maximum, all logs will be automatically pushed to the clickhouse. | +| max_retry_count | integer | optional | 0 | [0,...] | Maximum number of retries before removing from the processing pipe line. | +| retry_delay | integer | optional | 1 | [0,...] | Number of seconds the process execution should be delayed if the execution fails. | +| ssl_verify | boolean | optional | true | [true,false] | verify ssl. | ## How To Enable From 28087e0516891bff2f6b09fbe8c527c08d9ef7b8 Mon Sep 17 00:00:00 2001 From: leslie <59061168+leslie-tsang@users.noreply.github.com> Date: Wed, 23 Feb 2022 09:08:59 +0800 Subject: [PATCH 50/52] fix(deps): upgrade jsonschema to 0.9.8 (#6407) --- rockspec/apisix-master-0.rockspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rockspec/apisix-master-0.rockspec b/rockspec/apisix-master-0.rockspec index 1d654d7cfb238..2319eada38994 100644 --- a/rockspec/apisix-master-0.rockspec +++ b/rockspec/apisix-master-0.rockspec @@ -51,7 +51,7 @@ dependencies = { "luafilesystem = 1.7.0-2", "api7-lua-tinyyaml = 0.4.2", "nginx-lua-prometheus = 0.20220127", - "jsonschema = 0.9.7", + "jsonschema = 0.9.8", "lua-resty-ipmatcher = 0.6.1", "lua-resty-kafka = 0.07", "lua-resty-logger-socket = 2.0-0", From 8579a02a702df3d432bf7d51bda7c3edf1fe6a36 Mon Sep 17 00:00:00 2001 From: Gaoll Date: Wed, 23 Feb 2022 09:47:12 +0800 Subject: [PATCH 51/52] docs: fix For L7 proxy -> For L4 proxy (#6423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 高亮亮 --- docs/en/latest/admin-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/latest/admin-api.md b/docs/en/latest/admin-api.md index 017cbc32c49f3..32537d4852a03 100644 --- a/docs/en/latest/admin-api.md +++ b/docs/en/latest/admin-api.md @@ -554,7 +554,7 @@ In addition to the basic complex equalization algorithm selection, APISIX's Upst |desc |optional|upstream usage scenarios, and more.|| |pass_host |optional| `host` option when the request is sent to the upstream, can be one of [`pass`, `node`, `rewrite`], the default option is `pass`. `pass`: Pass the client's host transparently to the upstream; `node`: Use the host configured in the node of `upstream`; `rewrite`: Use the value of the configuration `upstream_host`.|| |upstream_host |optional|Specify the host of the upstream request. This option is only valid if the `pass_host` is `rewrite`.|| -|scheme |optional |The scheme used when talk with the upstream. For L7 proxy, the value is one of ['http', 'https', 'grpc', 'grpcs']. For L7 proxy, the value is one of ['tcp', 'udp', 'tls']. Default to 'http'. See below for more details.|| +|scheme |optional |The scheme used when talk with the upstream. For L7 proxy, the value is one of ['http', 'https', 'grpc', 'grpcs']. For L4 proxy, the value is one of ['tcp', 'udp', 'tls']. Default to 'http'. See below for more details.|| |labels |optional |Key/value pairs to specify attributes|{"version":"v2","build":"16","env":"production"}| |create_time |optional| epoch timestamp in second, like `1602883670`, will be created automatically if missing|1602883670| |update_time |optional| epoch timestamp in second, like `1602883670`, will be created automatically if missing|1602883670| From f7b50f28bae7ca6ed373fe7c1ea07e658a6bee3f Mon Sep 17 00:00:00 2001 From: zhixiongdu Date: Wed, 23 Feb 2022 10:26:54 +0800 Subject: [PATCH 52/52] feat: add kubernetes discovery module (#4880) Co-authored-by: zhixiogndu Co-authored-by: zhixiongdu --- .github/workflows/kubernetes-ci.yml | 90 +++ Makefile | 3 +- .../discovery/kubernetes/informer_factory.lua | 376 +++++++++ apisix/discovery/kubernetes/init.lua | 386 ++++++++++ apisix/discovery/kubernetes/schema.lua | 140 ++++ ci/kubernetes-ci.sh | 33 + docs/zh/latest/config.json | 3 +- docs/zh/latest/discovery/kubernetes.md | 120 +++ t_kubernetes/configs/account.yaml | 44 ++ t_kubernetes/configs/endpoint.yaml | 58 ++ t_kubernetes/configs/kind.yaml | 22 + t_kubernetes/discovery/kubernetes.t | 714 ++++++++++++++++++ 12 files changed, 1987 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/kubernetes-ci.yml create mode 100644 apisix/discovery/kubernetes/informer_factory.lua create mode 100644 apisix/discovery/kubernetes/init.lua create mode 100644 apisix/discovery/kubernetes/schema.lua create mode 100755 ci/kubernetes-ci.sh create mode 100644 docs/zh/latest/discovery/kubernetes.md create mode 100644 t_kubernetes/configs/account.yaml create mode 100644 t_kubernetes/configs/endpoint.yaml create mode 100644 t_kubernetes/configs/kind.yaml create mode 100644 t_kubernetes/discovery/kubernetes.t diff --git a/.github/workflows/kubernetes-ci.yml b/.github/workflows/kubernetes-ci.yml new file mode 100644 index 0000000000000..b622d34fef3be --- /dev/null +++ b/.github/workflows/kubernetes-ci.yml @@ -0,0 +1,90 @@ +name: CI Kubernetes + +on: + push: + branches: [ master, 'release/**' ] + paths-ignore: + - 'docs/**' + - '**/*.md' + pull_request: + branches: [ master, 'release/**' ] + paths-ignore: + - 'docs/**' + - '**/*.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_number || github.ref }} + cancel-in-progress: true + +jobs: + kubernetes-discovery: + strategy: + fail-fast: false + matrix: + platform: + - ubuntu-18.04 + os_name: + - linux_openresty + - linux_openresty_1_17 + + runs-on: ${{ matrix.platform }} + timeout-minutes: 15 + env: + SERVER_NAME: ${{ matrix.os_name }} + OPENRESTY_VERSION: default + + steps: + - name: Check out code + uses: actions/checkout@v2.4.0 + with: + submodules: recursive + + - name: Extract branch name + if: ${{ startsWith(github.ref, 'refs/heads/release/') }} + id: branch_env + shell: bash + run: | + echo "##[set-output name=version;]$(echo ${GITHUB_REF##*/})" + + - name: Setup kubernetes cluster + run: | + KIND_VERSION="v0.11.1" + KUBECTL_VERSION="v1.22.0" + curl -Lo ./kind "https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-$(uname)-amd64" + curl -Lo ./kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" + chmod +x ./kind + chmod +x ./kubectl + + ./kind create cluster --name apisix-test --config ./t_kubernetes/configs/kind.yaml + + ./kubectl wait --for=condition=Ready nodes --all --timeout=180s + + ./kubectl apply -f ./t_kubernetes/configs/account.yaml + + ./kubectl apply -f ./t_kubernetes/configs/endpoint.yaml + + KUBERNETES_CLIENT_TOKEN_CONTENT=$(./kubectl get secrets | grep apisix-test | awk '{system("./kubectl get secret -o jsonpath={.data.token} "$1" | base64 --decode")}') + + KUBERNETES_CLIENT_TOKEN_DIR="/tmp/var/run/secrets/kubernetes.io/serviceaccount" + + KUBERNETES_CLIENT_TOKEN_FILE=${KUBERNETES_CLIENT_TOKEN_DIR}/token + + mkdir -p ${KUBERNETES_CLIENT_TOKEN_DIR} + echo -n "$KUBERNETES_CLIENT_TOKEN_CONTENT" > ${KUBERNETES_CLIENT_TOKEN_FILE} + + echo 'KUBERNETES_SERVICE_HOST=127.0.0.1' + echo 'KUBERNETES_SERVICE_PORT=6443' + echo 'KUBERNETES_CLIENT_TOKEN='"${KUBERNETES_CLIENT_TOKEN_CONTENT}" + echo 'KUBERNETES_CLIENT_TOKEN_FILE='${KUBERNETES_CLIENT_TOKEN_FILE} + + ./kubectl proxy -p 6445 & + + - name: Linux Install + run: | + sudo apt install -y cpanminus build-essential libncurses5-dev libreadline-dev libssl-dev perl libpcre3 libpcre3-dev libldap2-dev + sudo cpanm --notest Test::Nginx >build.log 2>&1 || (cat build.log && exit 1) + sudo --preserve-env=OPENRESTY_VERSION ./ci/${{ matrix.os_name }}_runner.sh do_install + + - name: Run test cases + run: | + ./ci/kubernetes-ci.sh run_case diff --git a/Makefile b/Makefile index e37c80114b3b1..f7546bfbe03f5 100644 --- a/Makefile +++ b/Makefile @@ -284,11 +284,12 @@ install: runtime $(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/discovery $(ENV_INSTALL) apisix/discovery/*.lua $(ENV_INST_LUADIR)/apisix/discovery/ - $(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/discovery/{consul_kv,dns,eureka,nacos} + $(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/discovery/{consul_kv,dns,eureka,nacos,kubernetes} $(ENV_INSTALL) apisix/discovery/consul_kv/*.lua $(ENV_INST_LUADIR)/apisix/discovery/consul_kv $(ENV_INSTALL) apisix/discovery/dns/*.lua $(ENV_INST_LUADIR)/apisix/discovery/dns $(ENV_INSTALL) apisix/discovery/eureka/*.lua $(ENV_INST_LUADIR)/apisix/discovery/eureka $(ENV_INSTALL) apisix/discovery/nacos/*.lua $(ENV_INST_LUADIR)/apisix/discovery/nacos + $(ENV_INSTALL) apisix/discovery/kubernetes/*.lua $(ENV_INST_LUADIR)/apisix/discovery/kubernetes $(ENV_INSTALL) -d $(ENV_INST_LUADIR)/apisix/http $(ENV_INSTALL) apisix/http/*.lua $(ENV_INST_LUADIR)/apisix/http/ diff --git a/apisix/discovery/kubernetes/informer_factory.lua b/apisix/discovery/kubernetes/informer_factory.lua new file mode 100644 index 0000000000000..8b50fc338d8df --- /dev/null +++ b/apisix/discovery/kubernetes/informer_factory.lua @@ -0,0 +1,376 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +local ngx = ngx +local ipairs = ipairs +local string = string +local math = math +local type = type +local core = require("apisix.core") +local http = require("resty.http") + +local empty_table = {} + +local function list_query(informer) + local arguments = { + limit = informer.limit, + } + + if informer.continue and informer.continue ~= "" then + arguments.continue = informer.continue + end + + if informer.label_selector and informer.label_selector ~= "" then + arguments.labelSelector = informer.label_selector + end + + if informer.field_selector and informer.field_selector ~= "" then + arguments.fieldSelector = informer.field_selector + end + + return ngx.encode_args(arguments) +end + + +local function list(httpc, apiserver, informer) + local response, err = httpc:request({ + path = informer.path, + query = list_query(informer), + headers = { + ["Host"] = apiserver.host .. ":" .. apiserver.port, + ["Authorization"] = "Bearer " .. apiserver.token, + ["Accept"] = "application/json", + ["Connection"] = "keep-alive" + } + }) + + core.log.info("--raw=", informer.path, "?", list_query(informer)) + + if not response then + return false, "RequestError", err or "" + end + + if response.status ~= 200 then + return false, response.reason, response:read_body() or "" + end + + local body, err = response:read_body() + if err then + return false, "ReadBodyError", err + end + + local data = core.json.decode(body) + if not data or data.kind ~= informer.list_kind then + return false, "UnexpectedBody", body + end + + informer.version = data.metadata.resourceVersion + + if informer.on_added then + for _, item in ipairs(data.items or empty_table) do + informer:on_added(item, "list") + end + end + + informer.continue = data.metadata.continue + if informer.continue and informer.continue ~= "" then + list(httpc, apiserver, informer) + end + + return true +end + + +local function watch_query(informer) + local arguments = { + watch = "true", + allowWatchBookmarks = "true", + timeoutSeconds = informer.overtime, + } + + if informer.version and informer.version ~= "" then + arguments.resourceVersion = informer.version + end + + if informer.label_selector and informer.label_selector ~= "" then + arguments.labelSelector = informer.label_selector + end + + if informer.field_selector and informer.field_selector ~= "" then + arguments.fieldSelector = informer.field_selector + end + + return ngx.encode_args(arguments) +end + + +local function split_event (body, callback, ...) + local gmatch_iterator, err = ngx.re.gmatch(body, "{\"type\":.*}\n", "jao") + if not gmatch_iterator then + return false, nil, "GmatchError", err + end + + local captures + local captured_size = 0 + local ok, reason + while true do + captures, err = gmatch_iterator() + + if err then + return false, nil, "GmatchError", err + end + + if not captures then + break + end + + captured_size = captured_size + #captures[0] + + ok, reason, err = callback(captures[0], ...) + if not ok then + return false, nil, reason, err + end + end + + local remainder_body + if captured_size == #body then + remainder_body = "" + elseif captured_size == 0 then + remainder_body = body + elseif captured_size < #body then + remainder_body = string.sub(body, captured_size + 1) + end + + return true, remainder_body +end + + +local function dispatch_event(event_string, informer) + local event = core.json.decode(event_string) + + if not event or not event.type or not event.object then + return false, "UnexpectedBody", event_string + end + + local tp = event.type + + if tp == "ERROR" then + if event.object.code == 410 then + return false, "ResourceGone", nil + end + return false, "UnexpectedBody", event_string + end + + local object = event.object + informer.version = object.metadata.resourceVersion + + if tp == "ADDED" then + if informer.on_added then + informer:on_added(object, "watch") + end + elseif tp == "DELETED" then + if informer.on_deleted then + informer:on_deleted(object) + end + elseif tp == "MODIFIED" then + if informer.on_modified then + informer:on_modified(object) + end + -- elseif type == "BOOKMARK" then + -- do nothing + end + + return true +end + + +local function watch(httpc, apiserver, informer) + local watch_times = 8 + for _ = 1, watch_times do + local watch_seconds = 1800 + math.random(9, 999) + informer.overtime = watch_seconds + local http_seconds = watch_seconds + 120 + httpc:set_timeouts(2000, 3000, http_seconds * 1000) + + local response, err = httpc:request({ + path = informer.path, + query = watch_query(informer), + headers = { + ["Host"] = apiserver.host .. ":" .. apiserver.port, + ["Authorization"] = "Bearer " .. apiserver.token, + ["Accept"] = "application/json", + ["Connection"] = "keep-alive" + } + }) + + core.log.info("--raw=", informer.path, "?", watch_query(informer)) + + if err then + return false, "RequestError", err + end + + if response.status ~= 200 then + return false, response.reason, response:read_body() or "" + end + + local ok + local remainder_body + local body + local reason + + while true do + body, err = response.body_reader() + if err then + return false, "ReadBodyError", err + end + + if not body then + break + end + + if remainder_body and #remainder_body > 0 then + body = remainder_body .. body + end + + ok, remainder_body, reason, err = split_event(body, dispatch_event, informer) + if not ok then + if reason == "ResourceGone" then + return true + end + return false, reason, err + end + end + end + + return true +end + + +local function list_watch(informer, apiserver) + local ok + local reason, message + local httpc = http.new() + + informer.fetch_state = "connecting" + core.log.info("begin to connect ", apiserver.host, ":", apiserver.port) + + ok, message = httpc:connect({ + scheme = apiserver.schema, + host = apiserver.host, + port = apiserver.port, + ssl_verify = false + }) + + if not ok then + informer.fetch_state = "connect failed" + core.log.error("connect apiserver failed, apiserver.host: ", apiserver.host, + ", apiserver.port: ", apiserver.port, ", message : ", message) + return false + end + + core.log.info("begin to list ", informer.kind) + informer.fetch_state = "listing" + if informer.pre_List then + informer:pre_list() + end + + ok, reason, message = list(httpc, apiserver, informer) + if not ok then + informer.fetch_state = "list failed" + core.log.error("list failed, kind: ", informer.kind, + ", reason: ", reason, ", message : ", message) + return false + end + + informer.fetch_state = "list finished" + if informer.post_List then + informer:post_list() + end + + core.log.info("begin to watch ", informer.kind) + informer.fetch_state = "watching" + ok, reason, message = watch(httpc, apiserver, informer) + if not ok then + informer.fetch_state = "watch failed" + core.log.error("watch failed, kind: ", informer.kind, + ", reason: ", reason, ", message : ", message) + return false + end + + informer.fetch_state = "watch finished" + + return true +end + +local _M = { +} + +function _M.new(group, version, kind, plural, namespace) + local tp + tp = type(group) + if tp ~= "nil" and tp ~= "string" then + return nil, "group should set to string or nil type but " .. tp + end + + tp = type(namespace) + if tp ~= "nil" and tp ~= "string" then + return nil, "namespace should set to string or nil type but " .. tp + end + + tp = type(version) + if tp ~= "string" or version == "" then + return nil, "version should set to non-empty string" + end + + tp = type(kind) + if tp ~= "string" or kind == "" then + return nil, "kind should set to non-empty string" + end + + tp = type(plural) + if tp ~= "string" or plural == "" then + return nil, "plural should set to non-empty string" + end + + local path = "" + if group == nil or group == "" then + path = path .. "/api/" .. version + else + path = path .. "/apis/" .. group .. "/" .. version + end + + if namespace and namespace ~= "" then + path = path .. "/namespace/" .. namespace + end + path = path .. "/" .. plural + + return { + kind = kind, + list_kind = kind .. "List", + plural = plural, + path = path, + limit = 120, + label_selector = "", + field_selector = "", + overtime = "1800", + version = "", + continue = "", + list_watch = list_watch + } +end + +return _M diff --git a/apisix/discovery/kubernetes/init.lua b/apisix/discovery/kubernetes/init.lua new file mode 100644 index 0000000000000..ba83588a79d13 --- /dev/null +++ b/apisix/discovery/kubernetes/init.lua @@ -0,0 +1,386 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +local ngx = ngx +local ipairs = ipairs +local pairs = pairs +local string = string +local tonumber = tonumber +local tostring = tostring +local os = os +local error = error +local pcall = pcall +local process = require("ngx.process") +local core = require("apisix.core") +local util = require("apisix.cli.util") +local local_conf = require("apisix.core.config_local").local_conf() +local informer_factory = require("apisix.discovery.kubernetes.informer_factory") + +local endpoint_dict +local default_weight + +local endpoint_lrucache = core.lrucache.new({ + ttl = 300, + count = 1024 +}) + +local endpoint_buffer = {} +local empty_table = {} + +local function sort_nodes_cmp(left, right) + if left.host ~= right.host then + return left.host < right.host + end + + return left.port < right.port +end + + +local function on_endpoint_modified(informer, endpoint) + if informer.namespace_selector and + not informer:namespace_selector(endpoint.metadata.namespace) then + return + end + + core.log.debug(core.json.delay_encode(endpoint)) + core.table.clear(endpoint_buffer) + + local subsets = endpoint.subsets + for _, subset in ipairs(subsets or empty_table) do + if subset.addresses then + local addresses = subset.addresses + for _, port in ipairs(subset.ports or empty_table) do + local port_name + if port.name then + port_name = port.name + elseif port.targetPort then + port_name = tostring(port.targetPort) + else + port_name = tostring(port.port) + end + + local nodes = endpoint_buffer[port_name] + if nodes == nil then + nodes = core.table.new(0, #subsets * #addresses) + endpoint_buffer[port_name] = nodes + end + + for _, address in ipairs(subset.addresses) do + core.table.insert(nodes, { + host = address.ip, + port = port.port, + weight = default_weight + }) + end + end + end + end + + for _, ports in pairs(endpoint_buffer) do + for _, nodes in pairs(ports) do + core.table.sort(nodes, sort_nodes_cmp) + end + end + + local endpoint_key = endpoint.metadata.namespace .. "/" .. endpoint.metadata.name + local endpoint_content = core.json.encode(endpoint_buffer, true) + local endpoint_version = ngx.crc32_long(endpoint_content) + + local _, err + _, err = endpoint_dict:safe_set(endpoint_key .. "#version", endpoint_version) + if err then + core.log.error("set endpoint version into discovery DICT failed, ", err) + return + end + _, err = endpoint_dict:safe_set(endpoint_key, endpoint_content) + if err then + core.log.error("set endpoint into discovery DICT failed, ", err) + endpoint_dict:delete(endpoint_key .. "#version") + end +end + + +local function on_endpoint_deleted(informer, endpoint) + if informer.namespace_selector and + not informer:namespace_selector(endpoint.metadata.namespace) then + return + end + + core.log.debug(core.json.delay_encode(endpoint)) + local endpoint_key = endpoint.metadata.namespace .. "/" .. endpoint.metadata.name + endpoint_dict:delete(endpoint_key .. "#version") + endpoint_dict:delete(endpoint_key) +end + + +local function pre_list(informer) + endpoint_dict:flush_all() +end + + +local function post_list(informer) + endpoint_dict:flush_expired() +end + + +local function setup_label_selector(conf, informer) + informer.label_selector = conf.label_selector +end + + +local function setup_namespace_selector(conf, informer) + local ns = conf.namespace_selector + if ns == nil then + informer.namespace_selector = nil + return + end + + if ns.equal then + informer.field_selector = "metadata.namespace=" .. ns.equal + informer.namespace_selector = nil + return + end + + if ns.not_equal then + informer.field_selector = "metadata.namespace!=" .. ns.not_equal + informer.namespace_selector = nil + return + end + + if ns.match then + informer.namespace_selector = function(self, namespace) + local match = conf.namespace_selector.match + local m, err + for _, v in ipairs(match) do + m, err = ngx.re.match(namespace, v, "j") + if m and m[0] == namespace then + return true + end + if err then + core.log.error("ngx.re.match failed: ", err) + end + end + return false + end + return + end + + if ns.not_match then + informer.namespace_selector = function(self, namespace) + local not_match = conf.namespace_selector.not_match + local m, err + for _, v in ipairs(not_match) do + m, err = ngx.re.match(namespace, v, "j") + if m and m[0] == namespace then + return false + end + if err then + return false + end + end + return true + end + return + end +end + + +local function read_env(key) + if #key > 3 then + local a, b = string.byte(key, 1, 2) + local c = string.byte(key, #key, #key) + -- '$', '{', '}' == 36,123,125 + if a == 36 and b == 123 and c == 125 then + local env = string.sub(key, 3, #key - 1) + local value = os.getenv(env) + if not value then + return nil, "not found environment variable " .. env + end + return value, nil + end + end + + return key +end + + +local function get_apiserver(conf) + local apiserver = { + schema = "", + host = "", + port = "", + token = "" + } + + apiserver.schema = conf.service.schema + if apiserver.schema ~= "http" and apiserver.schema ~= "https" then + return nil, "service.schema should set to one of [http,https] but " .. apiserver.schema + end + + local err + apiserver.host, err = read_env(conf.service.host) + if err then + return nil, err + end + + if apiserver.host == "" then + return nil, "service.host should set to non-empty string" + end + + local port + port, err = read_env(conf.service.port) + if err then + return nil, err + end + + apiserver.port = tonumber(port) + if not apiserver.port or apiserver.port <= 0 or apiserver.port > 65535 then + return nil, "invalid port value: " .. apiserver.port + end + + if conf.client.token then + apiserver.token, err = read_env(conf.client.token) + if err then + return nil, err + end + elseif conf.client.token_file and conf.client.token_file ~= "" then + local file + file, err = read_env(conf.client.token_file) + if err then + return nil, err + end + + apiserver.token, err = util.read_file(file) + if err then + return nil, err + end + else + return nil, "one of [client.token,client.token_file] should be set but none" + end + + if apiserver.schema == "https" and apiserver.token == "" then + return nil, "apiserver.token should set to non-empty string when service.schema is https" + end + + return apiserver +end + + +local function create_endpoint_lrucache(endpoint_key, endpoint_port) + local endpoint_content = endpoint_dict:get_stale(endpoint_key) + if not endpoint_content then + core.log.error("get empty endpoint content from discovery DIC, this should not happen ", + endpoint_key) + return nil + end + + local endpoint = core.json.decode(endpoint_content) + if not endpoint then + core.log.error("decode endpoint content failed, this should not happen, content: ", + endpoint_content) + return nil + end + + return endpoint[endpoint_port] +end + +local _M = { + version = "0.0.1" +} + +function _M.nodes(service_name) + local pattern = "^(.*):(.*)$" -- namespace/name:port_name + local match = ngx.re.match(service_name, pattern, "jo") + if not match then + core.log.info("get unexpected upstream service_name: ", service_name) + return nil + end + + local endpoint_key = match[1] + local endpoint_port = match[2] + local endpoint_version = endpoint_dict:get_stale(endpoint_key .. "#version") + if not endpoint_version then + core.log.info("get empty endpoint version from discovery DICT ", endpoint_key) + return nil + end + + return endpoint_lrucache(service_name, endpoint_version, + create_endpoint_lrucache, endpoint_key, endpoint_port) +end + + +function _M.init_worker() + -- TODO: maybe we can read dict name from discovery config + endpoint_dict = ngx.shared.discovery + if not endpoint_dict then + error("failed to get nginx shared dict: discovery, please check your APISIX version") + end + + if process.type() ~= "privileged agent" then + return + end + + local discovery_conf = local_conf.discovery.kubernetes + + default_weight = discovery_conf.default_weight or 50 + + local apiserver, err = get_apiserver(discovery_conf) + if err then + error(err) + return + end + + local endpoints_informer, err = informer_factory.new("", "v1", + "Endpoints", "endpoints", "") + if err then + error(err) + return + end + + setup_namespace_selector(discovery_conf, endpoints_informer) + setup_label_selector(discovery_conf, endpoints_informer) + + endpoints_informer.on_added = on_endpoint_modified + endpoints_informer.on_modified = on_endpoint_modified + endpoints_informer.on_deleted = on_endpoint_deleted + endpoints_informer.pre_list = pre_list + endpoints_informer.post_list = post_list + + local timer_runner + timer_runner = function(premature) + if premature then + return + end + + local ok, status = pcall(endpoints_informer.list_watch, endpoints_informer, apiserver) + + local retry_interval = 0 + if not ok then + core.log.error("list_watch failed, kind: ", endpoints_informer.kind, + ", reason: ", "RuntimeException", ", message : ", status) + retry_interval = 40 + elseif not status then + retry_interval = 40 + end + + ngx.timer.at(retry_interval, timer_runner) + end + + ngx.timer.at(0, timer_runner) +end + +return _M diff --git a/apisix/discovery/kubernetes/schema.lua b/apisix/discovery/kubernetes/schema.lua new file mode 100644 index 0000000000000..4888de63c4849 --- /dev/null +++ b/apisix/discovery/kubernetes/schema.lua @@ -0,0 +1,140 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +local host_patterns = { + { pattern = [[^\${[_A-Za-z]([_A-Za-z0-9]*[_A-Za-z])*}$]] }, + { pattern = [[^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$]] }, +} + +local port_patterns = { + { pattern = [[^\${[_A-Za-z]([_A-Za-z0-9]*[_A-Za-z])*}$]] }, + { pattern = [[^(([1-9]\d{0,3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5]))$]] }, +} + +local namespace_pattern = [[^[a-z0-9]([-a-z0-9_.]*[a-z0-9])?$]] +local namespace_regex_pattern = [[^[\x21-\x7e]*$]] + +return { + type = "object", + properties = { + service = { + type = "object", + properties = { + schema = { + type = "string", + enum = { "http", "https" }, + default = "https", + }, + host = { + type = "string", + default = "${KUBERNETES_SERVICE_HOST}", + oneOf = host_patterns, + }, + port = { + type = "string", + default = "${KUBERNETES_SERVICE_PORT}", + oneOf = port_patterns, + }, + }, + default = { + schema = "https", + host = "${KUBERNETES_SERVICE_HOST}", + port = "${KUBERNETES_SERVICE_PORT}", + } + }, + client = { + type = "object", + properties = { + token = { + type = "string", + oneOf = { + { pattern = [[\${[_A-Za-z]([_A-Za-z0-9]*[_A-Za-z])*}$]] }, + { pattern = [[^[A-Za-z0-9+\/._=-]{0,4096}$]] }, + }, + }, + token_file = { + type = "string", + pattern = [[^[^\:*?"<>|]*$]], + minLength = 1, + maxLength = 500, + } + }, + oneOf = { + { required = { "token" } }, + { required = { "token_file" } }, + }, + default = { + token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token" + } + }, + default_weight = { + type = "integer", + default = 50, + minimum = 0, + }, + namespace_selector = { + type = "object", + properties = { + equal = { + type = "string", + pattern = namespace_pattern, + }, + not_equal = { + type = "string", + pattern = namespace_pattern, + }, + match = { + type = "array", + items = { + type = "string", + pattern = namespace_regex_pattern + }, + minItems = 1 + }, + not_match = { + type = "array", + items = { + type = "string", + pattern = namespace_regex_pattern + }, + minItems = 1 + }, + }, + oneOf = { + { required = { } }, + { required = { "equal" } }, + { required = { "not_equal" } }, + { required = { "match" } }, + { required = { "not_match" } } + }, + }, + label_selector = { + type = "string", + } + }, + default = { + service = { + schema = "https", + host = "${KUBERNETES_SERVICE_HOST}", + port = "${KUBERNETES_SERVICE_PORT}", + }, + client = { + token_file = "/var/run/secrets/kubernetes.io/serviceaccount/token" + }, + default_weight = 50 + } +} diff --git a/ci/kubernetes-ci.sh b/ci/kubernetes-ci.sh new file mode 100755 index 0000000000000..839929ba68f98 --- /dev/null +++ b/ci/kubernetes-ci.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +. ./ci/common.sh + +run_case() { + export_or_prefix + export PERL5LIB=.:$PERL5LIB + prove -Itest-nginx/lib -I./ -r t_kubernetes | tee test-result + rerun_flaky_tests test-result +} + +case_opt=$1 +case $case_opt in + (run_case) + run_case + ;; +esac diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json index cf5a3a154618a..14e185cbca992 100644 --- a/docs/zh/latest/config.json +++ b/docs/zh/latest/config.json @@ -189,7 +189,8 @@ "discovery", "discovery/dns", "discovery/nacos", - "discovery/eureka" + "discovery/eureka", + "discovery/kubernetes" ] }, { diff --git a/docs/zh/latest/discovery/kubernetes.md b/docs/zh/latest/discovery/kubernetes.md new file mode 100644 index 0000000000000..9ef14ffdce825 --- /dev/null +++ b/docs/zh/latest/discovery/kubernetes.md @@ -0,0 +1,120 @@ + + +# 基于 Kubernetes 的服务发现 + +Kubernetes 服务发现插件以 ListWatch 方式监听 Kubernetes 集群 v1.endpoints 的实时变化, +并将其值存储在 ngx.shared.dict 中, 同时遵循 APISIX Discovery 规范提供查询接口 + +# Kubernetes 服务发现插件的配置 + +Kubernetes 服务发现插件的样例配置如下: + +```yaml +discovery: + kubernetes: + service: + # apiserver schema, options [http, https] + schema: https #default https + + # apiserver host, options [ipv4, ipv6, domain, environment variable] + host: ${KUBERNETES_SERVICE_HOST} #default ${KUBERNETES_SERVICE_HOST} + + # apiserver port, options [port number, environment variable] + port: ${KUBERNETES_SERVICE_PORT} #default ${KUBERNETES_SERVICE_PORT} + + client: + # serviceaccount token or token_file + token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + #token: |- + # eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEif + # 6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEifeyJhbGciOiJSUzI1NiIsImtpZCI + + # kubernetes discovery plugin support use namespace_selector + # you can use one of [equal, not_equal, match, not_match] filter namespace + namespace_selector: + # only save endpoints with namespace equal default + equal: default + + # only save endpoints with namespace not equal default + #not_equal: default + + # only save endpoints with namespace match one of [default, ^my-[a-z]+$] + #match: + #- default + #- ^my-[a-z]+$ + + # only save endpoints with namespace not match one of [default, ^my-[a-z]+$] + #not_match: + #- default + #- ^my-[a-z]+$ + + # kubernetes discovery plugin support use label_selector + # for the expression of label_selector, please refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/labels + label_selector: |- + first="a",second="b" +``` + +如果 Kubernetes 服务插件运行在 Pod 内, 你可以使用最简配置: + +```yaml +discovery: + kubernetes: { } +``` + +如果 Kubernetes 服务插件运行在 Pod 外, 你需要新建或选取指定的 ServiceAccount, 获取其 Token 值, 并使用如下配置: + +```yaml +discovery: + kubernetes: + service: + schema: https + host: # enter apiserver host value here + port: # enter apiServer port value here + client: + token: # enter serviceaccount token value here + #token_file: # enter file path here +``` + +# Kubernetes 服务发现插件的使用 + +Kubernetes 服务发现插件提供与其他服务发现插件相同的查询接口 -> nodes(service_name) \ +service_name 的 pattern 如下: +> _[namespace]/[name]:[portName]_ + +如果 kubernetes Endpoint 没有定义 portName, Kubernetes 服务发现插件会依次使用 targetPort, port 代替 + +# Q&A + +> Q: 为什么只支持配置 token 来访问 Kubernetes ApiServer \ +> A: 通常情况下,我们会使用三种方式与 Kubernetes ApiServer 通信 : +> +>+ mTLS +>+ token +>+ basic authentication +> +> 因为 lua-resty-http 目前不支持 mTLS, 以及 basic authentication 不被推荐使用,\ +> 所以当前只实现了 token 认证方式 + +------- + +> Q: APISIX 是多进程模型, 是否意味着每个 APISIX 工作进程都会监听 Kubernetes v1.endpoints \ +> A: Kubernetes 服务发现插件只使用特权进程监听 Kubernetes v1.endpoints, 然后将结果存储\ +> 在 ngx.shared.dict 中, 业务进程是通过查询 ngx.shared.dict 来获取结果的 diff --git a/t_kubernetes/configs/account.yaml b/t_kubernetes/configs/account.yaml new file mode 100644 index 0000000000000..da7cf01f5cad5 --- /dev/null +++ b/t_kubernetes/configs/account.yaml @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +kind: ServiceAccount +apiVersion: v1 +metadata: + name: apisix-test + namespace: default +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: apisix-test +rules: + - apiGroups: [ "" ] + resources: [ endpoints ] + verbs: [ get,list,watch ] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: apisix-test +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: apisix-test +subjects: + - kind: ServiceAccount + name: apisix-test + namespace: default diff --git a/t_kubernetes/configs/endpoint.yaml b/t_kubernetes/configs/endpoint.yaml new file mode 100644 index 0000000000000..885f82503b5c7 --- /dev/null +++ b/t_kubernetes/configs/endpoint.yaml @@ -0,0 +1,58 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +kind: Namespace +apiVersion: v1 +metadata: + name: ns-a +--- + +kind: Endpoints +apiVersion: v1 +metadata: + name: ep + namespace: ns-a +subsets: [ ] +--- + +kind: Namespace +apiVersion: v1 +metadata: + name: ns-b +--- + +kind: Endpoints +apiVersion: v1 +metadata: + name: ep + namespace: ns-b +subsets: [ ] +--- + +kind: Namespace +apiVersion: v1 +metadata: + name: ns-c +--- + +kind: Endpoints +apiVersion: v1 +metadata: + name: ep + namespace: ns-c +subsets: [ ] +--- diff --git a/t_kubernetes/configs/kind.yaml b/t_kubernetes/configs/kind.yaml new file mode 100644 index 0000000000000..3db903fcad64d --- /dev/null +++ b/t_kubernetes/configs/kind.yaml @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: + apiServerAddress: 127.0.0.1 + apiServerPort: 6443 diff --git a/t_kubernetes/discovery/kubernetes.t b/t_kubernetes/discovery/kubernetes.t new file mode 100644 index 0000000000000..9d44e6a4e6ab9 --- /dev/null +++ b/t_kubernetes/discovery/kubernetes.t @@ -0,0 +1,714 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +BEGIN { + my $token_var_file = "/var/run/secrets/kubernetes.io/serviceaccount/token"; + my $token_from_var = eval {`cat $token_var_file 2>/dev/null`}; + if ($token_from_var) { + + our $yaml_config = <<_EOC_; +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: {} +_EOC_ + our $token_file = $token_var_file; + our $token_value = $token_from_var; + + } + + my $token_tmp_file = "/tmp/var/run/secrets/kubernetes.io/serviceaccount/token"; + my $token_from_tmp = eval {`cat $token_tmp_file 2>/dev/null`}; + if ($token_from_tmp) { + + our $yaml_config = <<_EOC_; +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: /tmp/var/run/secrets/kubernetes.io/serviceaccount/token +_EOC_ + our $token_file = $token_tmp_file; + our $token_value = $token_from_tmp; + } + + our $scale_ns_c = <<_EOC_; +[ + { + "op": "replace_subsets", + "name": "ep", + "namespace": "ns-c", + "subsets": [ + { + "addresses": [ + { + "ip": "10.0.0.1" + } + ], + "ports": [ + { + "name": "p1", + "port": 5001 + } + ] + } + ] + } +] +_EOC_ + +} + +use t::APISIX 'no_plan'; + +repeat_each(1); +log_level('debug'); +no_root_location(); +no_shuffle(); +workers(4); + +add_block_preprocessor(sub { + my ($block) = @_; + + my $apisix_yaml = $block->apisix_yaml // <<_EOC_; +routes: [] +#END +_EOC_ + + $block->set_value("apisix_yaml", $apisix_yaml); + + my $main_config = $block->main_config // <<_EOC_; +env KUBERNETES_SERVICE_HOST=127.0.0.1; +env KUBERNETES_SERVICE_PORT=6443; +env KUBERNETES_CLIENT_TOKEN=$::token_value; +env KUBERNETES_CLIENT_TOKEN_FILE=$::token_file; +_EOC_ + + $block->set_value("main_config", $main_config); + + my $config = $block->config // <<_EOC_; + location /queries { + content_by_lua_block { + local core = require("apisix.core") + local d = require("apisix.discovery.kubernetes") + + ngx.sleep(1) + + ngx.req.read_body() + local request_body = ngx.req.get_body_data() + local queries = core.json.decode(request_body) + local response_body = "{" + for _,query in ipairs(queries) do + local nodes = d.nodes(query) + if nodes==nil or #nodes==0 then + response_body=response_body.." "..0 + else + response_body=response_body.." "..#nodes + end + end + ngx.say(response_body.." }") + } + } + + location /operators { + content_by_lua_block { + local http = require("resty.http") + local core = require("apisix.core") + local ipairs = ipairs + + ngx.req.read_body() + local request_body = ngx.req.get_body_data() + local operators = core.json.decode(request_body) + + core.log.info("get body ", request_body) + core.log.info("get operators ", #operators) + for _, op in ipairs(operators) do + local method, path, body + local headers = { + ["Host"] = "127.0.0.1:6445" + } + + if op.op == "replace_subsets" then + method = "PATCH" + path = "/api/v1/namespaces/" .. op.namespace .. "/endpoints/" .. op.name + if #op.subsets == 0 then + body = '[{"path":"/subsets","op":"replace","value":[]}]' + else + local t = { { op = "replace", path = "/subsets", value = op.subsets } } + body = core.json.encode(t, true) + end + headers["Content-Type"] = "application/json-patch+json" + end + + if op.op == "replace_labels" then + method = "PATCH" + path = "/api/v1/namespaces/" .. op.namespace .. "/endpoints/" .. op.name + local t = { { op = "replace", path = "/metadata/labels", value = op.labels } } + body = core.json.encode(t, true) + headers["Content-Type"] = "application/json-patch+json" + end + + local httpc = http.new() + core.log.info("begin to connect ", "127.0.0.1:6445") + local ok, message = httpc:connect({ + scheme = "http", + host = "127.0.0.1", + port = 6445, + }) + if not ok then + core.log.error("connect 127.0.0.1:6445 failed, message : ", message) + ngx.say("FAILED") + end + local res, err = httpc:request({ + method = method, + path = path, + headers = headers, + body = body, + }) + if err ~= nil then + core.log.err("operator k8s cluster error: ", err) + return 500 + end + if res.status ~= 200 and res.status ~= 201 and res.status ~= 409 then + return res.status + end + end + ngx.say("DONE") + } + } + +_EOC_ + + $block->set_value("config", $config); +}); + +run_tests(); + +__DATA__ + +=== TEST 1: create namespace and endpoints +--- yaml_config eval: $::yaml_config +--- request +POST /operators +[ + { + "op": "replace_subsets", + "namespace": "ns-a", + "name": "ep", + "subsets": [ + { + "addresses": [ + { + "ip": "10.0.0.1" + }, + { + "ip": "10.0.0.2" + } + ], + "ports": [ + { + "name": "p1", + "port": 5001 + } + ] + }, + { + "addresses": [ + { + "ip": "20.0.0.1" + }, + { + "ip": "20.0.0.2" + } + ], + "ports": [ + { + "name": "p2", + "port": 5002 + } + ] + } + ] + }, + { + "op": "create_namespace", + "name": "ns-b" + }, + { + "op": "replace_subsets", + "namespace": "ns-b", + "name": "ep", + "subsets": [ + { + "addresses": [ + { + "ip": "10.0.0.1" + }, + { + "ip": "10.0.0.2" + } + ], + "ports": [ + { + "name": "p1", + "port": 5001 + } + ] + }, + { + "addresses": [ + { + "ip": "20.0.0.1" + }, + { + "ip": "20.0.0.2" + } + ], + "ports": [ + { + "name": "p2", + "port": 5002 + } + ] + } + ] + }, + { + "op": "create_namespace", + "name": "ns-c" + }, + { + "op": "replace_subsets", + "namespace": "ns-c", + "name": "ep", + "subsets": [ + { + "addresses": [ + { + "ip": "10.0.0.1" + }, + { + "ip": "10.0.0.2" + } + ], + "ports": [ + { + "port": 5001 + } + ] + }, + { + "addresses": [ + { + "ip": "20.0.0.1" + }, + { + "ip": "20.0.0.2" + } + ], + "ports": [ + { + "port": 5002 + } + ] + } + ] + } +] +--- more_headers +Content-type: application/json +--- error_code: 200 +--- no_error_log +[error] + + + +=== TEST 2: use default parameters +--- yaml_config eval: $::yaml_config +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 3: use specify parameters +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + service: + host: "127.0.0.1" + port: "6443" + client: + token: "${KUBERNETES_CLIENT_TOKEN}" +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 4: use specify environment parameters +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + service: + host: ${KUBERNETES_SERVICE_HOST} + port: ${KUBERNETES_SERVICE_PORT} + client: + token: ${KUBERNETES_CLIENT_TOKEN} +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 5: use token_file +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 6: use http +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + service: + schema: http + host: "127.0.0.1" + port: "6445" + client: + token: "" +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 7: use namespace selector equal +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + namespace_selector: + equal: ns-a +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 0 0 0 0 } +--- no_error_log +[error] + + + +=== TEST 8: use namespace selector not_equal +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + namespace_selector: + not_equal: ns-a +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 0 0 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 9: use namespace selector match +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + namespace_selector: + match: [ns-a,ns-b] +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 0 0 } +--- no_error_log +[error] + + + +=== TEST 10: use namespace selector match with regex +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + namespace_selector: + match: ["ns-[ab]"] +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 2 2 2 2 0 0 } +--- no_error_log +[error] + + + +=== TEST 11: use namespace selector not_match +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + namespace_selector: + not_match: ["ns-a"] +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 0 0 2 2 2 2 } +--- no_error_log +[error] + + + +=== TEST 12: use namespace selector not_match with regex +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + namespace_selector: + not_match: ["ns-[ab]"] +--- request +GET /queries +["ns-a/ep:p1","ns-a/ep:p2","ns-b/ep:p1","ns-b/ep:p2","ns-c/ep:5001","ns-c/ep:5002"] +--- more_headers +Content-type: application/json +--- response_body eval +qr{ 0 0 0 0 2 2 } +--- no_error_log +[error] + + + +=== TEST 13: use label selector +--- yaml_config +apisix: + node_listen: 1984 + config_center: yaml + enable_admin: false +discovery: + kubernetes: + client: + token_file: ${KUBERNETES_CLIENT_TOKEN_FILE} + label_selector: |- + first=1,second +--- request eval +[ + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-a\",\"labels\":{}}]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-b\",\"labels\":{}}]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-c\",\"labels\":{}}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-b/ep:p1\",\"ns-c/ep:5001\"]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-a\",\"labels\":{\"first\":\"1\" }}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-b/ep:p1\",\"ns-c/ep:5001\"]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-b\",\"labels\":{\"first\":\"1\",\"second\":\"o\" }}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-b/ep:p1\",\"ns-c/ep:5001\"]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-c\",\"labels\":{\"first\":\"2\",\"second\":\"o\" }}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-b/ep:p1\",\"ns-c/ep:5001\"]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-c\",\"labels\":{\"first\":\"1\" }}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-b/ep:p1\",\"ns-c/ep:5001\"]", + +"POST /operators +[{\"op\":\"replace_labels\",\"name\":\"ep\",\"namespace\":\"ns-c\",\"labels\":{\"first\":\"1\",\"second\":\"o\" }}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-b/ep:p1\",\"ns-c/ep:5001\"]", + +] +--- response_body eval +[ + "DONE\n", + "DONE\n", + "DONE\n", + "{ 0 0 0 }\n", + "DONE\n", + "{ 0 0 0 }\n", + "DONE\n", + "{ 0 2 0 }\n", + "DONE\n", + "{ 0 2 0 }\n", + "DONE\n", + "{ 0 2 0 }\n", + "DONE\n", + "{ 0 2 2 }\n", +] +--- no_error_log +[error] + + + +=== TEST 15: scale endpoints +--- yaml_config eval: $::yaml_config +--- request eval +[ +"GET /queries +[\"ns-a/ep:p1\",\"ns-a/ep:p2\"]", + +"POST /operators +[{\"op\":\"replace_subsets\",\"name\":\"ep\",\"namespace\":\"ns-a\",\"subsets\":[]}]", + +"GET /queries +[\"ns-a/ep:p1\",\"ns-a/ep:p2\"]", + +"GET /queries +[\"ns-c/ep:5001\",\"ns-c/ep:5002\",\"ns-c/ep:p1\"]", + +"POST /operators +$::scale_ns_c", + +"GET /queries +[\"ns-c/ep:5001\",\"ns-c/ep:5002\",\"ns-c/ep:p1\"]", + +] +--- response_body eval +[ + "{ 2 2 }\n", + "DONE\n", + "{ 0 0 }\n", + "{ 2 2 0 }\n", + "DONE\n", + "{ 0 0 1 }\n", +] +--- no_error_log +[error]