You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by ju...@apache.org on 2020/10/16 09:25:26 UTC
[apisix-dashboard] 01/01: feat: sync apis
This is an automated email from the ASF dual-hosted git repository.
juzhiyuan pushed a commit to branch feat-fe-refactor-sync
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git
commit 1819a2e3c98c6343476ab2918570155c4404fbe4
Merge: 43af140 061d9a2
Author: juzhiyuan <ju...@apache.org>
AuthorDate: Fri Oct 16 17:25:03 2020 +0800
feat: sync apis
.actions/ASF-Release.cfg | 5 +
.github/workflows/api_ci.yml | 82 +-
.github/workflows/api_cicd.yml | 32 +-
api/Dockerfile | 14 +
api/build-tools/json.lua | 400 ++++
api/build-tools/schema-sync.lua | 133 ++
api/conf/conf.go | 65 +-
api/conf/schema.json | 2203 ++++++++++++++++++++
api/errno/error.go | 170 --
api/filter/authentication.go | 32 +-
api/filter/logging.go | 5 +-
api/filter/request_id.go | 1 +
api/go.mod | 22 +-
api/go.sum | 402 +++-
api/internal/core/entity/entity.go | 182 ++
api/internal/core/entity/query.go | 153 ++
api/internal/core/storage/etcd.go | 138 ++
.../copy.go => internal/core/storage/storage.go} | 44 +-
api/internal/core/storage/storage_mock.go | 116 ++
api/internal/core/store/query.go | 151 ++
api/internal/core/store/selector.go | 144 ++
api/internal/core/store/selector_test.go | 285 +++
api/internal/core/store/store.go | 326 +++
api/internal/core/store/store_test.go | 763 +++++++
api/internal/core/store/storehub.go | 145 ++
api/internal/core/store/test_case.json | 19 +
api/internal/core/store/validate.go | 155 ++
api/internal/core/store/validate_mock.go | 24 +
api/internal/core/store/validate_test.go | 140 ++
.../handler/authentication/authentication.go | 78 +
.../handler/authentication/authentication_test.go | 67 +
api/internal/handler/consumer/consumer.go | 149 ++
api/internal/handler/consumer/consumer_test.go | 200 ++
.../base_test.go => internal/handler/handler.go} | 10 +-
api/{route => internal/handler/healthz}/healthz.go | 28 +-
api/internal/handler/plugin/plugin.go | 65 +
.../handler/plugin/plugin_test.go} | 47 +-
api/internal/handler/route/route.go | 345 +++
api/internal/handler/route/route_test.go | 847 ++++++++
api/internal/handler/service/service.go | 175 ++
api/internal/handler/service/service_test.go | 152 ++
api/internal/handler/ssl/ssl.go | 373 ++++
api/{route => internal/handler/ssl}/ssl_test.go | 132 +-
api/internal/handler/upstream/upstream.go | 252 +++
api/internal/handler/upstream/upstream_test.go | 183 ++
api/{route/base.go => internal/route.go} | 39 +-
api/{route/healthz.go => internal/utils/closer.go} | 27 +-
.../utils/consts/api_error.go} | 38 +-
.../utils/consts/error.go} | 25 +-
api/internal/utils/utils.go | 79 +
.../base_test.go => internal/utils/utils_test.go} | 29 +-
api/log/log.go | 55 +
api/main.go | 28 +-
api/route/authentication.go | 68 -
api/route/authentication_test.go | 52 -
api/route/consumer.go | 143 --
api/route/consumer_test.go | 98 -
api/route/plugin.go | 59 -
api/route/route.go | 631 ------
api/route/route_group.go | 233 ---
api/route/route_group_test.go | 131 --
api/route/route_test.go | 229 --
api/route/ssl.go | 197 --
api/route/upstream.go | 384 ----
api/script/db/schema.sql | 71 -
api/service/base.go | 49 -
api/service/consumer.go | 349 ----
api/service/consumer_test.go | 133 --
api/service/plugin.go | 62 -
api/service/route.go | 652 ------
api/service/route_group.go | 155 --
api/service/route_group_test.go | 120 --
api/service/route_test.go | 329 ---
api/service/ssl.go | 589 ------
api/service/ssl_test.go | 352 ----
api/service/upstream.go | 271 ---
api/service/upstream_test.go | 108 -
api/utils/http.go | 114 -
78 files changed, 9348 insertions(+), 6005 deletions(-)
diff --cc .github/workflows/api_ci.yml
index b17e583,907e0e6..3a380bd
--- a/.github/workflows/api_ci.yml
+++ b/.github/workflows/api_ci.yml
@@@ -7,9 -8,12 +8,10 @@@ on
pull_request:
branches:
- master
+ - refactor
jobs:
-
run-test:
-
runs-on: ubuntu-latest
services:
diff --cc .github/workflows/api_cicd.yml
index 13494fe,481c8cc..74aaa50
--- a/.github/workflows/api_cicd.yml
+++ b/.github/workflows/api_cicd.yml
@@@ -23,54 -23,65 +23,64 @@@ jobs
env:
MYSQL_ROOT_PASSWORD: 123456
ports:
- - '3306:3306'
+ - '3306:3306'
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
-
steps:
- - uses: actions/checkout@v2
-
- - name: run apisix
- run: |
- network=$(docker network ls | grep github_network | awk '{print $2}')
- docker run --name apisix -d -p 9080:9080 \
- -v ${{ github.workspace }}/.github/apisix-config.yaml:/usr/local/apisix/conf/config.yaml \
- --network "$network" --network-alias apisix \
- apache/apisix:dev
- sleep 5
- docker logs apisix
+ - uses: actions/checkout@v2
- - name: setting up database
- run: |
- mysql -h 127.0.0.1 --port 3306 -u root -p123456 < ./api/script/db/schema.sql
+ - name: run apisix
+ run: |
+ network=$(docker network ls | grep github_network | awk '{print $2}')
+ docker run --name apisix -d -p 9080:9080 \
+ -v ${{ github.workspace }}/.github/apisix-config.yaml:/usr/local/apisix/conf/config.yaml \
+ --network "$network" --network-alias apisix \
+ apache/apisix:dev
+ sleep 5
+ docker logs apisix
- - name: ping apisix
- run: |
- curl 127.0.0.1:9080
+ - name: setting up database
+ run: |
+ mysql -h 127.0.0.1 --port 3306 -u root -p123456 < ./api/script/db/schema.sql
+
+ - name: ping apisix
+ run: |
+ curl 127.0.0.1:9080
- - name: get lua lib
- run: |
- wget https://github.com/api7/dag-to-lua/archive/v1.1.tar.gz
- sudo mkdir -p /go/api7-manager-api/dag-to-lua/
- tar -zxvf v1.1.tar.gz
- sudo mv ./dag-to-lua-1.1/lib/* /go/api7-manager-api/dag-to-lua/
+ - name: get lua lib
+ run: |
+ wget https://github.com/api7/dag-to-lua/archive/v1.1.tar.gz
+ sudo mkdir -p /go/manager-api/dag-to-lua/
+ tar -zxvf v1.1.tar.gz
+ sudo mv ./dag-to-lua-1.1/lib/* /go/manager-api/dag-to-lua/
- - name: install runtime
- run: |
- sudo apt-get update
- sudo apt-get install lua5.1
- sudo add-apt-repository ppa:longsleep/golang-backports
- sudo apt update
- export GO111MOUDULE=on
- sudo apt install golang-1.14-go
+ - name: install runtime
+ run: |
+ sudo apt-get update
+ sudo apt-get install lua5.1
+ sudo add-apt-repository ppa:longsleep/golang-backports
+ sudo apt update
+ export GO111MOUDULE=on
+ sudo apt install golang-1.14-go
- - uses: Azure/docker-login@v1
- with:
- login-server: apisixacr.azurecr.cn
- username: ${{ secrets.REGISTRY_USERNAME }}
- password: ${{ secrets.REGISTRY_PASSWORD }}
+ - name: generate json schema
+ working-directory: ./api
+ run: |
+ wget https://github.com/apache/apisix/archive/master.zip
+ mkdir ./build-tools/apisix/
+ unzip master.zip
+ sudo mv ./apisix-master/apisix/* ./build-tools/apisix/
+ rm -rf ./apisix-master
+ cd ./build-tools/ && lua schema-sync.lua > ../conf/schema.json
+
+ - uses: Azure/docker-login@v1
+ with:
+ login-server: apisixacr.azurecr.cn
+ username: ${{ secrets.REGISTRY_USERNAME }}
+ password: ${{ secrets.REGISTRY_PASSWORD }}
- - name: build and push docker image
- run: |
- cd ./api
- docker build . -t apisixacr.azurecr.cn/managerapi:${{ github.sha }}
- docker push apisixacr.azurecr.cn/managerapi:${{ github.sha }}
+ - name: build and push docker image
+ run: |
+ cd ./api
+ docker build . -t apisixacr.azurecr.cn/managerapi:${{ github.sha }}
+ docker push apisixacr.azurecr.cn/managerapi:${{ github.sha }}
diff --cc api/conf/schema.json
index 0000000,087cf4c..861942a
mode 000000,100644..100644
--- a/api/conf/schema.json
+++ b/api/conf/schema.json
@@@ -1,0 -1,1 +1,2203 @@@
-{"main":{"upstream_hash_header_schema":{"type":"string","pattern":"^[a-zA-Z0-9-_]+$"},"stream_route":{"type":"object","properties":{"plugins":{"type":"object"},"id":{"anyOf":[{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9-_]+$"},{"type":"integer","minimum":1}]},"remote_addr":{"type":"string","anyOf":[{"title":"IPv4","type":"string","pattern":"^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"},{"title":"IPv4/CIDR","type":"string","pattern":"^[0-9]{1,3}.[0-9]{1,3}.[0-9] [...]
++{
++ "main": {
++ "upstream_hash_header_schema": { "type": "string", "pattern": "^[a-zA-Z0-9-_]+$" },
++ "stream_route": {
++ "type": "object",
++ "properties": {
++ "plugins": { "type": "object" },
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "remote_addr": {
++ "type": "string",
++ "anyOf": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ],
++ "description": "client IP"
++ },
++ "upstream_id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "upstream": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "create_time": { "type": "integer" },
++ "hash_on": {
++ "type": "string",
++ "enum": ["vars", "header", "cookie", "consumer"],
++ "default": "vars"
++ },
++ "pass_host": {
++ "type": "string",
++ "default": "pass",
++ "enum": ["pass", "node", "rewrite"],
++ "description": "mod of host passing"
++ },
++ "type": {
++ "type": "string",
++ "enum": ["chash", "roundrobin", "ewma"],
++ "description": "algorithms of load balancing"
++ },
++ "enable_websocket": {
++ "type": "boolean",
++ "description": "enable websocket for request"
++ },
++ "update_time": { "type": "integer" },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ },
++ "retries": { "type": "integer", "minimum": 0 },
++ "service_name": { "type": "string", "maxLength": 50 },
++ "id": {
++ "anyOf": [
++ {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 64,
++ "pattern": "^[a-zA-Z0-9-_]+$"
++ },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "key": {
++ "type": "string",
++ "description": "the key of chash for dynamic load balancing"
++ },
++ "name": { "type": "string", "maxLength": 50 },
++ "upstream_host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "timeout": {
++ "type": "object",
++ "properties": {
++ "send": { "type": "number", "minimum": 0 },
++ "read": { "type": "number", "minimum": 0 },
++ "connect": { "type": "number", "minimum": 0 }
++ },
++ "required": ["connect", "send", "read"]
++ },
++ "k8s_deployment_info": {
++ "type": "object",
++ "properties": {
++ "port": { "type": "number", "minimum": 0 },
++ "deploy_name": { "type": "string", "description": "k8s deployment name" },
++ "service_name": { "type": "string", "description": "k8s service name" },
++ "namespace": { "type": "string", "description": "k8s namespace" },
++ "backend_type": {
++ "type": "string",
++ "description": "k8s service name",
++ "enum": ["svc", "pod"],
++ "default": "pod"
++ }
++ },
++ "anyOf": [
++ { "required": ["namespace", "deploy_name", "port"] },
++ { "required": ["namespace", "service_name", "port"] }
++ ]
++ },
++ "desc": { "type": "string", "maxLength": 256 },
++ "checks": {
++ "type": "object",
++ "anyOf": [{ "required": ["active"] }, { "required": ["active", "passive"] }],
++ "properties": {
++ "active": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
++ "http_path": { "type": "string", "default": "/" },
++ "req_headers": {
++ "type": "array",
++ "items": { "type": "string", "uniqueItems": true },
++ "minItems": 1
++ },
++ "type": {
++ "type": "string",
++ "enum": ["http", "https", "tcp"],
++ "default": "http"
++ },
++ "timeout": { "type": "number", "default": 1 },
++ "concurrency": { "type": "integer", "default": 10 },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [200, 302],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "successes": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 404, 500, 501, 502, 503, 504, 505],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "timeouts": {
++ "type": "integer",
++ "default": 3,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "https_verify_certificate": { "type": "boolean", "default": true }
++ }
++ },
++ "passive": {
++ "type": "object",
++ "properties": {
++ "type": {
++ "type": "string",
++ "enum": ["http", "https", "tcp"],
++ "default": "http"
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 500, 503],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "timeouts": {
++ "type": "integer",
++ "default": 7,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [
++ 200,
++ 201,
++ 202,
++ 203,
++ 204,
++ 205,
++ 206,
++ 207,
++ 208,
++ 226,
++ 300,
++ 301,
++ 302,
++ 303,
++ 304,
++ 305,
++ 306,
++ 307,
++ 308
++ ],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "successes": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ }
++ }
++ }
++ },
++ "additionalProperties": false
++ },
++ "nodes": {
++ "anyOf": [
++ {
++ "type": "object",
++ "patternProperties": {
++ ".*": { "type": "integer", "minimum": 0, "description": "weight of node" }
++ },
++ "minProperties": 1
++ },
++ {
++ "type": "array",
++ "items": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "description": "port of node" },
++ "weight": {
++ "type": "integer",
++ "minimum": 0,
++ "description": "weight of node"
++ },
++ "metadata": { "type": "object", "description": "metadata of node" }
++ },
++ "required": ["host", "port", "weight"]
++ },
++ "minItems": 1
++ }
++ ]
++ }
++ },
++ "anyOf": [
++ { "required": ["type", "nodes"] },
++ { "required": ["type", "k8s_deployment_info"] },
++ { "required": ["type", "service_name"] }
++ ]
++ },
++ "server_addr": {
++ "type": "string",
++ "anyOf": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ],
++ "description": "server IP"
++ },
++ "server_port": { "type": "integer", "description": "server port" }
++ }
++ },
++ "label_value_def": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ },
++ "consumer": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "update_time": { "type": "integer" },
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "create_time": { "type": "integer" },
++ "plugins": { "type": "object" },
++ "desc": { "type": "string", "maxLength": 256 },
++ "username": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 32,
++ "pattern": "^[a-zA-Z0-9_]+$"
++ },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ }
++ },
++ "required": ["username"]
++ },
++ "proto": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": { "content": { "type": "string", "minLength": 1, "maxLength": 1048576 } },
++ "required": ["content"]
++ },
++ "version": 0.5,
++ "upstream_hash_vars_schema": {
++ "type": "string",
++ "pattern": "^((uri|server_name|server_addr|request_uri|remote_port|remote_addr|query_string|host|hostname)|arg_[0-9a-zA-z_-]+)$"
++ },
++ "global_rule": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "plugins": { "type": "object" }
++ },
++ "required": ["plugins"]
++ },
++ "ip_def": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ],
++ "id_schema": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "host_def": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "service": {
++ "type": "object",
++ "properties": {
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "create_time": { "type": "integer" },
++ "upstream_id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "script": { "type": "string", "minLength": 10, "maxLength": 102400 },
++ "name": { "type": "string", "maxLength": 50 },
++ "update_time": { "type": "integer" },
++ "upstream": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "create_time": { "type": "integer" },
++ "hash_on": {
++ "type": "string",
++ "enum": ["vars", "header", "cookie", "consumer"],
++ "default": "vars"
++ },
++ "pass_host": {
++ "type": "string",
++ "default": "pass",
++ "enum": ["pass", "node", "rewrite"],
++ "description": "mod of host passing"
++ },
++ "type": {
++ "type": "string",
++ "enum": ["chash", "roundrobin", "ewma"],
++ "description": "algorithms of load balancing"
++ },
++ "enable_websocket": {
++ "type": "boolean",
++ "description": "enable websocket for request"
++ },
++ "update_time": { "type": "integer" },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ },
++ "retries": { "type": "integer", "minimum": 0 },
++ "service_name": { "type": "string", "maxLength": 50 },
++ "id": {
++ "anyOf": [
++ {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 64,
++ "pattern": "^[a-zA-Z0-9-_]+$"
++ },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "key": {
++ "type": "string",
++ "description": "the key of chash for dynamic load balancing"
++ },
++ "name": { "type": "string", "maxLength": 50 },
++ "upstream_host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "timeout": {
++ "type": "object",
++ "properties": {
++ "send": { "type": "number", "minimum": 0 },
++ "read": { "type": "number", "minimum": 0 },
++ "connect": { "type": "number", "minimum": 0 }
++ },
++ "required": ["connect", "send", "read"]
++ },
++ "k8s_deployment_info": {
++ "type": "object",
++ "properties": {
++ "port": { "type": "number", "minimum": 0 },
++ "deploy_name": { "type": "string", "description": "k8s deployment name" },
++ "service_name": { "type": "string", "description": "k8s service name" },
++ "namespace": { "type": "string", "description": "k8s namespace" },
++ "backend_type": {
++ "type": "string",
++ "description": "k8s service name",
++ "enum": ["svc", "pod"],
++ "default": "pod"
++ }
++ },
++ "anyOf": [
++ { "required": ["namespace", "deploy_name", "port"] },
++ { "required": ["namespace", "service_name", "port"] }
++ ]
++ },
++ "desc": { "type": "string", "maxLength": 256 },
++ "checks": {
++ "type": "object",
++ "anyOf": [{ "required": ["active"] }, { "required": ["active", "passive"] }],
++ "properties": {
++ "active": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
++ "http_path": { "type": "string", "default": "/" },
++ "req_headers": {
++ "type": "array",
++ "items": { "type": "string", "uniqueItems": true },
++ "minItems": 1
++ },
++ "type": {
++ "type": "string",
++ "enum": ["http", "https", "tcp"],
++ "default": "http"
++ },
++ "timeout": { "type": "number", "default": 1 },
++ "concurrency": { "type": "integer", "default": 10 },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [200, 302],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "successes": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 404, 500, 501, 502, 503, 504, 505],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "timeouts": {
++ "type": "integer",
++ "default": 3,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "https_verify_certificate": { "type": "boolean", "default": true }
++ }
++ },
++ "passive": {
++ "type": "object",
++ "properties": {
++ "type": {
++ "type": "string",
++ "enum": ["http", "https", "tcp"],
++ "default": "http"
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 500, 503],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "timeouts": {
++ "type": "integer",
++ "default": 7,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [
++ 200,
++ 201,
++ 202,
++ 203,
++ 204,
++ 205,
++ 206,
++ 207,
++ 208,
++ 226,
++ 300,
++ 301,
++ 302,
++ 303,
++ 304,
++ 305,
++ 306,
++ 307,
++ 308
++ ],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "successes": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ }
++ }
++ }
++ },
++ "additionalProperties": false
++ },
++ "nodes": {
++ "anyOf": [
++ {
++ "type": "object",
++ "patternProperties": {
++ ".*": { "type": "integer", "minimum": 0, "description": "weight of node" }
++ },
++ "minProperties": 1
++ },
++ {
++ "type": "array",
++ "items": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "description": "port of node" },
++ "weight": {
++ "type": "integer",
++ "minimum": 0,
++ "description": "weight of node"
++ },
++ "metadata": { "type": "object", "description": "metadata of node" }
++ },
++ "required": ["host", "port", "weight"]
++ },
++ "minItems": 1
++ }
++ ]
++ }
++ },
++ "anyOf": [
++ { "required": ["type", "nodes"] },
++ { "required": ["type", "k8s_deployment_info"] },
++ { "required": ["type", "service_name"] }
++ ]
++ },
++ "desc": { "type": "string", "maxLength": 256 },
++ "plugins": { "type": "object" },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ }
++ },
++ "additionalProperties": false
++ },
++ "plugin_disable_schema": { "disable": { "type": "boolean" } },
++ "ssl": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "cert": { "type": "string", "minLength": 128, "maxLength": 65536 },
++ "keys": {
++ "type": "array",
++ "items": { "type": "string", "minLength": 128, "maxLength": 65536 }
++ },
++ "validity_end": { "type": "integer" },
++ "exptime": { "type": "integer", "minimum": 1588262400 },
++ "sni": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "key": { "type": "string", "minLength": 128, "maxLength": 65536 },
++ "snis": {
++ "type": "array",
++ "items": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" }
++ },
++ "create_time": { "type": "integer" },
++ "update_time": { "type": "integer" },
++ "status": {
++ "type": "integer",
++ "default": 1,
++ "enum": [1, 0],
++ "description": "ssl status, 1 to enable, 0 to disable"
++ },
++ "validity_start": { "type": "integer" },
++ "certs": {
++ "type": "array",
++ "items": { "type": "string", "minLength": 128, "maxLength": 65536 }
++ },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ }
++ },
++ "oneOf": [{ "required": ["sni", "key", "cert"] }, { "required": ["snis", "key", "cert"] }]
++ },
++ "upstream": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "create_time": { "type": "integer" },
++ "hash_on": {
++ "type": "string",
++ "enum": ["vars", "header", "cookie", "consumer"],
++ "default": "vars"
++ },
++ "pass_host": {
++ "type": "string",
++ "default": "pass",
++ "enum": ["pass", "node", "rewrite"],
++ "description": "mod of host passing"
++ },
++ "type": {
++ "type": "string",
++ "enum": ["chash", "roundrobin", "ewma"],
++ "description": "algorithms of load balancing"
++ },
++ "enable_websocket": { "type": "boolean", "description": "enable websocket for request" },
++ "update_time": { "type": "integer" },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ },
++ "retries": { "type": "integer", "minimum": 0 },
++ "service_name": { "type": "string", "maxLength": 50 },
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "key": { "type": "string", "description": "the key of chash for dynamic load balancing" },
++ "name": { "type": "string", "maxLength": 50 },
++ "upstream_host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "timeout": {
++ "type": "object",
++ "properties": {
++ "send": { "type": "number", "minimum": 0 },
++ "read": { "type": "number", "minimum": 0 },
++ "connect": { "type": "number", "minimum": 0 }
++ },
++ "required": ["connect", "send", "read"]
++ },
++ "k8s_deployment_info": {
++ "type": "object",
++ "properties": {
++ "port": { "type": "number", "minimum": 0 },
++ "deploy_name": { "type": "string", "description": "k8s deployment name" },
++ "service_name": { "type": "string", "description": "k8s service name" },
++ "namespace": { "type": "string", "description": "k8s namespace" },
++ "backend_type": {
++ "type": "string",
++ "description": "k8s service name",
++ "enum": ["svc", "pod"],
++ "default": "pod"
++ }
++ },
++ "anyOf": [
++ { "required": ["namespace", "deploy_name", "port"] },
++ { "required": ["namespace", "service_name", "port"] }
++ ]
++ },
++ "desc": { "type": "string", "maxLength": 256 },
++ "checks": {
++ "type": "object",
++ "anyOf": [{ "required": ["active"] }, { "required": ["active", "passive"] }],
++ "properties": {
++ "active": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
++ "http_path": { "type": "string", "default": "/" },
++ "req_headers": {
++ "type": "array",
++ "items": { "type": "string", "uniqueItems": true },
++ "minItems": 1
++ },
++ "type": { "type": "string", "enum": ["http", "https", "tcp"], "default": "http" },
++ "timeout": { "type": "number", "default": 1 },
++ "concurrency": { "type": "integer", "default": 10 },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [200, 302],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "successes": { "type": "integer", "default": 2, "minimum": 1, "maximum": 254 }
++ }
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 404, 500, 501, 502, 503, 504, 505],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "timeouts": { "type": "integer", "default": 3, "minimum": 1, "maximum": 254 },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "https_verify_certificate": { "type": "boolean", "default": true }
++ }
++ },
++ "passive": {
++ "type": "object",
++ "properties": {
++ "type": { "type": "string", "enum": ["http", "https", "tcp"], "default": "http" },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 500, 503],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "timeouts": { "type": "integer", "default": 7, "minimum": 1, "maximum": 254 },
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [
++ 200,
++ 201,
++ 202,
++ 203,
++ 204,
++ 205,
++ 206,
++ 207,
++ 208,
++ 226,
++ 300,
++ 301,
++ 302,
++ 303,
++ 304,
++ 305,
++ 306,
++ 307,
++ 308
++ ],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "successes": { "type": "integer", "default": 5, "minimum": 1, "maximum": 254 }
++ }
++ }
++ }
++ }
++ },
++ "additionalProperties": false
++ },
++ "nodes": {
++ "anyOf": [
++ {
++ "type": "object",
++ "patternProperties": {
++ ".*": { "type": "integer", "minimum": 0, "description": "weight of node" }
++ },
++ "minProperties": 1
++ },
++ {
++ "type": "array",
++ "items": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "description": "port of node" },
++ "weight": { "type": "integer", "minimum": 0, "description": "weight of node" },
++ "metadata": { "type": "object", "description": "metadata of node" }
++ },
++ "required": ["host", "port", "weight"]
++ },
++ "minItems": 1
++ }
++ ]
++ }
++ },
++ "anyOf": [
++ { "required": ["type", "nodes"] },
++ { "required": ["type", "k8s_deployment_info"] },
++ { "required": ["type", "service_name"] }
++ ]
++ },
++ "route": {
++ "type": "object",
++ "additionalProperties": false,
++ "not": { "anyOf": [{ "required": ["script", "plugins"] }] },
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "methods": {
++ "type": "array",
++ "items": {
++ "type": "string",
++ "enum": [
++ "GET",
++ "POST",
++ "PUT",
++ "DELETE",
++ "PATCH",
++ "HEAD",
++ "OPTIONS",
++ "CONNECT",
++ "TRACE"
++ ],
++ "description": "HTTP method"
++ },
++ "uniqueItems": true
++ },
++ "create_time": { "type": "integer" },
++ "hosts": {
++ "type": "array",
++ "items": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "uniqueItems": true
++ },
++ "name": { "type": "string", "maxLength": 50 },
++ "filter_func": { "type": "string", "minLength": 10, "pattern": "^function" },
++ "uri": { "type": "string", "minLength": 1, "maxLength": 4096 },
++ "priority": { "type": "integer", "default": 0 },
++ "remote_addrs": {
++ "type": "array",
++ "items": {
++ "type": "string",
++ "anyOf": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ],
++ "description": "client IP"
++ },
++ "uniqueItems": true
++ },
++ "upstream": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "create_time": { "type": "integer" },
++ "hash_on": {
++ "type": "string",
++ "enum": ["vars", "header", "cookie", "consumer"],
++ "default": "vars"
++ },
++ "pass_host": {
++ "type": "string",
++ "default": "pass",
++ "enum": ["pass", "node", "rewrite"],
++ "description": "mod of host passing"
++ },
++ "type": {
++ "type": "string",
++ "enum": ["chash", "roundrobin", "ewma"],
++ "description": "algorithms of load balancing"
++ },
++ "enable_websocket": {
++ "type": "boolean",
++ "description": "enable websocket for request"
++ },
++ "update_time": { "type": "integer" },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ },
++ "retries": { "type": "integer", "minimum": 0 },
++ "service_name": { "type": "string", "maxLength": 50 },
++ "id": {
++ "anyOf": [
++ {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 64,
++ "pattern": "^[a-zA-Z0-9-_]+$"
++ },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "key": {
++ "type": "string",
++ "description": "the key of chash for dynamic load balancing"
++ },
++ "name": { "type": "string", "maxLength": 50 },
++ "upstream_host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "timeout": {
++ "type": "object",
++ "properties": {
++ "send": { "type": "number", "minimum": 0 },
++ "read": { "type": "number", "minimum": 0 },
++ "connect": { "type": "number", "minimum": 0 }
++ },
++ "required": ["connect", "send", "read"]
++ },
++ "k8s_deployment_info": {
++ "type": "object",
++ "properties": {
++ "port": { "type": "number", "minimum": 0 },
++ "deploy_name": { "type": "string", "description": "k8s deployment name" },
++ "service_name": { "type": "string", "description": "k8s service name" },
++ "namespace": { "type": "string", "description": "k8s namespace" },
++ "backend_type": {
++ "type": "string",
++ "description": "k8s service name",
++ "enum": ["svc", "pod"],
++ "default": "pod"
++ }
++ },
++ "anyOf": [
++ { "required": ["namespace", "deploy_name", "port"] },
++ { "required": ["namespace", "service_name", "port"] }
++ ]
++ },
++ "desc": { "type": "string", "maxLength": 256 },
++ "checks": {
++ "type": "object",
++ "anyOf": [{ "required": ["active"] }, { "required": ["active", "passive"] }],
++ "properties": {
++ "active": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
++ "http_path": { "type": "string", "default": "/" },
++ "req_headers": {
++ "type": "array",
++ "items": { "type": "string", "uniqueItems": true },
++ "minItems": 1
++ },
++ "type": {
++ "type": "string",
++ "enum": ["http", "https", "tcp"],
++ "default": "http"
++ },
++ "timeout": { "type": "number", "default": 1 },
++ "concurrency": { "type": "integer", "default": 10 },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [200, 302],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "successes": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 404, 500, 501, 502, 503, 504, 505],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "interval": { "type": "integer", "minimum": 1, "default": 0 },
++ "timeouts": {
++ "type": "integer",
++ "default": 3,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "https_verify_certificate": { "type": "boolean", "default": true }
++ }
++ },
++ "passive": {
++ "type": "object",
++ "properties": {
++ "type": {
++ "type": "string",
++ "enum": ["http", "https", "tcp"],
++ "default": "http"
++ },
++ "unhealthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [429, 500, 503],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "timeouts": {
++ "type": "integer",
++ "default": 7,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "http_failures": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ },
++ "tcp_failures": {
++ "type": "integer",
++ "default": 2,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ },
++ "healthy": {
++ "type": "object",
++ "properties": {
++ "http_statuses": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [
++ 200,
++ 201,
++ 202,
++ 203,
++ 204,
++ 205,
++ 206,
++ 207,
++ 208,
++ 226,
++ 300,
++ 301,
++ 302,
++ 303,
++ 304,
++ 305,
++ 306,
++ 307,
++ 308
++ ],
++ "items": { "type": "integer", "minimum": 200, "maximum": 599 },
++ "minItems": 1
++ },
++ "successes": {
++ "type": "integer",
++ "default": 5,
++ "minimum": 1,
++ "maximum": 254
++ }
++ }
++ }
++ }
++ }
++ },
++ "additionalProperties": false
++ },
++ "nodes": {
++ "anyOf": [
++ {
++ "type": "object",
++ "patternProperties": {
++ ".*": { "type": "integer", "minimum": 0, "description": "weight of node" }
++ },
++ "minProperties": 1
++ },
++ {
++ "type": "array",
++ "items": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "port": { "type": "integer", "minimum": 1, "description": "port of node" },
++ "weight": {
++ "type": "integer",
++ "minimum": 0,
++ "description": "weight of node"
++ },
++ "metadata": { "type": "object", "description": "metadata of node" }
++ },
++ "required": ["host", "port", "weight"]
++ },
++ "minItems": 1
++ }
++ ]
++ }
++ },
++ "anyOf": [
++ { "required": ["type", "nodes"] },
++ { "required": ["type", "k8s_deployment_info"] },
++ { "required": ["type", "service_name"] }
++ ]
++ },
++ "remote_addr": {
++ "type": "string",
++ "anyOf": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ],
++ "description": "client IP"
++ },
++ "service_protocol": { "enum": ["grpc", "http"] },
++ "upstream_id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "update_time": { "type": "integer" },
++ "id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "script": { "type": "string", "minLength": 10, "maxLength": 102400 },
++ "service_id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ },
++ "labels": {
++ "type": "object",
++ "maxProperties": 16,
++ "patternProperties": {
++ ".*": {
++ "type": "string",
++ "maxLength": 64,
++ "minLength": 1,
++ "pattern": "^[a-zA-Z0-9-_.]+$",
++ "description": "value of label"
++ }
++ },
++ "description": "key/value pairs to specify attributes"
++ },
++ "plugins": { "type": "object" },
++ "uris": {
++ "type": "array",
++ "items": { "type": "string", "description": "HTTP uri" },
++ "uniqueItems": true
++ },
++ "vars": {
++ "type": "array",
++ "items": {
++ "type": "array",
++ "items": {
++ "maxItems": 3,
++ "anyOf": [{ "type": "string" }, { "type": "number" }],
++ "minItems": 2
++ },
++ "description": "Nginx builtin variable name and value"
++ }
++ },
++ "desc": { "type": "string", "maxLength": 256 }
++ },
++ "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"] }
++ ]
++ }
++ },
++ "plugins": {
++ "limit-req": {
++ "type": "object",
++ "properties": {
++ "key": {
++ "type": "string",
++ "enum": [
++ "remote_addr",
++ "server_addr",
++ "http_x_real_ip",
++ "http_x_forwarded_for",
++ "consumer_name"
++ ]
++ },
++ "rate": { "type": "number", "minimum": 0 },
++ "burst": { "type": "number", "minimum": 0 },
++ "rejected_code": { "type": "integer", "minimum": 200, "default": 503 }
++ },
++ "required": ["rate", "burst", "key"]
++ },
++ "request-validation": {
++ "type": "object",
++ "properties": { "header_schema": { "type": "object" }, "body_schema": { "type": "object" } },
++ "anyOf": [{ "required": ["body_schema"] }, { "required": ["header_schema"] }]
++ },
++ "referer-restriction": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "bypass_missing": { "type": "boolean", "default": false },
++ "whitelist": {
++ "type": "array",
++ "items": { "type": "string", "pattern": "^\\*?[0-9a-zA-Z-.]+$" },
++ "minItems": 1
++ }
++ },
++ "required": ["whitelist"]
++ },
++ "zipkin": {
++ "type": "object",
++ "properties": {
++ "sample_ratio": { "type": "number", "minimum": 1e-5, "maximum": 1 },
++ "service_name": {
++ "type": "string",
++ "default": "APISIX",
++ "description": "service name for zipkin reporter"
++ },
++ "server_addr": {
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$",
++ "description": "default is $server_addr, you can speific your external ip address"
++ },
++ "endpoint": { "type": "string" }
++ },
++ "required": ["endpoint", "sample_ratio"]
++ },
++ "jwt-auth": {
++ "type": "object",
++ "properties": {
++ "key": { "type": "string" },
++ "exp": { "type": "integer", "minimum": 1 },
++ "base64_secret": { "type": "boolean", "default": false },
++ "algorithm": { "type": "string", "enum": ["HS256", "HS512", "RS256"], "default": "HS256" },
++ "secret": { "type": "string" }
++ }
++ },
++ "wolf-rbac": {
++ "type": "object",
++ "properties": {
++ "header_prefix": { "type": "string", "default": "X-" },
++ "appid": { "type": "string", "default": "unset" },
++ "server": { "type": "string", "default": "http://127.0.0.1:10080" }
++ }
++ },
++ "limit-conn": {
++ "type": "object",
++ "properties": {
++ "key": {
++ "type": "string",
++ "enum": ["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for"]
++ },
++ "burst": { "type": "integer", "minimum": 0 },
++ "conn": { "type": "integer", "minimum": 0 },
++ "rejected_code": { "type": "integer", "minimum": 200, "default": 503 },
++ "default_conn_delay": { "type": "number", "minimum": 0 }
++ },
++ "required": ["conn", "burst", "default_conn_delay", "key"]
++ },
++ "prometheus": { "type": "object", "additionalProperties": false },
++ "example-plugin": {
++ "type": "object",
++ "properties": {
++ "port": { "type": "integer" },
++ "i": { "type": "number", "minimum": 0 },
++ "s": { "type": "string" },
++ "t": { "type": "array", "minItems": 1 },
++ "ip": { "type": "string" }
++ },
++ "required": ["i"]
++ },
++ "tcp-logger": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string" },
++ "port": { "type": "integer", "minimum": 0 },
++ "retry_delay": { "type": "integer", "minimum": 0, "default": 1 },
++ "include_req_body": { "type": "boolean", "default": false },
++ "batch_max_size": { "type": "integer", "minimum": 1, "default": 1000 },
++ "max_retry_count": { "type": "integer", "minimum": 0, "default": 0 },
++ "timeout": { "type": "integer", "minimum": 1, "default": 1000 },
++ "inactive_timeout": { "type": "integer", "minimum": 1, "default": 5 },
++ "buffer_duration": { "type": "integer", "minimum": 1, "default": 60 },
++ "name": { "type": "string", "default": "tcp logger" },
++ "tls": { "type": "boolean", "default": false },
++ "tls_options": { "type": "string" }
++ },
++ "required": ["host", "port"]
++ },
++ "request-id": {
++ "type": "object",
++ "properties": {
++ "include_in_response": { "type": "boolean", "default": true },
++ "header_name": { "type": "string", "default": "X-Request-Id" }
++ }
++ },
++ "proxy-rewrite": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "host": {
++ "type": "string",
++ "pattern": "^[0-9a-zA-Z-.]+$",
++ "description": "new host for upstream"
++ },
++ "regex_uri": {
++ "type": "array",
++ "maxItems": 2,
++ "items": { "type": "string", "description": "regex uri" },
++ "minItems": 2,
++ "description": "new uri that substitute from client uri for upstream, lower priority than uri property"
++ },
++ "headers": {
++ "type": "object",
++ "minProperties": 1,
++ "description": "new headers for request"
++ },
++ "uri": {
++ "type": "string",
++ "maxLength": 4096,
++ "minLength": 1,
++ "pattern": "^\\/.*",
++ "description": "new uri for upstream"
++ },
++ "scheme": {
++ "type": "string",
++ "enum": ["http", "https"],
++ "description": "new scheme for upstream"
++ }
++ },
++ "minProperties": 1
++ },
++ "basic-auth": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": [],
++ "title": "work with route or service object"
++ },
++ "echo": {
++ "type": "object",
++ "additionalProperties": false,
++ "anyOf": [
++ { "required": ["before_body"] },
++ { "required": ["body"] },
++ { "required": ["after_body"] }
++ ],
++ "properties": {
++ "body": { "type": "string", "description": "body to replace upstream response." },
++ "after_body": {
++ "type": "string",
++ "description": "body after the modification of filter phase."
++ },
++ "auth_value": { "type": "string", "description": "auth value" },
++ "before_body": { "type": "string", "description": "body before the filter phase." },
++ "headers": {
++ "type": "object",
++ "minProperties": 1,
++ "description": "new headers for response"
++ }
++ },
++ "minProperties": 1
++ },
++ "limit-count": {
++ "type": "object",
++ "dependencies": {
++ "policy": {
++ "oneOf": [
++ { "properties": { "policy": { "enum": ["local"] } } },
++ {
++ "properties": {
++ "redis_password": { "type": "string", "minLength": 0 },
++ "redis_host": { "type": "string", "minLength": 2 },
++ "redis_timeout": { "type": "integer", "minimum": 1, "default": 1000 },
++ "redis_port": { "type": "integer", "minimum": 1, "default": 6379 },
++ "policy": { "enum": ["redis"] }
++ },
++ "required": ["redis_host"]
++ }
++ ]
++ }
++ },
++ "properties": {
++ "key": {
++ "type": "string",
++ "enum": ["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for"]
++ },
++ "time_window": { "type": "integer", "minimum": 0 },
++ "count": { "type": "integer", "minimum": 0 },
++ "rejected_code": { "type": "integer", "default": 503, "minimum": 200, "maximum": 600 },
++ "policy": { "type": "string", "enum": ["local", "redis"], "default": "local" }
++ },
++ "required": ["count", "time_window", "key"]
++ },
++ "key-auth": { "type": "object", "properties": { "key": { "type": "string" } } },
++ "openid-connect": {
++ "type": "object",
++ "properties": {
++ "client_id": { "type": "string" },
++ "bearer_only": { "type": "boolean" },
++ "discovery": { "type": "string" },
++ "introspection_endpoint": { "type": "string" },
++ "token_signing_alg_values_expected": { "type": "string" },
++ "public_key": { "type": "string" },
++ "scope": { "type": "string" },
++ "logout_path": { "type": "string" },
++ "client_secret": { "type": "string" },
++ "redirect_uri": { "type": "string" },
++ "realm": { "type": "string" },
++ "introspection_endpoint_auth_method": { "type": "string" },
++ "timeout": { "type": "integer", "minimum": 1 },
++ "ssl_verify": { "type": "boolean" }
++ },
++ "required": ["client_id", "client_secret", "discovery"]
++ },
++ "log-rotate": { "type": "object", "properties": [], "additionalProperties": false },
++ "uri-blocker": {
++ "type": "object",
++ "properties": {
++ "block_rules": {
++ "type": "array",
++ "items": { "type": "string", "minLength": 1, "maxLength": 4096 },
++ "uniqueItems": true
++ },
++ "rejected_code": { "type": "integer", "minimum": 200, "default": 403 }
++ },
++ "required": ["block_rules"]
++ },
++ "hmac-auth": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": [],
++ "title": "work with route or service object"
++ },
++ "udp-logger": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string" },
++ "port": { "type": "integer", "minimum": 0 },
++ "timeout": { "type": "integer", "minimum": 1, "default": 3 },
++ "include_req_body": { "type": "boolean", "default": false },
++ "batch_max_size": { "type": "integer", "minimum": 1, "default": 1000 },
++ "inactive_timeout": { "type": "integer", "minimum": 1, "default": 5 },
++ "buffer_duration": { "type": "integer", "minimum": 1, "default": 60 },
++ "name": { "type": "string", "default": "udp logger" }
++ },
++ "required": ["host", "port"]
++ },
++ "response-rewrite": {
++ "type": "object",
++ "additionalProperties": false,
++ "properties": {
++ "headers": {
++ "type": "object",
++ "minProperties": 1,
++ "description": "new headers for repsonse"
++ },
++ "status_code": {
++ "type": "integer",
++ "maximum": 598,
++ "minimum": 200,
++ "description": "new status code for repsonse"
++ },
++ "body": { "type": "string", "description": "new body for repsonse" },
++ "body_base64": {
++ "type": "boolean",
++ "default": false,
++ "description": "whether new body for repsonse need base64 decode before return"
++ }
++ },
++ "minProperties": 1
++ },
++ "ip-restriction": {
++ "type": "object",
++ "oneOf": [
++ {
++ "title": "whitelist",
++ "additionalProperties": false,
++ "properties": {
++ "whitelist": {
++ "type": "array",
++ "items": {
++ "anyOf": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ]
++ },
++ "minItems": 1
++ }
++ },
++ "required": ["whitelist"]
++ },
++ {
++ "title": "blacklist",
++ "additionalProperties": false,
++ "properties": {
++ "blacklist": {
++ "type": "array",
++ "items": {
++ "anyOf": [
++ {
++ "title": "IPv4",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
++ },
++ {
++ "title": "IPv4/CIDR",
++ "type": "string",
++ "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}/[0-9]{1,2}$"
++ },
++ {
++ "title": "IPv6",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?$"
++ },
++ {
++ "title": "IPv6/CIDR",
++ "type": "string",
++ "pattern": "^([a-fA-F0-9]{0,4}:){0,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$"
++ }
++ ]
++ },
++ "minItems": 1
++ }
++ },
++ "required": ["blacklist"]
++ }
++ ]
++ },
++ "skywalking": {
++ "type": "object",
++ "required": ["endpoint"],
++ "properties": {
++ "sample_ratio": { "type": "number", "default": 1, "minimum": 1e-5, "maximum": 1 },
++ "endpoint": { "type": "string" }
++ },
++ "service_name": {
++ "type": "string",
++ "default": "APISIX",
++ "description": "service name for skywalking"
++ }
++ },
++ "syslog": {
++ "type": "object",
++ "properties": {
++ "host": { "type": "string" },
++ "port": { "type": "integer" },
++ "max_retry_times": { "type": "integer", "minimum": 1, "default": 1 },
++ "drop_limit": { "type": "integer", "default": 1048576 },
++ "include_req_body": { "type": "boolean", "default": false },
++ "buffer_duration": { "type": "integer", "minimum": 1, "default": 60 },
++ "batch_max_size": { "type": "integer", "minimum": 1, "default": 1000 },
++ "timeout": { "type": "integer", "minimum": 1, "default": 3 },
++ "name": { "type": "string", "default": "sys logger" },
++ "pool_size": { "type": "integer", "minimum": 5, "default": 5 },
++ "retry_interval": { "type": "integer", "minimum": 0, "default": 1 },
++ "sock_type": { "type": "string", "enum": ["tcp", "udp"], "default": "tcp" },
++ "tls": { "type": "boolean", "default": false },
++ "flush_limit": { "type": "integer", "minimum": 1, "default": 4096 }
++ },
++ "required": ["host", "port"]
++ },
++ "kafka-logger": {
++ "type": "object",
++ "properties": {
++ "kafka_topic": { "type": "string" },
++ "batch_max_size": { "type": "integer", "minimum": 1, "default": 1000 },
++ "retry_delay": { "type": "integer", "minimum": 0, "default": 1 },
++ "include_req_body": { "type": "boolean", "default": false },
++ "meta_format": { "type": "string", "enum": ["default", "origin"], "default": "default" },
++ "key": { "type": "string" },
++ "max_retry_count": { "type": "integer", "minimum": 0, "default": 0 },
++ "timeout": { "type": "integer", "minimum": 1, "default": 3 },
++ "inactive_timeout": { "type": "integer", "minimum": 1, "default": 5 },
++ "name": { "type": "string", "default": "kafka logger" },
++ "buffer_duration": { "type": "integer", "minimum": 1, "default": 60 },
++ "broker_list": { "type": "object" }
++ },
++ "required": ["broker_list", "kafka_topic", "key"]
++ },
++ "consumer-restriction": {
++ "type": "object",
++ "properties": {
++ "type": {
++ "type": "string",
++ "enum": ["consumer_name", "service_id"],
++ "default": "consumer_name"
++ },
++ "blacklist": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
++ "rejected_code": { "type": "integer", "minimum": 200, "default": 403 },
++ "whitelist": { "type": "array", "items": { "type": "string" }, "minItems": 1 }
++ },
++ "oneOf": [{ "required": ["whitelist"] }, { "required": ["blacklist"] }]
++ },
++ "proxy-cache": {
++ "type": "object",
++ "properties": {
++ "cache_method": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": ["GET", "HEAD"],
++ "items": {
++ "type": "string",
++ "enum": [
++ "GET",
++ "POST",
++ "PUT",
++ "DELETE",
++ "PATCH",
++ "HEAD",
++ "OPTIONS",
++ "CONNECT",
++ "TRACE"
++ ],
++ "description": "http method"
++ },
++ "minItems": 1
++ },
++ "cache_http_status": {
++ "type": "array",
++ "uniqueItems": true,
++ "default": [200, 301, 404],
++ "items": {
++ "type": "integer",
++ "maximum": 599,
++ "minimum": 200,
++ "description": "http response status"
++ },
++ "minItems": 1
++ },
++ "cache_key": {
++ "type": "array",
++ "default": ["$host", "$request_uri"],
++ "items": {
++ "type": "string",
++ "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)",
++ "description": "a key for caching"
++ },
++ "minItems": 1
++ },
++ "cache_zone": { "type": "string", "minLength": 1 },
++ "no_cache": {
++ "type": "array",
++ "items": { "type": "string", "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)" },
++ "minItems": 1
++ },
++ "cache_bypass": {
++ "type": "array",
++ "items": { "type": "string", "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)" },
++ "minItems": 1
++ },
++ "hide_cache_headers": { "type": "boolean", "default": false }
++ },
++ "required": ["cache_zone"]
++ },
++ "serverless-post-function": {
++ "type": "object",
++ "properties": {
++ "phase": {
++ "type": "string",
++ "enum": ["rewrite", "access", "header_filter", "body_filter", "log", "balancer"]
++ },
++ "functions": { "type": "array", "items": { "type": "string" }, "minItems": 1 }
++ },
++ "required": ["functions"]
++ },
++ "fault-injection": {
++ "type": "object",
++ "properties": {
++ "delay": {
++ "type": "object",
++ "properties": { "duration": { "type": "number", "minimum": 0 } },
++ "minProperties": 1
++ },
++ "abort": {
++ "type": "object",
++ "properties": {
++ "body": { "type": "string", "minLength": 0 },
++ "http_status": { "type": "integer", "minimum": 200 }
++ },
++ "minProperties": 1
++ }
++ },
++ "minProperties": 1
++ },
++ "redirect": {
++ "type": "object",
++ "properties": {
++ "http_to_https": { "type": "boolean" },
++ "uri": { "type": "string", "minLength": 2 },
++ "ret_code": { "type": "integer", "minimum": 200, "default": 302 }
++ },
++ "oneOf": [{ "required": ["uri"] }, { "required": ["http_to_https"] }]
++ },
++ "http-logger": {
++ "type": "object",
++ "properties": {
++ "batch_max_size": { "type": "integer", "minimum": 1, "default": 1000 },
++ "retry_delay": { "type": "integer", "minimum": 0, "default": 1 },
++ "include_req_body": { "type": "boolean", "default": false },
++ "concat_method": { "type": "string", "enum": ["json", "new_line"], "default": "json" },
++ "max_retry_count": { "type": "integer", "minimum": 0, "default": 0 },
++ "timeout": { "type": "integer", "minimum": 1, "default": 3 },
++ "inactive_timeout": { "type": "integer", "minimum": 1, "default": 5 },
++ "buffer_duration": { "type": "integer", "minimum": 1, "default": 60 },
++ "name": { "type": "string", "default": "http logger" },
++ "uri": { "type": "string" },
++ "auth_header": { "type": "string", "default": "" }
++ },
++ "required": ["uri"]
++ },
++ "authz-keycloak": {
++ "type": "object",
++ "properties": {
++ "keepalive": { "type": "boolean", "default": true },
++ "permissions": {
++ "type": "array",
++ "items": { "type": "string", "minLength": 1, "maxLength": 100 },
++ "uniqueItems": true
++ },
++ "policy_enforcement_mode": {
++ "type": "string",
++ "enum": ["ENFORCING", "PERMISSIVE"],
++ "default": "ENFORCING"
++ },
++ "ssl_verify": { "type": "boolean", "default": true },
++ "token_endpoint": { "type": "string", "minLength": 1, "maxLength": 4096 },
++ "timeout": { "type": "integer", "minimum": 1000, "default": 3000 },
++ "audience": { "type": "string", "minLength": 1, "maxLength": 100 },
++ "keepalive_pool": { "type": "integer", "minimum": 1, "default": 5 },
++ "keepalive_timeout": { "type": "integer", "minimum": 1000, "default": 60000 },
++ "grant_type": {
++ "type": "string",
++ "maxLength": 100,
++ "minLength": 1,
++ "enum": ["urn:ietf:params:oauth:grant-type:uma-ticket"],
++ "default": "urn:ietf:params:oauth:grant-type:uma-ticket"
++ }
++ },
++ "required": ["token_endpoint"]
++ },
++ "serverless-pre-function": {
++ "type": "object",
++ "properties": {
++ "phase": {
++ "type": "string",
++ "enum": ["rewrite", "access", "header_filter", "body_filter", "log", "balancer"]
++ },
++ "functions": { "type": "array", "items": { "type": "string" }, "minItems": 1 }
++ },
++ "required": ["functions"]
++ },
++ "cors": {
++ "type": "object",
++ "properties": {
++ "allow_credential": {
++ "type": "boolean",
++ "default": false,
++ "description": "allow client append crendential. according to CORS specification,if you set this option to 'true', you can not use '*' for other options."
++ },
++ "max_age": {
++ "type": "integer",
++ "default": 5,
++ "description": "maximum number of seconds the results can be cached.-1 mean no cached,the max value is depend on browser,more detail plz check MDN. default: 5."
++ },
++ "allow_origins": {
++ "type": "string",
++ "default": "*",
++ "description": "you can use '*' to allow all origins when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple origin use ',' to split. default: *."
++ },
++ "allow_methods": {
++ "type": "string",
++ "default": "*",
++ "description": "you can use '*' to allow all methods when no credentials and '**','**' to allow forcefully(it will bring some security risks, be carefully),multiple method use ',' to split. default: *."
++ },
++ "expose_headers": {
++ "type": "string",
++ "default": "*",
++ "description": "you can use '*' to expose all header when no credentials,multiple header use ',' to split. default: *."
++ },
++ "allow_headers": {
++ "type": "string",
++ "default": "*",
++ "description": "you can use '*' to allow all header when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple header use ',' to split. default: *."
++ }
++ }
++ },
++ "batch-requests": { "type": "object", "additionalProperties": false },
++ "grpc-transcode": {
++ "type": "object",
++ "required": ["proto_id", "service", "method"],
++ "properties": {
++ "pb_option": {
++ "type": "array",
++ "items": {
++ "type": "string",
++ "anyOf": [
++ {
++ "type": "string",
++ "enum": ["int64_as_number", "int64_as_string", "int64_as_hexstring"],
++ "description": "enum as result"
++ },
++ {
++ "type": "string",
++ "enum": ["ienum_as_name", "enum_as_value"],
++ "description": "int64 as result"
++ },
++ {
++ "type": "string",
++ "enum": [
++ "auto_default_values",
++ "no_default_values",
++ "use_default_values",
++ "use_default_metatable"
++ ],
++ "description": "default values option"
++ },
++ {
++ "type": "string",
++ "enum": ["enable_hooks", "disable_hooks"],
++ "description": "hooks option"
++ }
++ ]
++ },
++ "minItems": 1
++ },
++ "service": { "type": "string", "description": "the grpc service name" },
++ "method": { "type": "string", "description": "the method name in the grpc service." },
++ "deadline": {
++ "type": "number",
++ "default": 0,
++ "description": "deadline for grpc, millisecond"
++ },
++ "proto_id": {
++ "anyOf": [
++ { "type": "string", "minLength": 1, "maxLength": 64, "pattern": "^[a-zA-Z0-9-_]+$" },
++ { "type": "integer", "minimum": 1 }
++ ]
++ }
++ },
++ "additionalProperties": true
++ },
++ "proxy-mirror": {
++ "type": "object",
++ "required": ["host"],
++ "properties": {
++ "host": {
++ "type": "string",
++ "pattern": "^http(s)?:\\/\\/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:[0-9]{1,5})?$"
++ }
++ },
++ "minProperties": 1
++ },
++ "node-status": { "type": "object", "additionalProperties": false }
++ }
++}
diff --cc api/internal/core/store/test_case.json
index 0000000,77f524b..950edf3
mode 000000,100644..100644
--- a/api/internal/core/store/test_case.json
+++ b/api/internal/core/store/test_case.json
@@@ -1,0 -1,19 +1,19 @@@
+ {
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "type": "object",
+ "properties": {
- "name": {
++ "name": {
+ "type": "string",
+ "minLength": 10
+ },
+ "email": {
+ "type": "string",
+ "maxLength": 10
+ },
+ "age": {
+ "type": "integer",
+ "minimum": 0
+ }
+ },
+ "additionalProperties": false
+ }