From 31eb2d296d713207598734bf41396b1678552cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chu=20V=C4=83n=20H=E1=BA=A3i?= Date: Thu, 18 Jun 2026 00:01:35 +0700 Subject: [PATCH] apisix --- apisix-stack/README.MD | 248 + apisix-stack/apisix_conf/config.yaml | 28 + apisix-stack/apisix_conf/dashboard_conf.yaml | 102 + apisix-stack/apisix_conf/schema.json | 11343 ++++++++++++++++ apisix-stack/docker-compose.yml | 101 + .../dashboards/apisix_performance.json | 160 + .../provisioning/dashboards/dashboards.yaml | 11 + .../provisioning/datasources/datasources.yaml | 10 + .../promtail_conf/promtail-config.yaml | 19 + 9 files changed, 12022 insertions(+) create mode 100644 apisix-stack/README.MD create mode 100644 apisix-stack/apisix_conf/config.yaml create mode 100644 apisix-stack/apisix_conf/dashboard_conf.yaml create mode 100644 apisix-stack/apisix_conf/schema.json create mode 100644 apisix-stack/docker-compose.yml create mode 100644 apisix-stack/grafana_conf/provisioning/dashboards/apisix_performance.json create mode 100644 apisix-stack/grafana_conf/provisioning/dashboards/dashboards.yaml create mode 100644 apisix-stack/grafana_conf/provisioning/datasources/datasources.yaml create mode 100644 apisix-stack/promtail_conf/promtail-config.yaml diff --git a/apisix-stack/README.MD b/apisix-stack/README.MD new file mode 100644 index 0000000..b14f82f --- /dev/null +++ b/apisix-stack/README.MD @@ -0,0 +1,248 @@ +Chỉnh sysctl trên máy chủ Host (máy Linux chạy Docker) để TCP Stack hoạt động tốt hơn. + +# Cho phép tái sử dụng các socket đang ở trạng thái TIME_WAIT +sudo sysctl -w net.ipv4.tcp_tw_reuse=1 + +# Tăng hàng đợi kết nối (Backlog) +sudo sysctl -w net.core.somaxconn=65535 + +# Lưu lại cấu hình (để khi reboot không mất) +echo "net.ipv4.tcp_tw_reuse=1" | sudo tee -a /etc/sysctl.conf +echo "net.core.somaxconn=65535" | sudo tee -a /etc/sysctl.conf + + +---- +# Hệ Thống Cổng Kết Nối API Trung Gian (API Gateway) Cho Dynamics 365 Dataverse + +Tài liệu này hướng dẫn cách triển khai, cấu hình và vận hành hệ thống API Gateway tự host (Self-hosted) sử dụng **Apache APISIX** để cung cấp (expose) API của Microsoft Dynamics 365 Dataverse bảo mật cho bên thứ ba. Hệ thống tích hợp sẵn cụm quản lý log tập trung siêu nhẹ: **Grafana Loki + Promtail + Grafana**. + +## 📌 Kiến Trúc Hệ Thống + +```text +[Bên Thứ 3] ---> (Port: 9080 kèm API Key) ---> [APISIX Gateway] ---> (OAuth2 Token) ---> [Dataverse Web API] + | + (Docker Stdout JSON Log) + | + [Promtail] ---> [Grafana Loki] <--- [Grafana UI] +``` + +## 🛠️ Danh Sách Thành Phần & Cổng Kết Nối + +| Thành phần | Cổng công khai (Host Port) | Vai trò | Tài khoản mặc định | +| :--- | :--- | :--- | :--- | +| **APISIX Gateway** | `9080` (HTTP) / `9180` (Admin API) | Xử lý traffic, giới hạn lượt gọi, gán token bảo mật | - | +| **APISIX Dashboard** | `9090` | Giao diện cấu hình Route, Plugin trực quan | `admin` / `admin` | +| **Grafana** | `9300` | Giao diện truy vấn và giám sát log thời gian thực | `admin` / `admin` | +| **Loki** | `9100` | Cơ sở dữ liệu lưu trữ log tập trung (Siêu nhẹ) | - | +| **etcd** | *Không expose (Chỉ chạy nội bộ)* | Cơ sở dữ liệu phân tán lưu cấu hình của APISIX | Bảo mật nội bộ container | + +--- + +## 🚀 Hướng Dẫn Triển Khai Nhanh + +### Bước 1: Chuẩn bị cấu trúc thư mục +Tạo cấu trúc thư mục trên máy chủ của bạn như sau: +```text +apisix-stack/ +├── docker-compose.yml +├── apisix_conf/ +│ ├── config.yaml +│ ├── dashboard_conf.yaml +│ └── schema.json +├── promtail_conf/ +│ └── promtail-config.yaml +└── grafana_conf/ + └── provisioning/ + ├── datasources/ + │ └── datasources.yaml + └── dashboards/ + ├── dashboards.yaml + └── apisix_performance.json +``` + +### Bước 2: Khởi chạy cụm Docker +Tại thư mục gốc (`apisix-stack/`), chạy lệnh sau để tải và chạy các dịch vụ: +```bash +docker compose up -d +``` + +--- + +## ⚙️ Cấu Hình Kết Nối Dynamics 365 Dataverse + +### Bước 1: Đăng ký Ứng dụng trên Microsoft Entra ID (Azure AD) +1. Truy cập vào **Microsoft Entra ID** > **App registrations** > **New registration**. +2. Đặt tên (ví dụ: `APISIX-Dataverse-Proxy`) và bấm **Register**. +3. Lưu lại thông tin: `Application (client) ID` và `Directory (tenant) ID`. +4. Vào mục **Certificates & secrets** > **New client secret** > Tạo một Secret mới và sao chép lại **Value** của secret này. +5. Vào mục **API permissions** > **Add a permission** > Chọn **Dynamics CRM** > Tích chọn `user_impersonation` và bấm **Add permissions**. Sau đó bấm **Grant admin consent** cho tenant của bạn. + +### Bước 2: Tạo Application User trong Dataverse +1. Truy cập vào [Power Platform Admin Center](https://microsoft.com). +2. Chọn Môi trường (Environment) của bạn > **Settings** > **Users + permissions** > **Application users**. +3. Bấm **New app user** > **Add an app** > Chọn ứng dụng bạn vừa đăng ký ở Bước 1. +4. Chọn **Business unit** và gán **Security Role** phù hợp để giới hạn quyền truy cập bảng dữ liệu (Table). + +### Bước 3: Cấu hình Route trên APISIX Dashboard +Truy cập vào giao diện quản lý APISIX tại địa chỉ: `http://:9090`. + +#### 1. Tạo Consumer (Cấp API Key cho bên thứ ba) +* Vào mục **Consumers** > Bấm **Create**. +* Đặt tên định danh (Username), ví dụ: `doi-tac-A`. +* Ở phần Plugin, bật plugin **`key-auth`** và điền một chuỗi bí mật vào ô `key` (ví dụ: `partner-secret-key-2026`). + +#### 2. Tạo Route (Cấu hình luồng đi của API) +* Vào mục **Routes** > Bấm **Create**. +* **Định nghĩa đường dẫn (Request):** `Path`: `/ssm-vn-dev/*` +* **Cấu hình Đích đến (Upstream):** Chọn `Custom Upstream`. `Node URL`: `https://tngredev.crm5.dynamics.com` (Port: `443`). +* **Cấu hình Plugins:** + * **Cấu hình Plugins xác thực (Chọn một trong hai phương án sau tùy theo nhu cầu):** + * **Phương án A: Sử dụng OpenID Connect (Azure AD / Microsoft Entra ID) để bảo mật API đầu vào** + * Bật plugin **`openid-connect`** để APISIX đóng vai trò xác thực Token từ Client gửi lên: + * `client_id`: `` + * `client_secret`: `` + * `discovery`: `https://login.microsoftonline.com//v2.0/.well-known/openid-configuration` + * `bearer_only`: `true` (Chỉ chấp nhận Bearer Token ở header `Authorization`, không tự động redirect sang trang web login) + * **Phương án B: Xác thực Client bằng API Key (`key-auth`)** + * Bật plugin **`key-auth`** trên cấu hình Route. Giá trị cấu hình rất đơn giản, chỉ cần truyền một đối tượng rỗng: + ```json + "key-auth": {} + ``` + *(Mặc định APISIX sẽ tìm header tên là `apikey` gửi từ Client. Nếu bạn muốn đổi tên header tùy biến, ví dụ `X-API-Key`, bạn nhập:* `{"header": "X-API-Key"}`*)*. + * *Lưu ý*: Vì plugin `openid-connect` trong APISIX chỉ hỗ trợ xác thực đầu vào (Incoming Auth), nếu bạn muốn APISIX tự động lấy Token từ Azure AD (qua Client Credentials Flow) để đính kèm khi gọi sang Dynamics 365 Dataverse (Outbound Token Injection), bạn cần sử dụng một cơ chế bổ trợ (như viết Custom Lua Script trong plugin `serverless-pre-function` hoặc dùng service phụ qua plugin `forward-auth`). + * **Bật plugin `rate-limiting`**: Thiết lập giới hạn request phù hợp để bảo vệ Dataverse. + +--- + +### 🔑 Hướng dẫn cấu hình chi tiết Phương án B (API Key + Auto Inject Dynamics 365 Token) + +Phương án này cho phép **Client** chỉ cần truyền API Key đơn giản khi gọi Gateway (qua header `apikey` của plugin `key-auth`), sau đó **APISIX Gateway** sẽ tự động thực hiện Client Credentials Flow với Azure AD để lấy Access Token, cache lại trong bộ nhớ RAM của Gateway và đính kèm vào header `Authorization: Bearer ` trước khi chuyển tiếp request tới Dynamics 365. + +#### Bước 1: Khai báo bộ nhớ cache dùng chung (`lua_shared_dict`) +Để lưu trữ và tái sử dụng token (hạn dùng của Microsoft token là 1 tiếng), tránh việc mỗi request gửi lên lại phải gọi API xin token mới làm chậm hệ thống, ta cần cấp phát bộ nhớ cache trong `apisix_conf/config.yaml`: + +```yaml +nginx_config: + custom_lua_shared_dict: + oauth_cache: 1m # Cấp 1MB bộ nhớ để cache access token +``` + +#### Bước 2: Thiết lập Route với plugin `key-auth` và `serverless-pre-function` +Dưới đây là lệnh `curl` cấu hình Route `/ssm-vn-dev/*` tích hợp xác thực API Key đầu vào và tự lấy/đính kèm Token đầu ra thông qua Custom Lua Script: + +```bash +curl -i http://localhost:9180/apisix/admin/routes/ssm-vn-dev-route \ + -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \ + -H 'Content-Type: application/json' \ + -X PUT \ + -d '{ + "uri": "/ssm-vn-dev/*", + "name": "ssm-vn-dev-route", + "plugins": { + "key-auth": {}, + "serverless-pre-function": { + "phase": "access", + "functions": [ + "return function(conf, ctx) local core = require(\"apisix.core\"); local http = require(\"resty.http\"); local cache = ngx.shared.oauth_cache; if not cache then core.log.error(\"oauth_cache not defined in config.yaml\"); return end; local token = cache:get(\"dataverse_token\"); if not token then local httpc = http.new(); httpc:set_timeout(5000); local tenant_id = \"\"; local client_id = \"\"; local client_secret = \"\"; local scope = \"https://.crm.dynamics.com/.default\"; local body = \"grant_type=client_credentials&client_id=\" .. ngx.escape_uri(client_id) .. \"&client_secret=\" .. ngx.escape_uri(client_secret) .. \"&scope=\" .. ngx.escape_uri(scope); local res, err = httpc:request_uri(\"https://login.microsoftonline.com/\" .. tenant_id .. \"/oauth2/v2.0/token\", { method = \"POST\", body = body, headers = { [\"Content-Type\"] = \"application/x-www-form-urlencoded\" }, ssl_verify = false }); if not res or res.status ~= 200 then core.log.error(\"Failed to fetch Azure AD token: \", err or (res and res.body)); return core.response.exit(500, { error = \"Auth failed to upstream provider\" }) end; local data, decode_err = core.json.decode(res.body); if not data or not data.access_token then core.log.error(\"Failed to decode token response\"); return core.response.exit(500, { error = \"Invalid token response\" }) end; token = data.access_token; local expires_in = data.expires_in or 3600; cache:set(\"dataverse_token\", token, expires_in - 60) end; ngx.req.set_header(\"Authorization\", \"Bearer \" .. token) end" + ] + }, + "rate-limiting": { + "count": 100, + "time_window": 60, + "rejected_code": 429 + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "tngredev.crm5.dynamics.com:443": 1 + }, + "pass_host": "node", + "scheme": "https" + } + }' +``` + +> [!IMPORTANT] +> **Giải thích tham số cấu hình Upstream:** +> * `pass_host: "node"`: Bắt buộc cấu hình trường này để APISIX ghi đè giá trị header `Host` gửi tới Dynamics 365 trùng khớp với node URL (`.crm.dynamics.com`). Nếu thiếu, Dynamics 365 sẽ từ chối xử lý request vì host header không khớp. +> * Các tham số ``, ``, ``, `` trong đoạn mã Lua cần được thay thế bằng thông tin môi trường Azure AD và Dynamics 365 thực tế của bạn. + +#### Chi tiết kịch bản script Lua chạy trong APISIX: +1. **Kiểm tra Cache:** Truy cập vào `ngx.shared.oauth_cache` tìm xem có token `dataverse_token` nào chưa hết hạn không. +2. **Nếu chưa có:** Kích hoạt một cuộc gọi HTTP POST không đồng bộ (non-blocking) tới Endpoint của Azure AD sử dụng thư viện `resty.http`. +3. **Lưu trữ:** Giải mã JSON trả về, lấy Access Token và lưu lại vào cache với thời gian sống (TTL) ngắn hơn thời hạn thật của token 60 giây (để tránh rủi ro token hết hạn trong lúc đang truyền tin). +4. **Gán Header:** Ghi đè header `Authorization: Bearer ` bằng lệnh `ngx.req.set_header`. + +--- + +## 📊 Hướng Dẫn Giám Sát Và Xem Log Tập Trung (Grafana Loki) + +> [!NOTE] +> Hệ thống đã được cấu hình **tự động kết nối (provisioning)** giữa Grafana và Loki làm Data Source mặc định, đồng thời **tự động import sẵn Dashboard theo dõi hiệu năng APISIX**. Bạn không cần phải cấu hình thủ công sau khi khởi chạy container. + +### Bước 1: Xem Dashboard giám sát hiệu năng APISIX (Real-time Dashboard) +1. Truy cập vào **Grafana UI**: `http://:9300` (Tài khoản mặc định: `admin` / `admin`). +2. Vào phần **Dashboards** từ menu bên trái. +3. Chọn dashboard có tên là **APISIX Gateway Performance** (trong thư mục `APISIX API Gateway`). +4. Tại đây bạn sẽ thấy các biểu đồ trực quan hóa thời gian thực được phân tích từ log của Loki: + - **Request Rate (RPS)**: Tốc độ xử lý request mỗi giây. + - **Average Response Time (Latency)**: Thời gian phản hồi trung bình (Độ trễ). + - **HTTP Status Distribution**: Phân bố mã trạng thái phản hồi (2xx, 3xx, 4xx, 5xx). + - **Data Egress (Throughput)**: Băng thông dữ liệu trả về từ Gateway. + - **APISIX Gateway Logs**: Dòng log thời gian thực chạy trực tiếp bên dưới. + +### Bước 2: Xem log thời gian thực (Live Stream Log) trong Grafana Explore +1. Bấm vào biểu tượng **Explore** (Hình la bàn bên thanh công cụ trái). +2. Đảm bảo đã chọn Data Source là **Loki**. +3. Tại ô nhập câu lệnh truy vấn (Query) nhập: + ```text + {container="apisix-gateway"} + ``` +4. Bấm **Run query** và chọn **Live** để bắt đầu theo dõi dòng log thời gian thực. + +--- + +### 🛡️ Cấu hình ghi Log truy cập tự động kèm Request/Response Body sang Loki + +Mặc định, log stdout của APISIX Gateway không chứa nội dung Request/Response Body để tối ưu hiệu năng. Nếu bạn muốn tự động ghi nhận lại toàn bộ Payload (Request/Response Body) gửi từ bên thứ ba và đẩy trực tiếp sang Loki, thực hiện cấu hình dưới đây: + +#### Hướng dẫn thiết lập qua APISIX Admin API +*(Lưu ý: Vì phiên bản APISIX Dashboard (v3.0.1) ra đời trước khi plugin `loki-logger` có schema hiển thị đồ họa trên UI, nên plugin này sẽ không hiển thị trong danh sách Plugin Market của giao diện Dashboard. Tuy nhiên, APISIX Gateway (v3.11.0) hỗ trợ hoàn toàn plugin này. Bạn hãy cấu hình trực tiếp qua Admin API bằng lệnh `curl` dưới đây để kích hoạt ghi log toàn cục:)* +Chạy lệnh curl sau trực tiếp trên VPS để cấu hình plugin `loki-logger` toàn cục: +```bash +curl -i http://localhost:9180/apisix/admin/global_rules/1 \ + -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \ + -H 'Content-Type: application/json' \ + -X PUT \ + -d '\''{ + "plugins": { + "loki-logger": { + "endpoint_addrs": ["http://loki:3100"], + "include_req_body": true, + "include_resp_body": true, + "log_labels": { + "job": "apisix-gateway" + } + } + } + }'\'' +``` + +--- + +### 📊 Xem và truy vấn Payload log (Request/Response Body) trong Grafana +1. Truy cập **Grafana UI** (`http://:9300`) > **Explore**. +2. Chọn Data Source là **Loki**. +3. Nhập câu lệnh LogQL sau để lọc log được gửi trực tiếp từ plugin `loki-logger`: + ```text + {job="apisix-gateway"} + ``` +4. Để định dạng (parse) log JSON và hiển thị trực quan các trường Request/Response, bạn có thể thêm bộ phân tích cú pháp bằng cách nhập truy vấn sau: + ```text + {job="apisix-gateway"} | json + ``` +5. Click vào bất kỳ dòng log nào bên dưới kết quả. Bạn sẽ thấy các trường dữ liệu được phân tích cấu trúc, bao gồm: + - `request.body`: Chứa toàn bộ nội dung Request payload từ Client. + - `response.body` hoặc `resp_body`: Chứa toàn bộ nội dung Response payload trả về từ phía Dataverse. + diff --git a/apisix-stack/apisix_conf/config.yaml b/apisix-stack/apisix_conf/config.yaml new file mode 100644 index 0000000..e0ab4a1 --- /dev/null +++ b/apisix-stack/apisix_conf/config.yaml @@ -0,0 +1,28 @@ +apisix: + id: "apisix-gateway" + +deployment: + role: traditional + role_traditional: + config_provider: etcd + admin: + allow_admin: + - 0.0.0.0/0 + admin_key: + - name: "admin" + key: edd1c9f034335f136f87ad84b625c8f1 + role: admin + etcd: + host: + - "http://etcd:2379" + prefix: "/apisix" + +nginx_config: + custom_lua_shared_dict: + oauth_cache: 1m + http: + access_log: "/dev/stdout" + access_log_format: '{"time_local":"$time_local","client_ip":"$remote_addr","request":"$request","status":$status,"body_bytes_sent":$body_bytes_sent,"request_time":$request_time,"upstream_response_time":"$upstream_response_time"}' + access_log_format_escape: json + error_log: "/dev/stderr" + error_log_level: "warn" diff --git a/apisix-stack/apisix_conf/dashboard_conf.yaml b/apisix-stack/apisix_conf/dashboard_conf.yaml new file mode 100644 index 0000000..4be3789 --- /dev/null +++ b/apisix-stack/apisix_conf/dashboard_conf.yaml @@ -0,0 +1,102 @@ +conf: + listen: + host: 0.0.0.0 + port: 9090 + allow_list: + - 0.0.0.0/0 + etcd: + endpoints: + - etcd:2379 + log: + error_log: + level: warn + file_path: /dev/stderr + access_log: + file_path: /dev/stdout + security: + content_security_policy: "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-src *;" + +authentication: + secret: "edd1c9f034335f136f87ad84b625c8f1" + expire_time: 3600 + users: + - username: "admin" + password: "admin" + +plugins: + - api-breaker + - authz-casbin + - authz-casdoor + - authz-keycloak + - aws-lambda + - azure-functions + - basic-auth + - clickhouse-logger + - client-control + - consumer-restriction + - cors + - csrf + - datadog + - echo + - error-log-logger + - ext-plugin-post-req + - ext-plugin-post-resp + - ext-plugin-pre-req + - fault-injection + - file-logger + - forward-auth + - google-cloud-logging + - grpc-transcode + - grpc-web + - gzip + - hmac-auth + - http-logger + - ip-restriction + - jwt-auth + - kafka-logger + - kafka-proxy + - key-auth + - ldap-auth + - limit-conn + - limit-count + - limit-req + - loggly + - mocking + - opa + - openid-connect + - opentelemetry + - openwhisk + - prometheus + - proxy-cache + - proxy-control + - proxy-mirror + - proxy-rewrite + - public-api + - real-ip + - redirect + - referer-restriction + - request-id + - request-validation + - response-rewrite + - rocketmq-logger + - server-info + - serverless-post-function + - serverless-pre-function + - skywalking + - skywalking-logger + - sls-logger + - splunk-hec-logging + - syslog + - tcp-logger + - traffic-split + - ua-restriction + - udp-logger + - uri-blocker + - wolf-rbac + - zipkin + - elasticsearch-logge + - openfunction + - tencent-cloud-cls + - ai + - cas-auth + - loki-logger diff --git a/apisix-stack/apisix_conf/schema.json b/apisix-stack/apisix_conf/schema.json new file mode 100644 index 0000000..3cbb577 --- /dev/null +++ b/apisix-stack/apisix_conf/schema.json @@ -0,0 +1,11343 @@ +{ + "main": { + "consumer": { + "properties": { + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "group_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "plugins": { + "type": "object" + }, + "update_time": { + "type": "integer" + }, + "username": { + "maxLength": 100, + "minLength": 1, + "pattern": "^[a-zA-Z0-9_]+$", + "type": "string" + } + }, + "required": [ + "username" + ], + "type": "object" + }, + "global_rule": { + "properties": { + "create_time": { + "type": "integer" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "plugins": { + "type": "object" + }, + "update_time": { + "type": "integer" + } + }, + "required": [ + "plugins" + ], + "type": "object" + }, + "plugin_config": { + "properties": { + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "plugins": { + "type": "object" + }, + "update_time": { + "type": "integer" + } + }, + "required": [ + "id", + "plugins" + ], + "type": "object" + }, + "plugins": { + "items": { + "properties": { + "name": { + "minLength": 1, + "type": "string" + }, + "stream": { + "type": "boolean" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + }, + "proto": { + "properties": { + "content": { + "maxLength": 1048576, + "minLength": 1, + "type": "string" + }, + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "update_time": { + "type": "integer" + } + }, + "required": [ + "content" + ], + "type": "object" + }, + "route": { + "allOf": [ + { + "oneOf": [ + { + "required": [ + "uri" + ] + }, + { + "required": [ + "uris" + ] + } + ] + }, + { + "oneOf": [ + { + "not": { + "anyOf": [ + { + "required": [ + "host" + ] + }, + { + "required": [ + "hosts" + ] + } + ] + } + }, + { + "required": [ + "host" + ] + }, + { + "required": [ + "hosts" + ] + } + ] + }, + { + "oneOf": [ + { + "not": { + "anyOf": [ + { + "required": [ + "remote_addr" + ] + }, + { + "required": [ + "remote_addrs" + ] + } + ] + } + }, + { + "required": [ + "remote_addr" + ] + }, + { + "required": [ + "remote_addrs" + ] + } + ] + } + ], + "anyOf": [ + { + "required": [ + "plugins", + "uri" + ] + }, + { + "required": [ + "upstream", + "uri" + ] + }, + { + "required": [ + "upstream_id", + "uri" + ] + }, + { + "required": [ + "service_id", + "uri" + ] + }, + { + "required": [ + "plugins", + "uris" + ] + }, + { + "required": [ + "upstream", + "uris" + ] + }, + { + "required": [ + "upstream_id", + "uris" + ] + }, + { + "required": [ + "service_id", + "uris" + ] + }, + { + "required": [ + "script", + "uri" + ] + }, + { + "required": [ + "script", + "uris" + ] + } + ], + "not": { + "anyOf": [ + { + "required": [ + "plugins", + "script" + ] + }, + { + "required": [ + "plugin_config_id", + "script" + ] + } + ] + }, + "properties": { + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "enable_websocket": { + "description": "enable websocket for request", + "type": "boolean" + }, + "filter_func": { + "minLength": 10, + "pattern": "^function", + "type": "string" + }, + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "hosts": { + "items": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "methods": { + "items": { + "description": "HTTP method", + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PURGE", + "PUT", + "TRACE" + ], + "type": "string" + }, + "type": "array", + "uniqueItems": true + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "plugin_config_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "plugins": { + "type": "object" + }, + "priority": { + "default": 0, + "type": "integer" + }, + "remote_addr": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], + "description": "client IP", + "type": "string" + }, + "remote_addrs": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], + "description": "client IP", + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "script": { + "maxLength": 102400, + "minLength": 10, + "type": "string" + }, + "script_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "service_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "status": { + "default": 1, + "description": "route status, 1 to enable, 0 to disable", + "enum": [ + 0, + 1 + ], + "type": "integer" + }, + "timeout": { + "properties": { + "connect": { + "exclusiveMinimum": 0, + "type": "number" + }, + "read": { + "exclusiveMinimum": 0, + "type": "number" + }, + "send": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "connect", + "read", + "send" + ], + "type": "object" + }, + "update_time": { + "type": "integer" + }, + "upstream": { + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], + "properties": { + "checks": { + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], + "properties": { + "active": { + "properties": { + "concurrency": { + "default": 10, + "type": "integer" + }, + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 302 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "successes": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "http_path": { + "default": "/", + "type": "string" + }, + "https_verify_certificate": { + "default": true, + "type": "boolean" + }, + "port": { + "maximum": 65535, + "minimum": 1, + "type": "integer" + }, + "req_headers": { + "items": { + "type": "string", + "uniqueItems": true + }, + "minItems": 1, + "type": "array" + }, + "timeout": { + "default": 1, + "type": "number" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "http_statuses": { + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "timeouts": { + "default": 3, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "passive": { + "properties": { + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "successes": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "http_statuses": { + "default": [ + 429, + 500, + 503 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "timeouts": { + "default": 7, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "discovery_args": { + "properties": { + "group_name": { + "description": "group name", + "type": "string" + }, + "namespace_id": { + "description": "namespace id", + "type": "string" + } + }, + "type": "object" + }, + "discovery_type": { + "description": "discovery type", + "type": "string" + }, + "hash_on": { + "default": "vars", + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "keepalive_pool": { + "properties": { + "idle_timeout": { + "default": 60, + "minimum": 0, + "type": "number" + }, + "requests": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "size": { + "default": 320, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "key": { + "description": "the key of chash for dynamic load balancing", + "type": "string" + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nodes": { + "anyOf": [ + { + "patternProperties": { + ".*": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "pass_host": { + "default": "pass", + "description": "mod of host passing", + "enum": [ + "node", + "pass", + "rewrite" + ], + "type": "string" + }, + "retries": { + "minimum": 0, + "type": "integer" + }, + "retry_timeout": { + "minimum": 0, + "type": "number" + }, + "scheme": { + "default": "http", + "description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "kafka", + "tcp", + "tls", + "udp" + ] + }, + "service_name": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "timeout": { + "properties": { + "connect": { + "exclusiveMinimum": 0, + "type": "number" + }, + "read": { + "exclusiveMinimum": 0, + "type": "number" + }, + "send": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "connect", + "read", + "send" + ], + "type": "object" + }, + "tls": { + "dependencies": { + "client_cert": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_key" + ] + }, + "client_cert_id": { + "not": { + "required": [ + "client_client", + "client_key" + ] + } + }, + "client_key": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_cert" + ] + } + }, + "properties": { + "client_cert": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "client_cert_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "client_key": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "verify": { + "default": false, + "description": "Turn on server certificate verification, currently only kafka upstream is supported", + "type": "boolean" + } + }, + "type": "object" + }, + "type": { + "description": "algorithms of load balancing", + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream_host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + } + }, + "type": "object" + }, + "upstream_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "uri": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "uris": { + "items": { + "description": "HTTP uri", + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "vars": { + "type": "array" + } + }, + "type": "object" + }, + "service": { + "properties": { + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "enable_websocket": { + "description": "enable websocket for request", + "type": "boolean" + }, + "hosts": { + "items": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "plugins": { + "type": "object" + }, + "script": { + "maxLength": 102400, + "minLength": 10, + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream": { + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], + "properties": { + "checks": { + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], + "properties": { + "active": { + "properties": { + "concurrency": { + "default": 10, + "type": "integer" + }, + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 302 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "successes": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "http_path": { + "default": "/", + "type": "string" + }, + "https_verify_certificate": { + "default": true, + "type": "boolean" + }, + "port": { + "maximum": 65535, + "minimum": 1, + "type": "integer" + }, + "req_headers": { + "items": { + "type": "string", + "uniqueItems": true + }, + "minItems": 1, + "type": "array" + }, + "timeout": { + "default": 1, + "type": "number" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "http_statuses": { + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "timeouts": { + "default": 3, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "passive": { + "properties": { + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "successes": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "http_statuses": { + "default": [ + 429, + 500, + 503 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "timeouts": { + "default": 7, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "discovery_args": { + "properties": { + "group_name": { + "description": "group name", + "type": "string" + }, + "namespace_id": { + "description": "namespace id", + "type": "string" + } + }, + "type": "object" + }, + "discovery_type": { + "description": "discovery type", + "type": "string" + }, + "hash_on": { + "default": "vars", + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "keepalive_pool": { + "properties": { + "idle_timeout": { + "default": 60, + "minimum": 0, + "type": "number" + }, + "requests": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "size": { + "default": 320, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "key": { + "description": "the key of chash for dynamic load balancing", + "type": "string" + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nodes": { + "anyOf": [ + { + "patternProperties": { + ".*": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "pass_host": { + "default": "pass", + "description": "mod of host passing", + "enum": [ + "node", + "pass", + "rewrite" + ], + "type": "string" + }, + "retries": { + "minimum": 0, + "type": "integer" + }, + "retry_timeout": { + "minimum": 0, + "type": "number" + }, + "scheme": { + "default": "http", + "description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "kafka", + "tcp", + "tls", + "udp" + ] + }, + "service_name": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "timeout": { + "properties": { + "connect": { + "exclusiveMinimum": 0, + "type": "number" + }, + "read": { + "exclusiveMinimum": 0, + "type": "number" + }, + "send": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "connect", + "read", + "send" + ], + "type": "object" + }, + "tls": { + "dependencies": { + "client_cert": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_key" + ] + }, + "client_cert_id": { + "not": { + "required": [ + "client_client", + "client_key" + ] + } + }, + "client_key": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_cert" + ] + } + }, + "properties": { + "client_cert": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "client_cert_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "client_key": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "verify": { + "default": false, + "description": "Turn on server certificate verification, currently only kafka upstream is supported", + "type": "boolean" + } + }, + "type": "object" + }, + "type": { + "description": "algorithms of load balancing", + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream_host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + } + }, + "type": "object" + }, + "upstream_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + } + }, + "type": "object" + }, + "ssl": { + "properties": { + "cert": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "certs": { + "items": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "type": "array" + }, + "client": { + "properties": { + "ca": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "depth": { + "default": 1, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "ca" + ], + "type": "object" + }, + "create_time": { + "type": "integer" + }, + "exptime": { + "minimum": 1588262400, + "type": "integer" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "key": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "keys": { + "items": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "type": "array" + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "sni": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "snis": { + "items": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "status": { + "default": 1, + "description": "ssl status, 1 to enable, 0 to disable", + "enum": [ + 0, + 1 + ], + "type": "integer" + }, + "type": { + "default": "server", + "description": "ssl certificate type, server to server certificate, client to client certificate for upstream", + "enum": [ + "client", + "server" + ], + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "validity_end": { + "type": "integer" + }, + "validity_start": { + "type": "integer" + } + }, + "if": { + "properties": { + "type": { + "enum": [ + "server" + ] + } + } + }, + "else": { + "required": [ + "cert", + "key" + ] + }, + "then": { + "oneOf": [ + { + "required": [ + "cert", + "key", + "sni" + ] + }, + { + "required": [ + "cert", + "key", + "snis" + ] + } + ] + }, + "type": "object" + }, + "stream_route": { + "properties": { + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "plugins": { + "type": "object" + }, + "protocol": { + "properties": { + "conf": { + "description": "protocol-specific configuration", + "type": "object" + }, + "logger": { + "items": { + "dependencies": { + "name": [ + "conf" + ] + }, + "properties": { + "conf": { + "description": "logger plugin configuration", + "type": "object" + }, + "filter": { + "description": "logger filter rules", + "type": "array" + }, + "name": { + "type": "string" + } + } + }, + "type": "array" + }, + "name": { + "type": "string" + }, + "superior_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "remote_addr": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], + "description": "client IP", + "type": "string" + }, + "server_addr": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ], + "description": "server IP", + "type": "string" + }, + "server_port": { + "description": "server port", + "type": "integer" + }, + "sni": { + "description": "server name indication", + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream": { + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], + "properties": { + "checks": { + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], + "properties": { + "active": { + "properties": { + "concurrency": { + "default": 10, + "type": "integer" + }, + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 302 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "successes": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "http_path": { + "default": "/", + "type": "string" + }, + "https_verify_certificate": { + "default": true, + "type": "boolean" + }, + "port": { + "maximum": 65535, + "minimum": 1, + "type": "integer" + }, + "req_headers": { + "items": { + "type": "string", + "uniqueItems": true + }, + "minItems": 1, + "type": "array" + }, + "timeout": { + "default": 1, + "type": "number" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "http_statuses": { + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "timeouts": { + "default": 3, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "passive": { + "properties": { + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "successes": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "http_statuses": { + "default": [ + 429, + 500, + 503 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "timeouts": { + "default": 7, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "discovery_args": { + "properties": { + "group_name": { + "description": "group name", + "type": "string" + }, + "namespace_id": { + "description": "namespace id", + "type": "string" + } + }, + "type": "object" + }, + "discovery_type": { + "description": "discovery type", + "type": "string" + }, + "hash_on": { + "default": "vars", + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "keepalive_pool": { + "properties": { + "idle_timeout": { + "default": 60, + "minimum": 0, + "type": "number" + }, + "requests": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "size": { + "default": 320, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "key": { + "description": "the key of chash for dynamic load balancing", + "type": "string" + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nodes": { + "anyOf": [ + { + "patternProperties": { + ".*": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "pass_host": { + "default": "pass", + "description": "mod of host passing", + "enum": [ + "node", + "pass", + "rewrite" + ], + "type": "string" + }, + "retries": { + "minimum": 0, + "type": "integer" + }, + "retry_timeout": { + "minimum": 0, + "type": "number" + }, + "scheme": { + "default": "http", + "description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "kafka", + "tcp", + "tls", + "udp" + ] + }, + "service_name": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "timeout": { + "properties": { + "connect": { + "exclusiveMinimum": 0, + "type": "number" + }, + "read": { + "exclusiveMinimum": 0, + "type": "number" + }, + "send": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "connect", + "read", + "send" + ], + "type": "object" + }, + "tls": { + "dependencies": { + "client_cert": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_key" + ] + }, + "client_cert_id": { + "not": { + "required": [ + "client_client", + "client_key" + ] + } + }, + "client_key": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_cert" + ] + } + }, + "properties": { + "client_cert": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "client_cert_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "client_key": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "verify": { + "default": false, + "description": "Turn on server certificate verification, currently only kafka upstream is supported", + "type": "boolean" + } + }, + "type": "object" + }, + "type": { + "description": "algorithms of load balancing", + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream_host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + } + }, + "type": "object" + }, + "upstream_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + } + }, + "type": "object" + }, + "upstream": { + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], + "properties": { + "checks": { + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], + "properties": { + "active": { + "properties": { + "concurrency": { + "default": 10, + "type": "integer" + }, + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 302 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "successes": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "http_path": { + "default": "/", + "type": "string" + }, + "https_verify_certificate": { + "default": true, + "type": "boolean" + }, + "port": { + "maximum": 65535, + "minimum": 1, + "type": "integer" + }, + "req_headers": { + "items": { + "type": "string", + "uniqueItems": true + }, + "minItems": 1, + "type": "array" + }, + "timeout": { + "default": 1, + "type": "number" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "http_statuses": { + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "timeouts": { + "default": 3, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "passive": { + "properties": { + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "successes": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "http_statuses": { + "default": [ + 429, + 500, + 503 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "timeouts": { + "default": 7, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "discovery_args": { + "properties": { + "group_name": { + "description": "group name", + "type": "string" + }, + "namespace_id": { + "description": "namespace id", + "type": "string" + } + }, + "type": "object" + }, + "discovery_type": { + "description": "discovery type", + "type": "string" + }, + "hash_on": { + "default": "vars", + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "keepalive_pool": { + "properties": { + "idle_timeout": { + "default": 60, + "minimum": 0, + "type": "number" + }, + "requests": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "size": { + "default": 320, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "key": { + "description": "the key of chash for dynamic load balancing", + "type": "string" + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nodes": { + "anyOf": [ + { + "patternProperties": { + ".*": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "pass_host": { + "default": "pass", + "description": "mod of host passing", + "enum": [ + "node", + "pass", + "rewrite" + ], + "type": "string" + }, + "retries": { + "minimum": 0, + "type": "integer" + }, + "retry_timeout": { + "minimum": 0, + "type": "number" + }, + "scheme": { + "default": "http", + "description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "kafka", + "tcp", + "tls", + "udp" + ] + }, + "service_name": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "timeout": { + "properties": { + "connect": { + "exclusiveMinimum": 0, + "type": "number" + }, + "read": { + "exclusiveMinimum": 0, + "type": "number" + }, + "send": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "connect", + "read", + "send" + ], + "type": "object" + }, + "tls": { + "dependencies": { + "client_cert": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_key" + ] + }, + "client_cert_id": { + "not": { + "required": [ + "client_client", + "client_key" + ] + } + }, + "client_key": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_cert" + ] + } + }, + "properties": { + "client_cert": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "client_cert_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "client_key": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "verify": { + "default": false, + "description": "Turn on server certificate verification, currently only kafka upstream is supported", + "type": "boolean" + } + }, + "type": "object" + }, + "type": { + "description": "algorithms of load balancing", + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream_host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + } + }, + "type": "object" + }, + "upstream_hash_header_schema": { + "pattern": "^[a-zA-Z0-9-_]+$", + "type": "string" + }, + "upstream_hash_vars_schema": { + "pattern": "^((uri|server_name|server_addr|request_uri|remote_port|remote_addr|query_string|host|hostname)|arg_[0-9a-zA-z_-]+)$", + "type": "string" + } + }, + "plugins": { + "ai": { + "priority": 22900, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + } + }, + "scope": "global", + "version": 0.1 + }, + "api-breaker": { + "priority": 1005, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "break_response_body": { + "type": "string" + }, + "break_response_code": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "break_response_headers": { + "items": { + "properties": { + "key": { + "minLength": 1, + "type": "string" + }, + "value": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "key", + "value" + ], + "type": "object" + }, + "type": "array" + }, + "healthy": { + "default": { + "http_statuses": [ + 200 + ], + "successes": 3 + }, + "properties": { + "http_statuses": { + "default": [ + 200 + ], + "items": { + "maximum": 499, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "successes": { + "default": 3, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "max_breaker_sec": { + "default": 300, + "minimum": 3, + "type": "integer" + }, + "unhealthy": { + "default": { + "failures": 3, + "http_statuses": [ + 500 + ] + }, + "properties": { + "failures": { + "default": 3, + "minimum": 1, + "type": "integer" + }, + "http_statuses": { + "default": [ + 500 + ], + "items": { + "maximum": 599, + "minimum": 500, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + } + }, + "type": "object" + } + }, + "required": [ + "break_response_code" + ], + "type": "object" + }, + "version": 0.1 + }, + "authz-casbin": { + "metadata_schema": { + "properties": { + "model": { + "type": "string" + }, + "policy": { + "type": "string" + } + }, + "required": [ + "model", + "policy" + ], + "type": "object" + }, + "priority": 2560, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "model_path", + "policy_path", + "username" + ] + }, + { + "required": [ + "model", + "policy", + "username" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "model": { + "type": "string" + }, + "model_path": { + "type": "string" + }, + "policy": { + "type": "string" + }, + "policy_path": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "authz-casdoor": { + "priority": 2559, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "callback_url": { + "pattern": "^[^%?]+[^/]$", + "type": "string" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "endpoint_addr": { + "pattern": "^[^%?]+[^/]$", + "type": "string" + } + }, + "required": [ + "callback_url", + "client_id", + "client_secret", + "endpoint_addr" + ], + "type": "object" + }, + "version": 0.1 + }, + "authz-keycloak": { + "priority": 2000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "allOf": [ + { + "anyOf": [ + { + "required": [ + "discovery" + ] + }, + { + "required": [ + "token_endpoint" + ] + } + ] + }, + { + "anyOf": [ + { + "properties": { + "lazy_load_paths": { + "enum": [ + false + ] + } + } + }, + { + "anyOf": [ + { + "required": [ + "discovery" + ] + }, + { + "required": [ + "resource_registration_endpoint" + ] + } + ], + "properties": { + "lazy_load_paths": { + "enum": [ + true + ] + } + } + } + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "access_denied_redirect_uri": { + "maxLength": 2048, + "minLength": 1, + "type": "string" + }, + "access_token_expires_in": { + "default": 300, + "minimum": 1, + "type": "integer" + }, + "access_token_expires_leeway": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "cache_ttl_seconds": { + "default": 86400, + "minimum": 1, + "type": "integer" + }, + "client_id": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "client_secret": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "discovery": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "grant_type": { + "default": "urn:ietf:params:oauth:grant-type:uma-ticket", + "enum": [ + "urn:ietf:params:oauth:grant-type:uma-ticket" + ], + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "http_method_as_scope": { + "default": false, + "type": "boolean" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "lazy_load_paths": { + "default": false, + "type": "boolean" + }, + "password_grant_token_generation_incoming_uri": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "permissions": { + "default": {}, + "items": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "type": "array", + "uniqueItems": true + }, + "policy_enforcement_mode": { + "default": "ENFORCING", + "enum": [ + "ENFORCING", + "PERMISSIVE" + ], + "type": "string" + }, + "refresh_token_expires_in": { + "default": 3600, + "minimum": 1, + "type": "integer" + }, + "refresh_token_expires_leeway": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "resource_registration_endpoint": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "minimum": 1000, + "type": "integer" + }, + "token_endpoint": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "client_id" + ], + "type": "object" + }, + "version": 0.1 + }, + "aws-lambda": { + "priority": -1899, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "authorization": { + "properties": { + "apikey": { + "type": "string" + }, + "iam": { + "properties": { + "accesskey": { + "description": "access key id from from aws iam console", + "type": "string" + }, + "aws_region": { + "default": "us-east-1", + "description": "the aws region that is receiving the request", + "type": "string" + }, + "secretkey": { + "description": "secret access key from from aws iam console", + "type": "string" + }, + "service": { + "default": "execute-api", + "description": "the service that is receiving the request", + "type": "string" + } + }, + "required": [ + "accesskey", + "secretkey" + ], + "type": "object" + } + }, + "type": "object" + }, + "function_uri": { + "type": "string" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "minimum": 100, + "type": "integer" + } + }, + "required": [ + "function_uri" + ], + "type": "object" + }, + "version": 0.1 + }, + "azure-functions": { + "metadata_schema": { + "properties": { + "master_apikey": { + "default": "", + "type": "string" + }, + "master_clientid": { + "default": "", + "type": "string" + } + }, + "type": "object" + }, + "priority": -1900, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "authorization": { + "properties": { + "apikey": { + "type": "string" + }, + "clientid": { + "type": "string" + } + }, + "type": "object" + }, + "function_uri": { + "type": "string" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "minimum": 100, + "type": "integer" + } + }, + "required": [ + "function_uri" + ], + "type": "object" + }, + "version": 0.1 + }, + "basic-auth": { + "consumer_schema": { + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "title": "work with consumer object", + "type": "object" + }, + "priority": 2520, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "hide_credentials": { + "default": false, + "type": "boolean" + } + }, + "title": "work with route or service object", + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, + "batch-requests": { + "metadata_schema": { + "properties": { + "max_body_size": { + "default": 1048576, + "description": "max pipeline body size in bytes", + "exclusiveMinimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "priority": 4010, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "scope": "global", + "version": 0.1 + }, + "cas-auth": { + "priority": 2597, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "cas_callback_uri": { + "type": "string" + }, + "idp_uri": { + "type": "string" + }, + "logout_uri": { + "type": "string" + } + }, + "required": [ + "cas_callback_uri", + "idp_uri", + "logout_uri" + ], + "type": "object" + }, + "version": 0.1 + }, + "clickhouse-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 398, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "database", + "endpoint_addr", + "logtable", + "password", + "user" + ] + }, + { + "required": [ + "database", + "endpoint_addrs", + "logtable", + "password", + "user" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "database": { + "default": "", + "type": "string" + }, + "endpoint_addr": { + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + }, + "endpoint_addrs": { + "items": { + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "logtable": { + "default": "", + "type": "string" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "clickhouse-logger", + "type": "string" + }, + "password": { + "default": "", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + }, + "user": { + "default": "", + "type": "string" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "client-control": { + "priority": 22000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "max_body_size": { + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "consumer-restriction": { + "priority": 2400, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "anyOf": [ + { + "required": [ + "blacklist" + ] + }, + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "allowed_by_methods" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allowed_by_methods": { + "items": { + "properties": { + "methods": { + "items": { + "description": "HTTP method", + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PURGE", + "PUT", + "TRACE" + ], + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "user": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "blacklist": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "rejected_code": { + "default": 403, + "minimum": 200, + "type": "integer" + }, + "rejected_msg": { + "type": "string" + }, + "type": { + "default": "consumer_name", + "enum": [ + "consumer_name", + "route_id", + "service_id" + ], + "type": "string" + }, + "whitelist": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "cors": { + "metadata_schema": { + "properties": { + "allow_origins": { + "additionalProperties": { + "pattern": "^(\\*|\\*\\*|null|\\w+://[^,]+(,\\w+://[^,]+)*)$", + "type": "string" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 4000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_credential": { + "default": false, + "description": "allow client append credential. according to CORS specification,if you set this option to 'true', you can not use '*' for other options.", + "type": "boolean" + }, + "allow_headers": { + "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: *.", + "type": "string" + }, + "allow_methods": { + "default": "*", + "description": "you can use '*' to allow all methods when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple method use ',' to split. default: *.", + "type": "string" + }, + "allow_origins": { + "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: *.", + "pattern": "^(\\*|\\*\\*|null|\\w+://[^,]+(,\\w+://[^,]+)*)$", + "type": "string" + }, + "allow_origins_by_metadata": { + "description": "set allowed origins by referencing origins in plugin metadata", + "items": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "allow_origins_by_regex": { + "description": "you can use regex to allow specific origins when no credentials,for example use [.*\\.test.com] to allow a.test.com and b.test.com", + "items": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "expose_headers": { + "default": "*", + "description": "you can use '*' to expose all header when no credentials,'**' to allow forcefully(it will bring some security risks, be carefully),multiple header use ',' to split. default: *.", + "type": "string" + }, + "max_age": { + "default": 5, + "description": "maximum number of seconds the results can be cached.-1 means no cached, the max value is depend on browser,more details plz check MDN. default: 5.", + "type": "integer" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "csrf": { + "priority": 2980, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "expires": { + "default": 7200, + "description": "expires time(s) for csrf token", + "type": "integer" + }, + "key": { + "description": "use to generate csrf token", + "type": "string" + }, + "name": { + "default": "apisix-csrf-token", + "description": "the csrf token name", + "type": "string" + } + }, + "required": [ + "key" + ], + "type": "object" + }, + "version": 0.1 + }, + "datadog": { + "metadata_schema": { + "properties": { + "constant_tags": { + "default": [ + "source:apisix" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "host": { + "default": "127.0.0.1", + "type": "string" + }, + "namespace": { + "default": "apisix", + "type": "string" + }, + "port": { + "default": 8125, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "priority": 495, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "datadog", + "type": "string" + }, + "prefer_name": { + "default": true, + "type": "boolean" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "dubbo-proxy": { + "priority": 507, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "method": { + "minLength": 1, + "type": "string" + }, + "service_name": { + "minLength": 1, + "type": "string" + }, + "service_version": { + "pattern": "^\\d+\\.\\d+\\.\\d+", + "type": "string" + } + }, + "required": [ + "service_name", + "service_version" + ], + "type": "object" + }, + "version": 0.1 + }, + "echo": { + "priority": 412, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "anyOf": [ + { + "required": [ + "before_body" + ] + }, + { + "required": [ + "body" + ] + }, + { + "required": [ + "after_body" + ] + } + ], + "minProperties": 1, + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "after_body": { + "description": "body after the modification of filter phase.", + "type": "string" + }, + "before_body": { + "description": "body before the filter phase.", + "type": "string" + }, + "body": { + "description": "body to replace upstream response.", + "type": "string" + }, + "headers": { + "description": "new headers for response", + "minProperties": 1, + "type": "object" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "elasticsearch-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 413, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "auth": { + "properties": { + "password": { + "minLength": 1, + "type": "string" + }, + "username": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "endpoint_addr": { + "pattern": "[^/]$", + "type": "string" + }, + "field": { + "properties": { + "index": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "index" + ], + "type": "object" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "elasticsearch-logger", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 10, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "endpoint_addr", + "field" + ], + "type": "object" + }, + "version": 0.1 + }, + "error-log-logger": { + "metadata_schema": { + "oneOf": [ + { + "required": [ + "skywalking" + ] + }, + { + "required": [ + "tcp" + ] + }, + { + "required": [ + "clickhouse" + ] + }, + { + "required": [ + "host", + "port" + ] + } + ], + "properties": { + "batch_max_size": { + "default": 1000, + "minimum": 0, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "clickhouse": { + "properties": { + "database": { + "default": "", + "type": "string" + }, + "endpoint_addr": { + "1": { + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + }, + "default": "http://127.0.0.1:8123" + }, + "logtable": { + "default": "", + "type": "string" + }, + "password": { + "default": "", + "type": "string" + }, + "user": { + "default": "default", + "type": "string" + } + }, + "required": [ + "database", + "endpoint_addr", + "logtable", + "password", + "user" + ], + "type": "object" + }, + "inactive_timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + }, + "keepalive": { + "default": 30, + "minimum": 1, + "type": "integer" + }, + "level": { + "default": "WARN", + "enum": [ + "ALERT", + "CRIT", + "DEBUG", + "EMERG", + "ERR", + "ERROR", + "INFO", + "NOTICE", + "STDERR", + "WARN" + ], + "type": "string" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "error-log-logger", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "skywalking": { + "properties": { + "endpoint_addr": { + "default": "http://127.0.0.1:12900/v3/logs" + }, + "service_instance_name": { + "default": "APISIX Service Instance", + "type": "string" + }, + "service_name": { + "default": "APISIX", + "type": "string" + } + }, + "type": "object" + }, + "tcp": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "port": { + "minimum": 0, + "type": "integer" + }, + "tls": { + "default": false, + "type": "boolean" + }, + "tls_server_name": { + "type": "string" + } + }, + "required": [ + "host", + "port" + ], + "type": "object" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "priority": 1091, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "scope": "global", + "version": 0.1 + }, + "example-plugin": { + "metadata_schema": { + "properties": { + "ikey": { + "minimum": 0, + "type": "number" + }, + "skey": { + "type": "string" + } + }, + "required": [ + "ikey", + "skey" + ], + "type": "object" + }, + "priority": 0, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "i": { + "minimum": 0, + "type": "number" + }, + "ip": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "s": { + "type": "string" + }, + "t": { + "minItems": 1, + "type": "array" + } + }, + "required": [ + "i" + ], + "type": "object" + }, + "version": 0.1 + }, + "ext-plugin-post-req": { + "priority": -3000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_degradation": { + "default": false, + "type": "boolean" + }, + "conf": { + "items": { + "properties": { + "name": { + "maxLength": 128, + "minLength": 1, + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "ext-plugin-post-resp": { + "priority": -4000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_degradation": { + "default": false, + "type": "boolean" + }, + "conf": { + "items": { + "properties": { + "name": { + "maxLength": 128, + "minLength": 1, + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "ext-plugin-pre-req": { + "priority": 12000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_degradation": { + "default": false, + "type": "boolean" + }, + "conf": { + "items": { + "properties": { + "name": { + "maxLength": 128, + "minLength": 1, + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "fault-injection": { + "priority": 11000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "minProperties": 1, + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "abort": { + "properties": { + "body": { + "minLength": 0, + "type": "string" + }, + "http_status": { + "minimum": 200, + "type": "integer" + }, + "percentage": { + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "vars": { + "items": { + "type": "array" + }, + "maxItems": 20, + "type": "array" + } + }, + "required": [ + "http_status" + ], + "type": "object" + }, + "delay": { + "properties": { + "duration": { + "minimum": 0, + "type": "number" + }, + "percentage": { + "maximum": 100, + "minimum": 0, + "type": "integer" + }, + "vars": { + "items": { + "type": "array" + }, + "maxItems": 20, + "type": "array" + } + }, + "required": [ + "duration" + ], + "type": "object" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "file-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 399, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "path": { + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "version": 0.1 + }, + "forward-auth": { + "priority": 2002, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "client_headers": { + "default": {}, + "description": "authorization response header that will be sent tothe client when authorizing failed", + "items": { + "type": "string" + }, + "type": "array" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "request_headers": { + "default": {}, + "description": "client request header that will be sent to the authorization service", + "items": { + "type": "string" + }, + "type": "array" + }, + "request_method": { + "default": "GET", + "description": "the method for client to request the authorization service", + "enum": [ + "GET", + "POST" + ], + "type": "string" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "description": "timeout in milliseconds", + "maximum": 60000, + "minimum": 1, + "type": "integer" + }, + "upstream_headers": { + "default": {}, + "description": "authorization response header that will be sent to the upstream", + "items": { + "type": "string" + }, + "type": "array" + }, + "uri": { + "type": "string" + } + }, + "required": [ + "uri" + ], + "type": "object" + }, + "version": 0.1 + }, + "google-cloud-logging": { + "priority": 407, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "auth_config" + ] + }, + { + "required": [ + "auth_file" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "auth_config": { + "properties": { + "entries_uri": { + "default": "https://logging.googleapis.com/v2/entries:write", + "type": "string" + }, + "private_key": { + "type": "string" + }, + "project_id": { + "type": "string" + }, + "scopes": { + "default": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/logging.admin", + "https://www.googleapis.com/auth/logging.read", + "https://www.googleapis.com/auth/logging.write" + ], + "items": { + "description": "Google OAuth2 Authorization Scopes", + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "token_uri": { + "default": "https://oauth2.googleapis.com/token", + "type": "string" + } + }, + "required": [ + "private_key", + "project_id", + "token_uri" + ], + "type": "object" + }, + "auth_file": { + "type": "string" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "log_id": { + "default": "apisix.apache.org%2Flogs", + "type": "string" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "google-cloud-logging", + "type": "string" + }, + "resource": { + "default": { + "type": "global" + }, + "properties": { + "labels": { + "type": "object" + }, + "type": { + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "grpc-transcode": { + "priority": 506, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "additionalProperties": true, + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "deadline": { + "default": 0, + "description": "deadline for grpc, millisecond", + "type": "number" + }, + "method": { + "description": "the method name in the grpc service.", + "type": "string" + }, + "pb_option": { + "default": [ + "auto_default_values", + "disable_hooks", + "enum_as_name", + "int64_as_number" + ], + "items": { + "anyOf": [ + { + "description": "enum as result", + "enum": [ + "int64_as_hexstring", + "int64_as_number", + "int64_as_string" + ], + "type": "string" + }, + { + "description": "int64 as result", + "enum": [ + "enum_as_name", + "enum_as_value" + ], + "type": "string" + }, + { + "description": "default values option", + "enum": [ + "auto_default_values", + "no_default_values", + "use_default_metatable", + "use_default_values" + ], + "type": "string" + }, + { + "description": "hooks option", + "enum": [ + "disable_hooks", + "enable_hooks" + ], + "type": "string" + } + ], + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "proto_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "service": { + "description": "the grpc service name", + "type": "string" + } + }, + "required": [ + "method", + "proto_id", + "service" + ], + "type": "object" + }, + "version": 0.1 + }, + "grpc-web": { + "priority": 505, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "gzip": { + "priority": 995, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "buffers": { + "default": { + "number": 32, + "size": 4096 + }, + "properties": { + "number": { + "default": 32, + "minimum": 1, + "type": "integer" + }, + "size": { + "default": 4096, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "comp_level": { + "default": 1, + "maximum": 9, + "minimum": 1, + "type": "integer" + }, + "http_version": { + "default": 1.1, + "enum": [ + 1, + 1.1 + ] + }, + "min_length": { + "default": 20, + "minimum": 1, + "type": "integer" + }, + "types": { + "anyOf": [ + { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + { + "enum": [ + "*" + ] + } + ], + "default": [ + "text/html" + ] + }, + "vary": { + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "hmac-auth": { + "consumer_schema": { + "properties": { + "access_key": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "algorithm": { + "default": "hmac-sha256", + "enum": [ + "hmac-sha1", + "hmac-sha256", + "hmac-sha512" + ], + "type": "string" + }, + "clock_skew": { + "default": 0, + "type": "integer" + }, + "encode_uri_params": { + "default": true, + "title": "Whether to escape the uri parameter", + "type": "boolean" + }, + "keep_headers": { + "default": false, + "title": "whether to keep the http request header", + "type": "boolean" + }, + "max_req_body": { + "default": 524288, + "title": "Max request body size", + "type": "integer" + }, + "secret_key": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "signed_headers": { + "items": { + "maxLength": 50, + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "validate_request_body": { + "default": false, + "title": "A boolean value telling the plugin to enable body validation", + "type": "boolean" + } + }, + "required": [ + "access_key", + "secret_key" + ], + "title": "work with consumer object", + "type": "object" + }, + "priority": 2530, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "title": "work with route or service object", + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, + "http-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 410, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "auth_header": { + "type": "string" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "concat_method": { + "default": "json", + "enum": [ + "json", + "new_line" + ], + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body_expr": { + "items": { + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "http logger", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "ssl_verify": { + "default": false, + "type": "boolean" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + }, + "uri": { + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + } + }, + "required": [ + "uri" + ], + "type": "object" + }, + "version": 0.1 + }, + "ip-restriction": { + "priority": 3000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "blacklist" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "blacklist": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "message": { + "default": "Your IP address is not allowed", + "maxLength": 1024, + "minLength": 1, + "type": "string" + }, + "whitelist": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "jwt-auth": { + "consumer_schema": { + "dependencies": { + "algorithm": { + "oneOf": [ + { + "properties": { + "algorithm": { + "default": "HS256", + "enum": [ + "HS256", + "HS512" + ] + } + } + }, + { + "properties": { + "algorithm": { + "enum": [ + "ES256", + "RS256" + ] + }, + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } + }, + "required": [ + "private_key", + "public_key" + ] + }, + { + "properties": { + "algorithm": { + "enum": [ + "ES256", + "RS256" + ] + }, + "vault": { + "properties": {}, + "type": "object" + } + }, + "required": [ + "vault" + ] + } + ] + } + }, + "properties": { + "algorithm": { + "default": "HS256", + "enum": [ + "ES256", + "HS256", + "HS512", + "RS256" + ], + "type": "string" + }, + "base64_secret": { + "default": false, + "type": "boolean" + }, + "exp": { + "default": 86400, + "minimum": 1, + "type": "integer" + }, + "key": { + "type": "string" + }, + "lifetime_grace_period": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "secret": { + "type": "string" + }, + "vault": { + "properties": {}, + "type": "object" + } + }, + "required": [ + "key" + ], + "type": "object" + }, + "priority": 2510, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "cookie": { + "default": "jwt", + "type": "string" + }, + "header": { + "default": "authorization", + "type": "string" + }, + "query": { + "default": "jwt", + "type": "string" + } + }, + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, + "kafka-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 403, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "broker_list", + "kafka_topic" + ] + }, + { + "required": [ + "brokers", + "kafka_topic" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "broker_list": { + "minProperties": 1, + "patternProperties": { + ".*": { + "description": "the port of kafka broker", + "maximum": 65535, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "brokers": { + "items": { + "properties": { + "host": { + "description": "the host of kafka broker", + "type": "string" + }, + "port": { + "description": "the port of kafka broker", + "maximum": 65535, + "minimum": 1, + "type": "integer" + }, + "sasl_config": { + "description": "sasl config", + "properties": { + "mechanism": { + "default": "PLAIN", + "enum": [ + "PLAIN" + ], + "type": "string" + }, + "password": { + "description": "password", + "type": "string" + }, + "user": { + "description": "user", + "type": "string" + } + }, + "required": [ + "password", + "user" + ], + "type": "object" + } + }, + "required": [ + "host", + "port" + ], + "type": "object" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "cluster_name": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "include_req_body_expr": { + "items": { + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "include_resp_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body_expr": { + "items": { + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "kafka_topic": { + "type": "string" + }, + "key": { + "type": "string" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "meta_format": { + "default": "default", + "enum": [ + "default", + "origin" + ], + "type": "string" + }, + "name": { + "default": "kafka logger", + "type": "string" + }, + "producer_batch_num": { + "default": 200, + "minimum": 1, + "type": "integer" + }, + "producer_batch_size": { + "default": 1048576, + "minimum": 0, + "type": "integer" + }, + "producer_max_buffering": { + "default": 50000, + "minimum": 1, + "type": "integer" + }, + "producer_time_linger": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "producer_type": { + "default": "async", + "enum": [ + "async", + "sync" + ], + "type": "string" + }, + "required_acks": { + "default": 1, + "enum": [ + -1, + 0, + 1 + ], + "type": "integer" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "kafka-proxy": { + "priority": 508, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "sasl": { + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "password", + "username" + ], + "type": "object" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "key-auth": { + "consumer_schema": { + "properties": { + "key": { + "type": "string" + } + }, + "required": [ + "key" + ], + "type": "object" + }, + "priority": 2500, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "header": { + "default": "apikey", + "type": "string" + }, + "hide_credentials": { + "default": false, + "type": "boolean" + }, + "query": { + "default": "apikey", + "type": "string" + } + }, + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, + "ldap-auth": { + "consumer_schema": { + "properties": { + "user_dn": { + "type": "string" + } + }, + "required": [ + "user_dn" + ], + "title": "work with consumer object", + "type": "object" + }, + "priority": 2540, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "base_dn": { + "type": "string" + }, + "ldap_uri": { + "type": "string" + }, + "tls_verify": { + "default": false, + "type": "boolean" + }, + "uid": { + "default": "cn", + "type": "string" + }, + "use_tls": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "base_dn", + "ldap_uri" + ], + "title": "work with route or service object", + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, + "limit-conn": { + "priority": 1003, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_degradation": { + "default": false, + "type": "boolean" + }, + "burst": { + "minimum": 0, + "type": "integer" + }, + "conn": { + "exclusiveMinimum": 0, + "type": "integer" + }, + "default_conn_delay": { + "exclusiveMinimum": 0, + "type": "number" + }, + "key": { + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "var", + "var_combination" + ], + "type": "string" + }, + "only_use_default_delay": { + "default": false, + "type": "boolean" + }, + "rejected_code": { + "default": 503, + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "rejected_msg": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "burst", + "conn", + "default_conn_delay", + "key" + ], + "type": "object" + }, + "version": 0.1 + }, + "limit-count": { + "priority": 1002, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "else": { + "if": { + "properties": { + "policy": { + "enum": [ + "redis-cluster" + ] + } + } + }, + "then": { + "properties": { + "redis_cluster_name": { + "type": "string" + }, + "redis_cluster_nodes": { + "items": { + "maxLength": 100, + "minLength": 2, + "type": "string" + }, + "minItems": 2, + "type": "array" + }, + "redis_password": { + "minLength": 0, + "type": "string" + }, + "redis_timeout": { + "default": 1000, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "redis_cluster_name", + "redis_cluster_nodes" + ] + } + }, + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_degradation": { + "default": false, + "type": "boolean" + }, + "count": { + "exclusiveMinimum": 0, + "type": "integer" + }, + "group": { + "type": "string" + }, + "key": { + "default": "remote_addr", + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "constant", + "var", + "var_combination" + ], + "type": "string" + }, + "policy": { + "default": "local", + "enum": [ + "local", + "redis", + "redis-cluster" + ], + "type": "string" + }, + "rejected_code": { + "default": 503, + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "rejected_msg": { + "minLength": 1, + "type": "string" + }, + "show_limit_quota_header": { + "default": true, + "type": "boolean" + }, + "time_window": { + "exclusiveMinimum": 0, + "type": "integer" + } + }, + "required": [ + "count", + "time_window" + ], + "if": { + "properties": { + "policy": { + "enum": [ + "redis" + ] + } + } + }, + "then": { + "properties": { + "redis_database": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "redis_host": { + "minLength": 2, + "type": "string" + }, + "redis_password": { + "minLength": 0, + "type": "string" + }, + "redis_port": { + "default": 6379, + "minimum": 1, + "type": "integer" + }, + "redis_timeout": { + "default": 1000, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "redis_host" + ] + }, + "type": "object" + }, + "version": 0.4 + }, + "limit-req": { + "priority": 1001, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allow_degradation": { + "default": false, + "type": "boolean" + }, + "burst": { + "minimum": 0, + "type": "number" + }, + "key": { + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "var", + "var_combination" + ], + "type": "string" + }, + "nodelay": { + "default": false, + "type": "boolean" + }, + "rate": { + "exclusiveMinimum": 0, + "type": "number" + }, + "rejected_code": { + "default": 503, + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "rejected_msg": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "burst", + "key", + "rate" + ], + "type": "object" + }, + "version": 0.1 + }, + "log-rotate": { + "priority": 100, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "scope": "global", + "version": 0.1 + }, + "loggly": { + "metadata_schema": { + "properties": { + "host": { + "default": "logs-01.loggly.com", + "type": "string" + }, + "log_format": { + "type": "object" + }, + "port": { + "default": 514, + "type": "integer" + }, + "protocol": { + "default": "syslog", + "enum": [ + "http", + "https", + "syslog" + ], + "type": "string" + }, + "timeout": { + "default": 5000, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "priority": 411, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "customer_token": { + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body_expr": { + "items": { + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "loggly", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "severity": { + "default": "INFO", + "description": "base severity log level", + "enum": [ + "ALERT", + "CRIT", + "DEBUG", + "EMEGR", + "ERR", + "INFO", + "NOTICE", + "WARNING", + "alert", + "crit", + "debug", + "emegr", + "err", + "info", + "notice", + "warning" + ], + "type": "string" + }, + "severity_map": { + "additionalProperties": false, + "description": "upstream response code vs syslog severity mapping", + "patternProperties": { + "^[1-5][0-9]{2}$": { + "description": "keys are HTTP status code, values are severity", + "enum": [ + "ALERT", + "CRIT", + "DEBUG", + "EMEGR", + "ERR", + "INFO", + "NOTICE", + "WARNING", + "alert", + "crit", + "debug", + "emegr", + "err", + "info", + "notice", + "warning" + ], + "type": "string" + } + }, + "type": "object" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "tags": { + "default": [ + "apisix" + ], + "items": { + "pattern": "^(?!tag=)[ -~]*", + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "customer_token" + ], + "type": "object" + }, + "version": 0.1 + }, + "mocking": { + "priority": 10900, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "anyOf": [ + { + "required": [ + "response_example" + ] + }, + { + "required": [ + "response_schema" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "content_type": { + "default": "application/json;charset=utf8", + "type": "string" + }, + "delay": { + "default": 0, + "type": "integer" + }, + "response_example": { + "type": "string" + }, + "response_schema": { + "type": "object" + }, + "response_status": { + "default": 200, + "minimum": 100, + "type": "integer" + }, + "with_mock_header": { + "default": true, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "node-status": { + "priority": 1000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "scope": "global", + "version": 0.1 + }, + "opa": { + "priority": 2001, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "type": "string" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "policy": { + "type": "string" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "description": "timeout in milliseconds", + "maximum": 60000, + "minimum": 1, + "type": "integer" + }, + "with_consumer": { + "default": false, + "type": "boolean" + }, + "with_route": { + "default": false, + "type": "boolean" + }, + "with_service": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "host", + "policy" + ], + "type": "object" + }, + "version": 0.1 + }, + "openfunction": { + "priority": -1902, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "authorization": { + "service_token": { + "type": "string" + } + }, + "function_uri": { + "type": "string" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "minimum": 100, + "type": "integer" + } + }, + "required": [ + "function_uri" + ], + "type": "object" + }, + "version": 0.1 + }, + "openid-connect": { + "priority": 2599, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "access_token_in_authorization_header": { + "default": false, + "description": "Whether the access token should be added in the Authorization header as opposed to the X-Access-Token header.", + "type": "boolean" + }, + "bearer_only": { + "default": false, + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "discovery": { + "type": "string" + }, + "introspection_endpoint": { + "type": "string" + }, + "introspection_endpoint_auth_method": { + "default": "client_secret_basic", + "type": "string" + }, + "logout_path": { + "default": "/logout", + "type": "string" + }, + "post_logout_redirect_uri": { + "description": "the URI will be redirect when request logout_path", + "type": "string" + }, + "public_key": { + "type": "string" + }, + "realm": { + "default": "apisix", + "type": "string" + }, + "redirect_uri": { + "description": "use ngx.var.request_uri if not configured", + "type": "string" + }, + "scope": { + "default": "openid", + "type": "string" + }, + "session": { + "additionalProperties": false, + "properties": { + "secret": { + "description": "the key used for the encrypt and HMAC calculation", + "minLength": 16, + "type": "string" + } + }, + "required": [ + "secret" + ], + "type": "object" + }, + "set_access_token_header": { + "default": true, + "description": "Whether the access token should be added as a header to the request for downstream", + "type": "boolean" + }, + "set_id_token_header": { + "default": true, + "description": "Whether the ID token should be added in the X-ID-Token header to the request for downstream.", + "type": "boolean" + }, + "set_refresh_token_header": { + "default": false, + "description": "Whether the refresh token should be added in the X-Refresh-Token header to the request for downstream.", + "type": "boolean" + }, + "set_userinfo_header": { + "default": true, + "description": "Whether the user info token should be added in the X-Userinfo header to the request for downstream.", + "type": "boolean" + }, + "ssl_verify": { + "default": false, + "type": "boolean" + }, + "timeout": { + "default": 3, + "description": "timeout in seconds", + "minimum": 1, + "type": "integer" + }, + "token_signing_alg_values_expected": { + "type": "string" + }, + "use_pkce": { + "default": false, + "description": "when set to true the PKEC(Proof Key for Code Exchange) will be used.", + "type": "boolean" + } + }, + "required": [ + "client_id", + "client_secret", + "discovery" + ], + "type": "object" + }, + "version": 0.2 + }, + "opentelemetry": { + "priority": 12009, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "additional_attributes": { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "additional_header_prefix_attributes": { + "items": { + "minLength": 1, + "type": "string" + }, + "type": "array" + }, + "sampler": { + "default": { + "name": "always_off", + "options": { + "fraction": 0, + "root": { + "name": "always_off" + } + } + }, + "properties": { + "name": { + "default": "always_off", + "enum": [ + "always_off", + "always_on", + "parent_base", + "trace_id_ratio" + ], + "title": "sampling strategy", + "type": "string" + }, + "options": { + "default": { + "fraction": 0, + "root": { + "name": "always_off" + } + }, + "properties": { + "fraction": { + "default": 0, + "title": "trace_id_ratio fraction", + "type": "number" + }, + "root": { + "default": { + "name": "always_off", + "options": { + "fraction": 0 + } + }, + "properties": { + "name": { + "default": "always_off", + "enum": [ + "always_off", + "always_on", + "trace_id_ratio" + ], + "title": "sampling strategy", + "type": "string" + }, + "options": { + "default": { + "fraction": 0 + }, + "properties": { + "fraction": { + "default": 0, + "title": "trace_id_ratio fraction parameter", + "type": "number" + } + }, + "type": "object" + } + }, + "title": "parent_base root sampler", + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "openwhisk": { + "priority": -1901, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "action": { + "maxLength": 256, + "pattern": "\\A([\\w]|[\\w][\\w@ .-]*[\\w@.-]+)\\z", + "type": "string" + }, + "api_host": { + "type": "string" + }, + "keepalive": { + "default": true, + "type": "boolean" + }, + "keepalive_pool": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "keepalive_timeout": { + "default": 60000, + "minimum": 1000, + "type": "integer" + }, + "namespace": { + "maxLength": 256, + "pattern": "\\A([\\w]|[\\w][\\w@ .-]*[\\w@.-]+)\\z", + "type": "string" + }, + "package": { + "maxLength": 256, + "pattern": "\\A([\\w]|[\\w][\\w@ .-]*[\\w@.-]+)\\z", + "type": "string" + }, + "result": { + "default": true, + "type": "boolean" + }, + "service_token": { + "type": "string" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + }, + "timeout": { + "default": 3000, + "description": "timeout in milliseconds", + "maximum": 60000, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "action", + "api_host", + "namespace", + "service_token" + ], + "type": "object" + }, + "version": 0.1 + }, + "prometheus": { + "priority": 500, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "prefer_name": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.2 + }, + "proxy-cache": { + "priority": 1009, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "cache_bypass": { + "items": { + "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "cache_control": { + "default": false, + "type": "boolean" + }, + "cache_http_status": { + "default": [ + 200, + 301, + 404 + ], + "items": { + "description": "http response status", + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "cache_key": { + "default": [ + "$host", + "$request_uri" + ], + "items": { + "description": "a key for caching", + "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "cache_method": { + "default": [ + "GET", + "HEAD" + ], + "items": { + "description": "supported http method", + "enum": [ + "GET", + "HEAD", + "POST" + ], + "type": "string" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "cache_strategy": { + "default": "disk", + "enum": [ + "disk", + "memory" + ], + "type": "string" + }, + "cache_ttl": { + "default": 300, + "minimum": 1, + "type": "integer" + }, + "cache_zone": { + "default": "disk_cache_one", + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "hide_cache_headers": { + "default": false, + "type": "boolean" + }, + "no_cache": { + "items": { + "pattern": "(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)", + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.2 + }, + "proxy-control": { + "priority": 21990, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "request_buffering": { + "default": true, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "proxy-mirror": { + "priority": 1010, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "pattern": "^http(s)?:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?$", + "type": "string" + }, + "path": { + "pattern": "^/[^?&]+$", + "type": "string" + }, + "sample_ratio": { + "default": 1, + "maximum": 1, + "minimum": 0.00001, + "type": "number" + } + }, + "required": [ + "host" + ], + "type": "object" + }, + "version": 0.1 + }, + "proxy-rewrite": { + "priority": 1008, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "minProperties": 1, + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "headers": { + "description": "new headers for request", + "minProperties": 1, + "type": "object" + }, + "host": { + "description": "new host for upstream", + "pattern": "^[0-9a-zA-Z-.]+(:\\d{1,5})?$", + "type": "string" + }, + "method": { + "description": "proxy route method", + "enum": [ + "COPY", + "DELETE", + "GET", + "HEAD", + "LOCK", + "MKCOL", + "MOVE", + "OPTIONS", + "PATCH", + "POST", + "PROPFIND", + "PUT", + "TRACE", + "UNLOCK" + ], + "type": "string" + }, + "regex_uri": { + "description": "new uri that substitute from client uri for upstream, lower priority than uri property", + "items": { + "description": "regex uri", + "type": "string" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "uri": { + "description": "new uri for upstream", + "maxLength": 4096, + "minLength": 1, + "pattern": "^\\/.*", + "type": "string" + }, + "use_real_request_uri_unsafe": { + "default": false, + "description": "use real_request_uri instead, THIS IS VERY UNSAFE.", + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "public-api": { + "priority": 501, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "uri": { + "type": "string" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "real-ip": { + "priority": 23000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "recursive": { + "default": false, + "type": "boolean" + }, + "source": { + "minLength": 1, + "type": "string" + }, + "trusted_addresses": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "source" + ], + "type": "object" + }, + "version": 0.1 + }, + "redirect": { + "priority": 900, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "uri" + ] + }, + { + "required": [ + "regex_uri" + ] + }, + { + "required": [ + "http_to_https" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "append_query_string": { + "default": false, + "type": "boolean" + }, + "encode_uri": { + "default": false, + "type": "boolean" + }, + "http_to_https": { + "type": "boolean" + }, + "regex_uri": { + "description": "params for generating new uri that substitute from client uri, first param is regular expression, the second one is uri template", + "items": { + "description": "regex uri", + "type": "string" + }, + "maxItems": 2, + "minItems": 2, + "type": "array" + }, + "ret_code": { + "default": 302, + "minimum": 200, + "type": "integer" + }, + "uri": { + "minLength": 2, + "pattern": "(\\\\\\$[0-9a-zA-Z_]+)|\\$\\{([0-9a-zA-Z_]+)\\}|\\$([0-9a-zA-Z_]+)|(\\$|[^$\\\\]+)", + "type": "string" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "referer-restriction": { + "priority": 2990, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "blacklist" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "blacklist": { + "items": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "bypass_missing": { + "default": false, + "type": "boolean" + }, + "message": { + "default": "Your referer host is not allowed", + "maxLength": 1024, + "minLength": 1, + "type": "string" + }, + "whitelist": { + "items": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "request-id": { + "priority": 12015, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "algorithm": { + "default": "uuid", + "enum": [ + "nanoid", + "snowflake", + "uuid" + ], + "type": "string" + }, + "header_name": { + "default": "X-Request-Id", + "type": "string" + }, + "include_in_response": { + "default": true, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "request-validation": { + "priority": 2800, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "anyOf": [ + { + "required": [ + "header_schema" + ] + }, + { + "required": [ + "body_schema" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "body_schema": { + "type": "object" + }, + "header_schema": { + "type": "object" + }, + "rejected_code": { + "default": 400, + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "rejected_msg": { + "maxLength": 256, + "minLength": 1, + "type": "string" + } + }, + "type": "object" + }, + "type": "validation", + "version": 0.1 + }, + "response-rewrite": { + "priority": 899, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "dependencies": { + "body": { + "not": { + "required": [ + "filters" + ] + } + }, + "filters": { + "not": { + "required": [ + "body" + ] + } + } + }, + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "body": { + "description": "new body for response", + "type": "string" + }, + "body_base64": { + "default": false, + "description": "whether new body for response need base64 decode before return", + "type": "boolean" + }, + "filters": { + "description": "a group of filters that modify response bodyby replacing one specified string by another", + "items": { + "description": "filter that modifies response body", + "properties": { + "options": { + "default": "jo", + "description": "regex options", + "type": "string" + }, + "regex": { + "description": "match pattern on response body", + "minLength": 1, + "type": "string" + }, + "replace": { + "description": "regex substitution content", + "type": "string" + }, + "scope": { + "default": "once", + "description": "regex substitution range", + "enum": [ + "global", + "once" + ], + "type": "string" + } + }, + "required": [ + "regex", + "replace" + ], + "type": "object" + }, + "minItems": 1, + "type": "array" + }, + "headers": { + "anyOf": [ + { + "minProperties": 1, + "patternProperties": { + "^[^:]+$": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "type": "object" + }, + { + "properties": { + "add": { + "items": { + "pattern": "^[^:]+:[^:]+[^/]$", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "remove": { + "items": { + "pattern": "^[^:]+$", + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "set": { + "minProperties": 1, + "patternProperties": { + "^[^:]+$": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "type": "object" + } + } + } + ], + "description": "new headers for response" + }, + "status_code": { + "description": "new status code for response", + "maximum": 598, + "minimum": 200, + "type": "integer" + }, + "vars": { + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "rocketmq-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 402, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "access_key": { + "default": "", + "type": "string" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "include_req_body_expr": { + "items": { + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "include_resp_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body_expr": { + "items": { + "type": "array" + }, + "minItems": 1, + "type": "array" + }, + "key": { + "type": "string" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "meta_format": { + "default": "default", + "enum": [ + "default", + "origin" + ], + "type": "string" + }, + "name": { + "default": "rocketmq logger", + "type": "string" + }, + "nameserver_list": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "secret_key": { + "default": "", + "type": "string" + }, + "tag": { + "type": "string" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + }, + "topic": { + "type": "string" + }, + "use_tls": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "nameserver_list", + "topic" + ], + "type": "object" + }, + "version": 0.1 + }, + "server-info": { + "priority": 990, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "scope": "global", + "version": 0.1 + }, + "serverless-post-function": { + "priority": -2000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "functions": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "phase": { + "default": "access", + "enum": [ + "access", + "before_proxy", + "body_filter", + "header_filter", + "log", + "rewrite" + ], + "type": "string" + } + }, + "required": [ + "functions" + ], + "type": "object" + }, + "version": 0.1 + }, + "serverless-pre-function": { + "priority": 10000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "functions": { + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "phase": { + "default": "access", + "enum": [ + "access", + "before_proxy", + "body_filter", + "header_filter", + "log", + "rewrite" + ], + "type": "string" + } + }, + "required": [ + "functions" + ], + "type": "object" + }, + "version": 0.1 + }, + "skywalking": { + "priority": 12010, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "sample_ratio": { + "default": 1, + "maximum": 1, + "minimum": 0.00001, + "type": "number" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "skywalking-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 408, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "endpoint_addr": { + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "skywalking logger", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "service_instance_name": { + "default": "APISIX Instance Name", + "type": "string" + }, + "service_name": { + "default": "APISIX", + "type": "string" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "endpoint_addr" + ], + "type": "object" + }, + "version": 0.1 + }, + "sls-logger": { + "priority": 406, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "access_key_id": { + "type": "string" + }, + "access_key_secret": { + "type": "string" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "host": { + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "logstore": { + "type": "string" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "sls-logger", + "type": "string" + }, + "port": { + "type": "integer" + }, + "project": { + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "timeout": { + "default": 5000, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "access_key_id", + "access_key_secret", + "host", + "logstore", + "port", + "project" + ], + "type": "object" + }, + "version": 0.1 + }, + "splunk-hec-logging": { + "priority": 409, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "endpoint": { + "properties": { + "channel": { + "type": "string" + }, + "timeout": { + "default": 10, + "minimum": 1, + "type": "integer" + }, + "token": { + "type": "string" + }, + "uri": { + "pattern": "^[^\\/]+:\\/\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?", + "type": "string" + } + }, + "required": [ + "token", + "uri" + ], + "type": "object" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "splunk-hec-logging", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "ssl_verify": { + "default": true, + "type": "boolean" + } + }, + "required": [ + "endpoint" + ], + "type": "object" + }, + "version": 0.1 + }, + "syslog": { + "priority": 401, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "drop_limit": { + "default": 1048576, + "type": "integer" + }, + "flush_limit": { + "default": 4096, + "minimum": 1, + "type": "integer" + }, + "host": { + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "http sys logger", + "type": "string" + }, + "pool_size": { + "default": 5, + "minimum": 5, + "type": "integer" + }, + "port": { + "type": "integer" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "sock_type": { + "default": "tcp", + "enum": [ + "tcp", + "udp" + ], + "type": "string" + }, + "timeout": { + "default": 3000, + "minimum": 1, + "type": "integer" + }, + "tls": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "host", + "port" + ], + "type": "object" + }, + "version": 0.1 + }, + "tcp-logger": { + "priority": 405, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "host": { + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "tcp logger", + "type": "string" + }, + "port": { + "minimum": 0, + "type": "integer" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "timeout": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "tls": { + "default": false, + "type": "boolean" + }, + "tls_options": { + "type": "string" + } + }, + "required": [ + "host", + "port" + ], + "type": "object" + }, + "version": 0.1 + }, + "tencent-cloud-cls": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 397, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "cls_host": { + "type": "string" + }, + "cls_topic": { + "type": "string" + }, + "global_tag": { + "type": "object" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "include_resp_body": { + "default": false, + "type": "boolean" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "tencent-cloud-cls", + "type": "string" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "sample_ratio": { + "default": 1, + "maximum": 1, + "minimum": 0.00001, + "type": "number" + }, + "secret_id": { + "type": "string" + }, + "secret_key": { + "type": "string" + } + }, + "required": [ + "cls_host", + "cls_topic", + "secret_id", + "secret_key" + ], + "type": "object" + }, + "version": 0.1 + }, + "traffic-split": { + "priority": 966, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "rules": { + "items": { + "properties": { + "match": { + "items": { + "properties": { + "vars": { + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + }, + "weighted_upstreams": { + "default": [ + { + "weight": 1 + } + ], + "items": { + "properties": { + "upstream": { + "oneOf": [ + { + "required": [ + "nodes", + "type" + ] + }, + { + "required": [ + "discovery_type", + "service_name", + "type" + ] + } + ], + "properties": { + "checks": { + "anyOf": [ + { + "required": [ + "active" + ] + }, + { + "required": [ + "active", + "passive" + ] + } + ], + "properties": { + "active": { + "properties": { + "concurrency": { + "default": 10, + "type": "integer" + }, + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 302 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "successes": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "http_path": { + "default": "/", + "type": "string" + }, + "https_verify_certificate": { + "default": true, + "type": "boolean" + }, + "port": { + "maximum": 65535, + "minimum": 1, + "type": "integer" + }, + "req_headers": { + "items": { + "type": "string", + "uniqueItems": true + }, + "minItems": 1, + "type": "array" + }, + "timeout": { + "default": 1, + "type": "number" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "http_statuses": { + "default": [ + 404, + 429, + 500, + 501, + 502, + 503, + 504, + 505 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "interval": { + "default": 1, + "minimum": 1, + "type": "integer" + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 1, + "type": "integer" + }, + "timeouts": { + "default": 3, + "maximum": 254, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "passive": { + "properties": { + "healthy": { + "properties": { + "http_statuses": { + "default": [ + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 226, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "successes": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "type": { + "default": "http", + "enum": [ + "http", + "https", + "tcp" + ], + "type": "string" + }, + "unhealthy": { + "properties": { + "http_failures": { + "default": 5, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "http_statuses": { + "default": [ + 429, + 500, + 503 + ], + "items": { + "maximum": 599, + "minimum": 200, + "type": "integer" + }, + "minItems": 1, + "type": "array", + "uniqueItems": true + }, + "tcp_failures": { + "default": 2, + "maximum": 254, + "minimum": 0, + "type": "integer" + }, + "timeouts": { + "default": 7, + "maximum": 254, + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "create_time": { + "type": "integer" + }, + "desc": { + "maxLength": 256, + "type": "string" + }, + "discovery_args": { + "properties": { + "group_name": { + "description": "group name", + "type": "string" + }, + "namespace_id": { + "description": "namespace id", + "type": "string" + } + }, + "type": "object" + }, + "discovery_type": { + "description": "discovery type", + "type": "string" + }, + "hash_on": { + "default": "vars", + "enum": [ + "consumer", + "cookie", + "header", + "vars", + "vars_combinations" + ], + "type": "string" + }, + "id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "keepalive_pool": { + "properties": { + "idle_timeout": { + "default": 60, + "minimum": 0, + "type": "number" + }, + "requests": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "size": { + "default": 320, + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "key": { + "description": "the key of chash for dynamic load balancing", + "type": "string" + }, + "labels": { + "description": "key/value pairs to specify attributes", + "patternProperties": { + ".*": { + "description": "value of label", + "maxLength": 64, + "minLength": 1, + "pattern": "^\\S+$", + "type": "string" + } + }, + "type": "object" + }, + "name": { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + "nodes": { + "anyOf": [ + { + "patternProperties": { + ".*": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + { + "items": { + "properties": { + "host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + }, + "metadata": { + "description": "metadata of node", + "type": "object" + }, + "port": { + "description": "port of node", + "minimum": 1, + "type": "integer" + }, + "priority": { + "default": 0, + "description": "priority of node", + "type": "integer" + }, + "weight": { + "description": "weight of node", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "host", + "port", + "weight" + ], + "type": "object" + }, + "type": "array" + } + ] + }, + "pass_host": { + "default": "pass", + "description": "mod of host passing", + "enum": [ + "node", + "pass", + "rewrite" + ], + "type": "string" + }, + "retries": { + "minimum": 0, + "type": "integer" + }, + "retry_timeout": { + "minimum": 0, + "type": "number" + }, + "scheme": { + "default": "http", + "description": "The scheme of the upstream. For L7 proxy, it can be one of grpc/grpcs/http/https. For L4 proxy, it can be one of tcp/tls/udp. For specific protocols, it can be kafka.", + "enum": [ + "grpc", + "grpcs", + "http", + "https", + "kafka", + "tcp", + "tls", + "udp" + ] + }, + "service_name": { + "maxLength": 256, + "minLength": 1, + "type": "string" + }, + "timeout": { + "properties": { + "connect": { + "exclusiveMinimum": 0, + "type": "number" + }, + "read": { + "exclusiveMinimum": 0, + "type": "number" + }, + "send": { + "exclusiveMinimum": 0, + "type": "number" + } + }, + "required": [ + "connect", + "read", + "send" + ], + "type": "object" + }, + "tls": { + "dependencies": { + "client_cert": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_key" + ] + }, + "client_cert_id": { + "not": { + "required": [ + "client_client", + "client_key" + ] + } + }, + "client_key": { + "not": { + "required": [ + "client_cert_id" + ] + }, + "required": [ + "client_cert" + ] + } + }, + "properties": { + "client_cert": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "client_cert_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "client_key": { + "maxLength": 65536, + "minLength": 128, + "type": "string" + }, + "verify": { + "default": false, + "description": "Turn on server certificate verification, currently only kafka upstream is supported", + "type": "boolean" + } + }, + "type": "object" + }, + "type": { + "description": "algorithms of load balancing", + "type": "string" + }, + "update_time": { + "type": "integer" + }, + "upstream_host": { + "pattern": "^\\*?[0-9a-zA-Z-._\\[\\]:]+$", + "type": "string" + } + }, + "type": "object" + }, + "upstream_id": { + "anyOf": [ + { + "maxLength": 64, + "minLength": 1, + "pattern": "^[a-zA-Z0-9-_.]+$", + "type": "string" + }, + { + "minimum": 1, + "type": "integer" + } + ] + }, + "weight": { + "default": 1, + "description": "used to split traffic between differentupstreams for plugin configuration", + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "maxItems": 20, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "ua-restriction": { + "priority": 2999, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "allowlist": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "bypass_missing": { + "default": false, + "type": "boolean" + }, + "denylist": { + "items": { + "minLength": 1, + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "message": { + "default": "Not allowed", + "maxLength": 1024, + "minLength": 1, + "type": "string" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "udp-logger": { + "priority": 400, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "host": { + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "include_req_body": { + "default": false, + "type": "boolean" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "udp logger", + "type": "string" + }, + "port": { + "minimum": 0, + "type": "integer" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "timeout": { + "default": 3, + "minimum": 1, + "type": "integer" + } + }, + "required": [ + "host", + "port" + ], + "type": "object" + }, + "version": 0.1 + }, + "uri-blocker": { + "priority": 2900, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "block_rules": { + "items": { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + "type": "array", + "uniqueItems": true + }, + "case_insensitive": { + "default": false, + "type": "boolean" + }, + "rejected_code": { + "default": 403, + "minimum": 200, + "type": "integer" + }, + "rejected_msg": { + "minLength": 1, + "type": "string" + } + }, + "required": [ + "block_rules" + ], + "type": "object" + }, + "version": 0.1 + }, + "wolf-rbac": { + "priority": 2555, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "appid": { + "default": "unset", + "type": "string" + }, + "header_prefix": { + "default": "X-", + "type": "string" + }, + "server": { + "default": "http://127.0.0.1:12180", + "type": "string" + } + }, + "type": "object" + }, + "type": "auth", + "version": 0.1 + }, + "workflow": { + "priority": 1006, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "rules": { + "items": { + "properties": { + "actions": { + "items": { + "minItems": 1, + "type": "array" + }, + "type": "array" + }, + "case": { + "items": { + "anyOf": [ + { + "type": "array" + }, + { + "type": "string" + } + ] + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "actions", + "case" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "zipkin": { + "priority": 12011, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "endpoint": { + "type": "string" + }, + "sample_ratio": { + "maximum": 1, + "minimum": 0.00001, + "type": "number" + }, + "server_addr": { + "description": "default is $server_addr, you can specify your external ip address", + "pattern": "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$", + "type": "string" + }, + "service_name": { + "default": "APISIX", + "description": "service name for zipkin reporter", + "type": "string" + }, + "span_version": { + "default": 2, + "enum": [ + 1, + 2 + ] + } + }, + "required": [ + "endpoint", + "sample_ratio" + ], + "type": "object" + }, + "version": 0.1 + }, + "loki-logger": { + "metadata_schema": { + "properties": { + "log_format": { + "type": "object" + } + }, + "type": "object" + }, + "priority": 414, + "schema": { + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "type": "array" + }, + "priority": { + "type": "integer" + } + }, + "type": "object" + }, + "endpoint_addrs": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "endpoint_uri": { + "type": "string", + "minLength": 1, + "default": "/loki/api/v1/push" + }, + "tenant_id": { + "type": "string", + "default": "fake" + }, + "log_labels": { + "type": "object", + "patternProperties": { + ".*": { + "type": "string", + "minLength": 1 + } + }, + "default": { + "job": "apisix" + } + }, + "ssl_verify": { + "type": "boolean", + "default": false + }, + "timeout": { + "type": "integer", + "minimum": 1, + "maximum": 60000, + "default": 3000 + }, + "keepalive": { + "type": "boolean", + "default": true + }, + "keepalive_timeout": { + "type": "integer", + "minimum": 1000, + "default": 60000 + }, + "keepalive_pool": { + "type": "integer", + "minimum": 1, + "default": 5 + }, + "log_format": { + "type": "object" + }, + "include_req_body": { + "type": "boolean", + "default": false + }, + "include_req_body_expr": { + "type": "array", + "minItems": 1, + "items": { + "type": "array" + } + }, + "include_resp_body": { + "type": "boolean", + "default": false + }, + "include_resp_body_expr": { + "type": "array", + "minItems": 1, + "items": { + "type": "array" + } + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "endpoint_addrs" + ], + "type": "object" + }, + "version": 0.1 + } + }, + "stream_plugins": { + "ip-restriction": { + "priority": 3000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "oneOf": [ + { + "required": [ + "whitelist" + ] + }, + { + "required": [ + "blacklist" + ] + } + ], + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "blacklist": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] + }, + "minItems": 1, + "type": "array" + }, + "message": { + "default": "Your IP address is not allowed", + "maxLength": 1024, + "minLength": 1, + "type": "string" + }, + "whitelist": { + "items": { + "anyOf": [ + { + "format": "ipv4", + "title": "IPv4", + "type": "string" + }, + { + "pattern": "^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([12]?[0-9]|3[0-2])$", + "title": "IPv4/CIDR", + "type": "string" + }, + { + "format": "ipv6", + "title": "IPv6", + "type": "string" + }, + { + "pattern": "^([a-fA-F0-9]{0,4}:){1,8}(:[a-fA-F0-9]{0,4}){0,8}([a-fA-F0-9]{0,4})?/[0-9]{1,3}$", + "title": "IPv6/CIDR", + "type": "string" + } + ] + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "limit-conn": { + "priority": 1003, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "burst": { + "minimum": 0, + "type": "integer" + }, + "conn": { + "exclusiveMinimum": 0, + "type": "integer" + }, + "default_conn_delay": { + "exclusiveMinimum": 0, + "type": "number" + }, + "key": { + "type": "string" + }, + "key_type": { + "default": "var", + "enum": [ + "var", + "var_combination" + ], + "type": "string" + }, + "only_use_default_delay": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "burst", + "conn", + "default_conn_delay", + "key" + ], + "type": "object" + }, + "version": 0.1 + }, + "mqtt-proxy": { + "priority": 1000, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "protocol_level": { + "type": "integer" + }, + "protocol_name": { + "type": "string" + } + }, + "required": [ + "protocol_level", + "protocol_name" + ], + "type": "object" + }, + "version": 0.1 + }, + "prometheus": { + "priority": 500, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "prefer_name": { + "default": false, + "type": "boolean" + } + }, + "type": "object" + }, + "version": 0.1 + }, + "syslog": { + "metadata_schema": { + "properties": { + "log_format": { + "default": { + "@timestamp": "$time_iso8601", + "client_ip": "$remote_addr", + "host": "$host" + }, + "type": "object" + } + }, + "type": "object" + }, + "priority": 401, + "schema": { + "$comment": "this is a mark for our injected plugin schema", + "properties": { + "_meta": { + "properties": { + "disable": { + "type": "boolean" + }, + "error_response": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object" + } + ] + }, + "filter": { + "description": "filter determines whether the plugin needs to be executed at runtime", + "type": "array" + }, + "priority": { + "description": "priority of plugins by customized order", + "type": "integer" + } + }, + "type": "object" + }, + "batch_max_size": { + "default": 1000, + "minimum": 1, + "type": "integer" + }, + "buffer_duration": { + "default": 60, + "minimum": 1, + "type": "integer" + }, + "drop_limit": { + "default": 1048576, + "type": "integer" + }, + "flush_limit": { + "default": 4096, + "minimum": 1, + "type": "integer" + }, + "host": { + "type": "string" + }, + "inactive_timeout": { + "default": 5, + "minimum": 1, + "type": "integer" + }, + "max_retry_count": { + "default": 0, + "minimum": 0, + "type": "integer" + }, + "name": { + "default": "stream sys logger", + "type": "string" + }, + "pool_size": { + "default": 5, + "minimum": 5, + "type": "integer" + }, + "port": { + "type": "integer" + }, + "retry_delay": { + "default": 1, + "minimum": 0, + "type": "integer" + }, + "sock_type": { + "default": "tcp", + "enum": [ + "tcp", + "udp" + ], + "type": "string" + }, + "timeout": { + "default": 3000, + "minimum": 1, + "type": "integer" + }, + "tls": { + "default": false, + "type": "boolean" + } + }, + "required": [ + "host", + "port" + ], + "type": "object" + }, + "version": 0.1 + } + } +} \ No newline at end of file diff --git a/apisix-stack/docker-compose.yml b/apisix-stack/docker-compose.yml new file mode 100644 index 0000000..8d2db5e --- /dev/null +++ b/apisix-stack/docker-compose.yml @@ -0,0 +1,101 @@ +networks: + apisix_net: + driver: bridge + +services: + # 1. Cơ sở dữ liệu cấu hình cho APISIX + etcd: + image: bitnamilegacy/etcd:3.5.11 + container_name: apisix-etcd + restart: always + volumes: + - etcd_data:/bitnami/etcd + environment: + ETCD_ENABLE_V2: "true" + ALLOW_NONE_AUTHENTICATION: "yes" + ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379" + ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" + networks: + - apisix_net + + # 2. Apache APISIX Gateway + apisix: + image: apache/apisix:3.16.0-debian + container_name: apisix-gateway + user: "root" + restart: always + volumes: + - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml + depends_on: + - etcd + networks: + - apisix_net + ports: + - "9080:9080" # HTTP Traffic + - "9443:9443" # HTTPS Traffic + - "9180:9180" # Admin API + + # 3. APISIX Dashboard (Đổi sang cổng 9090) + apisix-dashboard: + image: apache/apisix-dashboard:3.0.1-alpine + container_name: apisix-dashboard + restart: always + volumes: + - ./apisix_conf/dashboard_conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml:ro + - ./apisix_conf/schema.json:/usr/local/apisix-dashboard/conf/schema.json:ro + depends_on: + - etcd + networks: + - apisix_net + ports: + - "9090:9090" + + # 4. Grafana Loki (Đổi sang cổng 9100) + loki: + image: grafana/loki:3.0.0 + container_name: apisix-loki + restart: always + volumes: + - loki_data:/tmp/loki + command: -config.file=/etc/loki/local-config.yaml + networks: + - apisix_net + + # 5. Promtail (Thu thập log gửi sang Loki) + promtail: + image: grafana/promtail:3.0.0 + container_name: apisix-promtail + restart: always + volumes: + - ./promtail_conf/promtail-config.yaml:/etc/promtail/config.yml:ro + - /var/run/docker.sock:/var/run/docker.sock:ro + command: -config.file=/etc/promtail/config.yml + depends_on: + - loki + networks: + - apisix_net + + # 6. Grafana (Đổi sang cổng 9300) + grafana: + image: grafana/grafana:11.0.0 + container_name: apisix-grafana + restart: always + environment: + - GF_SECURITY_ALLOW_EMBEDDING=true + ports: + - "9300:3000" + volumes: + - grafana_data:/var/lib/grafana + - ./grafana_conf/provisioning:/etc/grafana/provisioning:ro + depends_on: + - loki + networks: + - apisix_net + +volumes: + etcd_data: + driver: local + loki_data: + driver: local + grafana_data: + driver: local diff --git a/apisix-stack/grafana_conf/provisioning/dashboards/apisix_performance.json b/apisix-stack/grafana_conf/provisioning/dashboards/apisix_performance.json new file mode 100644 index 0000000..19cb256 --- /dev/null +++ b/apisix-stack/grafana_conf/provisioning/dashboards/apisix_performance.json @@ -0,0 +1,160 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": true, + "panels": [ + { + "id": 1, + "title": "Request Rate (RPS)", + "type": "timeseries", + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "targets": [ + { + "expr": "sum(rate({container=\"apisix-gateway\"}[$__interval]))", + "legendFormat": "Requests / Sec", + "datasource": { + "type": "loki", + "uid": "Loki" + } + } + ], + "fieldConfig": { + "defaults": { + "unit": "reqps" + } + } + }, + { + "id": 2, + "title": "Average Response Time (Latency)", + "type": "timeseries", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "targets": [ + { + "expr": "avg(avg_over_time({container=\"apisix-gateway\"} | json | unwrap request_time [$__interval]))", + "legendFormat": "Avg Latency", + "datasource": { + "type": "loki", + "uid": "Loki" + } + } + ], + "fieldConfig": { + "defaults": { + "unit": "s", + "custom": { + "drawStyle": "line", + "lineInterpolation": "smooth" + } + } + } + }, + { + "id": 3, + "title": "HTTP Status Distribution", + "type": "bargauge", + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 8 + }, + "targets": [ + { + "expr": "sum by(status) (count_over_time({container=\"apisix-gateway\"} | json [$__interval]))", + "legendFormat": "HTTP {{status}}", + "datasource": { + "type": "loki", + "uid": "Loki" + } + } + ], + "options": { + "orientation": "horizontal", + "displayMode": "basic" + } + }, + { + "id": 4, + "title": "Data Egress (Throughput)", + "type": "timeseries", + "gridPos": { + "h": 6, + "w": 16, + "x": 8, + "y": 8 + }, + "targets": [ + { + "expr": "sum(rate({container=\"apisix-gateway\"} | json | unwrap body_bytes_sent [$__interval]))", + "legendFormat": "Bytes / Sec", + "datasource": { + "type": "loki", + "uid": "Loki" + } + } + ], + "fieldConfig": { + "defaults": { + "unit": "Bps" + } + } + }, + { + "id": 5, + "title": "APISIX Gateway Logs", + "type": "logs", + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 14 + }, + "targets": [ + { + "expr": "{container=\"apisix-gateway\"}", + "datasource": { + "type": "loki", + "uid": "Loki" + } + } + ], + "options": { + "showLabels": false, + "wrapLogMessage": true, + "enableLogDetails": true + } + } + ], + "schemaVersion": 39, + "style": "dark", + "tags": ["apisix"], + "templating": { + "list": [] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "APISIX Gateway Performance", + "uid": "apisix-loki-perf", + "version": 1 +} diff --git a/apisix-stack/grafana_conf/provisioning/dashboards/dashboards.yaml b/apisix-stack/grafana_conf/provisioning/dashboards/dashboards.yaml new file mode 100644 index 0000000..bbf6166 --- /dev/null +++ b/apisix-stack/grafana_conf/provisioning/dashboards/dashboards.yaml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: + - name: 'APISIX Stack Dashboards' + orgId: 1 + folder: 'APISIX API Gateway' + type: file + disableDeletion: false + editable: true + options: + path: /etc/grafana/provisioning/dashboards diff --git a/apisix-stack/grafana_conf/provisioning/datasources/datasources.yaml b/apisix-stack/grafana_conf/provisioning/datasources/datasources.yaml new file mode 100644 index 0000000..8f87872 --- /dev/null +++ b/apisix-stack/grafana_conf/provisioning/datasources/datasources.yaml @@ -0,0 +1,10 @@ +apiVersion: 1 + +datasources: + - name: Loki + type: loki + access: proxy + url: http://loki:3100 + jsonData: + maxLines: 1000 + isDefault: true diff --git a/apisix-stack/promtail_conf/promtail-config.yaml b/apisix-stack/promtail_conf/promtail-config.yaml new file mode 100644 index 0000000..d649c95 --- /dev/null +++ b/apisix-stack/promtail_conf/promtail-config.yaml @@ -0,0 +1,19 @@ +server: + http_listen_port: 9080 + grpc_listen_port: 0 + +positions: + filename: /tmp/positions.yaml + +clients: + - url: http://loki:3100/loki/api/v1/push + +scrape_configs: + - job_name: docker-containers + docker_sd_configs: + - host: unix:///var/run/docker.sock + refresh_interval: 5s + relabel_configs: + - source_labels: ['__meta_docker_container_name'] + regex: '/(.*)' + target_label: 'container'