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 <[email protected]> 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 + }
