This is an automated email from the ASF dual-hosted git repository.
wenming pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 0e97e9139 feat: add plugin attach-consmer-label (#11604)
0e97e9139 is described below
commit 0e97e913926e2fe1a77b37cec8aa1e8ffd762287
Author: 悟空 <[email protected]>
AuthorDate: Fri Sep 27 13:56:38 2024 +0800
feat: add plugin attach-consmer-label (#11604)
---
apisix/cli/config.lua | 1 +
apisix/plugins/attach-consumer-label.lua | 68 ++++
conf/config.yaml.example | 1 +
docs/en/latest/config.json | 3 +-
docs/en/latest/plugins/attach-consumer-label.md | 180 +++++++++
docs/zh/latest/config.json | 3 +-
docs/zh/latest/plugins/attach-consumer-label.md | 180 +++++++++
t/admin/plugins.t | 1 +
t/plugin/attach-consumer-label.t | 465 ++++++++++++++++++++++++
9 files changed, 900 insertions(+), 2 deletions(-)
diff --git a/apisix/cli/config.lua b/apisix/cli/config.lua
index f5c5d8dca..067e69d4c 100644
--- a/apisix/cli/config.lua
+++ b/apisix/cli/config.lua
@@ -208,6 +208,7 @@ local _M = {
"jwe-decrypt",
"key-auth",
"consumer-restriction",
+ "attach-consumer-label",
"forward-auth",
"opa",
"authz-keycloak",
diff --git a/apisix/plugins/attach-consumer-label.lua
b/apisix/plugins/attach-consumer-label.lua
new file mode 100644
index 000000000..6d3396a02
--- /dev/null
+++ b/apisix/plugins/attach-consumer-label.lua
@@ -0,0 +1,68 @@
+--
+-- 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 core = require("apisix.core")
+local pairs = pairs
+local plugin_name = "attach-consumer-label"
+
+local schema = {
+ type = "object",
+ properties = {
+ headers = {
+ type = "object",
+ additionalProperties = {
+ type = "string",
+ pattern = "^\\$.*"
+ },
+ minProperties = 1
+ },
+ },
+ required = {"headers"},
+}
+
+local _M = {
+ version = 0.1,
+ priority = 2399,
+ name = plugin_name,
+ schema = schema,
+}
+
+function _M.check_schema(conf)
+ return core.schema.check(schema, conf)
+end
+
+function _M.before_proxy(conf, ctx)
+ -- check if the consumer is exists in the context
+ if not ctx.consumer then
+ return
+ end
+
+ local labels = ctx.consumer.labels
+ core.log.info("consumer username: ", ctx.consumer.username, " labels: ",
+ core.json.delay_encode(labels))
+ if not labels then
+ return
+ end
+
+ for header, label_key in pairs(conf.headers) do
+ -- remove leading $ character
+ local label_value = labels[label_key:sub(2)]
+ core.request.set_header(ctx, header, label_value)
+ end
+end
+
+return _M
diff --git a/conf/config.yaml.example b/conf/config.yaml.example
index bd741b2f7..e6d10118f 100644
--- a/conf/config.yaml.example
+++ b/conf/config.yaml.example
@@ -470,6 +470,7 @@ plugins: # plugin list (sorted by
priority)
- jwe-decrypt # priority: 2509
- key-auth # priority: 2500
- consumer-restriction # priority: 2400
+ - attach-consumer-label # priority: 2399
- forward-auth # priority: 2002
- opa # priority: 2001
- authz-keycloak # priority: 2000
diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json
index 5c43fc55a..0db360eac 100644
--- a/docs/en/latest/config.json
+++ b/docs/en/latest/config.json
@@ -98,7 +98,8 @@
"plugins/mocking",
"plugins/degraphql",
"plugins/body-transformer",
- "plugins/ai-proxy"
+ "plugins/ai-proxy",
+ "plugins/attach-consumer-label"
]
},
{
diff --git a/docs/en/latest/plugins/attach-consumer-label.md
b/docs/en/latest/plugins/attach-consumer-label.md
new file mode 100644
index 000000000..2e977a4ba
--- /dev/null
+++ b/docs/en/latest/plugins/attach-consumer-label.md
@@ -0,0 +1,180 @@
+---
+title: attach-consumer-label
+keywords:
+ - Apache APISIX
+ - API Gateway
+ - API Consumer
+description: This article describes the Apache APISIX attach-consumer-label
plugin, which you can use to pass custom consumer labels to upstream services.
+---
+
+<!--
+#
+# 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.
+#
+-->
+
+## Description
+
+The `attach-consumer-label` plugin attaches custom consumer-related labels, in
addition to `X-Consumer-Username` and `X-Credential-Indentifier`, to
authenticated requests, for upstream services to differentiate between
consumers and implement additional logics.
+
+## Attributes
+
+| Name | Type | Required | Default | Valid values | Description
|
+|----------|--------|----------|---------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| headers | object | True | | | Key-value pairs of
consumer labels to be attached to request headers, where key is the request
header name, such as `X-Consumer-Role`, and the value is a reference to the
custom label key, such as `$role`. Note that the value should always start with
a dollar sign (`$`). If a referenced consumer value is not configured on the
consumer, the corresponding header will not be attached to the request. |
+
+## Enable Plugin
+
+The following example demonstrates how you can attach custom labels to request
headers before authenticated requests are forwarded to upstream services. If
the request is rejected, you should not see any consumer labels attached to
request headers. If a certain label value is not configured on the consumer but
referenced in the `attach-consumer-label` plugin, the corresponding header will
also not be attached.
+
+:::note
+
+You can fetch the `admin_key` from `config.yaml` and save to an environment
variable with the following command:
+
+```bash
+admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed
's/"//g')
+```
+
+:::
+
+Create a consumer `john` with custom labels:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "username": "john",
+ # highlight-start
+ "labels": {
+ // Annotate 1
+ "department": "devops",
+ // Annotate 2
+ "company": "api7"
+ }
+ # highlight-end
+ }'
+```
+
+❶ Label the `department` information for the consumer.
+
+❷ Label the `company` information for the consumer.
+
+Configure the `key-auth` credential for the consumer `john`:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "id": "cred-john-key-auth",
+ "plugins": {
+ "key-auth": {
+ "key": "john-key"
+ }
+ }
+ }'
+```
+
+Create a route enabling the `key-auth` and `attach-consumer-label` plugins:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "id": "attach-consumer-label-route",
+ "uri": "/get",
+ "plugins": {
+ "key-auth": {},
+ # highlight-start
+ "attach-consumer-label": {
+ "headers": {
+ // Annotate 1
+ "X-Consumer-Department": "$department",
+ // Annotate 2
+ "X-Consumer-Company": "$company",
+ // Annotate 3
+ "X-Consumer-Role": "$role"
+ }
+ }
+ # highlight-end
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "httpbin.org:80": 1
+ }
+ }
+ }'
+```
+
+❶ Attach the `department` consumer label value in the `X-Consumer-Department`
request header.
+
+❷ Attach the `company` consumer label value in the `X-Consumer-Company`
request header.
+
+❸ Attach the `role` consumer label value in the `X-Consumer-Role` request
header. As the `role` label is not configured on the consumer, it is expected
that the header will not appear in the request forwarded to the upstream
service.
+
+:::tip
+
+The consumer label references must be prefixed by a dollar sign (`$`).
+
+:::
+
+To verify, send a request to the route with the valid credential:
+
+```shell
+curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key'
+```
+
+You should see an `HTTP/1.1 200 OK` response similar to the following:
+
+```text
+{
+ "args": {},
+ "headers": {
+ "Accept": "*/*",
+ "Apikey": "john-key",
+ "Host": "127.0.0.1",
+ # highlight-start
+ "X-Consumer-Username": "john",
+ "X-Credential-Indentifier": "cred-john-key-auth",
+ "X-Consumer-Company": "api7",
+ "X-Consumer-Department": "devops",
+ # highlight-end
+ "User-Agent": "curl/8.6.0",
+ "X-Amzn-Trace-Id": "Root=1-66e5107c-5bb3e24f2de5baf733aec1cc",
+ "X-Forwarded-Host": "127.0.0.1"
+ },
+ "origin": "192.168.65.1, 205.198.122.37",
+ "url": "http://127.0.0.1/get"
+}
+```
+
+## Delete plugin
+
+To remove the Plugin, you can delete the corresponding JSON configuration from
the Plugin configuration. APISIX will automatically reload and you do not have
to restart for this to take effect.
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/routes/attach-consumer-label-route"
-X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "uri": "/get",
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "httpbin.org:80": 1
+ }
+ }
+ }'
+```
diff --git a/docs/zh/latest/config.json b/docs/zh/latest/config.json
index 15547299a..6694dc80d 100644
--- a/docs/zh/latest/config.json
+++ b/docs/zh/latest/config.json
@@ -81,7 +81,8 @@
"plugins/grpc-transcode",
"plugins/grpc-web",
"plugins/fault-injection",
- "plugins/mocking"
+ "plugins/mocking",
+ "plugins/attach-consumer-label"
]
},
{
diff --git a/docs/zh/latest/plugins/attach-consumer-label.md
b/docs/zh/latest/plugins/attach-consumer-label.md
new file mode 100644
index 000000000..21111c7c3
--- /dev/null
+++ b/docs/zh/latest/plugins/attach-consumer-label.md
@@ -0,0 +1,180 @@
+---
+title: attach-consumer-label
+keywords:
+ - Apache APISIX
+ - API 网关
+ - API Consumer
+description: 本文介绍了 Apache APISIX attach-consumer-label
插件的相关操作,你可以使用此插件向上游服务传递自定义的 Consumer labels。
+---
+
+<!--
+#
+# 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.
+#
+-->
+
+## 描述
+
+`attach-consumer-label` 插件在 X-Consumer-Username 和 X-Credential-Indentifier
之外,还将自定义的消费者相关标签附加到经过身份验证的请求,以便上游服务区分消费者并实现额外的逻辑。
+
+## 属性
+
+| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述
|
+|----------|--------|--------|----------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| headers | object | 是 | | | 要附加到请求标头的 Consumer
标签的键值对,其中键是请求标头名称,例如 "X-Consumer-Role",值是对客户标签键的引用,例如 "$role"。请注意,该值应始终以美元符号
(`$`) 开头。如果 Consumer 上没有配置引用的值,则相应的标头将不会附加到请求中。 |
+
+## 启用插件
+
+下面的示例演示了如何在通过身份验证的请求转发到上游服务之前,将自定义标签附加到请求标头。如果请求被拒绝,就不会在请求标头上附加任何消费者标签。如果某个标签值未在消费者上配置,但在“attach-consumer-label”插件中被引用,相应的标头也不会被附加。
+
+:::note
+
+您可以这样从 `config.yaml` 中获取 `admin_key` 并存入环境变量:
+
+```bash
+admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed
's/"//g')
+```
+
+:::
+
+创建一个有自定义标签的 Consumer `john`:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "username": "john",
+ # highlight-start
+ "labels": {
+ // Annotate 1
+ "department": "devops",
+ // Annotate 2
+ "company": "api7"
+ }
+ # highlight-end
+ }'
+```
+
+❶ Consumer 的 `department` 标签信息。
+
+❷ Consumer 的 `company` 标签信息。
+
+为 Consumer `john` 配置 `key-auth`:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/consumers/john/credentials" -X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "id": "cred-john-key-auth",
+ "plugins": {
+ "key-auth": {
+ "key": "john-key"
+ }
+ }
+ }'
+```
+
+创建路由并启用 `key-auth` 和 `attach-consumer-label` 插件:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "id": "attach-consumer-label-route",
+ "uri": "/get",
+ "plugins": {
+ "key-auth": {},
+ # highlight-start
+ "attach-consumer-label": {
+ "headers": {
+ // Annotate 1
+ "X-Consumer-Department": "$department",
+ // Annotate 2
+ "X-Consumer-Company": "$company",
+ // Annotate 3
+ "X-Consumer-Role": "$role"
+ }
+ }
+ # highlight-end
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "httpbin.org:80": 1
+ }
+ }
+ }'
+```
+
+❶ 将 Consumer 标签 `department` 的值附加到请求头的 `X-Consumer-Department` 字段。
+
+❷ 将 Consumer 标签 `company` 的值附加到请求头的 `X-Consumer-Company` 字段。
+
+❸ 将 Consumer 标签 `role` 的值附加到请求头的 `X-Consumer-Role` 字段。由于 Consumer 标签中没有配置
`role` 这个标签,该字段不会出现在发往上游的请求头中。
+
+:::tip
+
+引用标签的值必须以 `$` 符号开头。
+
+:::
+
+使用正确的 apikey 请求该路由,验证插件:
+
+```shell
+curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key'
+```
+
+可以看到类似的 `HTTP/1.1 200 OK` 响应:
+
+```text
+{
+ "args": {},
+ "headers": {
+ "Accept": "*/*",
+ "Apikey": "john-key",
+ "Host": "127.0.0.1",
+ # highlight-start
+ "X-Consumer-Username": "john",
+ "X-Credential-Indentifier": "cred-john-key-auth",
+ "X-Consumer-Company": "api7",
+ "X-Consumer-Department": "devops",
+ # highlight-end
+ "User-Agent": "curl/8.6.0",
+ "X-Amzn-Trace-Id": "Root=1-66e5107c-5bb3e24f2de5baf733aec1cc",
+ "X-Forwarded-Host": "127.0.0.1"
+ },
+ "origin": "192.168.65.1, 205.198.122.37",
+ "url": "http://127.0.0.1/get"
+}
+```
+
+## 删除插件
+
+当你需要禁用该插件时,可以通过以下命令删除相应的 JSON 配置,APISIX 将会自动重新加载相关配置,无需重启服务:
+
+```shell
+curl "http://127.0.0.1:9180/apisix/admin/routes/attach-consumer-label-route"
-X PUT \
+ -H "X-API-KEY: ${ADMIN_API_KEY}" \
+ -d '{
+ "uri": "/get",
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "httpbin.org:80": 1
+ }
+ }
+ }'
+```
diff --git a/t/admin/plugins.t b/t/admin/plugins.t
index bf3d485e8..e66662c91 100644
--- a/t/admin/plugins.t
+++ b/t/admin/plugins.t
@@ -88,6 +88,7 @@ jwt-auth
jwe-decrypt
key-auth
consumer-restriction
+attach-consumer-label
forward-auth
opa
authz-keycloak
diff --git a/t/plugin/attach-consumer-label.t b/t/plugin/attach-consumer-label.t
new file mode 100644
index 000000000..615b1cf09
--- /dev/null
+++ b/t/plugin/attach-consumer-label.t
@@ -0,0 +1,465 @@
+#
+# 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';
+
+repeat_each(1);
+no_long_string();
+no_shuffle();
+no_root_location();
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: invalid schema (missing headers)
+--- config
+ location /t {
+ content_by_lua_block {
+ local plugin = require("apisix.plugins.attach-consumer-label")
+ local ok, err = plugin.check_schema({})
+ if not ok then
+ ngx.say(err)
+ return
+ end
+
+ ngx.say("done")
+ }
+ }
+--- request
+GET /t
+--- response_body
+property "headers" is required
+--- no_error_log
+[error]
+
+
+
+=== TEST 2: invalid schema (headers is an empty object)
+--- config
+ location /t {
+ content_by_lua_block {
+ local plugin = require("apisix.plugins.attach-consumer-label")
+ local ok, err = plugin.check_schema({
+ headers = {}
+ })
+ if not ok then
+ ngx.say(err)
+ return
+ end
+
+ ngx.say("done")
+ }
+ }
+--- request
+GET /t
+--- response_body
+property "headers" validation failed: expect object to have at least 1
properties
+--- no_error_log
+[error]
+
+
+
+=== TEST 3: invalid schema (missing $ prefix)
+--- config
+ location /t {
+ content_by_lua_block {
+ local plugin = require("apisix.plugins.attach-consumer-label")
+ local ok, err = plugin.check_schema({
+ headers = {
+ ["X-Consumer-Department"] = "department",
+ ["X-Consumer-Company"] = "$company"
+ }
+ })
+ if not ok then
+ ngx.say(err)
+ return
+ end
+
+ ngx.say("done")
+ }
+ }
+--- request
+GET /t
+--- response_body
+property "headers" validation failed: failed to validate additional property
X-Consumer-Department: failed to match pattern "^\\$.*" with "department"
+--- no_error_log
+[error]
+
+
+
+=== TEST 4: valid schema
+--- config
+ location /t {
+ content_by_lua_block {
+ local plugin = require("apisix.plugins.attach-consumer-label")
+ local ok, err = plugin.check_schema({
+ headers = {
+ ["X-Consumer-Department"] = "$department",
+ ["X-Consumer-Company"] = "$company"
+ }
+ })
+ if not ok then
+ ngx.say(err)
+ return
+ end
+
+ ngx.say("done")
+ }
+ }
+--- request
+GET /t
+--- response_body
+done
+--- no_error_log
+[error]
+
+
+
+=== TEST 5: add consumer with labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack",
+ "labels": {
+ "department": "devops",
+ "company": "api7"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ local code, body = t('/apisix/admin/consumers/jack/credentials/a',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "key-auth": {
+ "key": "key-a"
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 6: add route with only attach-consumer-label plugin (no key-auth)
+--- 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": "/echo",
+ "plugins": {
+ "attach-consumer-label": {
+ "_meta": {
+ "disable": false
+ },
+ "headers": {
+ "X-Consumer-Department": "$department",
+ "X-Consumer-Company": "$company"
+ }
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 7: access without auth (should not contain consumer labels)
+--- request
+GET /echo
+--- response_headers
+!X-Consumer-Department
+!X-Consumer-Company
+--- no_error_log
+[error]
+
+
+
+=== TEST 8: add route with attach-consumer-label plugin (with key-auth)
+--- 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": "/echo",
+ "plugins": {
+ "key-auth": {},
+ "attach-consumer-label": {
+ "headers": {
+ "X-Consumer-Department": "$department",
+ "X-Consumer-Company": "$company",
+ "X-Consumer-Role": "$role"
+ }
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 9: access with auth (should contain consumer labels headers, but no
x-consumer-role)
+--- request
+GET /echo
+--- more_headers
+apikey: key-a
+X-Consumer-Role: admin
+--- response_headers
+X-Consumer-Company: api7
+X-Consumer-Department: devops
+!X-Consumer-Role
+--- no_error_log
+[error]
+
+
+
+=== TEST 10: modify consumer without labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers/jack',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 11: access with auth (should not contain headers because consumer has
no labels)
+--- request
+GET /echo
+--- more_headers
+apikey: key-a
+--- response_headers
+!X-Consumer-Company
+!X-Consumer-Department
+--- noerror_log
+[error]
+
+
+
+=== TEST 12: modify consumer with labels
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers/jack',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack",
+ "labels": {
+ "department": "devops",
+ "company": "api7"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 13: modify route without attach-consumer-label plugin
+--- 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": "/echo",
+ "plugins": {
+ "key-auth": {}
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 14: add global rule with attach-consumer-label plugin
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/global_rules/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "attach-consumer-label": {
+ "headers": {
+ "X-Global-Consumer-Department": "$department",
+ "X-Global-Consumer-Company": "$company"
+ }
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 15: access with auth (should contain expected consumer labels headers)
+--- request
+GET /echo
+--- more_headers
+apikey: key-a
+--- response_headers
+X-Global-Consumer-Company: api7
+X-Global-Consumer-Department: devops
+--- no_error_log
+[error]