This is an automated email from the ASF dual-hosted git repository. bzp2010 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
The following commit(s) were added to refs/heads/master by this push: new 6b86ff4 feat: basic support Apache APISIX 2.11 (#2233) 6b86ff4 is described below commit 6b86ff4c4ee7b129cfeda48108fe5d4f5a2e7c6c Author: Zeping Bai <bzp2...@apache.org> AuthorDate: Fri Dec 3 14:49:26 2021 +0800 feat: basic support Apache APISIX 2.11 (#2233) --- api/conf/schema.json | 3345 ++++++++++++++------ api/internal/handler/schema/plugin_test.go | 2 +- web/cypress/fixtures/plugin-dataset.json | 2 +- .../create-upstream-with-limit-req-form.spec.js | 5 +- .../consumer/create-with-limit-conn-form.spec.js | 7 +- .../consumer/create_and_delete_consumer.spec.js | 2 +- .../route/create-route-with-limit-req-form.spec.js | 5 +- .../create-route-with-proxy-rewrite-plugin.spec.js | 8 + web/src/components/Plugin/UI/limit-conn.tsx | 18 +- web/src/components/Plugin/UI/limit-count.tsx | 190 +- web/src/components/Plugin/UI/limit-req.tsx | 38 +- web/src/components/Plugin/UI/plugin.tsx | 10 +- web/src/components/Plugin/data.tsx | 18 + web/src/components/Plugin/locales/en-US.ts | 14 +- web/src/components/Plugin/locales/zh-CN.ts | 13 +- .../pages/Route/components/Step1/ProxyRewrite.tsx | 43 +- web/src/pages/Route/locales/en-US.ts | 2 + web/src/pages/Route/locales/zh-CN.ts | 2 + web/src/pages/Route/transform.ts | 9 +- web/src/pages/Route/typing.d.ts | 1 + 20 files changed, 2592 insertions(+), 1142 deletions(-) diff --git a/api/conf/schema.json b/api/conf/schema.json index ba4f438..37f7c48 100644 --- a/api/conf/schema.json +++ b/api/conf/schema.json @@ -36,7 +36,9 @@ "type": "string" } }, - "required": ["username"], + "required": [ + "username" + ], "type": "object" }, "global_rule": { @@ -45,15 +47,18 @@ "type": "integer" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "plugins": { "type": "object" @@ -62,7 +67,9 @@ "type": "integer" } }, - "required": ["plugins"], + "required": [ + "plugins" + ], "type": "object" }, "plugin_config": { @@ -75,15 +82,18 @@ "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "labels": { "description": "key/value pairs to specify attributes", @@ -106,7 +116,10 @@ "type": "integer" } }, - "required": ["id", "plugins"], + "required": [ + "id", + "plugins" + ], "type": "object" }, "plugins": { @@ -120,7 +133,9 @@ "type": "boolean" } }, - "required": ["name"], + "required": [ + "name" + ], "type": "object" }, "type": "array" @@ -140,86 +155,182 @@ "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "update_time": { "type": "integer" } }, - "required": ["content"], + "required": [ + "content" + ], "type": "object" }, "route": { - "allOf": [{ - "oneOf": [{ - "required": ["uri"] - }, { - "required": ["uris"] - }] - }, { - "oneOf": [{ - "not": { - "anyOf": [{ - "required": ["host"] - }, { - "required": ["hosts"] - }] - } - }, { - "required": ["host"] - }, { - "required": ["hosts"] - }] - }, { - "oneOf": [{ - "not": { - "anyOf": [{ - "required": ["remote_addr"] - }, { - "required": ["remote_addrs"] - }] - } - }, { - "required": ["remote_addr"] - }, { - "required": ["remote_addrs"] - }] - }], - "anyOf": [{ - "required": ["plugins", "uri"] - }, { - "required": ["upstream", "uri"] - }, { - "required": ["upstream_id", "uri"] - }, { - "required": ["service_id", "uri"] - }, { - "required": ["plugins", "uris"] - }, { - "required": ["upstream", "uris"] - }, { - "required": ["upstream_id", "uris"] - }, { - "required": ["service_id", "uris"] - }, { - "required": ["script", "uri"] - }, { - "required": ["script", "uris"] - }], + "allOf": [ + { + "oneOf": [ + { + "required": [ + "uri" + ] + }, + { + "required": [ + "uris" + ] + } + ] + }, + { + "oneOf": [ + { + "not": { + "anyOf": [ + { + "required": [ + "host" + ] + }, + { + "required": [ + "hosts" + ] + } + ] + } + }, + { + "required": [ + "host" + ] + }, + { + "required": [ + "hosts" + ] + } + ] + }, + { + "oneOf": [ + { + "not": { + "anyOf": [ + { + "required": [ + "remote_addr" + ] + }, + { + "required": [ + "remote_addrs" + ] + } + ] + } + }, + { + "required": [ + "remote_addr" + ] + }, + { + "required": [ + "remote_addrs" + ] + } + ] + } + ], + "anyOf": [ + { + "required": [ + "plugins", + "uri" + ] + }, + { + "required": [ + "upstream", + "uri" + ] + }, + { + "required": [ + "upstream_id", + "uri" + ] + }, + { + "required": [ + "service_id", + "uri" + ] + }, + { + "required": [ + "plugins", + "uris" + ] + }, + { + "required": [ + "upstream", + "uris" + ] + }, + { + "required": [ + "upstream_id", + "uris" + ] + }, + { + "required": [ + "service_id", + "uris" + ] + }, + { + "required": [ + "script", + "uri" + ] + }, + { + "required": [ + "script", + "uris" + ] + } + ], "not": { - "anyOf": [{ - "required": ["plugins", "script"] - }, { - "required": ["plugin_config_id", "script"] - }] + "anyOf": [ + { + "required": [ + "plugins", + "script" + ] + }, + { + "required": [ + "plugin_config_id", + "script" + ] + } + ] }, "properties": { "create_time": { @@ -252,15 +363,18 @@ "uniqueItems": true }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "labels": { "description": "key/value pairs to specify attributes", @@ -279,7 +393,17 @@ "methods": { "items": { "description": "HTTP method", - "enum": ["CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"], + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ], "type": "string" }, "type": "array", @@ -291,15 +415,18 @@ "type": "string" }, "plugin_config_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "plugins": { "type": "object" @@ -309,45 +436,55 @@ "type": "integer" }, "remote_addr": { - "anyOf": [{ - "format": "ipv4", - "title": "IPv4", - "type": "string" - }, { - "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", - "title": "IPv4/CIDR", - "type": "string" - }, { - "format": "ipv6", - "title": "IPv6", - "type": "string" - }, { - "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", - "title": "IPv6/CIDR", - "type": "string" - }], - "description": "client IP", - "type": "string" - }, - "remote_addrs": { - "items": { - "anyOf": [{ + "anyOf": [ + { "format": "ipv4", "title": "IPv4", "type": "string" - }, { + }, + { "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", "title": "IPv4/CIDR", "type": "string" - }, { + }, + { "format": "ipv6", "title": "IPv6", "type": "string" - }, { + }, + { "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", "title": "IPv6/CIDR", "type": "string" - }], + } + ], + "description": "client IP", + "type": "string" + }, + "remote_addrs": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], "description": "client IP", "type": "string" }, @@ -361,34 +498,46 @@ "type": "string" }, "script_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "service_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "service_protocol": { - "enum": ["grpc", "http"] + "enum": [ + "grpc", + "http" + ] }, "status": { "default": 1, "description": "route status, 1 to enable, 0 to disable", - "enum": [0, 1], + "enum": [ + 0, + 1 + ], "type": "integer" }, "timeout": { @@ -406,25 +555,47 @@ "type": "number" } }, - "required": ["connect", "read", "send"], + "required": [ + "connect", + "read", + "send" + ], "type": "object" }, "update_time": { "type": "integer" }, "upstream": { - "oneOf": [{ - "required": ["nodes", "type"] - }, { - "required": ["discovery_type", "service_name", "type"] - }], + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], "properties": { "checks": { - "anyOf": [{ - "required": ["active"] - }, { - "required": ["active", "passive"] - }], + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], "properties": { "active": { "properties": { @@ -435,7 +606,10 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 302], + "default": [ + 200, + 302 + ], "items": { "maximum": 599, "minimum": 200, @@ -490,7 +664,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -502,7 +680,16 @@ "type": "integer" }, "http_statuses": { - "default": [404, 429, 500, 501, 502, 503, 504, 505], + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], "items": { "maximum": 599, "minimum": 200, @@ -540,7 +727,27 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308], + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], "items": { "maximum": 599, "minimum": 200, @@ -561,7 +768,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -573,7 +784,11 @@ "type": "integer" }, "http_statuses": { - "default": [429, 500, 503], + "default": [ + 429, + 500, + 503 + ], "items": { "maximum": 599, "minimum": 200, @@ -630,19 +845,28 @@ }, "hash_on": { "default": "vars", - "enum": ["consumer", "cookie", "header", "vars", "vars_combinations"], + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "keepalive_pool": { "properties": { @@ -688,52 +912,63 @@ "type": "string" }, "nodes": { - "anyOf": [{ - "patternProperties": { - ".*": { - "description": "weight of node", - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, { - "items": { - "properties": { - "host": { - "pattern": "^\\*?[0-9a-zA-Z-._]+$", - "type": "string" - }, - "metadata": { - "description": "metadata of node", - "type": "object" - }, - "port": { - "description": "port of node", - "minimum": 1, - "type": "integer" - }, - "priority": { - "default": 0, - "description": "priority of node", - "type": "integer" - }, - "weight": { + "anyOf": [ + { + "patternProperties": { + ".*": { "description": "weight of node", "minimum": 0, "type": "integer" } }, - "required": ["host", "port", "weight"], "type": "object" }, - "type": "array" - }] + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] }, "pass_host": { "default": "pass", "description": "mod of host passing", - "enum": ["node", "pass", "rewrite"], + "enum": [ + "node", + "pass", + "rewrite" + ], "type": "string" }, "retries": { @@ -746,7 +981,12 @@ }, "scheme": { "default": "http", - "enum": ["grpc", "grpcs", "http", "https"] + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] }, "service_name": { "maxLength": 256, @@ -768,7 +1008,11 @@ "type": "number" } }, - "required": ["connect", "read", "send"], + "required": [ + "connect", + "read", + "send" + ], "type": "object" }, "tls": { @@ -784,7 +1028,10 @@ "type": "string" } }, - "required": ["client_cert", "client_key"], + "required": [ + "client_cert", + "client_key" + ], "type": "object" }, "type": { @@ -802,15 +1049,18 @@ "type": "object" }, "upstream_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "uri": { "maxLength": 4096, @@ -855,15 +1105,18 @@ "uniqueItems": true }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "labels": { "description": "key/value pairs to specify attributes", @@ -896,18 +1149,36 @@ "type": "integer" }, "upstream": { - "oneOf": [{ - "required": ["nodes", "type"] - }, { - "required": ["discovery_type", "service_name", "type"] - }], + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], "properties": { "checks": { - "anyOf": [{ - "required": ["active"] - }, { - "required": ["active", "passive"] - }], + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], "properties": { "active": { "properties": { @@ -918,7 +1189,10 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 302], + "default": [ + 200, + 302 + ], "items": { "maximum": 599, "minimum": 200, @@ -973,7 +1247,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -985,7 +1263,16 @@ "type": "integer" }, "http_statuses": { - "default": [404, 429, 500, 501, 502, 503, 504, 505], + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], "items": { "maximum": 599, "minimum": 200, @@ -1023,7 +1310,27 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308], + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], "items": { "maximum": 599, "minimum": 200, @@ -1044,7 +1351,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -1056,7 +1367,11 @@ "type": "integer" }, "http_statuses": { - "default": [429, 500, 503], + "default": [ + 429, + 500, + 503 + ], "items": { "maximum": 599, "minimum": 200, @@ -1113,19 +1428,28 @@ }, "hash_on": { "default": "vars", - "enum": ["consumer", "cookie", "header", "vars", "vars_combinations"], + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "keepalive_pool": { "properties": { @@ -1171,52 +1495,63 @@ "type": "string" }, "nodes": { - "anyOf": [{ - "patternProperties": { - ".*": { - "description": "weight of node", - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, { - "items": { - "properties": { - "host": { - "pattern": "^\\*?[0-9a-zA-Z-._]+$", - "type": "string" - }, - "metadata": { - "description": "metadata of node", - "type": "object" - }, - "port": { - "description": "port of node", - "minimum": 1, - "type": "integer" - }, - "priority": { - "default": 0, - "description": "priority of node", - "type": "integer" - }, - "weight": { + "anyOf": [ + { + "patternProperties": { + ".*": { "description": "weight of node", "minimum": 0, "type": "integer" } }, - "required": ["host", "port", "weight"], "type": "object" }, - "type": "array" - }] + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] }, "pass_host": { "default": "pass", "description": "mod of host passing", - "enum": ["node", "pass", "rewrite"], + "enum": [ + "node", + "pass", + "rewrite" + ], "type": "string" }, "retries": { @@ -1229,7 +1564,12 @@ }, "scheme": { "default": "http", - "enum": ["grpc", "grpcs", "http", "https"] + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] }, "service_name": { "maxLength": 256, @@ -1251,7 +1591,11 @@ "type": "number" } }, - "required": ["connect", "read", "send"], + "required": [ + "connect", + "read", + "send" + ], "type": "object" }, "tls": { @@ -1267,7 +1611,10 @@ "type": "string" } }, - "required": ["client_cert", "client_key"], + "required": [ + "client_cert", + "client_key" + ], "type": "object" }, "type": { @@ -1285,25 +1632,39 @@ "type": "object" }, "upstream_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] } }, "type": "object" }, "ssl": { - "oneOf": [{ - "required": ["cert", "key", "sni"] - }, { - "required": ["cert", "key", "snis"] - }], + "oneOf": [ + { + "required": [ + "cert", + "key", + "sni" + ] + }, + { + "required": [ + "cert", + "key", + "snis" + ] + } + ], "properties": { "cert": { "maxLength": 65536, @@ -1331,7 +1692,9 @@ "type": "integer" } }, - "required": ["ca"], + "required": [ + "ca" + ], "type": "object" }, "create_time": { @@ -1342,15 +1705,18 @@ "type": "integer" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "key": { "maxLength": 65536, @@ -1394,7 +1760,10 @@ "status": { "default": 1, "description": "ssl status, 1 to enable, 0 to disable", - "enum": [0, 1], + "enum": [ + 0, + 1 + ], "type": "integer" }, "update_time": { @@ -1419,58 +1788,71 @@ "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "plugins": { "type": "object" }, "remote_addr": { - "anyOf": [{ - "format": "ipv4", - "title": "IPv4", - "type": "string" - }, { - "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", - "title": "IPv4/CIDR", - "type": "string" - }, { - "format": "ipv6", - "title": "IPv6", - "type": "string" - }, { - "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", - "title": "IPv6/CIDR", - "type": "string" - }], + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], "description": "client IP", "type": "string" }, "server_addr": { - "anyOf": [{ - "format": "ipv4", - "title": "IPv4", - "type": "string" - }, { - "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", - "title": "IPv4/CIDR", - "type": "string" - }, { - "format": "ipv6", - "title": "IPv6", - "type": "string" - }, { - "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", - "title": "IPv6/CIDR", - "type": "string" - }], + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], "description": "server IP", "type": "string" }, @@ -1487,18 +1869,36 @@ "type": "integer" }, "upstream": { - "oneOf": [{ - "required": ["nodes", "type"] - }, { - "required": ["discovery_type", "service_name", "type"] - }], + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], "properties": { "checks": { - "anyOf": [{ - "required": ["active"] - }, { - "required": ["active", "passive"] - }], + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], "properties": { "active": { "properties": { @@ -1509,7 +1909,10 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 302], + "default": [ + 200, + 302 + ], "items": { "maximum": 599, "minimum": 200, @@ -1564,7 +1967,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -1576,7 +1983,16 @@ "type": "integer" }, "http_statuses": { - "default": [404, 429, 500, 501, 502, 503, 504, 505], + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], "items": { "maximum": 599, "minimum": 200, @@ -1614,7 +2030,27 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308], + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], "items": { "maximum": 599, "minimum": 200, @@ -1635,7 +2071,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -1647,7 +2087,11 @@ "type": "integer" }, "http_statuses": { - "default": [429, 500, 503], + "default": [ + 429, + 500, + 503 + ], "items": { "maximum": 599, "minimum": 200, @@ -1704,19 +2148,28 @@ }, "hash_on": { "default": "vars", - "enum": ["consumer", "cookie", "header", "vars", "vars_combinations"], + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "keepalive_pool": { "properties": { @@ -1762,52 +2215,63 @@ "type": "string" }, "nodes": { - "anyOf": [{ - "patternProperties": { - ".*": { - "description": "weight of node", - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, { - "items": { - "properties": { - "host": { - "pattern": "^\\*?[0-9a-zA-Z-._]+$", - "type": "string" - }, - "metadata": { - "description": "metadata of node", - "type": "object" - }, - "port": { - "description": "port of node", - "minimum": 1, - "type": "integer" - }, - "priority": { - "default": 0, - "description": "priority of node", - "type": "integer" - }, - "weight": { + "anyOf": [ + { + "patternProperties": { + ".*": { "description": "weight of node", "minimum": 0, "type": "integer" } }, - "required": ["host", "port", "weight"], "type": "object" }, - "type": "array" - }] + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] }, "pass_host": { "default": "pass", "description": "mod of host passing", - "enum": ["node", "pass", "rewrite"], + "enum": [ + "node", + "pass", + "rewrite" + ], "type": "string" }, "retries": { @@ -1820,7 +2284,12 @@ }, "scheme": { "default": "http", - "enum": ["grpc", "grpcs", "http", "https"] + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] }, "service_name": { "maxLength": 256, @@ -1842,7 +2311,11 @@ "type": "number" } }, - "required": ["connect", "read", "send"], + "required": [ + "connect", + "read", + "send" + ], "type": "object" }, "tls": { @@ -1858,7 +2331,10 @@ "type": "string" } }, - "required": ["client_cert", "client_key"], + "required": [ + "client_cert", + "client_key" + ], "type": "object" }, "type": { @@ -1876,32 +2352,53 @@ "type": "object" }, "upstream_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] } }, "type": "object" }, "upstream": { - "oneOf": [{ - "required": ["nodes", "type"] - }, { - "required": ["discovery_type", "service_name", "type"] - }], + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], "properties": { "checks": { - "anyOf": [{ - "required": ["active"] - }, { - "required": ["active", "passive"] - }], + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], "properties": { "active": { "properties": { @@ -1912,7 +2409,10 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 302], + "default": [ + 200, + 302 + ], "items": { "maximum": 599, "minimum": 200, @@ -1967,7 +2467,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -1979,7 +2483,16 @@ "type": "integer" }, "http_statuses": { - "default": [404, 429, 500, 501, 502, 503, 504, 505], + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], "items": { "maximum": 599, "minimum": 200, @@ -2017,7 +2530,27 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308], + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], "items": { "maximum": 599, "minimum": 200, @@ -2038,7 +2571,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -2050,7 +2587,11 @@ "type": "integer" }, "http_statuses": { - "default": [429, 500, 503], + "default": [ + 429, + 500, + 503 + ], "items": { "maximum": 599, "minimum": 200, @@ -2107,19 +2648,28 @@ }, "hash_on": { "default": "vars", - "enum": ["consumer", "cookie", "header", "vars", "vars_combinations"], + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "keepalive_pool": { "properties": { @@ -2165,52 +2715,63 @@ "type": "string" }, "nodes": { - "anyOf": [{ - "patternProperties": { - ".*": { - "description": "weight of node", - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, { - "items": { - "properties": { - "host": { - "pattern": "^\\*?[0-9a-zA-Z-._]+$", - "type": "string" - }, - "metadata": { - "description": "metadata of node", - "type": "object" - }, - "port": { - "description": "port of node", - "minimum": 1, - "type": "integer" - }, - "priority": { - "default": 0, - "description": "priority of node", - "type": "integer" - }, - "weight": { - "description": "weight of node", - "minimum": 0, + "anyOf": [ + { + "patternProperties": { + ".*": { + "description": "weight of node", + "minimum": 0, "type": "integer" } }, - "required": ["host", "port", "weight"], "type": "object" }, - "type": "array" - }] + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] }, "pass_host": { "default": "pass", "description": "mod of host passing", - "enum": ["node", "pass", "rewrite"], + "enum": [ + "node", + "pass", + "rewrite" + ], "type": "string" }, "retries": { @@ -2223,7 +2784,12 @@ }, "scheme": { "default": "http", - "enum": ["grpc", "grpcs", "http", "https"] + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] }, "service_name": { "maxLength": 256, @@ -2245,7 +2811,11 @@ "type": "number" } }, - "required": ["connect", "read", "send"], + "required": [ + "connect", + "read", + "send" + ], "type": "object" }, "tls": { @@ -2261,7 +2831,10 @@ "type": "string" } }, - "required": ["client_cert", "client_key"], + "required": [ + "client_cert", + "client_key" + ], "type": "object" }, "type": { @@ -2303,12 +2876,16 @@ }, "healthy": { "default": { - "http_statuses": [200], + "http_statuses": [ + 200 + ], "successes": 3 }, "properties": { "http_statuses": { - "default": [200], + "default": [ + 200 + ], "items": { "maximum": 499, "minimum": 200, @@ -2334,7 +2911,9 @@ "unhealthy": { "default": { "failures": 3, - "http_statuses": [500] + "http_statuses": [ + 500 + ] }, "properties": { "failures": { @@ -2343,7 +2922,9 @@ "type": "integer" }, "http_statuses": { - "default": [500], + "default": [ + 500 + ], "items": { "maximum": 599, "minimum": 500, @@ -2357,7 +2938,9 @@ "type": "object" } }, - "required": ["break_response_code"], + "required": [ + "break_response_code" + ], "type": "object" }, "version": 0.1 @@ -2372,17 +2955,31 @@ "type": "string" } }, - "required": ["model", "policy"], + "required": [ + "model", + "policy" + ], "type": "object" }, "priority": 2560, "schema": { "$comment": "this is a mark for our injected plugin schema", - "oneOf": [{ - "required": ["model_path", "policy_path", "username"] - }, { - "required": ["model", "policy", "username"] - }], + "oneOf": [ + { + "required": [ + "model_path", + "policy_path", + "username" + ] + }, + { + "required": [ + "model", + "policy", + "username" + ] + } + ], "properties": { "disable": { "type": "boolean" @@ -2411,38 +3008,70 @@ "priority": 2000, "schema": { "$comment": "this is a mark for our injected plugin schema", - "allOf": [{ - "anyOf": [{ - "required": ["discovery"] - }, { - "required": ["token_endpoint"] - }] - }, { - "anyOf": [{ - "required": ["client_id"] - }, { - "required": ["audience"] - }] - }, { - "anyOf": [{ - "properties": { - "lazy_load_paths": { - "enum": [false] + "allOf": [ + { + "anyOf": [ + { + "required": [ + "discovery" + ] + }, + { + "required": [ + "token_endpoint" + ] } - } - }, { - "anyOf": [{ - "required": ["discovery"] - }, { - "required": ["resource_registration_endpoint"] - }], - "properties": { - "lazy_load_paths": { - "enum": [true] + ] + }, + { + "anyOf": [ + { + "required": [ + "client_id" + ] + }, + { + "required": [ + "audience" + ] } - } - }] - }], + ] + }, + { + "anyOf": [ + { + "properties": { + "lazy_load_paths": { + "enum": [ + false + ] + } + } + }, + { + "anyOf": [ + { + "required": [ + "discovery" + ] + }, + { + "required": [ + "resource_registration_endpoint" + ] + } + ], + "properties": { + "lazy_load_paths": { + "enum": [ + true + ] + } + } + } + ] + } + ], "properties": { "audience": { "description": "Deprecated, use `client_id` instead.", @@ -2475,7 +3104,9 @@ }, "grant_type": { "default": "urn:ietf:params:oauth:grant-type:uma-ticket", - "enum": ["urn:ietf:params:oauth:grant-type:uma-ticket"], + "enum": [ + "urn:ietf:params:oauth:grant-type:uma-ticket" + ], "maxLength": 100, "minLength": 1, "type": "string" @@ -2514,7 +3145,10 @@ }, "policy_enforcement_mode": { "default": "ENFORCING", - "enum": ["ENFORCING", "PERMISSIVE"], + "enum": [ + "ENFORCING", + "PERMISSIVE" + ], "type": "string" }, "resource_registration_endpoint": { @@ -2541,6 +3175,72 @@ }, "version": 0.1 }, + "azure-functions": { + "metadata_schema": { + "properties": { + "master_apikey": { + "default": "", + "type": "string" + }, + "master_clientid": { + "default": "", + "type": "string" + } + }, + "type": "object" + }, + "priority": -1900, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "authorization": { + "properties": { + "apikey": { + "type": "string" + }, + "clientid": { + "type": "string" + } + }, + "type": "object" + }, + "disable": { + "type": "boolean" + }, + "function_uri": { + "type": "string" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "minimum": 100, + "type": "integer" + } + }, + "required": [ + "function_uri" + ], + "type": "object" + }, + "version": 0.1 + }, "basic-auth": { "consumer_schema": { "properties": { @@ -2551,7 +3251,10 @@ "type": "string" } }, - "required": ["password", "username"], + "required": [ + "password", + "username" + ], "title": "work with consumer object", "type": "object" }, @@ -2615,13 +3318,23 @@ "priority": 2400, "schema": { "$comment": "this is a mark for our injected plugin schema", - "anyOf": [{ - "required": ["blacklist"] - }, { - "required": ["whitelist"] - }, { - "required": ["allowed_by_methods"] - }], + "anyOf": [ + { + "required": [ + "blacklist" + ] + }, + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "allowed_by_methods" + ] + } + ], "properties": { "allowed_by_methods": { "items": { @@ -2629,7 +3342,17 @@ "methods": { "items": { "description": "HTTP method", - "enum": ["CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"], + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ], "type": "string" }, "minItems": 1, @@ -2660,7 +3383,11 @@ }, "type": { "default": "consumer_name", - "enum": ["consumer_name", "route_id", "service_id"], + "enum": [ + "consumer_name", + "route_id", + "service_id" + ], "type": "string" }, "whitelist": { @@ -2730,6 +3457,70 @@ }, "version": 0.1 }, + "datadog": { + "metadata_schema": { + "properties": { + "constant_tags": { + "default": [ + "source:apisix" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "host": { + "default": "127.0.0.1", + "type": "string" + }, + "namespace": { + "default": "apisix", + "type": "string" + }, + "port": { + "default": 8125, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "priority": 495, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "batch_max_size": { + "default": 5000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "disable": { + "type": "boolean" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "max_retry_count": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "prefer_name": { + "default": true, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, "dubbo-proxy": { "priority": 507, "schema": { @@ -2751,7 +3542,10 @@ "type": "string" } }, - "required": ["service_name", "service_version"], + "required": [ + "service_name", + "service_version" + ], "type": "object" }, "version": 0.1 @@ -2760,13 +3554,23 @@ "priority": 412, "schema": { "$comment": "this is a mark for our injected plugin schema", - "anyOf": [{ - "required": ["before_body"] - }, { - "required": ["body"] - }, { - "required": ["after_body"] - }], + "anyOf": [ + { + "required": [ + "before_body" + ] + }, + { + "required": [ + "body" + ] + }, + { + "required": [ + "after_body" + ] + } + ], "minProperties": 1, "properties": { "after_body": { @@ -2796,16 +3600,24 @@ }, "error-log-logger": { "metadata_schema": { - "oneOf":[ + "oneOf": [ { - "required":["skywalking"] + "required": [ + "skywalking" + ] }, { - "required":["tcp"] + "required": [ + "tcp" + ] }, { - "required":["host", "port"] - }], + "required": [ + "host", + "port" + ] + } + ], "properties": { "batch_max_size": { "default": 1000, @@ -2818,11 +3630,11 @@ "type": "integer" }, "host": { - "1":{ - "pattern":"^\\*?[0-9a-zA-Z-._]+$", - "type":"string" + "1": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" }, - "description":"Deprecated, use `tcp.host` instead." + "description": "Deprecated, use `tcp.host` instead." }, "inactive_timeout": { "default": 3, @@ -2836,7 +3648,18 @@ }, "level": { "default": "WARN", - "enum": ["ALERT", "CRIT", "DEBUG", "EMERG", "ERR", "ERROR", "INFO", "NOTICE", "STDERR", "WARN"], + "enum": [ + "ALERT", + "CRIT", + "DEBUG", + "EMERG", + "ERR", + "ERROR", + "INFO", + "NOTICE", + "STDERR", + "WARN" + ], "type": "string" }, "max_retry_count": { @@ -2849,7 +3672,7 @@ "type": "string" }, "port": { - "description":"Deprecated, use `tcp.port` instead.", + "description": "Deprecated, use `tcp.port` instead.", "minimum": 0, "type": "integer" }, @@ -2858,42 +3681,45 @@ "minimum": 0, "type": "integer" }, - "skywalking":{ - "properties":{ - "endpoint_addr":{ - "default":"http://127.0.0.1:12900/v3/logs" + "skywalking": { + "properties": { + "endpoint_addr": { + "default": "http://127.0.0.1:12900/v3/logs" }, - "service_instance_name":{ - "default":"APISIX Service Instance", - "type":"string" + "service_instance_name": { + "default": "APISIX Service Instance", + "type": "string" }, - "service_name":{ - "default":"APISIX", - "type":"string" + "service_name": { + "default": "APISIX", + "type": "string" } }, - "type":"object" + "type": "object" }, - "tcp":{ - "properties":{ - "host":{ - "pattern":"^\\*?[0-9a-zA-Z-._]+$", - "type":"string" + "tcp": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" }, - "port":{ - "minimum":0, - "type":"integer" + "port": { + "minimum": 0, + "type": "integer" }, - "tls":{ - "default":false, - "type":"boolean" + "tls": { + "default": false, + "type": "boolean" }, - "tls_server_name":{ - "type":"string" + "tls_server_name": { + "type": "string" } }, - "required":["host", "port"], - "type":"object" + "required": [ + "host", + "port" + ], + "type": "object" }, "timeout": { "default": 3, @@ -2902,11 +3728,11 @@ }, "tls": { "default": false, - "description":"Deprecated, use `tcp.tls` instead.", + "description": "Deprecated, use `tcp.tls` instead.", "type": "boolean" }, "tls_server_name": { - "description":"Deprecated, use `tcp.tls_server_name` instead.", + "description": "Deprecated, use `tcp.tls_server_name` instead.", "type": "string" } }, @@ -2936,7 +3762,10 @@ "type": "string" } }, - "required": ["ikey", "skey"], + "required": [ + "ikey", + "skey" + ], "type": "object" }, "priority": 0, @@ -2964,7 +3793,9 @@ "type": "array" } }, - "required": ["i"], + "required": [ + "i" + ], "type": "object" }, "version": 0.1 @@ -2986,7 +3817,10 @@ "type": "string" } }, - "required": ["name", "value"], + "required": [ + "name", + "value" + ], "type": "object" }, "minItems": 1, @@ -3017,7 +3851,10 @@ "type": "string" } }, - "required": ["name", "value"], + "required": [ + "name", + "value" + ], "type": "object" }, "minItems": 1, @@ -3060,7 +3897,9 @@ "type": "array" } }, - "required": ["http_status"], + "required": [ + "http_status" + ], "type": "object" }, "delay": { @@ -3082,7 +3921,9 @@ "type": "array" } }, - "required": ["duration"], + "required": [ + "duration" + ], "type": "object" }, "disable": { @@ -3113,45 +3954,72 @@ }, "pb_option": { "items": { - "anyOf": [{ - "description": "enum as result", - "enum": ["int64_as_hexstring", "int64_as_number", "int64_as_string"], - "type": "string" - }, { - "description": "int64 as result", - "enum": ["enum_as_name", "enum_as_value"], - "type": "string" - }, { - "description": "default values option", - "enum": ["auto_default_values", "no_default_values", "use_default_metatable", "use_default_values"], - "type": "string" - }, { - "description": "hooks option", - "enum": ["disable_hooks", "enable_hooks"], - "type": "string" - }], + "anyOf": [ + { + "description": "enum as result", + "enum": [ + "int64_as_hexstring", + "int64_as_number", + "int64_as_string" + ], + "type": "string" + }, + { + "description": "int64 as result", + "enum": [ + "enum_as_name", + "enum_as_value" + ], + "type": "string" + }, + { + "description": "default values option", + "enum": [ + "auto_default_values", + "no_default_values", + "use_default_metatable", + "use_default_values" + ], + "type": "string" + }, + { + "description": "hooks option", + "enum": [ + "disable_hooks", + "enable_hooks" + ], + "type": "string" + } + ], "type": "string" }, "minItems": 1, "type": "array" }, "proto_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "service": { "description": "the grpc service name", "type": "string" } }, - "required": ["method", "proto_id", "service"], + "required": [ + "method", + "proto_id", + "service" + ], "type": "object" }, "version": 0.1 @@ -3191,7 +4059,10 @@ }, "http_version": { "default": 1.1, - "enum": [1, 1.1] + "enum": [ + 1, + 1.1 + ] }, "min_length": { "default": 20, @@ -3199,17 +4070,24 @@ "type": "integer" }, "types": { - "anyOf": [{ - "items": { - "minLength": 1, - "type": "string" + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" }, - "minItems": 1, - "type": "array" - }, { - "enum": ["*"] - }], - "default": ["text/html"] + { + "enum": [ + "*" + ] + } + ], + "default": [ + "text/html" + ] }, "vary": { "type": "boolean" @@ -3229,7 +4107,11 @@ }, "algorithm": { "default": "hmac-sha256", - "enum": ["hmac-sha1", "hmac-sha256", "hmac-sha512"], + "enum": [ + "hmac-sha1", + "hmac-sha256", + "hmac-sha512" + ], "type": "string" }, "clock_skew": { @@ -3246,7 +4128,7 @@ "title": "whether to keep the http request header", "type": "boolean" }, - "max_req_body":{ + "max_req_body": { "default": 524288, "title": "Max request body size", "type": "integer" @@ -3270,7 +4152,10 @@ "type": "boolean" } }, - "required": ["access_key", "secret_key"], + "required": [ + "access_key", + "secret_key" + ], "title": "work with consumer object", "type": "object" }, @@ -3322,7 +4207,10 @@ }, "concat_method": { "default": "json", - "enum": ["json", "new_line"], + "enum": [ + "json", + "new_line" + ], "type": "string" }, "disable": { @@ -3361,7 +4249,9 @@ "type": "string" } }, - "required": ["uri"], + "required": [ + "uri" + ], "type": "object" }, "version": 0.1 @@ -3370,31 +4260,43 @@ "priority": 3000, "schema": { "$comment": "this is a mark for our injected plugin schema", - "oneOf": [{ - "required": ["whitelist"] - }, { - "required": ["blacklist"] - }], + "oneOf": [ + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "blacklist" + ] + } + ], "properties": { "blacklist": { "items": { - "anyOf": [{ - "format": "ipv4", - "title": "IPv4", - "type": "string" - }, { - "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", - "title": "IPv4/CIDR", - "type": "string" - }, { - "format": "ipv6", - "title": "IPv6", - "type": "string" - }, { - "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", - "title": "IPv6/CIDR", - "type": "string" - }] + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] }, "minItems": 1, "type": "array" @@ -3410,23 +4312,28 @@ }, "whitelist": { "items": { - "anyOf": [{ - "format": "ipv4", - "title": "IPv4", - "type": "string" - }, { - "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", - "title": "IPv4/CIDR", - "type": "string" - }, { - "format": "ipv6", - "title": "IPv6", - "type": "string" - }, { - "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", - "title": "IPv6/CIDR", - "type": "string" - }] + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] }, "minItems": 1, "type": "array" @@ -3440,33 +4347,48 @@ "consumer_schema": { "dependencies": { "algorithm": { - "oneOf": [{ - "properties": { - "algorithm": { - "default": "HS256", - "enum": ["HS256", "HS512"] - } - } - }, { - "properties": { - "algorithm": { - "enum": ["RS256"] - }, - "private_key": { - "type": "string" - }, - "public_key": { - "type": "string" + "oneOf": [ + { + "properties": { + "algorithm": { + "default": "HS256", + "enum": [ + "HS256", + "HS512" + ] + } } }, - "required": ["private_key", "public_key"] - }] + { + "properties": { + "algorithm": { + "enum": [ + "RS256" + ] + }, + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } + }, + "required": [ + "private_key", + "public_key" + ] + } + ] } }, "properties": { "algorithm": { "default": "HS256", - "enum": ["HS256", "HS512", "RS256"], + "enum": [ + "HS256", + "HS512", + "RS256" + ], "type": "string" }, "base64_secret": { @@ -3485,7 +4407,9 @@ "type": "string" } }, - "required": ["key"], + "required": [ + "key" + ], "type": "object" }, "priority": 2510, @@ -3558,6 +4482,16 @@ "default": false, "type": "boolean" }, + "include_req_body_expr": { + "items": { + "items": { + "type": "string" + }, + "type": "array" + }, + "minItems": 1, + "type": "array" + }, "kafka_topic": { "type": "string" }, @@ -3571,7 +4505,10 @@ }, "meta_format": { "default": "default", - "enum": ["default", "origin"], + "enum": [ + "default", + "origin" + ], "type": "string" }, "name": { @@ -3580,12 +4517,19 @@ }, "producer_type": { "default": "async", - "enum": ["async", "sync"], + "enum": [ + "async", + "sync" + ], "type": "string" }, "required_acks": { "default": 1, - "enum": [-1, 0, 1], + "enum": [ + -1, + 0, + 1 + ], "type": "integer" }, "retry_delay": { @@ -3599,7 +4543,10 @@ "type": "integer" } }, - "required": ["broker_list", "kafka_topic"], + "required": [ + "broker_list", + "kafka_topic" + ], "type": "object" }, "version": 0.1 @@ -3611,7 +4558,9 @@ "type": "string" } }, - "required": ["key"], + "required": [ + "key" + ], "type": "object" }, "priority": 2500, @@ -3635,6 +4584,49 @@ "type": "auth", "version": 0.1 }, + "ldap-auth": { + "consumer_schema": { + "properties": { + "user_dn": { + "type": "string" + } + }, + "required": [ + "user_dn" + ], + "title": "work with consumer object", + "type": "object" + }, + "priority": 2540, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "base_dn": { + "type": "string" + }, + "disable": { + "type": "boolean" + }, + "ldap_uri": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "use_tls": { + "type": "boolean" + } + }, + "required": [ + "base_dn", + "ldap_uri" + ], + "title": "work with route or service object", + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, "limit-conn": { "priority": 1003, "schema": { @@ -3660,12 +4652,13 @@ "type": "boolean" }, "key": { + "type": "string" + }, + "key_type": { + "default": "var", "enum": [ - "consumer_name", - "http_x_forwarded_for", - "http_x_real_ip", - "remote_addr", - "server_addr" + "var", + "var_combination" ], "type": "string" }, @@ -3684,7 +4677,12 @@ "type": "string" } }, - "required": ["burst", "conn", "default_conn_delay", "key"], + "required": [ + "burst", + "conn", + "default_conn_delay", + "key" + ], "type": "object" }, "version": 0.1 @@ -3695,71 +4693,86 @@ "$comment": "this is a mark for our injected plugin schema", "dependencies": { "policy": { - "oneOf": [{ - "properties": { - "policy": { - "enum": ["local"] - } - } - }, { - "properties": { - "policy": { - "enum": ["redis"] - }, - "redis_database": { - "default": 0, - "minimum": 0, - "type": "integer" - }, - "redis_host": { - "minLength": 2, - "type": "string" - }, - "redis_password": { - "minLength": 0, - "type": "string" - }, - "redis_port": { - "default": 6379, - "minimum": 1, - "type": "integer" - }, - "redis_timeout": { - "default": 1000, - "minimum": 1, - "type": "integer" + "oneOf": [ + { + "properties": { + "policy": { + "enum": [ + "local" + ] + } } }, - "required": ["redis_host"] - }, { - "properties": { - "policy": { - "enum": ["redis-cluster"] - }, - "redis_cluster_name": { - "type": "string" - }, - "redis_cluster_nodes": { - "items": { - "maxLength": 100, + { + "properties": { + "policy": { + "enum": [ + "redis" + ] + }, + "redis_database": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "redis_host": { "minLength": 2, "type": "string" }, - "minItems": 2, - "type": "array" - }, - "redis_password": { - "minLength": 0, - "type": "string" + "redis_password": { + "minLength": 0, + "type": "string" + }, + "redis_port": { + "default": 6379, + "minimum": 1, + "type": "integer" + }, + "redis_timeout": { + "default": 1000, + "minimum": 1, + "type": "integer" + } }, - "redis_timeout": { - "default": 1000, - "minimum": 1, - "type": "integer" - } + "required": [ + "redis_host" + ] }, - "required": ["redis_cluster_name", "redis_cluster_nodes"] - }] + { + "properties": { + "policy": { + "enum": [ + "redis-cluster" + ] + }, + "redis_cluster_name": { + "type": "string" + }, + "redis_cluster_nodes": { + "items": { + "maxLength": 100, + "minLength": 2, + "type": "string" + }, + "minItems": 2, + "type": "array" + }, + "redis_password": { + "minLength": 0, + "type": "string" + }, + "redis_timeout": { + "default": 1000, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "redis_cluster_name", + "redis_cluster_nodes" + ] + } + ] } }, "properties": { @@ -3776,12 +4789,23 @@ }, "key": { "default": "remote_addr", - "enum": ["consumer_name", "http_x_forwarded_for", "http_x_real_ip", "remote_addr", "server_addr", "service_id"], + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "var", + "var_combination" + ], "type": "string" }, "policy": { "default": "local", - "enum": ["local", "redis", "redis-cluster"], + "enum": [ + "local", + "redis", + "redis-cluster" + ], "type": "string" }, "rejected_code": { @@ -3803,7 +4827,10 @@ "type": "integer" } }, - "required": ["count", "time_window"], + "required": [ + "count", + "time_window" + ], "type": "object" }, "version": 0.4 @@ -3825,7 +4852,14 @@ "type": "boolean" }, "key": { - "enum": ["consumer_name", "http_x_forwarded_for", "http_x_real_ip", "remote_addr", "server_addr"], + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "var", + "var_combination" + ], "type": "string" }, "nodelay": { @@ -3847,62 +4881,27 @@ "type": "string" } }, - "required": ["burst", "key", "rate"], + "required": [ + "burst", + "key", + "rate" + ], "type": "object" }, "version": 0.1 }, - "log-rotate": { - "priority": 100, - "schema": { - "$comment": "this is a mark for our injected plugin schema", - "properties": { - "disable": { - "type": "boolean" - } - }, - "type": "object" - }, - "scope": "global", - "version": 0.1 - }, - "mqtt-proxy": { - "priority": 1000, + "log-rotate": { + "priority": 100, "schema": { "$comment": "this is a mark for our injected plugin schema", "properties": { "disable": { "type": "boolean" - }, - "protocol_level": { - "type": "integer" - }, - "protocol_name": { - "type": "string" - }, - "upstream": { - "oneOf": [{ - "required": ["host", "port"] - }, { - "required": ["ip", "port"] - }], - "properties": { - "host": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "port": { - "type": "number" - } - }, - "type": "object" } }, - "required": ["protocol_level", "protocol_name", "upstream"], "type": "object" }, + "scope": "global", "version": 0.1 }, "node-status": { @@ -4000,7 +4999,11 @@ "type": "string" } }, - "required": ["client_id", "client_secret", "discovery"], + "required": [ + "client_id", + "client_secret", + "discovery" + ], "type": "object" }, "version": 0.1 @@ -4035,8 +5038,16 @@ "minItems": 1, "type": "array" }, + "cache_control": { + "default": false, + "type": "boolean" + }, "cache_http_status": { - "default": [200, 301, 404], + "default": [ + 200, + 301, + 404 + ], "items": { "description": "http response status", "maximum": 599, @@ -4048,7 +5059,10 @@ "uniqueItems": true }, "cache_key": { - "default": ["$host", "$request_uri"], + "default": [ + "$host", + "$request_uri" + ], "items": { "description": "a key for caching", "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)", @@ -4058,16 +5072,36 @@ "type": "array" }, "cache_method": { - "default": ["GET", "HEAD"], + "default": [ + "GET", + "HEAD" + ], "items": { "description": "supported http method", - "enum": ["GET", "HEAD", "POST"], + "enum": [ + "GET", + "HEAD", + "POST" + ], "type": "string" }, "minItems": 1, "type": "array", "uniqueItems": true }, + "cache_strategy": { + "default": "disk", + "enum": [ + "disk", + "memory" + ], + "type": "string" + }, + "cache_ttl": { + "default": 300, + "minimum": 1, + "type": "integer" + }, "cache_zone": { "default": "disk_cache_one", "maxLength": 100, @@ -4092,7 +5126,7 @@ }, "type": "object" }, - "version": 0.1 + "version": 0.2 }, "proxy-mirror": { "priority": 1010, @@ -4114,7 +5148,9 @@ "type": "number" } }, - "required": ["host"], + "required": [ + "host" + ], "type": "object" }, "version": 0.1 @@ -4138,6 +5174,26 @@ "pattern": "^[0-9a-zA-Z-.]+(:\\d{1,5})?$", "type": "string" }, + "method": { + "description": "proxy route method", + "enum": [ + "COPY", + "DELETE", + "GET", + "HEAD", + "LOCK", + "MKCOL", + "MOVE", + "OPTIONS", + "PATCH", + "POST", + "PROPFIND", + "PUT", + "TRACE", + "UNLOCK" + ], + "type": "string" + }, "regex_uri": { "description": "new uri that substitute from client uri for upstream, lower priority than uri property", "items": { @@ -4150,7 +5206,10 @@ }, "scheme": { "description": "new scheme for upstream", - "enum": ["http", "https"], + "enum": [ + "http", + "https" + ], "type": "string" }, "uri": { @@ -4179,29 +5238,36 @@ }, "trusted_addresses": { "items": { - "anyOf": [{ - "format": "ipv4", - "title": "IPv4", - "type": "string" - }, { - "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", - "title": "IPv4/CIDR", - "type": "string" - }, { - "format": "ipv6", - "title": "IPv6", - "type": "string" - }, { - "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", - "title": "IPv6/CIDR", - "type": "string" - }] + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] }, "minItems": 1, "type": "array" } }, - "required": ["source"], + "required": [ + "source" + ], "type": "object" }, "version": 0.1 @@ -4210,13 +5276,23 @@ "priority": 900, "schema": { "$comment": "this is a mark for our injected plugin schema", - "oneOf": [{ - "required": ["uri"] - }, { - "required": ["regex_uri"] - }, { - "required": ["http_to_https"] - }], + "oneOf": [ + { + "required": [ + "uri" + ] + }, + { + "required": [ + "regex_uri" + ] + }, + { + "required": [ + "http_to_https" + ] + } + ], "properties": { "append_query_string": { "default": false, @@ -4261,11 +5337,18 @@ "priority": 2990, "schema": { "$comment": "this is a mark for our injected plugin schema", - "oneOf": [{ - "required": ["whitelist"] - },{ - "required": ["blacklist"] - }], + "oneOf": [ + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "blacklist" + ] + } + ], "properties": { "blacklist": { "items": { @@ -4308,7 +5391,10 @@ "properties": { "algorithm": { "default": "uuid", - "enum": ["snowflake", "uuid"], + "enum": [ + "snowflake", + "uuid" + ], "type": "string" }, "disable": { @@ -4331,26 +5417,32 @@ "priority": 2800, "schema": { "$comment": "this is a mark for our injected plugin schema", - "anyOf": [{ - "properties": { - "body_schema": { - "type": "object" - } - }, - "required": ["body_schema"], - "title": "Body schema" - }, { - "properties": { - "header_schema": { - "type": "object" - } + "anyOf": [ + { + "required": [ + "header_schema" + ] }, - "required": ["header_schema"], - "title": "Header schema" - }], + { + "required": [ + "body_schema" + ] + } + ], "properties": { + "body_schema": { + "type": "object" + }, "disable": { "type": "boolean" + }, + "header_schema": { + "type": "object" + }, + "rejected_msg": { + "maxLength": 256, + "minLength": 1, + "type": "string" } }, "type": "object" @@ -4426,11 +5518,20 @@ }, "phase": { "default": "access", - "enum": ["access", "balancer", "body_filter", "header_filter", "log", "rewrite"], + "enum": [ + "access", + "balancer", + "body_filter", + "header_filter", + "log", + "rewrite" + ], "type": "string" } }, - "required": ["functions"], + "required": [ + "functions" + ], "type": "object" }, "version": 0.1 @@ -4452,54 +5553,118 @@ }, "phase": { "default": "access", - "enum": ["access", "balancer", "body_filter", "header_filter", "log", "rewrite"], + "enum": [ + "access", + "balancer", + "body_filter", + "header_filter", + "log", + "rewrite" + ], "type": "string" } }, - "required": ["functions"], + "required": [ + "functions" + ], "type": "object" }, "version": 0.1 }, "skywalking": { + "priority": -1100, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "disable": { + "type": "boolean" + }, + "sample_ratio": { + "default": 1, + "maximum": 1, + "minimum": 0.00001, + "type": "number" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "skywalking-logger": { "metadata_schema": { - "additionalProperties": false, "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 408, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "disable": { + "type": "boolean" + }, "endpoint_addr": { - "default": "http://127.0.0.1:12800", + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "skywalking logger", "type": "string" }, - "report_interval": { + "retry_delay": { + "default": 1, + "minimum": 0, "type": "integer" }, "service_instance_name": { "default": "APISIX Instance Name", - "description": "User Service Instance Name", "type": "string" }, "service_name": { "default": "APISIX", - "description": "service name for skywalking", "type": "string" - } - }, - "type": "object" - }, - "priority": -1100, - "schema": { - "$comment": "this is a mark for our injected plugin schema", - "additionalProperties": false, - "properties": { - "disable": { - "type": "boolean" }, - "sample_ratio": { - "default": 1, - "maximum": 1, - "minimum": 0.00001, - "type": "number" + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" } }, + "required": [ + "endpoint_addr" + ], "type": "object" }, "version": 0.1 @@ -4569,7 +5734,14 @@ "type": "integer" } }, - "required": ["access_key_id", "access_key_secret", "host", "logstore", "port", "project"], + "required": [ + "access_key_id", + "access_key_secret", + "host", + "logstore", + "port", + "project" + ], "type": "object" }, "version": 0.1 @@ -4632,7 +5804,10 @@ }, "sock_type": { "default": "tcp", - "enum": ["tcp", "udp"], + "enum": [ + "tcp", + "udp" + ], "type": "string" }, "timeout": { @@ -4645,7 +5820,10 @@ "type": "boolean" } }, - "required": ["host", "port"], + "required": [ + "host", + "port" + ], "type": "object" }, "version": 0.1 @@ -4711,7 +5889,10 @@ "type": "string" } }, - "required": ["host", "port"], + "required": [ + "host", + "port" + ], "type": "object" }, "version": 0.1 @@ -4739,24 +5920,44 @@ "type": "array" }, "weighted_upstreams": { - "default": [{ - "weight": 1 - }], + "default": [ + { + "weight": 1 + } + ], "items": { "properties": { "upstream": { - "oneOf": [{ - "required": ["nodes", "type"] - }, { - "required": ["discovery_type", "service_name", "type"] - }], + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], "properties": { "checks": { - "anyOf": [{ - "required": ["active"] - }, { - "required": ["active", "passive"] - }], + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], "properties": { "active": { "properties": { @@ -4767,7 +5968,10 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 302], + "default": [ + 200, + 302 + ], "items": { "maximum": 599, "minimum": 200, @@ -4822,7 +6026,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -4834,7 +6042,16 @@ "type": "integer" }, "http_statuses": { - "default": [404, 429, 500, 501, 502, 503, 504, 505], + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], "items": { "maximum": 599, "minimum": 200, @@ -4872,7 +6089,27 @@ "healthy": { "properties": { "http_statuses": { - "default": [200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 304, 305, 306, 307, 308], + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], "items": { "maximum": 599, "minimum": 200, @@ -4893,7 +6130,11 @@ }, "type": { "default": "http", - "enum": ["http", "https", "tcp"], + "enum": [ + "http", + "https", + "tcp" + ], "type": "string" }, "unhealthy": { @@ -4905,7 +6146,11 @@ "type": "integer" }, "http_statuses": { - "default": [429, 500, 503], + "default": [ + 429, + 500, + 503 + ], "items": { "maximum": 599, "minimum": 200, @@ -4962,19 +6207,28 @@ }, "hash_on": { "default": "vars", - "enum": ["consumer", "cookie", "header", "vars", "vars_combinations"], + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], "type": "string" }, "id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "keepalive_pool": { "properties": { @@ -5020,52 +6274,63 @@ "type": "string" }, "nodes": { - "anyOf": [{ - "patternProperties": { - ".*": { - "description": "weight of node", - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, { - "items": { - "properties": { - "host": { - "pattern": "^\\*?[0-9a-zA-Z-._]+$", - "type": "string" - }, - "metadata": { - "description": "metadata of node", - "type": "object" - }, - "port": { - "description": "port of node", - "minimum": 1, - "type": "integer" - }, - "priority": { - "default": 0, - "description": "priority of node", - "type": "integer" - }, - "weight": { + "anyOf": [ + { + "patternProperties": { + ".*": { "description": "weight of node", "minimum": 0, "type": "integer" } }, - "required": ["host", "port", "weight"], "type": "object" }, - "type": "array" - }] + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] }, "pass_host": { "default": "pass", "description": "mod of host passing", - "enum": ["node", "pass", "rewrite"], + "enum": [ + "node", + "pass", + "rewrite" + ], "type": "string" }, "retries": { @@ -5078,7 +6343,12 @@ }, "scheme": { "default": "http", - "enum": ["grpc", "grpcs", "http", "https"] + "enum": [ + "grpc", + "grpcs", + "http", + "https" + ] }, "service_name": { "maxLength": 256, @@ -5100,7 +6370,11 @@ "type": "number" } }, - "required": ["connect", "read", "send"], + "required": [ + "connect", + "read", + "send" + ], "type": "object" }, "tls": { @@ -5116,7 +6390,10 @@ "type": "string" } }, - "required": ["client_cert", "client_key"], + "required": [ + "client_cert", + "client_key" + ], "type": "object" }, "type": { @@ -5134,15 +6411,18 @@ "type": "object" }, "upstream_id": { - "anyOf": [{ - "maxLength": 64, - "minLength": 1, - "pattern": "^[a-zA-Z0-9-_.]+$", - "type": "string" - }, { - "minimum": 1, - "type": "integer" - }] + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] }, "weight": { "default": 1, @@ -5242,7 +6522,10 @@ "type": "integer" } }, - "required": ["host", "port"], + "required": [ + "host", + "port" + ], "type": "object" }, "version": 0.1 @@ -5278,7 +6561,9 @@ "type": "string" } }, - "required": ["block_rules"], + "required": [ + "block_rules" + ], "type": "object" }, "version": 0.1 @@ -5300,7 +6585,7 @@ "type": "string" }, "server": { - "default": "http://127.0.0.1:10080", + "default": "http://127.0.0.1:12180", "type": "string" } }, @@ -5337,10 +6622,16 @@ }, "span_version": { "default": 2, - "enum": [1, 2] + "enum": [ + 1, + 2 + ] } }, - "required": ["endpoint", "sample_ratio"], + "required": [ + "endpoint", + "sample_ratio" + ], "type": "object" }, "version": 0.1 @@ -5351,11 +6642,18 @@ "priority": 3000, "schema": { "$comment": "this is a mark for our injected plugin schema", - "oneOf": [{ - "required": ["whitelist"] - }, { - "required": ["blacklist"] - }], + "oneOf": [ + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "blacklist" + ] + } + ], "properties": { "blacklist": { "items": { @@ -5448,7 +6746,14 @@ "type": "boolean" }, "key": { - "enum": ["remote_addr", "server_addr"], + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "var", + "var_combination" + ], "type": "string" }, "only_use_default_delay": { @@ -5456,7 +6761,12 @@ "type": "boolean" } }, - "required": ["burst", "conn", "default_conn_delay", "key"], + "required": [ + "burst", + "conn", + "default_conn_delay", + "key" + ], "type": "object" }, "version": 0.1 @@ -5476,17 +6786,20 @@ "type": "string" }, "upstream": { - "oneOf": [{ + "oneOf": [ + { "required": [ "host", "port" ] - }, { + }, + { "required": [ "ip", "port" ] - }], + } + ], "properties": { "host": { "type": "string" @@ -5501,7 +6814,11 @@ "type": "object" } }, - "required": ["protocol_level", "protocol_name", "upstream"], + "required": [ + "protocol_level", + "protocol_name", + "upstream" + ], "type": "object" }, "version": 0.1 diff --git a/api/internal/handler/schema/plugin_test.go b/api/internal/handler/schema/plugin_test.go index eb61e79..251a45c 100644 --- a/api/internal/handler/schema/plugin_test.go +++ b/api/internal/handler/schema/plugin_test.go @@ -60,7 +60,7 @@ func TestPlugin(t *testing.T) { } } // plugin type - assert.ElementsMatch(t, []string{"basic-auth", "jwt-auth", "hmac-auth", "key-auth", "wolf-rbac"}, authPlugins) + assert.ElementsMatch(t, []string{"basic-auth", "jwt-auth", "hmac-auth", "key-auth", "wolf-rbac", "ldap-auth"}, authPlugins) // consumer schema assert.Equal(t, `{"properties":{"password":{"type":"string"},"username":{"type":"string"}},"required":["password","username"],"title":"work with consumer object","type":"object"}`, basicAuthConsumerSchema) } diff --git a/web/cypress/fixtures/plugin-dataset.json b/web/cypress/fixtures/plugin-dataset.json index 4bbae88..6f02cde 100644 --- a/web/cypress/fixtures/plugin-dataset.json +++ b/web/cypress/fixtures/plugin-dataset.json @@ -596,7 +596,7 @@ "data": { "count": 2, "time_window": 60, "rejected_code": 503, "key": "remote_addr" } }, { - "shouldValid": false, + "shouldValid": true, "data": { "count": 2, "time_window": 60, diff --git a/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js b/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js index d00eb25..109b023 100644 --- a/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js +++ b/web/cypress/integration/consumer/create-upstream-with-limit-req-form.spec.js @@ -30,7 +30,6 @@ context('Create and Delete Consumer', () => { burst: '#burst', key: '#key', nodelay: '#nodelay', - remote_addr: '[title=remote_addr]', monacoViewZones: '.view-zones', }; @@ -40,6 +39,7 @@ context('Create and Delete Consumer', () => { createConsumerSuccess: 'Create Consumer Successfully', deleteConsumerSuccess: 'Delete Consumer Successfully', time: 2, + key: 'remote_addr', }; beforeEach(() => { @@ -87,8 +87,7 @@ context('Create and Delete Consumer', () => { cy.get(selector.rate).type(data.time); cy.get(selector.burst).type(data.time); - cy.get(selector.key).click(); - cy.get(selector.remote_addr).click(); + cy.get(selector.key).type(data.key); cy.get(selector.nodelay).click(); cy.get(selector.drawer).within(() => { cy.contains('Submit').click({ diff --git a/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js b/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js index 8eb41ae..3636823 100644 --- a/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js +++ b/web/cypress/integration/consumer/create-with-limit-conn-form.spec.js @@ -33,7 +33,6 @@ context('Create and delete consumer with limit-conn plugin form', () => { only_use_default_delay: '#only_use_default_delay', key: '#key', rejected_code: '#rejected_code', - title: '[title="remote_addr"]', monacoViewZones: '.view-zones', }; @@ -91,11 +90,7 @@ context('Create and delete consumer with limit-conn plugin form', () => { cy.get(selector.burst).type(data.burst); cy.get(selector.default_conn_delay).type(data.default_conn_delay); cy.get(selector.only_use_default_delay).click(); - cy.get(selector.key).click(); - cy.get(selector.selectDropdown).should('be.visible'); - cy.get(selector.title).click({ - timeout: 5000, - }); + cy.get(selector.key).type(data.key); cy.get(selector.disabledSwitcher).click(); cy.get(selector.drawer).within(() => { cy.contains('Submit').click({ diff --git a/web/cypress/integration/consumer/create_and_delete_consumer.spec.js b/web/cypress/integration/consumer/create_and_delete_consumer.spec.js index ba9ec3c..74c73c4 100644 --- a/web/cypress/integration/consumer/create_and_delete_consumer.spec.js +++ b/web/cypress/integration/consumer/create_and_delete_consumer.spec.js @@ -60,7 +60,7 @@ context('Create and Delete Consumer', () => { cy.contains('Next').click(); cy.get(selector.notification).should( 'contain', - 'Please enable at least one of the following authentication plugin: basic-auth, hmac-auth, jwt-auth, key-auth, wolf-rbac', + 'Please enable at least one of the following authentication plugin: basic-auth, hmac-auth, jwt-auth, key-auth, ldap-auth, wolf-rbac', ); cy.get(selector.notificationCloseIcon).click().should('not.exist'); diff --git a/web/cypress/integration/route/create-route-with-limit-req-form.spec.js b/web/cypress/integration/route/create-route-with-limit-req-form.spec.js index 60f9664..d8f8c22 100644 --- a/web/cypress/integration/route/create-route-with-limit-req-form.spec.js +++ b/web/cypress/integration/route/create-route-with-limit-req-form.spec.js @@ -34,7 +34,6 @@ context('Create and delete route with limit-req form', () => { rate: '#rate', burst: '#burst', key: '#key', - remote_addr: '[title=remote_addr]', }; const data = { @@ -42,6 +41,7 @@ context('Create and delete route with limit-req form', () => { submitSuccess: 'Submit Successfully', port: '80', weight: 1, + key: 'remote_addr', }; beforeEach(() => { @@ -91,8 +91,7 @@ context('Create and delete route with limit-req form', () => { // config limit-req form cy.get(selector.rate).type(1); cy.get(selector.burst).type(0); - cy.get(selector.key).click(); - cy.get(selector.remote_addr).click(); + cy.get(selector.key).type(data.key); cy.get(selector.drawer).within(() => { cy.contains('Submit').click({ force: true, diff --git a/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js b/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js index 6669c17..721d317 100644 --- a/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js +++ b/web/cypress/integration/route/create-route-with-proxy-rewrite-plugin.spec.js @@ -35,6 +35,8 @@ context('create route with proxy-rewrite plugin', () => { uriRewriteReg: '#proxyRewrite_regex_uri_0', uriRewriteTemp: '#proxyRewrite_regex_uri_1', newHost: '#proxyRewrite_host', + methodRewriteSelect: '[data-cy=proxyRewrite-method]', + methodRewriteSelectOption: '.ant-select-item-option', buttonCreateNewRewriteHeader: '[data-cy=create-new-rewrite-header]', rewriteHeaderKey1: '#proxyRewrite_kvHeaders_0_key', rewriteHeaderValue1: '#proxyRewrite_kvHeaders_0_value', @@ -93,6 +95,10 @@ context('create route with proxy-rewrite plugin', () => { cy.get(selector.keepHost).click(); cy.get(selector.newHost).should('not.exist'); + // method rewrite + cy.get(selector.methodRewriteSelect).click(); + cy.get(selector.methodRewriteSelectOption).contains('POST').click(); + // new header key value input after createNewRewriteHeader button clicked cy.get(selector.buttonCreateNewRewriteHeader).click(); cy.get(selector.rewriteHeaderKey1).should('be.visible').type(data.rewriteHeaderKey1); @@ -130,6 +136,8 @@ context('create route with proxy-rewrite plugin', () => { cy.get(selector.newHost).should('not.exist'); + cy.get(selector.methodRewriteSelect).contains('POST').should('exist'); + cy.get(selector.rewriteHeaderKey1).should('have.value', data.rewriteHeaderKey1); cy.get(selector.rewriteHeaderValue1).should('have.value', data.rewriteHeaderValue1); cy.get(selector.rewriteHeaderKey2).should('have.value', data.rewriteHeaderKey2); diff --git a/web/src/components/Plugin/UI/limit-conn.tsx b/web/src/components/Plugin/UI/limit-conn.tsx index 3a81795..7542c17 100644 --- a/web/src/components/Plugin/UI/limit-conn.tsx +++ b/web/src/components/Plugin/UI/limit-conn.tsx @@ -83,13 +83,13 @@ const LimitConn: React.FC<Props> = ({ form, schema }) => { <Switch defaultChecked={onlyUseDefaultDelay} /> </Form.Item> <Form.Item - label="key" - required - name="key" - tooltip={formatMessage({ id: 'component.pluginForm.limit-conn.key.tooltip' })} + label="key_type" + name="key_type" + tooltip={formatMessage({ id: 'component.pluginForm.limit-conn.key_type.tooltip' })} + initialValue={properties.key_type.default} > <Select> - {properties.key.enum.map((item: string) => { + {properties.key_type.enum.map((item: string) => { return ( <Select.Option value={item} key={item}> {item} @@ -99,6 +99,14 @@ const LimitConn: React.FC<Props> = ({ form, schema }) => { </Select> </Form.Item> <Form.Item + label="key" + name="key" + required + tooltip={formatMessage({ id: 'component.pluginForm.limit-conn.key.tooltip' })} + > + <Input min={1} /> + </Form.Item> + <Form.Item label="rejected_code" name="rejected_code" tooltip={formatMessage({ id: 'component.pluginForm.limit-conn.rejected_code.tooltip' })} diff --git a/web/src/components/Plugin/UI/limit-count.tsx b/web/src/components/Plugin/UI/limit-count.tsx index 94d25a8..adb384f 100644 --- a/web/src/components/Plugin/UI/limit-count.tsx +++ b/web/src/components/Plugin/UI/limit-count.tsx @@ -27,7 +27,7 @@ type Props = { type PolicyProps = 'local' | 'redis' | 'redis-cluster'; -type FormsProps={ +type FormsProps = { schema: Record<string, any> | undefined; }; @@ -57,56 +57,74 @@ const RedisForm: React.FC<FormsProps> = ({ schema }) => { const { formatMessage } = useIntl(); const properties = schema?.properties; - return (<> - <Form.Item - label="redis_host" - name="redis_host" - tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })} - rules={[ - { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` }, - { min: properties.redis_host.minLength, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) } - ]} - validateTrigger={['onChange', 'onBlur', 'onClick']} - > - <Input /> - </Form.Item> - <Form.Item - initialValue={properties.redis_port.default} - label="redis_port" - name="redis_port" - tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })} - > - <InputNumber min={properties.redis_port.minimum} max={properties.redis_port.maximum || 65535} /> - </Form.Item> - <Form.Item - label="redis_password" - name="redis_password" - tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })} - rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]} - validateTrigger={['onChange', 'onBlur', 'onClick']} - > - <Input /> - </Form.Item> - <Form.Item - initialValue={properties.redis_database.default} - label="redis_database" - name="redis_database" - tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })} - > - <InputNumber min={properties.redis_database.minimum} /> - </Form.Item> - <Form.Item - initialValue={properties.redis_timeout.default} - label="redis_timeout" - name="redis_timeout" - tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })} - > - <InputNumber min={properties.redis_timeout.minimum} /> - </Form.Item> - </>) -} + return ( + <> + <Form.Item + label="redis_host" + name="redis_host" + tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })} + rules={[ + { + required: true, + message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host`, + }, + { + min: properties.redis_host.minLength, + message: formatMessage({ + id: 'component.pluginForm.limit-count.atLeast2Characters.rule', + }), + }, + ]} + validateTrigger={['onChange', 'onBlur', 'onClick']} + > + <Input /> + </Form.Item> + <Form.Item + initialValue={properties.redis_port.default} + label="redis_port" + name="redis_port" + tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })} + > + <InputNumber + min={properties.redis_port.minimum} + max={properties.redis_port.maximum || 65535} + /> + </Form.Item> + <Form.Item + label="redis_password" + name="redis_password" + tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })} + rules={[ + { + required: true, + message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password`, + }, + ]} + validateTrigger={['onChange', 'onBlur', 'onClick']} + > + <Input /> + </Form.Item> + <Form.Item + initialValue={properties.redis_database.default} + label="redis_database" + name="redis_database" + tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })} + > + <InputNumber min={properties.redis_database.minimum} /> + </Form.Item> + <Form.Item + initialValue={properties.redis_timeout.default} + label="redis_timeout" + name="redis_timeout" + tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })} + > + <InputNumber min={properties.redis_timeout.minimum} /> + </Form.Item> + </> + ); +}; -const RedisClusterForm: React.FC <FormsProps> = ({ schema }) => { +const RedisClusterForm: React.FC<FormsProps> = ({ schema }) => { const { formatMessage } = useIntl(); const properties = schema?.properties; const nodesPro = properties.redis_cluster_nodes; @@ -169,28 +187,30 @@ const RedisClusterForm: React.FC <FormsProps> = ({ schema }) => { </Form.Item> </Col> <Col style={{ ...removeBtnStyle, marginLeft: -10 }}> - {fields.length > minLength && + {fields.length > minLength && ( <MinusCircleOutlined className="dynamic-delete-button" onClick={() => { remove(field.name); }} /> - } + )} </Col> </Row> ))} </Form.Item> <Form.Item {...FORM_ITEM_WITHOUT_LABEL}> - {fields.length < maxLength && <Button - type="dashed" - onClick={() => { - add(); - }} - > - <PlusOutlined /> {formatMessage({ id: 'component.global.add' })} - </Button>} + {fields.length < maxLength && ( + <Button + type="dashed" + onClick={() => { + add(); + }} + > + <PlusOutlined /> {formatMessage({ id: 'component.global.add' })} + </Button> + )} </Form.Item> </div> ); @@ -216,9 +236,9 @@ const RedisClusterForm: React.FC <FormsProps> = ({ schema }) => { }; const LimitCount: React.FC<Props> = ({ form, schema }) => { - const propertires = schema?.properties; - const [policy, setPoicy] = useState<PolicyProps>(propertires.policy.default); - const { formatMessage } = useIntl() + const properties = schema?.properties; + const [policy, setPoicy] = useState<PolicyProps>(properties.policy.default); + const { formatMessage } = useIntl(); const dependSchema = schema?.dependencies.policy.oneOf; return ( @@ -235,7 +255,7 @@ const LimitCount: React.FC<Props> = ({ form, schema }) => { tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })} validateTrigger={['onChange', 'onBlur', 'onClick']} > - <InputNumber min={propertires.count.exclusiveMinimum} /> + <InputNumber min={properties.count.exclusiveMinimum} /> </Form.Item> <Form.Item label="time_window" @@ -249,25 +269,41 @@ const LimitCount: React.FC<Props> = ({ form, schema }) => { tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })} validateTrigger={['onChange', 'onBlur', 'onClick']} > - <InputNumber min={propertires.time_window.exclusiveMinimum} /> + <InputNumber min={properties.time_window.exclusiveMinimum} /> + </Form.Item> + <Form.Item + label="key_type" + name="key_type" + tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key_type.tooltip' })} + initialValue={properties.key_type.default} + > + <Select> + {properties.key_type.enum.map((item: string) => { + return ( + <Select.Option value={item} key={item}> + {item} + </Select.Option> + ); + })} + </Select> </Form.Item> <Form.Item - initialValue={propertires.key.default} label="key" name="key" tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key.tooltip' })} > - <Select> - {propertires.key.enum.map((item: string) => (<Select.Option value={item} key={item}>{item}</Select.Option>))} - </Select> + <Input min={1} /> </Form.Item> <Form.Item - initialValue={propertires.rejected_code.default} + initialValue={properties.rejected_code.default} label="rejected_code" name="rejected_code" tooltip={formatMessage({ id: 'component.pluginForm.limit-count.rejected_code.tooltip' })} > - <InputNumber min={propertires.rejected_code.minimum} max={propertires.rejected_code.maximum} /> + <InputNumber + min={properties.rejected_code.minimum} + max={properties.rejected_code.maximum} + /> </Form.Item> <Form.Item initialValue={policy} @@ -275,8 +311,16 @@ const LimitCount: React.FC<Props> = ({ form, schema }) => { name="policy" tooltip={formatMessage({ id: 'component.pluginForm.limit-count.policy.tooltip' })} > - <Select onChange={(e: PolicyProps) => { setPoicy(e) }}> - {propertires.policy.enum.map((item: string) => (<Select.Option value={item} key={item}>{item}</Select.Option>))} + <Select + onChange={(e: PolicyProps) => { + setPoicy(e); + }} + > + {properties.policy.enum.map((item: string) => ( + <Select.Option value={item} key={item}> + {item} + </Select.Option> + ))} </Select> </Form.Item> <Form.Item diff --git a/web/src/components/Plugin/UI/limit-req.tsx b/web/src/components/Plugin/UI/limit-req.tsx index e01e331..f055f6e 100644 --- a/web/src/components/Plugin/UI/limit-req.tsx +++ b/web/src/components/Plugin/UI/limit-req.tsx @@ -16,7 +16,7 @@ */ import React from 'react'; import type { FormInstance } from 'antd/es/form'; -import { Form, InputNumber, Select, Switch } from 'antd'; +import { Form, Input, InputNumber, Select, Switch } from 'antd'; import { useIntl } from 'umi'; type Props = { @@ -36,7 +36,7 @@ export const FORM_ITEM_LAYOUT = { const LimitReq: React.FC<Props> = ({ form, schema }) => { const { formatMessage } = useIntl(); - const propertires = schema?.properties; + const properties = schema?.properties; return ( <Form form={form} {...FORM_ITEM_LAYOUT}> <Form.Item @@ -51,7 +51,7 @@ const LimitReq: React.FC<Props> = ({ form, schema }) => { tooltip={formatMessage({ id: 'component.pluginForm.limit-req.rate.tooltip' })} validateTrigger={['onChange', 'onBlur', 'onClick']} > - <InputNumber min={propertires.rate.exclusiveMinimum} required /> + <InputNumber min={properties.rate.exclusiveMinimum} required /> </Form.Item> <Form.Item label="burst" @@ -65,22 +65,16 @@ const LimitReq: React.FC<Props> = ({ form, schema }) => { tooltip={formatMessage({ id: 'component.pluginForm.limit-req.burst.tooltip' })} validateTrigger={['onChange', 'onBlur', 'onClick']} > - <InputNumber min={propertires.burst.minimum} required /> + <InputNumber min={properties.burst.minimum} required /> </Form.Item> <Form.Item - label="key" - name="key" - rules={[ - { - required: true, - message: `${formatMessage({ id: 'component.global.pleaseChoose' })} key`, - }, - ]} - tooltip={formatMessage({ id: 'component.pluginForm.limit-req.key.tooltip' })} - validateTrigger={['onChange', 'onBlur', 'onClick']} + label="key_type" + name="key_type" + tooltip={formatMessage({ id: 'component.pluginForm.limit-req.key_type.tooltip' })} + initialValue={properties.key_type.default} > <Select> - {propertires.key.enum.map((item: string) => { + {properties.key_type.enum.map((item: string) => { return ( <Select.Option value={item} key={item}> {item} @@ -90,14 +84,22 @@ const LimitReq: React.FC<Props> = ({ form, schema }) => { </Select> </Form.Item> <Form.Item + label="key" + name="key" + required + tooltip={formatMessage({ id: 'component.pluginForm.limit-req.key.tooltip' })} + > + <Input min={1} /> + </Form.Item> + <Form.Item label="rejected_code" name="rejected_code" - initialValue={propertires.rejected_code.default} + initialValue={properties.rejected_code.default} tooltip={formatMessage({ id: 'component.pluginForm.limit-req.rejected_code.tooltip' })} > <InputNumber - min={propertires.rejected_code.minimum} - max={propertires.rejected_code.maximum} + min={properties.rejected_code.minimum} + max={properties.rejected_code.maximum} /> </Form.Item> <Form.Item diff --git a/web/src/components/Plugin/UI/plugin.tsx b/web/src/components/Plugin/UI/plugin.tsx index f0dd43c..5fe0533 100644 --- a/web/src/components/Plugin/UI/plugin.tsx +++ b/web/src/components/Plugin/UI/plugin.tsx @@ -60,21 +60,21 @@ export const PluginForm: React.FC<Props> = ({ name, schema, renderForm, form }) switch (name) { case 'api-breaker': - return <ApiBreaker form={form} schema={schema} /> + return <ApiBreaker form={form} schema={schema} />; case 'basic-auth': return <BasicAuth form={form} schema={schema} />; case 'limit-count': - return <LimitCount form={form} schema={schema} /> + return <LimitCount form={form} schema={schema} />; case 'cors': - return <Cors form={form} schema={schema} /> + return <Cors form={form} schema={schema} />; case 'limit-req': return <LimitReq form={form} schema={schema} />; case 'proxy-mirror': - return <ProxyMirror form={form} schema={schema} /> + return <ProxyMirror form={form} schema={schema} />; case 'limit-conn': return <LimitConn form={form} schema={schema} />; case 'referer-restriction': - return <RefererRestriction form={form} schema={schema} /> + return <RefererRestriction form={form} schema={schema} />; default: return null; } diff --git a/web/src/components/Plugin/data.tsx b/web/src/components/Plugin/data.tsx index 79d1dfb..143b703 100644 --- a/web/src/components/Plugin/data.tsx +++ b/web/src/components/Plugin/data.tsx @@ -224,4 +224,22 @@ export const PLUGIN_LIST = { type: PluginType.other, hidden: true, }, + 'authz-casbin': { + type: PluginType.authentication, + }, + 'ldap-auth': { + type: PluginType.authentication, + }, + datadog: { + type: PluginType.observability, + }, + 'skywalking-logger': { + type: PluginType.observability, + }, + 'azure-functions': { + type: PluginType.serverless, + }, + 'ua-restriction': { + type: PluginType.security, + }, }; diff --git a/web/src/components/Plugin/locales/en-US.ts b/web/src/components/Plugin/locales/en-US.ts index ec28027..d62764d 100644 --- a/web/src/components/Plugin/locales/en-US.ts +++ b/web/src/components/Plugin/locales/en-US.ts @@ -88,8 +88,10 @@ export default { 'the number of excessive concurrent requests (or connections) allowed to be delayed.', 'component.pluginForm.limit-conn.default_conn_delay.tooltip': 'the latency seconds of request when concurrent requests exceeding conn but below (conn + burst).', + 'component.pluginForm.limit-conn.key_type.tooltip': + 'The key type, support: "var" (single var) and "var_combination" (combine var)', 'component.pluginForm.limit-conn.key.tooltip': - 'to limit the concurrency level. For example, one can use the host name (or server zone) as the key so that we limit concurrency per host name. Otherwise, we can also use the client address as the key so that we can avoid a single client from flooding our service with too many parallel connections or requests. Now accept those as key: "remote_addr"(client\'s IP), "server_addr"(server\'s IP), "X-Forwarded-For/X-Real-IP" in request header, "consumer_name"(consumer\'s username).', + 'to limit the concurrency level. For example, one can use the host name (or server zone) as the key so that we limit concurrency per host name. Otherwise, we can also use the client address as the key so that we can avoid a single client from flooding our service with too many parallel connections or requests.', 'component.pluginForm.limit-conn.rejected_code.tooltip': 'returned when the request exceeds conn + burst will be rejected.', 'component.pluginForm.limit-conn.rejected_msg.tooltip': @@ -104,8 +106,9 @@ export default { 'The specified request rate (number per second) threshold. Requests exceeding this rate (and below burst) will get delayed to conform to the rate.', 'component.pluginForm.limit-req.burst.tooltip': 'The number of excessive requests per second allowed to be delayed. Requests exceeding this hard limit will get rejected immediately.', - 'component.pluginForm.limit-req.key.tooltip': - 'The user specified key to limit the rate, now accept those as key: "remote_addr"(client\'s IP), "server_addr"(server\'s IP), "X-Forwarded-For/X-Real-IP" in request header, "consumer_name"(consumer\'s username).', + 'component.pluginForm.limit-req.key_type.tooltip': + 'The key type, support: "var" (single var) and "var_combination" (combine var)', + 'component.pluginForm.limit-req.key.tooltip': 'The user specified key to limit the rate.', 'component.pluginForm.limit-req.rejected_code.tooltip': 'The HTTP status code returned when the request exceeds the threshold is rejected.', 'component.pluginForm.limit-req.nodelay.tooltip': @@ -120,8 +123,9 @@ export default { 'component.pluginForm.limit-count.count.tooltip': 'The specified number of requests threshold.', 'component.pluginForm.limit-count.time_window.tooltip': 'The time window in seconds before the request count is reset.', - 'component.pluginForm.limit-count.key.tooltip': - 'The user specified key to limit the count, now accept those as key: "remote_addr"(client\'s IP), "server_addr"(server\'s IP), "X-Forwarded-For/X-Real-IP" in request header, "consumer_name"(consumer\'s username) and "service_id".', + 'component.pluginForm.limit-count.key_type.tooltip': + 'The key type, support: "var" (single var) and "var_combination" (combine var)', + 'component.pluginForm.limit-count.key.tooltip': 'The user specified key to limit the count.', 'component.pluginForm.limit-count.rejected_code.tooltip': 'The HTTP status code returned when the request exceeds the threshold is rejected, default 503.', 'component.pluginForm.limit-count.policy.tooltip': diff --git a/web/src/components/Plugin/locales/zh-CN.ts b/web/src/components/Plugin/locales/zh-CN.ts index 04cacbd..c76f2d3 100644 --- a/web/src/components/Plugin/locales/zh-CN.ts +++ b/web/src/components/Plugin/locales/zh-CN.ts @@ -81,8 +81,10 @@ export default { 'component.pluginForm.limit-conn.burst.tooltip': '允许被延迟处理的并发请求数。', 'component.pluginForm.limit-conn.default_conn_delay.tooltip': '默认的典型连接(或请求)的处理延迟时间。', + 'component.pluginForm.limit-conn.key_type.tooltip': + '关键字类型,支持:var(单变量)和 var_combination(组合变量)', 'component.pluginForm.limit-conn.key.tooltip': - '用户指定的限制并发级别的关键字,可以是客户端 IP 或服务端 IP。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名的并发性。 否则,我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端用太多的并行连接或请求淹没我们的服务。当前接受的 key 有:"remote_addr"(客户端 IP 地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP", "consumer_name"(consumer 的 username)。', + '用户指定的限制并发级别的关键字,可以是客户端 IP 或服务端 IP。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名的并发性。 否则,我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端用太多的并行连接或请求淹没我们的服务。', 'component.pluginForm.limit-conn.rejected_code.tooltip': '当请求超过 conn + burst 这个阈值时,返回的 HTTP 状态码。', 'component.pluginForm.limit-conn.rejected_msg.tooltip': @@ -97,8 +99,9 @@ export default { '指定的请求速率(以秒为单位),请求速率超过 rate 但没有超过 (rate + brust)的请求会被加上延时。', 'component.pluginForm.limit-req.burst.tooltip': '请求速率超过(rate + brust)的请求会被直接拒绝。', - 'component.pluginForm.limit-req.key.tooltip': - '用来做请求计数的依据,当前接受的 key 有:"remote_addr"(客户端IP地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP","consumer_name"(consumer 的 username).', + 'component.pluginForm.limit-req.key_type.tooltip': + '关键字类型,支持:var(单变量)和 var_combination(组合变量)', + 'component.pluginForm.limit-req.key.tooltip': '用来做请求计数的依据', 'component.pluginForm.limit-req.rejected_code.tooltip': '当请求超过阈值被拒绝时,返回的 HTTP 状态码。', 'component.pluginForm.limit-req.nodelay.tooltip': '开启后突发的请求不会延迟', @@ -112,8 +115,10 @@ export default { 'component.pluginForm.limit-count.count.tooltip': '指定时间窗口内的请求数量阈值。', 'component.pluginForm.limit-count.time_window.tooltip': '时间窗口的大小(以秒为单位),超过这个时间就会重置。', + 'component.pluginForm.limit-count.key_type.tooltip': + '关键字类型,支持:var(单变量)和 var_combination(组合变量)', 'component.pluginForm.limit-count.key.tooltip': - '用来做请求计数的有效值。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名规定时间内的请求次数。我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端规定时间内多次的连接我们的服务。当前接受的 key 有:"remote_addr"(客户端 IP 地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP", "consumer_name"(consumer 的 username), "service_id" 。', + '用来做请求计数的有效值。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名规定时间内的请求次数。我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端规定时间内多次的连接我们的服务。', 'component.pluginForm.limit-count.rejected_code.tooltip': '当请求超过阈值被拒绝时,返回的 HTTP 状态码。', 'component.pluginForm.limit-count.policy.tooltip': diff --git a/web/src/pages/Route/components/Step1/ProxyRewrite.tsx b/web/src/pages/Route/components/Step1/ProxyRewrite.tsx index 9844305..5359fbb 100644 --- a/web/src/pages/Route/components/Step1/ProxyRewrite.tsx +++ b/web/src/pages/Route/components/Step1/ProxyRewrite.tsx @@ -16,7 +16,7 @@ */ import React from 'react'; import Form from 'antd/es/form'; -import { Button, Input, Radio, Row, Col } from 'antd'; +import { Button, Input, Radio, Row, Col, Select } from 'antd'; import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons'; import { useIntl } from 'umi'; @@ -279,6 +279,46 @@ const ProxyRewrite: React.FC<RouteModule.Step1PassProps> = ({ form, disabled }) ); }; + const MethodRewriteType: React.FC = () => { + const methods = [ + 'GET', + 'POST', + 'PUT', + 'DELETE', + 'PATCH', + 'OPTIONS', + 'HEAD', + 'TRACE', + 'MKCOL', + 'COPY', + 'MOVE', + 'PROPFIND', + 'LOCK', + 'UNLOCK', + ]; + return ( + <React.Fragment> + <Form.Item + label={formatMessage({ id: 'page.route.form.itemLabel.methodRewrite' })} + name={['proxyRewrite', 'method']} + wrapperCol={{ span: 3 }} + initialValue="" + > + <Select data-cy="proxyRewrite-method"> + <Select.Option value=""> + {formatMessage({ id: 'page.route.select.option.methodRewriteNone' })} + </Select.Option> + {methods.map((method) => ( + <Select.Option value={method} key={method}> + {method} + </Select.Option> + ))} + </Select> + </Form.Item> + </React.Fragment> + ); + }; + const Headers: React.FC = () => { return ( <Form.List name={['proxyRewrite', 'kvHeaders']} initialValue={[{}]}> @@ -351,6 +391,7 @@ const ProxyRewrite: React.FC<RouteModule.Step1PassProps> = ({ form, disabled }) <SchemeComponent /> <URIRewriteType /> <HostRewriteType /> + <MethodRewriteType /> <Headers /> </PanelSection> ); diff --git a/web/src/pages/Route/locales/en-US.ts b/web/src/pages/Route/locales/en-US.ts index db78212..0a5e6a0 100644 --- a/web/src/pages/Route/locales/en-US.ts +++ b/web/src/pages/Route/locales/en-US.ts @@ -98,6 +98,7 @@ export default { 'page.route.unpublished': 'UnPublished', 'page.route.select.option.inputManually': 'Input Manually', + 'page.route.select.option.methodRewriteNone': 'Not modify', 'page.route.form.itemLabel.domainNameOrIp': 'Domain Name/IP', 'page.route.form.itemExtraMessage.domainNameOrIp': 'When using Domain Name, it will analysis the local: /etc/resolv.conf by default', @@ -110,6 +111,7 @@ export default { 'page.route.form.itemLabel.template': 'Template', 'page.route.form.itemLabel.URIRewriteType': 'URI Override', 'page.route.form.itemLabel.hostRewriteType': 'Host Override', + 'page.route.form.itemLabel.methodRewrite': 'Method Override', 'page.route.form.itemLabel.redirectURI': 'Redirect URI', 'page.route.input.placeholder.newPath': 'For example: /foo/bar/index.html', diff --git a/web/src/pages/Route/locales/zh-CN.ts b/web/src/pages/Route/locales/zh-CN.ts index 64adf5e..4c0e7ff 100644 --- a/web/src/pages/Route/locales/zh-CN.ts +++ b/web/src/pages/Route/locales/zh-CN.ts @@ -74,6 +74,7 @@ export default { 'page.route.form.itemLabel.redirectCustom': '自定义重定向', 'page.route.form.itemLabel.URIRewriteType': '路径改写', 'page.route.form.itemLabel.hostRewriteType': '域名改写', + 'page.route.form.itemLabel.methodRewrite': 'HTTP 方法改写', 'page.route.form.itemLabel.headerRewrite': '请求头改写', 'page.route.form.itemLabel.redirectURI': '重定向路径', 'page.route.form.itemExtraMessage.domain': '路由匹配的域名列表。支持泛域名,如:*.test.com', @@ -97,6 +98,7 @@ export default { 'page.route.select.option.redirect301': '301(永久重定向)', 'page.route.select.option.redirect302': '302(临时重定向)', 'page.route.select.option.inputManually': '手动填写', + 'page.route.select.option.methodRewriteNone': '不改写', // steps 'page.route.steps.stepTitle.defineApiRequest': '设置路由信息', diff --git a/web/src/pages/Route/transform.ts b/web/src/pages/Route/transform.ts index a8a4f8a..14d4fa7 100644 --- a/web/src/pages/Route/transform.ts +++ b/web/src/pages/Route/transform.ts @@ -23,11 +23,15 @@ import { convertToFormData } from '@/components/Upstream/service'; export const transformProxyRewrite2Plugin = ( data: RouteModule.ProxyRewrite, ): RouteModule.ProxyRewrite => { - let omitFieldsList: string[] = ['kvHeaders']; + const omitFieldsList: string[] = ['kvHeaders']; let headers: Record<string, string> = {}; if (data.scheme !== 'http' && data.scheme !== 'https') { - omitFieldsList = [...omitFieldsList, 'scheme']; + omitFieldsList.push('scheme'); + } + + if (data.method === '') { + omitFieldsList.push('method'); } (data.kvHeaders || []).forEach((kvHeader) => { @@ -84,6 +88,7 @@ const transformProxyRewrite2Formdata = (pluginsData: any) => { case 'uri': case 'regex_uri': case 'host': + case 'method': proxyRewriteData[key] = pluginsData[key]; break; case 'headers': diff --git a/web/src/pages/Route/typing.d.ts b/web/src/pages/Route/typing.d.ts index 5d16958..2eefa15 100644 --- a/web/src/pages/Route/typing.d.ts +++ b/web/src/pages/Route/typing.d.ts @@ -137,6 +137,7 @@ declare namespace RouteModule { uri?: string; regex_uri?: string[]; host?: string; + method?: string; kvHeaders?: Kvobject[]; headers?: Record<string, string>; };