首页 > 其他分享 >APISIX干货:详解API管理利器,启动与部署一步到位(上)

APISIX干货:详解API管理利器,启动与部署一步到位(上)

时间:2024-11-20 17:48:42浏览次数:3  
标签:string default object minimum 干货 API integer type APISIX

文章目录


概述

管好微服务,成为云原生时代的新难题。

从建好微服务到管好微服务,差的虽是一个字,连接起两边的却需要大量的微服务落地经验。因为软件架构的核心挑战是解决业务快速增长带来的系统复杂性问题,而微服务将应用进行解耦的过程中,服务和服务之间的调用和依赖关系也变得愈加复杂,关系越复杂、小的技术问题越可能被放大,造成大的线上故障。而容器和 Kubernetes 为代表技术的云原生时代,则加重了其中的复杂程度。网关是整个服务API请求的入口,可以统一对所有请求进行处理。

作用:可以实现用户的验证登录、解决跨域、日志拦截、权限控制、限流、熔断、负载均衡、黑名单与白名单机制等。对于微服务网关本文进行了对应的评估,以供参考。

微服务网关基本概念

不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:

  1. 客户端会多次请求不同的微服务,增加了客户端的复杂性
  2. 存在跨域请求,在一定场景下处理相对复杂
  3. 认证复杂,每个服务都需要独立认证
  4. 难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施

某些微服务可能使用了防火墙、浏览器不友好的协议,直接访问会有一定困难
以上这些问题可以借助网关解决。

网关是介于客户端和服务器端之间的中间层,所有的外部请求都会先经过 网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控可以交由 网关来做,这样既提高业务灵活性又不缺安全性,典型的架构图如图所示:
在这里插入图片描述
优点如下:

  • 安全 :只有网关系统对外进行暴露,微服务可以隐藏在内网,通过防火墙保护。
  • 易于监控:可以在网关收集监控数据并将其推送到外部系统进行分析。
  • 易于认证:可以在网关上进行认证,然后再将请求转发到后端的微服务,而无须在每个微服务中进行认证。减少了客户端与各个微服务之间的交互次数
  • 易于统一授权。

总结:微服务网关就是一个系统,通过暴露该微服务网关系统,方便我们进行相关的鉴权,安全控制,日志统一处理,易于监控的相关功能。

微服务网关技术
实现微服务网关的技术有很多:
在这里插入图片描述
Nginx Nginx (tengine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务

Spring-cloud-gateway, 是spring 出品的 基于spring 的网关项目,集成断路器,路径重写,性能比Zuul好。

APIsix APIsix是一个云原生、高性能、可扩展的微服务 API 开源网关,基于OpenResty(Nginx+Lua)和etcd来实现,对比传统的API网关,具有动态路由和热插件加载的特点(访问任何域名、URL会匹配到http_access_phase这个lua函数,这个函数将会基于C语言实现的基数前缀树匹配域名、URI等,每次路由发生变化,lua会去重建这颗基数树)

Zuul Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器。

Kong Kong基于Nginx来实现Api Gateway基本的负载均衡、反向代理等功能。

应用场景对比


NginxSpring-cloud-gatewayAPIsixZuulKong
应用场景HTTP服务器
静态服务器
方向代理
负载均衡
动静分离
IO密集的任务
大请求或者大文件
队列的流式数据
超大量的连接
负载均衡
限速限流
身份验证
服务治理
动态路由
服务发现
反向代理
身份验证
动态路由
压力测试
静态响应处理
负载均衡
反向代理
监控
限流
认证

我们调研的APIsix这个微服务网关技术,无供应商锁定(云原生),APISIX可以从裸机运行到Kubernetes。同时支持OpenResty和Tengine,不用担心基础技术的锁定。(支持ARM64)

第一章 APISIX简介

1、什么是APISIX

官方地址:https://apisix.apache.org/
APISIX 是一个云原生、高性能、可扩展的微服务 API 开源网关,基于OpenResty(Nginx+Lua)和etcd来实现,对比传统的API网关,具有动态路由和热插件加载的特点。系统本身自带前端,可以手动配置路由、负载均衡、限速限流、熔断、金丝雀发布、身份验证、可监控等插件,操作方便。可以使用Apache APISIX来处理传统的南北流量,以及服务之间的东西流量。它也可以用作k8s入口控制器。
在这里插入图片描述

2、架构组成

第一部分叫做数据面,它是真正去处理来自客户端请求的一个组件,去处理用户的真实流量,包括像身份验证、证书卸载、日志分析和可观测性等功能。数据面本身并不会存储任何数据,所以它是一个无状态结构。
第二部分叫做控制面。APISIX 在控制面上并没有使用传统的类似于像 MySQL 去做配置存储,而是选择使用 etcd。
好处:

  • 与产品架构的云原生技术体系更统一
  • 更贴合 API 网关存放的数据类型
  • 能更好地体现高可用特性
    拥有低于毫秒级别的变化通知

使用 etcd 后,对于数据面而言只需监听 etcd 的变化即可。如果轮询数据库的话,可能需要 5-10 秒才能获取到最新的配置;但如果监听 etcd 的配置变更,就可以将时间控制在毫秒级别之内,达到实时生效的效果。

所以使用 etcd 而不是关系型数据库,不仅让 APISIX 在底层上更加贴合云原生,也让它在系统高可用的体现上带来了更多优势。

3、组件功能

你可以把 Apache APISIX 当做流量入口,来处理所有的业务数据,包括动态路由、动态上游、动态证书、 A/B 测试、金丝雀发布(灰度发布)、蓝绿部署、限流限速、抵御恶意攻击、监控报警、服务可观测性、服务治理等。

4、组件特点

全平台
云原生: 平台无关,没有供应商锁定,无论裸机还是 Kubernetes,APISIX 都可以运行。
运行环境: OpenResty 和 Tengine 都支持。
支持 ARM64: 不用担心底层技术的锁定。
多协议
TCP/UDP 代理: 动态 TCP/UDP 代理。
Dubbo 代理: 动态代理 HTTP 请求到 Dubbo 后端。
动态 MQTT 代理: 支持用 client_id 对 MQTT 进行负载均衡,同时支持 MQTT 3.1.* 和 5.0 两个协议标准。
gRPC 代理:通过 APISIX 代理 gRPC 连接,并使用 APISIX 的大部分特性管理你的 gRPC 服务。
gRPC 协议转换:支持协议的转换,这样客户端可以通过 HTTP/JSON 来访问你的 gRPC API。
Websocket 代理
Proxy Protocol
Dubbo 代理:基于 Tengine,可以实现 Dubbo 请求的代理。
HTTP(S) 反向代理
SSL:动态加载 SSL 证书。

全平台
云原生: 平台无关,没有供应商锁定,无论裸机还是 Kubernetes,APISIX 都可以运行。
运行环境: OpenResty 和 Tengine 都支持。
支持 ARM64: 不用担心底层技术的锁定。

多协议
TCP/UDP 代理: 动态 TCP/UDP 代理。
Dubbo 代理: 动态代理 HTTP 请求到 Dubbo 后端。
动态 MQTT 代理: 支持用 client_id 对 MQTT 进行负载均衡,同时支持 MQTT 3.1.* 和 5.0 两个协议标准。
gRPC 代理:通过 APISIX 代理 gRPC 连接,并使用 APISIX 的大部分特性管理你的 gRPC 服务。
gRPC 协议转换:支持协议的转换,这样客户端可以通过 HTTP/JSON 来访问你的 gRPC API。
Websocket 代理
Proxy Protocol
Dubbo 代理:基于 Tengine,可以实现 Dubbo 请求的代理。
HTTP(S) 反向代理
SSL:动态加载 SSL 证书。

全动态能力
热更新和热插件: 无需重启服务,就可以持续更新配置和插件。
代理请求重写: 支持重写请求上游的host、uri、schema、enable_websocket、headers信息。
输出内容重写: 支持自定义修改返回内容的 status code、body、headers。
Serverless: 在 APISIX 的每一个阶段,你都可以添加并调用自己编写的函数。
动态负载均衡:动态支持有权重的 round-robin 负载平衡。
支持一致性 hash 的负载均衡:动态支持一致性 hash 的负载均衡。
健康检查:启用上游节点的健康检查,将在负载均衡期间自动过滤不健康的节点,以确保系统稳定性。
熔断器: 智能跟踪不健康上游服务。
代理镜像: 提供镜像客户端请求的能力。
流量拆分: 允许用户逐步控制各个上游之间的流量百分比。

精细化路由
支持全路径匹配和前缀匹配
支持使用 Nginx 所有内置变量做为路由的条件,所以你可以使用 cookie, args 等做为路由的条件,来实现灰度发布、A/B 测试等功能
支持各类操作符做为路由的判断条件,比如 {“arg_age”, “>”, 24}
支持自定义路由匹配函数
IPv6:支持使用 IPv6 格式匹配路由
支持路由的自动过期(TTL)
支持路由的优先级
支持批量 Http 请求
支持通过GraphQL属性过滤路由

安全防护
多种身份认证方式: key-auth, JWT, basic-auth, wolf-rbac。
IP 黑白名单
Referer 白名单
IdP 支持: 支持外部的身份认证服务,比如 Auth0,Okta,Authing 等,用户可以借此来对接 Oauth2.0 等认证方式。
限制速率
限制请求数
限制并发
防御 ReDoS(正则表达式拒绝服务):内置策略,无需配置即可抵御 ReDoS。
CORS:为你的 API 启用 CORS。
URI 拦截器:根据 URI 拦截用户请求。
请求验证器。

运维友好
OpenTracing 可观测性: 支持 Apache Skywalking 和 Zipkin。
对接外部服务发现:除了内置的 etcd 外,还支持 Consul 和 Nacos,以及 Eureka。
监控和指标: Prometheus
集群:APISIX 节点是无状态的,创建配置中心集群请参考 etcd Clustering Guide。
高可用:支持配置同一个集群内的多个 etcd 地址。
控制台: 操作 APISIX 集群。
版本控制:支持操作的多次回滚。
CLI: 使用命令行来启动、关闭和重启 APISIX。
单机模式: 支持从本地配置文件中加载路由规则,在 kubernetes(k8s) 等环境下更友好。
全局规则:允许对所有请求执行插件,比如黑白名单、限流限速等。
高性能:在单核上 QPS 可以达到 18k,同时延迟只有 0.2 毫秒。
故障注入
REST Admin API: 使用 REST Admin API 来控制 Apache APISIX,默认只允许 127.0.0.1访问,你可以修改 conf/config.yaml 中的 allow_admin 字段,指定允许调用 Admin API 的 IP 列表。同时需要注意的是,Admin API 使用 key auth 来校验调用者身份,在部署前需要修改 conf/config.yaml 中的 admin_key 字段,来保证安全。
外部日志记录器:将访问日志导出到外部日志管理工具。(HTTP Logger,TCP Logger,Kafka Logger,UDP Logger)
Helm charts

高度可扩展
自定义插件: 允许挂载常见阶段,例如init, rewrite,access,balancer,header filter,body filter 和 log 阶段。
插件可以用 Java/Go 编写
自定义负载均衡算法:可以在 balancer 阶段使用自定义负载均衡算法。
自定义路由: 支持用户自己实现路由算法。
使用场景:
APISIX的功能有很多,包括动态路由、url重写、动态上游、IP黑白名单、A/B测试、灰度发布、限速限流、监控报警、健康检查等等,本文只介绍几个比较常用的功能,其他功能具体可以查看APISIX的官方文档说明。

  1. 服务热启动功能
    使用过Nginx的同学都会遇到过这种情况,在修改nginx.conf后需要重启nginx服务修改才会生效,重启时间虽然短暂,但难免会有一段服务不可用时间。当然,可以通过其他方式进行规避服务不可用。APISIX的服务热启动通过在路由、Service、Upstreams等插件中动态的修改配置即可,并不需要再重启APISIX服务来使修改生效。
  2. 热插件功能
    不再需要在nginx.conf文件中编写复杂的规则代码来实现需求,通过使用自带的路由、Upstreams等插件,在前端页面中添加所需要的规则即可实现。下文应用会详细介绍。目前通过插件可以实现uri重写、根据请求信息中的内容实现路由跳转等等。也可以根据自己的需求开发符合自己需求的插件。
  3. 动态负载均衡
    通过Upstreams插件,可以实现基于权重的roundrobin和chash负载均衡。
  4. 数据集群
    APISIX支持etcd集群,通过etcd集群增强了系统的可用性,大大减小了故障损失。
  5. 监控
    APISIX外接第三方prometheus监控系统,提供符合prometheus数据格式的监控指标数据。Prometheus 是由 SoundCloud 开源监控告警解决方案,已经比较成熟完善。

5、启动步骤

在这里插入图片描述
apisix 启动时调用:
apisix init , 运行LUA脚本,执行apisix init,生成nginx配置文件,初始化 nginx 配置,通过读取 conf/config.yaml 生成 nginx config 文件。供 openresty(nginx)使用。
apisix init_etcd,初始化 etcd 配置,用于与 etcd 同步数据。
apisix start;实际执行了 openresty -p /usr/local/apisix -g ‘daemon off;’ 启动 openresty 。

第二章 安装部署

2.1裸金属

部署ETCD
wget https://github.com/etcd-io/etcd/releases/download/v3.4.13/etcd-v3.4.13-linux-amd64.tar.gz
tar -xvf etcd-v3.4.13-linux-amd64.tar.gz && \
    cd etcd-v3.4.13-linux-amd64 && \
    sudo cp -a etcd etcdctl /usr/bin/ 
# add OpenResty source
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo 
# install OpenResty and some compilation tools
sudo yum install -y openresty curl git gcc openresty-openssl-devel unzip 
# install LuaRocks
curl https://raw.githubusercontent.com/apache/apisix/master/utils/linux-install-luarocks.sh -sL | bash - 
# start etcd server
nohup etcd & 
 
# 防火墙关闭 
systemctl stop firewalld.service
systemctl disable firewalld.service
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
​
部署APIsix
$ mkdir apisix-2.3
$ wget https://archive.apache.org/dist/apisix/2.3/apache-apisix-2.3-src.tgz
$ tar zxvf apache-apisix-2.3-src.tgz -C apisix-2.3
安装依赖包
​
$ make deps
检查版本
​
$ ./bin/apisix version
启动服务
​
$ ./bin/apisix start
部署Dashboard
https://github.com/apache/apisix-dashboard
https://github.com/apache/apisix-dashboard/blob/master/docs/en/latest/deploy.md
​
web依赖安装
node安装
https://nodejs.org/en/download/
​
yarn 安装
https://yarnpkg.com/getting-started/install
​
克隆工程
git clone -b v2.4 https://github.com/apache/apisix-dashboard.git
编译
cd apisix-dashboard
make build
启动服务
cd output
./manager-api
nohup ./manager-api &
通过浏览器进行访问
​
http://ip:9080

2.2 Docker部署

克隆项目
#将 Apache APISIX 的 Docker 镜像下载到本地
git clone https://github.com/apache/apisix-docker.git
# 将当前的目录切换到 apisix-docker/example 路径下
cd apisix-docker/example
# 运行 docker-compose 命令,安装 Apache APISIX
docker-compose -p docker-apisix up -d
Apache APISIX 已支持 ARM64 架构。如果您正在使用 ARM64,请在最后一步执行 docker-compose -p docker-apisix -f docker-compose-arm64.yml up -d。
​
http://ip:9080

2.3 K8S部署

Etcd.yaml

apiVersion: v1
data:
  jwt-token.pem: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS2dJQkFBS0NBZ0VBN1d6LzVNb3AzVHF0QWNMeFVMU2p5Mm9SbmhJSXBvTndBV2pLb2Uxb08reDFlKzMzCjc1dG1BTU91SmhxS0c3TGhIdFVxWENiQXZlYWRyZ09QTnJ4MGVLS0J2Ni9sY0FBbUh2Y2FVdyt3d2lYNFFxWXgKSWE0NTVGODkyL3pBT2YwUm5UMVVjUXJQbDR3SDZWWndvY3QrNzhZL3lDaWRQcGpoWTNra0IveWszUmlxUVFMMwpqR3NHMXZLYURNUEl3bFgxc0xkRUdzTjhjN1pvd0x5SWtCc1BiSWlYSHdPeWE3Mkp2cVRZc2dydWw5Ri8yRFl1ClBWZEhaMzREdTBpd1NVNCt1N1lQS0lFYUp6RmdSd3c2czJXYlZBQXVEN1h6LzU2anMvTm5uZEFNWHlYT1RReGsKTnQwZlZVS2R5SWNPdGJGK2w0blFnNG1RVXBDS3MvdGhHYzFzY1hMWHpqWVJaclo3NjFkVFRYSm15UWRWbWhOYgpaemZ2SzJEZ3ppYkZBcStPQ29PaWE2TlByYUhTZEFsejlWcS92MFB4T0RlbXZDR2Q1clg2VHF4eUdqcGtGcWxOCmdNbVpWR2pHdVBEWXN5TVpjUDZOWEVoUFFhWmRWNzY5Q1kyY0xlSWVsWk1LNC9TUDNOL0RiU3E2cEdZaDhOV1kKV3pyV2k0UWtyUVI0UnBlOGhGL1FRbmo5RnpVTUxlR05zUG91L0JnTGJCbDIyN2E3NmdlUEsrMmp2VW5UMXlCVApLbzJmWFlnYTgxVEhpYzhOR2VCSDlrU1VQMThXVUVTcGI2cXVJTVQ5dHAzTmx6SDdYc3E4TnNqQlEwMVJqb2VCCm9Tc1hYcDZteWhJdU90QjZINkFLbTJwTitCU0lrRW9XL0RUYlJwTllkdE5FSjRpT3BWZFNYaFE1d1dzQ0F3RUEKQVFLQ0FnRUE0R3VHV2NGSjN3WkdZQUxmVExUaW1qU3hZR09WYjZlUHFKVmY2NzFYS0VVeks2aGRFa3dtRjVUZgpPTDhmU2wxRDgzdjBaVlJ3SFZBdVBUeTZFemdCTThJUHVKdlAySlViYzJ1SW8zaVNVSUhKYjE1ZDFJTTF6NHJECkV2eU95b0ZPTS8yem9vSmdoTlBrNm9jOVFZSHpnenMyTU1GTEdNOHpSRzVPUTRwb1gyQ2dGWUZ6Y25QNzdCTTIKejlnRUhNVlp6ZWI4NWZ0ZjJKUlQ0ZEtUbHZzdEVoN3VFVy9TSjRycDk1MGtBdTdZWmdLdHdEWStjTmJkOUpJbApmdEtQWjBzaGV4YjByd21SS2ZpL0U0a1l0MWZVZ1lzRi91MnpMQ3pNZWgwYUZRNkJrekpPRllBZi9jZjNoUVRKCjFiRHJrNHlwcHgycVRac3JJdy9qTzRyaVZweFk0ZlVjOW5MeVJPeG1CaC9uTHlFNFVEQWhZSGMwZjZhUWxYSVYKcGtpZ3d4ZENrditRNm9uaUZLUFU0RDF3VlhQOVVxZ2ltaFJ5V2tPcmxXUGZWa09laWIwek03Z3NvVXBtRGJ4TAoyOXAweHB6WVBPQ3REbXVXTEZxZWZmSUFFM0g5UFowWHVRUlJPQTV3cHlBdUVqK1U1cjJPMGQ5T0ZLQVA0akpXCmM3aHEwK29pZHhHNmZMK3VJZ0d1T1hPZW9uYU5jNFQ2NVZPbG9EQWkrdkZycUlXVktSbm9qMjFLdytyYzg0aHoKK2tPTktnbHVjZ2JjbUgrb1AvanU3dklTdW8raXpRUFViZnZ2alhwRThxc1l0eW1UY1J2UW5pd2I2c3h0ekNBVgpuZVE5ZElZMGYzT2JvQitucHBQMUFIZWszZlJLN1hZZ2c5eTJ4eE1IdFpyRitvUXNpaGtDZ2dFQkFPNHNzVnVLCmhLcWNJcmdkZUc2OEg0TGNtT09GWHRyZlRMNTVzTS83STI5UWhjMmczc3pYYXZoM1BndEo1ekxJeDMwdWdKdWYKN1h6Snh2Tjl2RGs1SUlVTXc3SnRJYXZKNGVQWks2L0lHZUVkOXhWTUF2NTIrVE5rOFJSbW5oeW5ua0FPNlkxcwpGM21GTURmblVxbFhzODRCVlM1N1Y3Z3RZMXV2TWpOMHRSdmdjNkxFeStpd1NQYTRnUXM2aFY4R3dMSVk3ekQvCmJHWU93bVgxNjhwbVBhbXFxOXIyUU1ubnNiWFhJb3R5aVZ1YzFwY3B5aFdqOHI1MWw4RFR6eVpEVUZWcTlXcC8KOFdkYXZ3OURwS0srckIxcEM5dFJadXF2ZjNQTkJ2UjdXdnZNS3FXTCtGZi9LdXhTMk9yenRCSXBSeVJJQTNwNgowTnBDbVVNenJObDRBRGNDZ2dFQkFQOHg5Y255dlVXbHl4b01xKzVLaTVpS3ppVzBBb1loWlZVajFLN3BRNktPCkwxeEs1UHg0WS9aTmNlNGs0c3F4azBkZmpCT3J1eFdYSk1oMGhYSHhPVzhBUDBSYU1waWc5YVh4MWkwVXp6anIKbEZLZWtoNzNrQWpFcHBYN0FGcVRHOHF2NUJ2azArRWI1cGhPNFM4ZFlSQngxdzdSKzYvVisxS3JuYm1LOTE1RQoxbVBWTWtzQ2dlNnFwUGs4aHhWeHVhcStrOWR3eVVVSXhQR2w1NW5BU0hyN1JYaldYa3pkallIZk8vZHFxSGwwCkc3MWx2QmN5dUMwOERsMW5LVE5KQlAvY0pEeGVNVlVha25NM00yN2FNeitPSmRnTUE2YVV1V3pYS3NIWHdBeHkKeWM0ZWJwZEdKcVkrRGRhNGNLckV6VTQ4T2hTM1l6cGxZcXlyemtqeXBtMENnZ0VCQU5PSFUvbEdHNjlldmlNZwo0VjRQckRqUDdPVmRCVEtFVWFkMWNvZzB0bkxkWkFpTlVITkMrdGt6SmlKbWYzU0dCMDV4WjMxUDIxOFI0YVZOClRVYlJLc1dmNFlwdERCT0RXQ0RCTnVDR2FoMmFQR0Jvd3R2M0ZEb0Y4MnEzL01MY1Ixc0RJNEFidVBtUFJaVFEKMklSWHhQUTRFTXdZZFg2NHFONjd5VzBUd09uQ1BWRVpVVFFXcEthaWxORkJKMFNQUGNLdkRIaEswWjRPaTY1OAphKzYxUVJ5WDNNdTZHeTUyblVrdmlabXBucjZEbTc1ak9meGdRRzNSQ0hjVVpveklDZWZpOTVXZmplbktHWmZYCjdyY3Zlck1nSVl5bVRpNHVzWlpLU0Z3SDFuVjlEWDg3d2ROOVowUytDN01Yd0J6RkZrN3R1bEVrRkt0VHJNU1gKZDNNbzlaOENnZ0VCQUptaFhCVHRtMkI0aFNMemlmWDB6c0ZRbnZZM3ZtVTlhYUd0NW5ZK1c4ZGF6Y3hFRWtLagp2NW9oMlhyQ25mM2tsWU9jVTlucndyOG10TEF3NWIxSXVZakhuMDdvOWhqSW5kbi9FeThrbmZQb2J1eW1KZFdhCnVBMXZSZEo0dnlmSDlDMDdZcG9nVWlYdEJBK2hQUk4rSGxjbUVaQU1mZmJIWFh2UmNTeW9LbStJQllFb2NoU1MKTitLVXZLaUc5ZFBGR1Q5ZlorV0ZNc1hxbDVYYWlPa1l4d215aDRwTms0dTJ2Vi80SWtPNjVCM3A5bUU1QTlqNwpZY0ZwckVReXZLenhRcDg5eWxyRllmR1lBNTUxRnZPZlRNYndMbnc0RDJLVG1tV1p5MVhUS3Z6VGhnWWViL21GCjgvS1UzUVB0R1hiVTc3d3ZxYythNzVQU1FXc3VLd3ZqZUtrQ2dnRUFWMHlBbG9YQ2hicnQrYml3MTVsek50dmwKUktWbFlyeXNoWlJ4VTNoRU9yTllPY042WkwxazZLWnUySVhWckJBVjlQNlVPbmdaK1VxUVpibHluSGVZcTZteApDWU1HSjVaNVZkYzJEYXVVaUNkczRybkd5U0pKWGFpUC82WVlxbEJvWkMvdnlHK3dBTy9ybThtdFlrR1hhdEc5CkRqMkJqd2l5Z0ROQUlKZ2l0OHZYTWM0RFlvK3Z5WkJUZVRNb21RNkFITDJiNUc2NE81ZWxHU08yZzd3SnJ6QysKdjhCZUIyTCs3U0x0amNVTEsydktoWFNnVE9EZTUwWWU4UVFBVTRYM1lIQStPc3pGa1pLWVNGaEtnV3hzNDdzUApIRGU1ZS92NjFNRDFnbkdaVjBrS1hIRHhwVWExNkpTKzlya3Z2UEF6aVQwNzltUnJ4YTliUnhmd2lZS3FQUT09Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
kind: Secret
metadata:
  labels:
    app.kubernetes.io/instance: etcd
    app.kubernetes.io/name: etcd
  name: etcd-jwt-token
  namespace: apisix
type: Opaque
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  generation: 1
  labels:
    app.kubernetes.io/instance: etcd
    app.kubernetes.io/name: etcd
  name: etcd
  namespace: apisix
spec:
  podManagementPolicy: Parallel
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app.kubernetes.io/instance: etcd
      app.kubernetes.io/name: etcd
  serviceName: etcd-headless
  template:
    metadata:
      annotations:
        checksum/token-secret: 60156acd10c1cc700c72beb227921dd1c20bf596700362f42d7ab98b32f67a44
        prometheus.io/port: "2379"
        prometheus.io/scrape: "true"
      labels:
        app.kubernetes.io/instance: etcd
        app.kubernetes.io/name: etcd
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - podAffinityTerm:
              labelSelector:
                matchLabels:
                  app.kubernetes.io/instance: etcd
                  app.kubernetes.io/name: etcd
              namespaces:
              - apisix
              topologyKey: kubernetes.io/hostname
            weight: 1
      containers:
      - env:
        - name: BITNAMI_DEBUG
          value: "false"
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: ETCDCTL_API
          value: "3"
        - name: ETCD_ON_K8S
          value: "yes"
        - name: ETCD_START_FROM_SNAPSHOT
          value: "no"
        - name: ETCD_DISASTER_RECOVERY
          value: "no"
        - name: ETCD_NAME
          value: $(MY_POD_NAME)
        - name: ETCD_DATA_DIR
          value: /bitnami/etcd/data
        - name: ETCD_LOG_LEVEL
          value: info
        - name: ALLOW_NONE_AUTHENTICATION
          value: "yes"
        - name: ETCD_AUTH_TOKEN
          value: jwt,priv-key=/opt/bitnami/etcd/certs/token/jwt-token.pem,sign-method=RS256,ttl=10m
        - name: ETCD_ADVERTISE_CLIENT_URLS
          value: http://$(MY_POD_NAME).etcd-headless.$(MY_POD_NAMESPACE).svc.cluster.local:2379,http://etcd.$(MY_POD_NAMESPACE).svc.cluster.local:2379
        - name: ETCD_LISTEN_CLIENT_URLS
          value: http://0.0.0.0:2379
        - name: ETCD_INITIAL_ADVERTISE_PEER_URLS
          value: http://$(MY_POD_NAME).etcd-headless.$(MY_POD_NAMESPACE).svc.cluster.local:2380
        - name: ETCD_LISTEN_PEER_URLS
          value: http://0.0.0.0:2380
        - name: ETCD_INITIAL_CLUSTER_TOKEN
          value: etcd-cluster-k8s
        - name: ETCD_INITIAL_CLUSTER_STATE
          value: new
        - name: ETCD_INITIAL_CLUSTER
          value: etcd-0=http://etcd-0.etcd-headless.$(MY_POD_NAMESPACE).svc.cluster.local:2380,etcd-1=http://etcd-1.etcd-headless.$(MY_POD_NAMESPACE).svc.cluster.local:2380,etcd-2=http://etcd-2.etcd-headless.$(MY_POD_NAMESPACE).svc.cluster.local:2380
        - name: ETCD_CLUSTER_DOMAIN
          value: etcd-headless.$(MY_POD_NAMESPACE).svc.cluster.local
        image:  artifactory.dep.devops.cmit.cloud:20101/panji_middleware_docker/etcd:3.5.4
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              command:
              - /opt/bitnami/scripts/etcd/prestop.sh
        livenessProbe:
          failureThreshold: 5
          initialDelaySeconds: 60
          periodSeconds: 30
          successThreshold: 1
          tcpSocket:
            port: 2379
          timeoutSeconds: 5
        name: etcd
        ports:
        - containerPort: 2379
          name: client
          protocol: TCP
        - containerPort: 2380
          name: peer
          protocol: TCP
        resources: {}
        securityContext:
          runAsNonRoot: true
          runAsUser: 1001
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /bitnami/etcd
          name: data
        - mountPath: /opt/bitnami/etcd/certs/token/
          name: etcd-jwt-token
          readOnly: true
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext:
        fsGroup: 1001
      serviceAccount: default
      serviceAccountName: default
      terminationGracePeriodSeconds: 30
      volumes:
      - name: etcd-jwt-token
        secret:
          defaultMode: 256
          secretName: etcd-jwt-token
  updateStrategy:
    type: RollingUpdate
  volumeClaimTemplates:
  - apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      creationTimestamp: null
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 8Gi
      storageClassName: nfs-controller-plane
      volumeMode: Filesystem
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/instance: etcd
    helm.sh/chart: etcd-3.4.13
  name: etcd
  namespace: apisix
spec:
  ports:
  - name: client
    port: 2379
    protocol: TCP
    targetPort: client
  - name: peer
    port: 2380
    protocol: TCP
    targetPort: peer
  selector:
    app.kubernetes.io/instance: etcd
    app.kubernetes.io/name: etcd
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
  labels:
    app.kubernetes.io/instance: etcd
    app.kubernetes.io/name: etcd
  name: etcd-headless
  namespace: apisix
spec:
  clusterIP: None
  ports:
  - name: client
    port: 2379
    protocol: TCP
    targetPort: client
  - name: peer
    port: 2380
    protocol: TCP
    targetPort: peer
  publishNotReadyAddresses: true
  selector:
    app.kubernetes.io/instance: etcd
    app.kubernetes.io/name: etcd
  sessionAffinity: None
  type: ClusterIP

Apisix.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  labels:
  name: apisix-pvc
  namespace: apisix
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  storageClassName: nfs-controller-plane
apiVersion: v1
data:
  config.yaml: |-
    apisix:
      # node_listen: 9080               # APISIX listening port
      node_listen:                      # This style support multiple ports
        - 9080
      #   - port: 9081
      #     enable_http2: true          # If not set, the default value is `false`.
      #   - ip: 127.0.0.2               # Specific IP, If not set, the default value is `0.0.0.0`.
      #     port: 9082
      #     enable_http2: true
      enable_admin: true
      enable_admin_cors: true           # Admin API support CORS response headers.
      enable_dev_mode: false            # Sets nginx worker_processes to 1 if set to true
      enable_reuseport: true            # Enable nginx SO_REUSEPORT switch if set to true.
      show_upstream_status_in_response_header: true # when true all upstream status write to `X-APISIX-Upstream-Status` otherwise only 5xx code
      enable_ipv6: true
      config_center: etcd               # etcd: use etcd to store the config value
                                        # yaml: fetch the config value from local yaml file `/your_path/conf/apisix.yaml`
    
      #proxy_protocol:                  # Proxy Protocol configuration
      #listen_http_port: 9181           # The port with proxy protocol for http, it differs from node_listen and port_admin.
                                        # This port can only receive http request with proxy protocol, but node_listen & port_admin
                                        # can only receive http request. If you enable proxy protocol, you must use this port to
                                        # receive http request with proxy protocol
      #listen_https_port: 9182          # The port with proxy protocol for https
      #enable_tcp_pp: true              # Enable the proxy protocol for tcp proxy, it works for stream_proxy.tcp option
      #enable_tcp_pp_to_upstream: true  # Enables the proxy protocol to the upstream server
      enable_server_tokens: true        # Whether the APISIX version number should be shown in Server header.
                                        # It's enabled by default.
    
      # configurations to load third party code and/or override the builtin one.
      extra_lua_path: ""                # extend lua_package_path to load third party code
      extra_lua_cpath: ""               # extend lua_package_cpath to load third party code
      #lua_module_hook: "my_project.my_hook"  # the hook module which will be used to inject third party code into APISIX
    
      proxy_cache:                      # Proxy Caching configuration
        cache_ttl: 10s                  # The default caching time in disk if the upstream does not specify the cache time
        zones:                          # The parameters of a cache
          - name: disk_cache_one        # The name of the cache, administrator can specify
                                        # which cache to use by name in the admin api (disk|memory)
            memory_size: 50m            # The size of shared memory, it's used to store the cache index for
                                        # disk strategy, store cache content for memory strategy (disk|memory)
            disk_size: 1G               # The size of disk, it's used to store the cache data (disk)
            disk_path: /tmp/disk_cache_one  # The path to store the cache data (disk)
            cache_levels: 1:2           # The hierarchy levels of a cache (disk)
          #- name: disk_cache_two
          #  memory_size: 50m
          #  disk_size: 1G
          #  disk_path: "/tmp/disk_cache_two"
          #  cache_levels: "1:2"
          - name: memory_cache
            memory_size: 50m
    
      allow_admin:                  # http://nginx.org/en/docs/http/ngx_http_access_module.html#allow
        - 127.0.0.1/32              # If we don't set any IP list, then any IP access is allowed by default.
        #- "::/64"
      admin_listen:                # use a separate port
        ip: 127.0.0.1              # Specific IP, if not set, the default value is `0.0.0.0`.
        port: 9180
      #port_admin: 9180             # Not recommend: This parameter should be set via the `admin_listen`.
      #https_admin: true            # enable HTTPS when use a separate port for Admin API.
                                    # Admin API will use conf/apisix_admin_api.crt and conf/apisix_admin_api.key as certificate.
      admin_api_mtls:               # Depends on `port_admin` and `https_admin`.
        admin_ssl_cert: ""          # Path of your self-signed server side cert.
        admin_ssl_cert_key: ""      # Path of your self-signed server side key.
        admin_ssl_ca_cert: ""       # Path of your self-signed ca cert.The CA is used to sign all admin api callers' certificates.
    
      # Default token when use API to call for Admin API.
      # *NOTE*: Highly recommended to modify this value to protect APISIX's Admin API.
      # Disabling this configuration item means that the Admin API does not
      # require any authentication.
      admin_key:
        -
          name: admin
          key: 84b625edd1c95f136f87adc8f1f03433
          role: admin                 # admin: manage all configuration data
                                      # viewer: only can view configuration data
        -
          name: viewer
          key: 4054f7cf07e344346cd3f287985e76a2
          role: viewer
    
      delete_uri_tail_slash: false    # delete the '/' at the end of the URI
      # The URI normalization in servlet is a little different from the RFC's.
      # See https://github.com/jakartaee/servlet/blob/master/spec/src/main/asciidoc/servlet-spec-body.adoc#352-uri-path-canonicalization,
      # which is used under Tomcat.
      # Turn this option on if you want to be compatible with servlet when matching URI path.
      normalize_uri_like_servlet: false
      router:
        http: radixtree_uri         # radixtree_uri: match route by uri(base on radixtree)
                                      # radixtree_host_uri: match route by host + uri(base on radixtree)
                                      # radixtree_uri_with_parameter: like radixtree_uri but match uri with parameters,
                                      #   see https://github.com/api7/lua-resty-radixtree/#parameters-in-path for
                                      #   more details.
        ssl: radixtree_sni          # radixtree_sni: match route by SNI(base on radixtree)
      #stream_proxy:                  # TCP/UDP proxy
      #  only: true                   # use stream proxy only, don't enable HTTP stuff
      #  tcp:                         # TCP proxy port list
      #    - addr: 9100
      #      tls: true
      #    - addr: "127.0.0.1:9101"
      #  udp:                         # UDP proxy port list
      #    - 9200
      #    - "127.0.0.1:9201"
      #dns_resolver:                  # If not set, read from `/etc/resolv.conf`
      #  - 1.1.1.1
      #  - 8.8.8.8
      dns_resolver_valid: 30         # if given, override the TTL of the valid records. The unit is second.
      resolver_timeout: 5             # resolver timeout
      enable_resolv_search_opt: true  # enable search option in resolv.conf
      ssl:
        enable: true
        listen:                       # APISIX listening port in https.
          - 9443
        #   - port: 9444
        #     enable_http2: true      # If not set, the default value is `false`.
        #   - ip: 127.0.0.3           # Specific IP, If not set, the default value is `0.0.0.0`.
        #     port: 9445
        #     enable_http2: true
        enable_http2: true            # Not recommend: This parameter should be set via the `listen`.
        # listen_port: 9443           # Not recommend: This parameter should be set via the `listen`.
        #ssl_trusted_certificate: /path/to/ca-cert  # Specifies a file path with trusted CA certificates in the PEM format
                                                    # used to verify the certificate when APISIX needs to do SSL/TLS handshaking
                                                    # with external services (e.g. etcd)
        ssl_protocols: TLSv1.2 TLSv1.3
        ssl_ciphers: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
        ssl_session_tickets: false              #  disable ssl_session_tickets by default for 'ssl_session_tickets' would make Perfect Forward Secrecy useless.
                                                #  ref: https://github.com/mozilla/server-side-tls/issues/135
    
        key_encrypt_salt: edd1c9f0985e76a2      #  If not set, will save origin ssl key into etcd.
                                                #  If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC
                                                #  !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !!
    
        #fallback_sni: "my.default.domain"      # If set this, when the client doesn't send SNI during handshake, the fallback SNI will be used instead
      enable_control: true
      #control:
      #  ip: 127.0.0.1
      #  port: 9090
      disable_sync_configuration_during_start: false  # safe exit. Remove this once the feature is stable
    
    nginx_config:                     # config for render the template to generate nginx.conf
      #user: root                     # specifies the execution user of the worker process.
                                      # the "user" directive makes sense only if the master process runs with super-user privileges.
                                      # if you're not root user,the default is current user.
      error_log: logs/error.log
      error_log_level:  warn          # warn,error
      worker_processes: 2          # if you want use multiple cores in container, you can inject the number of cpu as environment variable "APISIX_WORKER_PROCESSES"
      enable_cpu_affinity: true       # enable cpu affinity, this is just work well only on physical machine
      worker_rlimit_nofile: 20480     # the number of files a worker process can open, should be larger than worker_connections
      worker_shutdown_timeout: 240s   # timeout for a graceful shutdown of worker processes
    
      max_pending_timers: 16384       # increase it if you see "too many pending timers" error
      max_running_timers: 4096        # increase it if you see "lua_max_running_timers are not enough" error
    
      event:
        worker_connections: 10620
      #envs:                          # allow to get a list of environment variables
      #  - TEST_ENV
    
      stream:
        enable_access_log: false         # enable access log or not, default false
        access_log: logs/access_stream.log
        access_log_format: "$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time"
                                                # create your custom log format by visiting http://nginx.org/en/docs/varindex.html
        access_log_format_escape: default       # allows setting json or default characters escaping in variables
        lua_shared_dict:
          etcd-cluster-health-check-stream: 10m
          lrucache-lock-stream: 10m
          plugin-limit-conn-stream: 10m
    
      # As user can add arbitrary configurations in the snippet,
      # it is user's responsibility to check the configurations
      # don't conflict with APISIX.
      main_configuration_snippet: |
        # Add custom Nginx main configuration to nginx.conf.
        # The configuration should be well indented!
      http_configuration_snippet: |
        # Add custom Nginx http configuration to nginx.conf.
        # The configuration should be well indented!
      http_server_configuration_snippet: |
        # Add custom Nginx http server configuration to nginx.conf.
        # The configuration should be well indented!
      http_server_location_configuration_snippet: |
        # Add custom Nginx http server location configuration to nginx.conf.
        # The configuration should be well indented!
      http_admin_configuration_snippet: |
        # Add custom Nginx admin server configuration to nginx.conf.
        # The configuration should be well indented!
      http_end_configuration_snippet: |
        # Add custom Nginx http end configuration to nginx.conf.
        # The configuration should be well indented!
      stream_configuration_snippet: |
        # Add custom Nginx stream configuration to nginx.conf.
        # The configuration should be well indented!
      http:
        enable_access_log: true         # enable access log or not, default true
        access_log: logs/access.log
        access_log_format: "apikey:[$http_apikey] - $remote_addr - $remote_user [$time_local] $http_host \"$request\" $status $body_bytes_sent $request_time \"$http_referer\" \"$http_user_agent\" $upstream_addr $upstream_status $upstream_response_time \"$upstream_scheme://$upstream_host$upstream_uri\""
        access_log_format_escape: default       # allows setting json or default characters escaping in variables
        keepalive_timeout: 75s          # timeout during which a keep-alive client connection will stay open on the server side.
        client_header_timeout: 60s      # timeout for reading client request header, then 408 (Request Time-out) error is returned to the client
        client_body_timeout: 60s        # timeout for reading client request body, then 408 (Request Time-out) error is returned to the client
        client_max_body_size: 0         # The maximum allowed size of the client request body.
                                        # If exceeded, the 413 (Request Entity Too Large) error is returned to the client.
                                        # Note that unlike Nginx, we don't limit the body size by default.
    
        send_timeout: 10s              # timeout for transmitting a response to the client.then the connection is closed
        underscores_in_headers: "on"   # default enables the use of underscores in client request header fields
        real_ip_header: X-Real-IP      # http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header
        real_ip_recursive: "off"       # http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive
        real_ip_from:                  # http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from
          - 127.0.0.1
          - "unix:"
        #custom_lua_shared_dict:       # add custom shared cache to nginx.conf
        #  ipc_shared_dict: 100m       # custom shared cache, format: `cache-key: cache-size`
    
        # Enables or disables passing of the server name through TLS Server Name Indication extension (SNI, RFC 6066)
        # when establishing a connection with the proxied HTTPS server.
        proxy_ssl_server_name: true
        upstream:
          keepalive: 320                # Sets the maximum number of idle keepalive connections to upstream servers that are preserved in the cache of each worker process.
                                        # When this number is exceeded, the least recently used connections are closed.
          keepalive_requests: 1000      # Sets the maximum number of requests that can be served through one keepalive connection.
                                        # After the maximum number of requests is made, the connection is closed.
          keepalive_timeout: 60s        # Sets a timeout during which an idle keepalive connection to an upstream server will stay open.
        charset: utf-8                  # Adds the specified charset to the "Content-Type" response header field, see
                                        # http://nginx.org/en/docs/http/ngx_http_charset_module.html#charset
        variables_hash_max_size: 2048   # Sets the maximum size of the variables hash table.
    
        lua_shared_dict:
          internal-status: 10m
          plugin-limit-req: 10m
          plugin-limit-count: 10m
          prometheus-metrics: 10m
          plugin-limit-conn: 10m
          upstream-healthcheck: 10m
          worker-events: 10m
          lrucache-lock: 10m
          balancer-ewma: 10m
          balancer-ewma-locks: 10m
          balancer-ewma-last-touched-at: 10m
          plugin-limit-count-redis-cluster-slot-lock: 1m
          tracing_buffer: 10m
          plugin-api-breaker: 10m
          etcd-cluster-health-check: 10m
          discovery: 1m
          jwks: 1m
          introspection: 10m
          access-tokens: 1m
          ext-plugin: 1m
          kubernetes: 1m
          tars: 1m
    
    etcd:
      host:                           # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
        #- "http://127.0.0.1:2379"     # multiple etcd address, if your etcd cluster enables TLS, please use https scheme,
        - "http://etcd-0.etcd-headless.apisix.svc.cluster.local:2379"     # multiple etcd address
        - "http://etcd-1.etcd-headless.apisix.svc.cluster.local:2379"
        - "http://etcd-2.etcd-headless.apisix.svc.cluster.local:2379"
                                      # e.g. https://127.0.0.1:2379.
      prefix: /apisix                 # apisix configurations prefix
      timeout: 30                     # 30 seconds
      #resync_delay: 5                # when sync failed and a rest is needed, resync after the configured seconds plus 50% random jitter
      #health_check_timeout: 10       # etcd retry the unhealthy nodes after the configured seconds
      health_check_retry: 2           # etcd retry time that only affects the health check, default 2
      #user: root                     # root username for etcd
      #password: 5tHkHhYkjr6cQY       # root password for etcd
      tls:
        # To enable etcd client certificate you need to build APISIX-Base, see
        # https://apisix.apache.org/docs/apisix/FAQ#how-do-i-build-the-apisix-base-environment?
        #cert: /path/to/cert          # path of certificate used by the etcd client
        #key: /path/to/key            # path of key used by the etcd client
    
        verify: true                  # whether to verify the etcd endpoint certificate when setup a TLS connection to etcd,
                                      # the default value is true, e.g. the certificate will be verified strictly.
        #sni:                         # the SNI for etcd TLS requests. If missed, the host part of the URL will be used.
    
    # HashiCorp Vault storage backend for sensitive data retrieval. The config shows an example of what APISIX expects if you
    # wish to integrate Vault for secret (sensetive string, public private keys etc.) retrieval. APISIX communicates with Vault
    # server HTTP APIs. By default, APISIX doesn't need this configuration.
    # vault:
    #   host: "http://0.0.0.0:8200"   # The host address where the vault server is running.
    #   timeout: 10                   # request timeout 30 seconds
    #   token: root                   # Authentication token to access Vault HTTP APIs
    #   prefix: kv/apisix             # APISIX supports vault kv engine v1, where sensitive data are being stored
                                      # and retrieved through vault HTTP APIs. enabling a prefix allows you to better enforcement of
                                      # policies, generate limited scoped tokens and tightly control the data that can be accessed
                                      # from APISIX.
    
    
    #discovery:                       # service discovery center
    #  dns:
    #    servers:
    #      - "127.0.0.1:8600"         # use the real address of your dns server
    #  eureka:
    #    host:                        # it's possible to define multiple eureka hosts addresses of the same eureka cluster.
    #      - "http://127.0.0.1:8761"
    #    prefix: /eureka/
    #    fetch_interval: 30           # default 30s
    #    weight: 100                  # default weight for node
    #    timeout:
    #      connect: 2000              # default 2000ms
    #      send: 2000                 # default 2000ms
    #      read: 5000                 # default 5000ms
    
    graphql:
      max_size: 1048576               # the maximum size limitation of graphql in bytes, default 1MiB
    
    #ext-plugin:
      #cmd: ["ls", "-l"]
    
    plugins:                          # plugin list (sorted by priority)
      - real-ip                        # priority: 23000
      - client-control                 # priority: 22000
      - proxy-control                  # priority: 21990
      - zipkin                         # priority: 12011
      #- skywalking                    # priority: 12010
      #- opentelemetry                 # priority: 12009
      - ext-plugin-pre-req             # priority: 12000
      - request-id                     # priority: 11010
      - fault-injection                # priority: 11000
      - mocking                        # priority: 10900
      - serverless-pre-function        # priority: 10000
      #- batch-requests                # priority: 4010
      - cors                           # priority: 4000
      - ip-restriction                 # priority: 3000
      - ua-restriction                 # priority: 2999
      - referer-restriction            # priority: 2990
      - csrf                           # priority: 2980
      - uri-blocker                    # priority: 2900
      - request-validation             # priority: 2800
      - openid-connect                 # priority: 2599
      - authz-casbin                   # priority: 2560
      - authz-casdoor                  # priority: 2559
      - wolf-rbac                      # priority: 2555
      - ldap-auth                      # priority: 2540
      - hmac-auth                      # priority: 2530
      - basic-auth                     # priority: 2520
      - jwt-auth                       # priority: 2510
      - key-auth                       # priority: 2500
      - consumer-restriction           # priority: 2400
      - forward-auth                   # priority: 2002
      - opa                            # priority: 2001
      - authz-keycloak                 # priority: 2000
      - pj-auth                        # priority: 1999
      #- error-log-logger              # priority: 1091
      - proxy-mirror                   # priority: 1010
      - proxy-cache                    # priority: 1009
      - proxy-rewrite                  # priority: 1008
      - api-breaker                    # priority: 1005
      - limit-conn                     # priority: 1003
      - limit-count                    # priority: 1002
      - limit-req                      # priority: 1001
      - node-status                    # priority: 1000
      - gzip                           # priority: 995
      - server-info                    # priority: 990
      - traffic-split                  # priority: 966
      - redirect                       # priority: 900
      - response-rewrite               # priority: 899
      - kafka-proxy                    # priority: 508
      #- dubbo-proxy                   # priority: 507
      - grpc-transcode                 # priority: 506
      - grpc-web                       # priority: 505
      - public-api                     # priority: 501
      - prometheus                     # priority: 500
      - datadog                        # priority: 495
      - echo                           # priority: 412
      - loggly                         # priority: 411
      - http-logger                    # priority: 410
      - splunk-hec-logging             # priority: 409
      - skywalking-logger              # priority: 408
      - google-cloud-logging           # priority: 407
      - sls-logger                     # priority: 406
      - tcp-logger                     # priority: 405
      - kafka-logger                   # priority: 403
      - rocketmq-logger                # priority: 402
      - syslog                         # priority: 401
      - udp-logger                     # priority: 400
      - file-logger                    # priority: 399
      - clickhouse-logger              # priority: 398
      - log-rotate                    # priority: 100
      # <- recommend to use priority (0, 100) for your custom plugins
      - example-plugin                 # priority: 0
      - aws-lambda                     # priority: -1899
      - azure-functions                # priority: -1900
      - openwhisk                      # priority: -1901
      - serverless-post-function       # priority: -2000
      - ext-plugin-post-req            # priority: -3000
      - ext-plugin-post-resp           # priority: -4000
    
    stream_plugins: # sorted by priority
      - ip-restriction                 # priority: 3000
      - limit-conn                     # priority: 1003
      - mqtt-proxy                     # priority: 1000
      - syslog                         # priority: 401
      # <- recommend to use priority (0, 100) for your custom plugins
    
    #wasm:
      #plugins:
        #- name: wasm_log
          #priority: 7999
          #file: t/wasm/log/main.go.wasm
    
    #xrpc:
      #protocols:
        #- name: pingpong
    
    plugin_attr:
      log-rotate:
        interval: 3600    # rotate interval (unit: second)
        max_kept: 12     # max number of log files will be kept
        enable_compression: false    # enable log file compression(gzip) or not, default false
      skywalking:
        service_name: APISIX
        service_instance_name: APISIX Instance Name
        endpoint_addr: http://127.0.0.1:12800
      opentelemetry:
        trace_id_source: x-request-id
        resource:
          service.name: APISIX
        collector:
          address: 127.0.0.1:4318
          request_timeout: 3
          request_headers:
            Authorization: token
        batch_span_processor:
          drop_on_queue_full: false
          max_queue_size: 1024
          batch_timeout: 2
          inactive_timeout: 1
          max_export_batch_size: 16
      prometheus:
        export_uri: /apisix/prometheus/metrics
        metric_prefix: apisix_
        enable_export_server: true
        export_addr:
          ip: 0.0.0.0
          port: 9091
      server-info:
        report_ttl: 60   # live time for server info in etcd (unit: second)
      dubbo-proxy:
        upstream_multiplex_count: 32
      request-id:
        snowflake:
          enable: false
          snowflake_epoc: 1609459200000   # the starting timestamp is expressed in milliseconds
          data_machine_bits: 12           # data machine bit, maximum 31, because Lua cannot do bit operations greater than 31
          sequence_bits: 10               # each machine generates a maximum of (1 << sequence_bits) serial numbers per millisecond
          data_machine_ttl: 30            # live time for data_machine in etcd (unit: second)
          data_machine_interval: 10       # lease renewal interval in etcd (unit: second)
      proxy-mirror:
        timeout:                          # proxy timeout in mirrored sub-request
          connect: 60s
          read: 60s
          send: 60s
    #  redirect:
    #    https_port: 8443   # the default port for use by HTTP redirects to HTTPS
kind: ConfigMap
metadata:
  labels:
    clus_id: "1"
  name: apisix-cm
  namespace: apisix
apiVersion: v1
data:
  pj-auth.lua: |-
    --
    -- Licensed to the Apache Software Foundation (ASF) under one or more
    -- contributor license agreements.  See the NOTICE file distributed with
    -- this work for additional information regarding copyright ownership.
    -- The ASF licenses this file to You under the Apache License, Version 2.0
    -- (the "License"); you may not use this file except in compliance with
    -- the License.  You may obtain a copy of the License at
    --
    --     http://www.apache.org/licenses/LICENSE-2.0
    --
    -- Unless required by applicable law or agreed to in writing, software
    -- distributed under the License is distributed on an "AS IS" BASIS,
    -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    -- See the License for the specific language governing permissions and
    -- limitations under the License.
    --
    local core = require("apisix.core")
    local ck       = require("resty.cookie")
    local http     = require("resty.http")
    local json     = require("apisix.core.json")
    local posix    = require'posix'
    local sub_str  = string.sub
    
    local schema = {
        type = "object",
        properties = {
            address = {
                type = "string",
                default = "portal-auth.paas-portal.svc.cluster.local:8080",
            },
        }
    }
    
    -- 常量 自身插件名
    local plugin_name = "pj-auth-plugin"
    
    
    local _M = {
        version = 0.1,
        priority = 1999,        -- TODO: add a type field, may be a good idea
        name = plugin_name,
        schema = schema,
    }
    
    
    local create_consume_cache
    do
        local consumer_ids = {}
    
        function create_consume_cache(consumers)
            core.table.clear(consumer_ids)
    
            for _, consumer in ipairs(consumers.nodes) do
                core.log.info("consumer node: ", core.json.delay_encode(consumer))
                consumer_ids[consumer.auth_conf.appid] = consumer
            end
    
            return consumer_ids
        end
    
    end -- do
    

    local function fetch_jwt_token(ctx)
        -- 从请求中获得token
        local token = core.request.header(ctx, "authorization")
        if token then
            local prefix = sub_str(token, 1, 7)
            if prefix == 'Bearer ' or prefix == 'bearer ' then
                return sub_str(token, 8)
            end
            return token
        end
    
        token = ctx.var.arg_jwt
        if token then
            return token
        end
    
        local cookie, err = ck:new()
        if not cookie then
            return nil, err
        end
    
        local val, err = cookie:get("jwt")
        return val, err
    end

    local function new_headers()
        -- 子请求的头
        local t = {}
        local lt = {}
        local _mt = {
            __index = function(t, k)
                return rawget(lt, string.lower(k))
            end,
            __newindex = function(t, k, v)
                rawset(t, k, v)
                rawset(lt, string.lower(k), v)
            end,
        }
        return setmetatable(t, _mt)
    end

    
    local function http_req(method, uri, body, myheaders, timeout)
        -- 子请求构造,timeout单位ms 
        if myheaders == nil then myheaders = new_headers() end
    
        local httpc = http.new()
        if timeout then
            httpc:set_timeouts(timeout, timeout, timeout)
        end
    
        local params = {method = method, headers = myheaders, body = body, keepalive = false, ssl_verify = false}
        
        local res, err = httpc:request_uri(uri, params)

        if err then
            return nil, err
        end
    
        return res
    end
    
    
    local function http_post(uri, body, myheaders, timeout)
        -- post请求方法 
        return http_req("POST", uri, body, myheaders, timeout)
    end
    
    
    function _M.check_schema(conf)
        local ok, err = core.schema.check(schema, conf)
    
        if not ok then
            return false, err
        end
    
        return true
    end
    
    
    local function check_url_acl(server, action, req_uri, req_token)
        -- 验证acl
        -- 入参: acl服务接口地址,用户名,req的method,uri
        local retry_max = 3
        local errmsg
        
        local res
        local err
        local access_check_url = server .. "/api/v1/auth-api"
    
        local headers = new_headers()
        headers["Content-Type"] = "application/json; charset=utf-8"
        
        local ts_req1, ts_req2 = posix.clock_gettime()
        local args = { uri = req_uri, method = action, token = req_token}
        local timeout = 1000 * 10
    
        for i = 1, retry_max do
            res, err = http_post("http://" .. access_check_url, core.json.encode(args), headers, timeout)
            if err then
                break
            else
                if res.status < 500 then
                    break
                else
                    core.log.error("request [curl -v ", url, "] failed! status:", res.status)
                    if i < retry_max then
                        ngx.sleep(0.1)
                    end
                end
                

            end
        end
    
        if err then
            -- 访问acl-server异常 
            return {res_body = nil, status = 500, err = "request to acl-server failed, err:" .. tostring(err)}
        end

        if res.status ~= 200 and res.status ~= 403 then
            -- 非200和403的未知http码
            return {res_body = nil, status = 500, err = 'request to acl-server failed, status:' .. tostring(res.status)}
        end
    
        local ts_req3, ts_req4 = posix.clock_gettime()
        
        if ts_req3-ts_req1 >= 1 then
            core.log.error("over_1_s")
        elseif ts_req4/1000000-ts_req2/1000000 >= 200 then
            core.log.error("over_200_ms")
        end
    
        local body, err = json.decode(res.body)
        if err then
            errmsg = 'check permission failed! parse response json failed!'
            return {res_body = nil, status = res.status, err = errmsg}
        else
            core.log.error("rsp_bdy:", core.json.delay_encode(res.body))
            return {res_body = body, status = res.status}
        end
    end
    
    function _M.rewrite(conf, ctx)
        local uri = ctx.var.uri
        
        local action = ctx.var.request_method
        -- 如果是游览器为了跨域而发的OPTIONS,直接返回OK
        if 'OPTIONS' == action then
            return 200
        end
        
        local jwt_token, err = fetch_jwt_token(ctx)
        if not jwt_token then
            return 401, {message = "Missing JWT token in request"}
        end
    
        local res = check_url_acl(conf.address, action, uri, jwt_token)
        if res.status ~= 200 then
                return 401, {message = "no permission. code:10001"}
        end
        
        local code = res.res_body.code
        if code ~= 200 then
                if code == 30001 then
                    return 403, {message = "no permission. code:30001"}
                elseif code == 30002 then
                    return 401, {message = "no permission. code:30002"}
                elseif code == 30003 then
                    return 401, {message = "no permission. code:30002"}
                elseif code == 40001 then
                    return 403, {message = "no permission. code:30002"}
                elseif code == 40002 then
                    return 403, {message = "no permission. code:30002"}
                elseif code == 40003 then
                    return 403, {message = "no permission. code:30002"}
                elseif code == 40004 then
                    return 403, {message = "no permission. code:30002"}
                else
                    return 403, {message = "no permission. code:10001"}
                end
        end
        
        if res.res_body.data.auth ~= true then
            return 403, {message = "no permission. code:30002"}
        end
        
        core.request.set_header(ctx, "username", res.res_body.data.userName)
        core.request.set_header(ctx, "tenantcode", res.res_body.data.tenantCode)
        
    end
    
    
    return _M
kind: ConfigMap
metadata:
  labels:
    clus_id: "1"
  name: apisix-pj-auth-cm
  namespace: apisix
apiVersion: v1
kind: Service
metadata:
  labels:
    app: apisix
  name: apisix
  namespace: apisix
spec:
  ports:
  - name: http-apisix
    port: 34088
    protocol: TCP
    targetPort: 9080
  - name: http-apisix-prometheus
    port: 34080
    protocol: TCP
    targetPort: 9091
  selector:
    app: apisix
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: apisix
  name: apisix
  namespace: apisix
spec:
  progressDeadlineSeconds: 600
  replicas: 4
  revisionHistoryLimit: 10
  selector:  # 匹配Pod标签的选择器,必须匹配到spec.template.metadata.labels的pod标签
    matchLabels:
      app: apisix
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  template:   #spec.template里的内容就是声明Pod对象时要定义的各种属性所以叫PodTemplate
    metadata:
      creationTimestamp: null
      labels:
        app: apisix
    spec:   # pod里的容器属性配置
      containers:
      - image: artifactory.dep.devops.cmit.cloud:20101/panji_middleware/apisix:2.13.3
        imagePullPolicy: Always
        readinessProbe:
          failureThreshold: 6
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          tcpSocket:
            port: 9080
          timeoutSeconds: 1
        lifecycle:
          preStop:
            exec:
              command:
                - /bin/sh
                - '-c'
                - sleep 30
        name: apisix
        ports:
        - containerPort: 9080
          protocol: TCP
        - containerPort: 9091
          protocol: TCP
        resources:
          requests:
            cpu: "1"
            memory: "1Gi"
            ephemeral-storage: "3Gi"
          limits:
            cpu: "2"
            memory: "2Gi"
            ephemeral-storage: "4Gi"
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/localtime
          name: timezone
        - mountPath: /usr/local/apisix/logs/
          name: paas-pvc-log
          subPath: apisixlog
        - mountPath: /usr/local/apisix/conf/config.yaml
          name: apisix-conf-path
          subPath: config.yaml
        - mountPath: /usr/local/apisix/apisix/plugins/pj-auth.lua
          name: apisix-conf-pj-auth-path
          subPath: pj-auth.lua
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      dnsPolicy: ClusterFirst
      terminationGracePeriodSeconds: 30
      volumes:
      - name: paas-pvc-log
        persistentVolumeClaim:
          claimName: apisix-pvc
      - configMap:
          defaultMode: 420
          items:
          - key: config.yaml
            path: config.yaml
          name: apisix-cm
        name: apisix-conf-path
      - configMap:
          defaultMode: 420
          items:
          - key: pj-auth.lua
            path: pj-auth.lua
          name: apisix-pj-auth-cm
        name: apisix-conf-pj-auth-path
      - hostPath:
          path: /etc/localtime
          type: ""
        name: timezone

Apisix-dashboard.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
  name: apisix-dashboard-role
  namespace: apisix
rules:
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - list
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
  name: apisix-dashboard-sa
  namespace: apisix
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
  name: apisix-dashboard-rolebinding
  namespace: apisix
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: apisix-dashboard-role
subjects:
- kind: ServiceAccount
  name: apisix-dashboard-sa
  namespace: apisix
apiVersion: v1
data:
  conf.yaml: |-
    conf:
      listen:
        # host: 127.0.0.1     # the address on which the `Manager API` should listen.
                              # The default value is 0.0.0.0, if want to specify, please enable it.
                              # This value accepts IPv4, IPv6, and hostname.
        port: 9000            # The port on which the `Manager API` should listen.
    
      # ssl:
      #   host: 127.0.0.1     # the address on which the `Manager API` should listen for HTTPS.
                              # The default value is 0.0.0.0, if want to specify, please enable it.
      #   port: 9001            # The port on which the `Manager API` should listen for HTTPS.
      #   cert: "/tmp/cert/example.crt" # Path of your SSL cert.
      #   key:  "/tmp/cert/example.key"  # Path of your SSL key.
    
      allow_list:             # If we don't set any IP list, then any IP access is allowed by default.
        - 0.0.0.0/0           # The rules are checked in sequence until the first match is found.
        - ::1                 # In this example, access is allowed only for IPv4 network 127.0.0.1, and for IPv6 network ::1.
                              # It also support CIDR like 192.168.1.0/24 and 2001:0db8::/32
      etcd:
        endpoints:            # supports defining multiple etcd host addresses for an etcd cluster
          - http://etcd-0.etcd-headless.apisix.svc.cluster.local:2379
          - http://etcd-1.etcd-headless.apisix.svc.cluster.local:2379
          - http://etcd-2.etcd-headless.apisix.svc.cluster.local:2379
                              # yamllint disable rule:comments-indentation
                              # etcd basic auth info
        # username: "root"    # ignore etcd username if not enable etcd auth
        # password: "123456"  # ignore etcd password if not enable etcd auth
        mtls:
          key_file: ""          # Path of your self-signed client side key
          cert_file: ""         # Path of your self-signed client side cert
          ca_file: ""           # Path of your self-signed ca cert, the CA is used to sign callers' certificates
        # prefix: /apisix       # apisix config's prefix in etcd, /apisix by default
      log:
        error_log:
          level: warn       # supports levels, lower to higher: debug, info, warn, error, panic, fatal
          file_path:
            logs/error.log  # supports relative path, absolute path, standard output
                            # such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
                            # such as absolute path on Windows: winfile:///C:\error.log
        access_log:
          file_path:
            logs/access.log  # supports relative path, absolute path, standard output
                             # such as: logs/access.log, /tmp/logs/access.log, /dev/stdout, /dev/stderr
                             # such as absolute path on Windows: winfile:///C:\access.log
                             # log example: 2020-12-09T16:38:09.039+0800	INFO	filter/logging.go:46	/apisix/admin/routes/r1	{"status": 401, "host": "127.0.0.1:9000", "query": "asdfsafd=adf&a=a", "requestId": "3d50ecb8-758c-46d1-af5b-cd9d1c820156", "latency": 0, "remoteIP": "127.0.0.1", "method": "PUT", "errs": []}
      max_cpu: 0             # supports tweaking with the number of OS threads are going to be used for parallelism. Default value: 0 [will use max number of available cpu cores considering hyperthreading (if any)]. If the value is negative, is will not touch the existing parallelism profile.
      # security:
      #   access_control_allow_origin: "http://httpbin.org"
      #   access_control_allow_credentials: true          # support using custom cors configration
      #   access_control_allow_headers: "Authorization"
      #   access_control-allow_methods: "*"
      #   x_frame_options: "deny"
      #   content_security_policy: ""default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'""
    
    
    authentication:
      secret:
        secret              # secret for jwt token generation.
                            # NOTE: Highly recommended to modify this value to protect `manager api`.
                            # if it's default value, when `manager api` start, it will generate a random string to replace it.
      expire_time: 3600     # jwt token expire time, in second
      users:                # yamllint enable rule:comments-indentation
        - username: admin   # username and password for login `manager api`
          password: af7aaf061243bf1f3bb8679a2492dfe2
        - username: user
          password: 9c313a7d7a48e29f5bc0423d28be264c
    
    plugins:                          # plugin list (sorted in alphabetical order)
      - api-breaker
      - authz-keycloak
      - basic-auth
      - batch-requests
      - consumer-restriction
      - cors
      # - dubbo-proxy
      - echo
      # - error-log-logger
      # - example-plugin
      - fault-injection
      - grpc-transcode
      - hmac-auth
      - http-logger
      - ip-restriction
      - jwt-auth
      - kafka-logger
      - key-auth
      - limit-conn
      - limit-count
      - limit-req
      - log-rotate
      - node-status
      - openid-connect
      - prometheus
      - proxy-cache
      - proxy-mirror
      - proxy-rewrite
      - redirect
      - referer-restriction
      - request-id
      - request-validation
      - response-rewrite
      - serverless-post-function
      - serverless-pre-function
      # - skywalking
      - sls-logger
      - syslog
      - tcp-logger
      - udp-logger
      - uri-blocker
      - wolf-rbac
      - zipkin
      - server-info
      - traffic-split
    
kind: ConfigMap
metadata:
  labels:
  name: apisix-dashboard-cm
  namespace: apisix
apiVersion: v1
data:
  schema.json: |-
    {"main":{"proto":{"properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"update_time":{"type":"integer"},"content":{"minLength":1,"type":"string","maxLength":1048576},"desc":{"type":"string","maxLength":256},"create_time":{"type":"integer"}},"type":"object","required":["content"]},"plugins":{"type":"array","items":{"properties":{"name":{"type":"string","minLength":1},"stream":{"type":"boolean"}},"type":"object","required":["name"]}},"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"]}]}],"properties":{"status":{"description":"route status, 1 to enable, 0 to disable","default":1,"type":"integer","enum":[1,0]},"uris":{"minItems":1,"items":{"description":"HTTP uri","type":"string"},"type":"array","uniqueItems":true},"enable_websocket":{"description":"enable websocket for request","type":"boolean"},"methods":{"uniqueItems":true,"items":{"description":"HTTP method","type":"string","enum":["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS","CONNECT","TRACE"]},"type":"array"},"hosts":{"minItems":1,"items":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"type":"array","uniqueItems":true},"priority":{"type":"integer","default":0},"filter_func":{"minLength":10,"type":"string","pattern":"^function"},"script":{"minLength":10,"type":"string","maxLength":102400},"script_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"service_protocol":{"enum":["grpc","http"]},"plugins":{"type":"object"},"remote_addrs":{"minItems":1,"items":{"description":"client IP","type":"string","anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"type":"array","uniqueItems":true},"service_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"desc":{"type":"string","maxLength":256},"uri":{"minLength":1,"type":"string","maxLength":4096},"upstream":{"properties":{"retries":{"type":"integer","minimum":0},"retry_timeout":{"type":"number","minimum":0},"keepalive_pool":{"type":"object","properties":{"idle_timeout":{"minimum":0,"type":"number","default":60},"requests":{"minimum":1,"type":"integer","default":1000},"size":{"minimum":1,"type":"integer","default":320}}},"type":{"description":"algorithms of load balancing","type":"string"},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"discovery_type":{"description":"discovery type","type":"string"},"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"discovery_args":{"type":"object","properties":{"namespace_id":{"description":"namespace id","type":"string"},"group_name":{"description":"group name","type":"string"}}},"checks":{"anyOf":[{"required":["active"]},{"required":["active","passive"]}],"properties":{"active":{"type":"object","properties":{"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"req_headers":{"minItems":1,"items":{"type":"string","uniqueItems":true},"type":"array"},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"port":{"maximum":65535,"type":"integer","minimum":1},"healthy":{"type":"object","properties":{"interval":{"default":1,"type":"integer","minimum":1},"http_statuses":{"default":[200,302],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"successes":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":1},"http_statuses":{"default":[429,404,500,501,502,503,504,505],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"timeouts":{"default":3,"maximum":254,"type":"integer","minimum":1},"interval":{"default":1,"type":"integer","minimum":1},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"concurrency":{"type":"integer","default":10},"http_path":{"type":"string","default":"\/"},"https_verify_certificate":{"type":"boolean","default":true},"timeout":{"type":"number","default":1}}},"passive":{"properties":{"healthy":{"type":"object","properties":{"successes":{"default":5,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":0},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":0},"timeouts":{"default":7,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[429,500,503],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}}},"type":"object","default":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"type":"http","unhealthy":{"http_failures":0,"tcp_failures":0,"timeouts":0,"http_statuses":[429,500,503]}}}},"type":"object"},"service_name":{"minLength":1,"type":"string","maxLength":256},"desc":{"type":"string","maxLength":256},"key":{"description":"the key of chash for dynamic load balancing","type":"string"},"upstream_host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"pass_host":{"description":"mod of host passing","default":"pass","type":"string","enum":["pass","node","rewrite"]},"timeout":{"properties":{"connect":{"type":"number","exclusiveMinimum":0},"send":{"type":"number","exclusiveMinimum":0},"read":{"type":"number","exclusiveMinimum":0}},"type":"object","required":["connect","send","read"]},"hash_on":{"default":"vars","type":"string","enum":["vars","header","cookie","consumer","vars_combinations"]},"nodes":{"anyOf":[{"type":"object","patternProperties":{".*":{"description":"weight of node","type":"integer","minimum":0}}},{"type":"array","items":{"properties":{"weight":{"description":"weight of node","type":"integer","minimum":0},"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"priority":{"description":"priority of node","type":"integer","default":0},"metadata":{"description":"metadata of node","type":"object"},"port":{"description":"port of node","type":"integer","minimum":1}},"type":"object","required":["host","port","weight"]}}]},"scheme":{"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.","default":"http","enum":["grpc","grpcs","http","https","tcp","tls","udp"]},"tls":{"properties":{"client_cert":{"minLength":128,"type":"string","maxLength":65536},"client_key":{"minLength":128,"type":"string","maxLength":65536}},"type":"object","required":["client_cert","client_key"]},"create_time":{"type":"integer"}},"type":"object","oneOf":[{"required":["type","nodes"]},{"required":["type","service_name","discovery_type"]}]},"plugin_config_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"create_time":{"type":"integer"},"remote_addr":{"description":"client IP","type":"string","anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"upstream_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"vars":{"type":"array"},"timeout":{"properties":{"connect":{"type":"number","exclusiveMinimum":0},"send":{"type":"number","exclusiveMinimum":0},"read":{"type":"number","exclusiveMinimum":0}},"type":"object","required":["connect","send","read"]}},"not":{"anyOf":[{"required":["script","plugins"]},{"required":["script","plugin_config_id"]}]},"type":"object","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"]}]},"upstream":{"properties":{"retries":{"type":"integer","minimum":0},"retry_timeout":{"type":"number","minimum":0},"keepalive_pool":{"type":"object","properties":{"idle_timeout":{"minimum":0,"type":"number","default":60},"requests":{"minimum":1,"type":"integer","default":1000},"size":{"minimum":1,"type":"integer","default":320}}},"type":{"description":"algorithms of load balancing","type":"string"},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"discovery_type":{"description":"discovery type","type":"string"},"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"discovery_args":{"type":"object","properties":{"namespace_id":{"description":"namespace id","type":"string"},"group_name":{"description":"group name","type":"string"}}},"checks":{"anyOf":[{"required":["active"]},{"required":["active","passive"]}],"properties":{"active":{"type":"object","properties":{"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"req_headers":{"minItems":1,"items":{"type":"string","uniqueItems":true},"type":"array"},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"port":{"maximum":65535,"type":"integer","minimum":1},"healthy":{"type":"object","properties":{"interval":{"default":1,"type":"integer","minimum":1},"http_statuses":{"default":[200,302],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"successes":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":1},"http_statuses":{"default":[429,404,500,501,502,503,504,505],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"timeouts":{"default":3,"maximum":254,"type":"integer","minimum":1},"interval":{"default":1,"type":"integer","minimum":1},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"concurrency":{"type":"integer","default":10},"http_path":{"type":"string","default":"\/"},"https_verify_certificate":{"type":"boolean","default":true},"timeout":{"type":"number","default":1}}},"passive":{"properties":{"healthy":{"type":"object","properties":{"successes":{"default":5,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":0},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":0},"timeouts":{"default":7,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[429,500,503],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}}},"type":"object","default":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"type":"http","unhealthy":{"http_failures":0,"tcp_failures":0,"timeouts":0,"http_statuses":[429,500,503]}}}},"type":"object"},"service_name":{"minLength":1,"type":"string","maxLength":256},"desc":{"type":"string","maxLength":256},"key":{"description":"the key of chash for dynamic load balancing","type":"string"},"upstream_host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"pass_host":{"description":"mod of host passing","default":"pass","type":"string","enum":["pass","node","rewrite"]},"timeout":{"properties":{"connect":{"type":"number","exclusiveMinimum":0},"send":{"type":"number","exclusiveMinimum":0},"read":{"type":"number","exclusiveMinimum":0}},"type":"object","required":["connect","send","read"]},"hash_on":{"default":"vars","type":"string","enum":["vars","header","cookie","consumer","vars_combinations"]},"nodes":{"anyOf":[{"type":"object","patternProperties":{".*":{"description":"weight of node","type":"integer","minimum":0}}},{"type":"array","items":{"properties":{"weight":{"description":"weight of node","type":"integer","minimum":0},"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"priority":{"description":"priority of node","type":"integer","default":0},"metadata":{"description":"metadata of node","type":"object"},"port":{"description":"port of node","type":"integer","minimum":1}},"type":"object","required":["host","port","weight"]}}]},"scheme":{"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.","default":"http","enum":["grpc","grpcs","http","https","tcp","tls","udp"]},"tls":{"properties":{"client_cert":{"minLength":128,"type":"string","maxLength":65536},"client_key":{"minLength":128,"type":"string","maxLength":65536}},"type":"object","required":["client_cert","client_key"]},"create_time":{"type":"integer"}},"type":"object","oneOf":[{"required":["type","nodes"]},{"required":["type","service_name","discovery_type"]}]},"global_rule":{"properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"update_time":{"type":"integer"},"plugins":{"type":"object"},"create_time":{"type":"integer"}},"type":"object","required":["plugins"]},"stream_route":{"type":"object","properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"plugins":{"type":"object"},"remote_addr":{"description":"client IP","type":"string","anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"desc":{"type":"string","maxLength":256},"update_time":{"type":"integer"},"server_addr":{"description":"server IP","type":"string","anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"upstream_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"upstream":{"properties":{"retries":{"type":"integer","minimum":0},"retry_timeout":{"type":"number","minimum":0},"keepalive_pool":{"type":"object","properties":{"idle_timeout":{"minimum":0,"type":"number","default":60},"requests":{"minimum":1,"type":"integer","default":1000},"size":{"minimum":1,"type":"integer","default":320}}},"type":{"description":"algorithms of load balancing","type":"string"},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"discovery_type":{"description":"discovery type","type":"string"},"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"discovery_args":{"type":"object","properties":{"namespace_id":{"description":"namespace id","type":"string"},"group_name":{"description":"group name","type":"string"}}},"checks":{"anyOf":[{"required":["active"]},{"required":["active","passive"]}],"properties":{"active":{"type":"object","properties":{"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"req_headers":{"minItems":1,"items":{"type":"string","uniqueItems":true},"type":"array"},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"port":{"maximum":65535,"type":"integer","minimum":1},"healthy":{"type":"object","properties":{"interval":{"default":1,"type":"integer","minimum":1},"http_statuses":{"default":[200,302],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"successes":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":1},"http_statuses":{"default":[429,404,500,501,502,503,504,505],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"timeouts":{"default":3,"maximum":254,"type":"integer","minimum":1},"interval":{"default":1,"type":"integer","minimum":1},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"concurrency":{"type":"integer","default":10},"http_path":{"type":"string","default":"\/"},"https_verify_certificate":{"type":"boolean","default":true},"timeout":{"type":"number","default":1}}},"passive":{"properties":{"healthy":{"type":"object","properties":{"successes":{"default":5,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":0},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":0},"timeouts":{"default":7,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[429,500,503],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}}},"type":"object","default":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"type":"http","unhealthy":{"http_failures":0,"tcp_failures":0,"timeouts":0,"http_statuses":[429,500,503]}}}},"type":"object"},"service_name":{"minLength":1,"type":"string","maxLength":256},"desc":{"type":"string","maxLength":256},"key":{"description":"the key of chash for dynamic load balancing","type":"string"},"upstream_host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"pass_host":{"description":"mod of host passing","default":"pass","type":"string","enum":["pass","node","rewrite"]},"timeout":{"properties":{"connect":{"type":"number","exclusiveMinimum":0},"send":{"type":"number","exclusiveMinimum":0},"read":{"type":"number","exclusiveMinimum":0}},"type":"object","required":["connect","send","read"]},"hash_on":{"default":"vars","type":"string","enum":["vars","header","cookie","consumer","vars_combinations"]},"nodes":{"anyOf":[{"type":"object","patternProperties":{".*":{"description":"weight of node","type":"integer","minimum":0}}},{"type":"array","items":{"properties":{"weight":{"description":"weight of node","type":"integer","minimum":0},"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"priority":{"description":"priority of node","type":"integer","default":0},"metadata":{"description":"metadata of node","type":"object"},"port":{"description":"port of node","type":"integer","minimum":1}},"type":"object","required":["host","port","weight"]}}]},"scheme":{"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.","default":"http","enum":["grpc","grpcs","http","https","tcp","tls","udp"]},"tls":{"properties":{"client_cert":{"minLength":128,"type":"string","maxLength":65536},"client_key":{"minLength":128,"type":"string","maxLength":65536}},"type":"object","required":["client_cert","client_key"]},"create_time":{"type":"integer"}},"type":"object","oneOf":[{"required":["type","nodes"]},{"required":["type","service_name","discovery_type"]}]},"server_port":{"description":"server port","type":"integer"},"sni":{"description":"server name indication","type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"create_time":{"type":"integer"}}},"upstream_hash_vars_schema":{"type":"string","pattern":"^((uri|server_name|server_addr|request_uri|remote_port|remote_addr|query_string|host|hostname)|arg_[0-9a-zA-z_-]+)$"},"service":{"type":"object","properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"enable_websocket":{"description":"enable websocket for request","type":"boolean"},"plugins":{"type":"object"},"script":{"minLength":10,"type":"string","maxLength":102400},"hosts":{"minItems":1,"items":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"type":"array","uniqueItems":true},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"desc":{"type":"string","maxLength":256},"upstream":{"properties":{"retries":{"type":"integer","minimum":0},"retry_timeout":{"type":"number","minimum":0},"keepalive_pool":{"type":"object","properties":{"idle_timeout":{"minimum":0,"type":"number","default":60},"requests":{"minimum":1,"type":"integer","default":1000},"size":{"minimum":1,"type":"integer","default":320}}},"type":{"description":"algorithms of load balancing","type":"string"},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"discovery_type":{"description":"discovery type","type":"string"},"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"discovery_args":{"type":"object","properties":{"namespace_id":{"description":"namespace id","type":"string"},"group_name":{"description":"group name","type":"string"}}},"checks":{"anyOf":[{"required":["active"]},{"required":["active","passive"]}],"properties":{"active":{"type":"object","properties":{"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"req_headers":{"minItems":1,"items":{"type":"string","uniqueItems":true},"type":"array"},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"port":{"maximum":65535,"type":"integer","minimum":1},"healthy":{"type":"object","properties":{"interval":{"default":1,"type":"integer","minimum":1},"http_statuses":{"default":[200,302],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"successes":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":1},"http_statuses":{"default":[429,404,500,501,502,503,504,505],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"timeouts":{"default":3,"maximum":254,"type":"integer","minimum":1},"interval":{"default":1,"type":"integer","minimum":1},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"concurrency":{"type":"integer","default":10},"http_path":{"type":"string","default":"\/"},"https_verify_certificate":{"type":"boolean","default":true},"timeout":{"type":"number","default":1}}},"passive":{"properties":{"healthy":{"type":"object","properties":{"successes":{"default":5,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":0},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":0},"timeouts":{"default":7,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[429,500,503],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}}},"type":"object","default":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"type":"http","unhealthy":{"http_failures":0,"tcp_failures":0,"timeouts":0,"http_statuses":[429,500,503]}}}},"type":"object"},"service_name":{"minLength":1,"type":"string","maxLength":256},"desc":{"type":"string","maxLength":256},"key":{"description":"the key of chash for dynamic load balancing","type":"string"},"upstream_host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"pass_host":{"description":"mod of host passing","default":"pass","type":"string","enum":["pass","node","rewrite"]},"timeout":{"properties":{"connect":{"type":"number","exclusiveMinimum":0},"send":{"type":"number","exclusiveMinimum":0},"read":{"type":"number","exclusiveMinimum":0}},"type":"object","required":["connect","send","read"]},"hash_on":{"default":"vars","type":"string","enum":["vars","header","cookie","consumer","vars_combinations"]},"nodes":{"anyOf":[{"type":"object","patternProperties":{".*":{"description":"weight of node","type":"integer","minimum":0}}},{"type":"array","items":{"properties":{"weight":{"description":"weight of node","type":"integer","minimum":0},"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"priority":{"description":"priority of node","type":"integer","default":0},"metadata":{"description":"metadata of node","type":"object"},"port":{"description":"port of node","type":"integer","minimum":1}},"type":"object","required":["host","port","weight"]}}]},"scheme":{"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.","default":"http","enum":["grpc","grpcs","http","https","tcp","tls","udp"]},"tls":{"properties":{"client_cert":{"minLength":128,"type":"string","maxLength":65536},"client_key":{"minLength":128,"type":"string","maxLength":65536}},"type":"object","required":["client_cert","client_key"]},"create_time":{"type":"integer"}},"type":"object","oneOf":[{"required":["type","nodes"]},{"required":["type","service_name","discovery_type"]}]},"upstream_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"create_time":{"type":"integer"}}},"upstream_hash_header_schema":{"type":"string","pattern":"^[a-zA-Z0-9-_]+$"},"plugin_config":{"properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"update_time":{"type":"integer"},"plugins":{"type":"object"},"create_time":{"type":"integer"},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"desc":{"type":"string","maxLength":256}},"type":"object","required":["id","plugins"]},"ssl":{"properties":{"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"validity_end":{"type":"integer"},"status":{"description":"ssl status, 1 to enable, 0 to disable","default":1,"type":"integer","enum":[1,0]},"keys":{"type":"array","items":{"minLength":128,"type":"string","maxLength":65536}},"validity_start":{"type":"integer"},"client":{"properties":{"depth":{"default":1,"type":"integer","minimum":0},"ca":{"minLength":128,"type":"string","maxLength":65536}},"type":"object","required":["ca"]},"cert":{"minLength":128,"type":"string","maxLength":65536},"exptime":{"type":"integer","minimum":1588262400},"update_time":{"type":"integer"},"sni":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"key":{"minLength":128,"type":"string","maxLength":65536},"snis":{"minItems":1,"items":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"type":"array"},"certs":{"type":"array","items":{"minLength":128,"type":"string","maxLength":65536}},"create_time":{"type":"integer"}},"type":"object","oneOf":[{"required":["sni","key","cert"]},{"required":["snis","key","cert"]}]},"consumer":{"properties":{"update_time":{"type":"integer"},"username":{"pattern":"^[a-zA-Z0-9_]+$","minLength":1,"type":"string","maxLength":100},"plugins":{"type":"object"},"desc":{"type":"string","maxLength":256},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"create_time":{"type":"integer"}},"type":"object","required":["username"]}},"stream_plugins":{"ip-restriction":{"version":0.1,"priority":3000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"whitelist":{"minItems":1,"items":{"anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"type":"array"},"blacklist":{"minItems":1,"items":{"anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"type":"array"},"message":{"default":"Your IP address is not allowed","minLength":1,"type":"string","maxLength":1024},"disable":{"type":"boolean"}},"type":"object","oneOf":[{"required":["whitelist"]},{"required":["blacklist"]}]}},"limit-conn":{"version":0.1,"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"key_type":{"default":"var","type":"string","enum":["var","var_combination"]},"disable":{"type":"boolean"},"burst":{"type":"integer","minimum":0},"default_conn_delay":{"type":"number","exclusiveMinimum":0},"only_use_default_delay":{"type":"boolean","default":false},"conn":{"type":"integer","exclusiveMinimum":0},"key":{"type":"string"}},"type":"object","required":["conn","burst","default_conn_delay","key"]}},"mqtt-proxy":{"version":0.1,"priority":1000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"protocol_level":{"type":"integer"},"upstream":{"description":"Deprecated. We should configure upstream outside of the plugin","properties":{"ip":{"type":"string"},"host":{"type":"string"},"port":{"type":"number"}},"type":"object","oneOf":[{"required":["host","port"]},{"required":["ip","port"]}]},"disable":{"type":"boolean"},"protocol_name":{"type":"string"}},"type":"object","required":["protocol_name","protocol_level"]}}},"plugins":{"api-breaker":{"version":0.1,"priority":1005,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"healthy":{"properties":{"successes":{"default":3,"type":"integer","minimum":1},"http_statuses":{"default":[200],"minItems":1,"items":{"maximum":499,"type":"integer","minimum":200},"type":"array","uniqueItems":true}},"type":"object","default":{"successes":3,"http_statuses":[200]}},"disable":{"type":"boolean"},"break_response_code":{"maximum":599,"type":"integer","minimum":200},"max_breaker_sec":{"default":300,"type":"integer","minimum":3},"unhealthy":{"properties":{"failures":{"default":3,"type":"integer","minimum":1},"http_statuses":{"default":[500],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":500},"type":"array","uniqueItems":true}},"type":"object","default":{"failures":3,"http_statuses":[500]}}},"type":"object","required":["break_response_code"]}},"http-logger":{"version":0.1,"priority":410,"metadata_schema":{"type":"object","properties":{"log_format":{"type":"object","default":{"client_ip":"$remote_addr","host":"$host","@timestamp":"$time_iso8601"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"include_resp_body":{"type":"boolean","default":false},"include_resp_body_expr":{"minItems":1,"items":{"type":"array"},"type":"array"},"concat_method":{"default":"json","type":"string","enum":["json","new_line"]},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"disable":{"type":"boolean"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"uri":{"type":"string","pattern":"^[^\\\/]+:\\\/\\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?"},"include_req_body":{"type":"boolean","default":false},"name":{"type":"string","default":"http logger"},"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"ssl_verify":{"type":"boolean","default":false},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"auth_header":{"type":"string","default":""},"timeout":{"default":3,"type":"integer","minimum":1}},"type":"object","required":["uri"]}},"tcp-logger":{"version":0.1,"priority":405,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"tls":{"type":"boolean","default":false},"host":{"type":"string"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"tls_options":{"type":"string"},"port":{"type":"integer","minimum":0},"disable":{"type":"boolean"},"name":{"type":"string","default":"tcp logger"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"timeout":{"default":1000,"type":"integer","minimum":1},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"include_req_body":{"type":"boolean","default":false}},"type":"object","required":["host","port"]}},"kafka-logger":{"version":0.1,"priority":403,"metadata_schema":{"type":"object","properties":{"log_format":{"type":"object","default":{"client_ip":"$remote_addr","host":"$host","@timestamp":"$time_iso8601"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"include_resp_body":{"type":"boolean","default":false},"include_resp_body_expr":{"minItems":1,"items":{"type":"array"},"type":"array"},"disable":{"type":"boolean"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"meta_format":{"default":"default","type":"string","enum":["default","origin"]},"name":{"type":"string","default":"kafka logger"},"kafka_topic":{"type":"string"},"producer_type":{"default":"async","type":"string","enum":["async","sync"]},"required_acks":{"default":1,"type":"integer","enum":[0,1,-1]},"cluster_name":{"default":1,"type":"integer","minimum":1},"key":{"type":"string"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"include_req_body_expr":{"minItems":1,"items":{"type":"array"},"type":"array"},"broker_list":{"patternProperties":{".*":{"description":"the port of kafka broker","maximum":65535,"type":"integer","minimum":1}},"type":"object","minProperties":1},"include_req_body":{"type":"boolean","default":false},"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"timeout":{"default":3,"type":"integer","minimum":1}},"type":"object","required":["broker_list","kafka_topic"]}},"grpc-transcode":{"version":0.1,"priority":506,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"method":{"description":"the method name in the grpc service.","type":"string"},"disable":{"type":"boolean"},"service":{"description":"the grpc service name","type":"string"},"pb_option":{"minItems":1,"items":{"type":"string","anyOf":[{"description":"enum as result","type":"string","enum":["int64_as_number","int64_as_string","int64_as_hexstring"]},{"description":"int64 as result","type":"string","enum":["enum_as_name","enum_as_value"]},{"description":"default values option","type":"string","enum":["auto_default_values","no_default_values","use_default_values","use_default_metatable"]},{"description":"hooks option","type":"string","enum":["enable_hooks","disable_hooks"]}]},"type":"array"},"proto_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"deadline":{"description":"deadline for grpc, millisecond","type":"number","default":0}},"required":["proto_id","service","method"],"additionalProperties":true,"type":"object"}},"limit-req":{"version":0.1,"priority":1001,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"rejected_code":{"default":503,"maximum":599,"type":"integer","minimum":200},"rejected_msg":{"type":"string","minLength":1},"nodelay":{"type":"boolean","default":false},"allow_degradation":{"type":"boolean","default":false},"key":{"type":"string"},"disable":{"type":"boolean"},"rate":{"type":"number","exclusiveMinimum":0},"burst":{"type":"number","minimum":0},"key_type":{"default":"var","type":"string","enum":["var","var_combination"]}},"type":"object","required":["rate","burst","key"]}},"limit-conn":{"version":0.1,"priority":1003,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"rejected_code":{"default":503,"maximum":599,"type":"integer","minimum":200},"rejected_msg":{"type":"string","minLength":1},"default_conn_delay":{"type":"number","exclusiveMinimum":0},"only_use_default_delay":{"type":"boolean","default":false},"key":{"type":"string"},"disable":{"type":"boolean"},"allow_degradation":{"type":"boolean","default":false},"conn":{"type":"integer","exclusiveMinimum":0},"burst":{"type":"integer","minimum":0},"key_type":{"default":"var","type":"string","enum":["var","var_combination"]}},"type":"object","required":["conn","burst","default_conn_delay","key"]}},"authz-keycloak":{"version":0.1,"priority":2000,"schema":{"allOf":[{"anyOf":[{"required":["discovery"]},{"required":["token_endpoint"]}]},{"anyOf":[{"required":["client_id"]},{"required":["audience"]}]},{"anyOf":[{"properties":{"lazy_load_paths":{"enum":[false]}}},{"anyOf":[{"required":["discovery"]},{"required":["resource_registration_endpoint"]}],"properties":{"lazy_load_paths":{"enum":[true]}}}]}],"properties":{"disable":{"type":"boolean"},"keepalive_pool":{"default":5,"type":"integer","minimum":1},"token_endpoint":{"minLength":1,"type":"string","maxLength":4096},"resource_registration_endpoint":{"minLength":1,"type":"string","maxLength":4096},"audience":{"description":"Deprecated, use `client_id` instead.","minLength":1,"type":"string","maxLength":100},"keepalive":{"type":"boolean","default":true},"client_secret":{"minLength":1,"type":"string","maxLength":100},"grant_type":{"minLength":1,"default":"urn:ietf:params:oauth:grant-type:uma-ticket","maxLength":100,"type":"string","enum":["urn:ietf:params:oauth:grant-type:uma-ticket"]},"ssl_verify":{"type":"boolean","default":true},"policy_enforcement_mode":{"default":"ENFORCING","type":"string","enum":["ENFORCING","PERMISSIVE"]},"lazy_load_paths":{"type":"boolean","default":false},"http_method_as_scope":{"type":"boolean","default":false},"cache_ttl_seconds":{"default":86400,"type":"integer","minimum":1},"access_denied_redirect_uri":{"minLength":1,"type":"string","maxLength":2048},"client_id":{"minLength":1,"type":"string","maxLength":100},"access_token_expires_leeway":{"default":0,"type":"integer","minimum":0},"discovery":{"minLength":1,"type":"string","maxLength":4096},"refresh_token_expires_leeway":{"default":0,"type":"integer","minimum":0},"refresh_token_expires_in":{"default":3600,"type":"integer","minimum":1},"access_token_expires_in":{"default":300,"type":"integer","minimum":1},"keepalive_timeout":{"default":60000,"type":"integer","minimum":1000},"permissions":{"uniqueItems":true,"items":{"minLength":1,"type":"string","maxLength":100},"type":"array","default":{}},"timeout":{"default":3000,"type":"integer","minimum":1000}},"type":"object","$comment":"this is a mark for our injected plugin schema"}},"udp-logger":{"version":0.1,"priority":400,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"host":{"type":"string"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"port":{"type":"integer","minimum":0},"disable":{"type":"boolean"},"name":{"type":"string","default":"udp logger"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"include_req_body":{"type":"boolean","default":false},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"timeout":{"default":3,"type":"integer","minimum":1}},"type":"object","required":["host","port"]}},"key-auth":{"consumer_schema":{"properties":{"key":{"type":"string"}},"type":"object","required":["key"]},"version":0.1,"priority":2500,"type":"auth","schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"header":{"type":"string","default":"apikey"},"disable":{"type":"boolean"},"query":{"type":"string","default":"apikey"}},"type":"object"}},"hmac-auth":{"consumer_schema":{"title":"work with consumer object","properties":{"keep_headers":{"title":"whether to keep the http request header","type":"boolean","default":false},"encode_uri_params":{"title":"Whether to escape the uri parameter","type":"boolean","default":true},"validate_request_body":{"title":"A boolean value telling the plugin to enable body validation","type":"boolean","default":false},"max_req_body":{"title":"Max request body size","type":"integer","default":524288},"access_key":{"minLength":1,"type":"string","maxLength":256},"secret_key":{"minLength":1,"type":"string","maxLength":256},"algorithm":{"default":"hmac-sha256","type":"string","enum":["hmac-sha1","hmac-sha256","hmac-sha512"]},"clock_skew":{"type":"integer","default":0},"signed_headers":{"type":"array","items":{"minLength":1,"type":"string","maxLength":50}}},"type":"object","required":["access_key","secret_key"]},"version":0.1,"priority":2530,"type":"auth","schema":{"title":"work with route or service object","properties":{"disable":{"type":"boolean"}},"type":"object","$comment":"this is a mark for our injected plugin schema"}},"gzip":{"version":0.1,"priority":995,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"min_length":{"default":20,"type":"integer","minimum":1},"types":{"anyOf":[{"minItems":1,"items":{"type":"string","minLength":1},"type":"array"},{"enum":["*"]}],"default":["text\/html"]},"vary":{"type":"boolean"},"buffers":{"properties":{"size":{"default":4096,"type":"integer","minimum":1},"number":{"default":32,"type":"integer","minimum":1}},"type":"object","default":{"size":4096,"number":32}},"disable":{"type":"boolean"},"comp_level":{"default":1,"maximum":9,"type":"integer","minimum":1},"http_version":{"default":1.1,"enum":[1.1,1]}},"type":"object"}},"pj-auth":{"version":0.1,"priority":1999,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"address":{"type":"string","default":"portal-server.paas-portal.svc.cluster.local:8080"}},"type":"object"}},"grpc-web":{"version":0.1,"priority":505,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"}},"type":"object"}},"basic-auth":{"consumer_schema":{"title":"work with consumer object","properties":{"username":{"type":"string"},"password":{"type":"string"}},"type":"object","required":["username","password"]},"version":0.1,"priority":2520,"type":"auth","schema":{"title":"work with route or service object","properties":{"hide_credentials":{"type":"boolean","default":false},"disable":{"type":"boolean"}},"type":"object","$comment":"this is a mark for our injected plugin schema"}},"authz-casbin":{"version":0.1,"priority":2560,"metadata_schema":{"properties":{"model":{"type":"string"},"policy":{"type":"string"}},"type":"object","required":["model","policy"]},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"model":{"type":"string"},"policy":{"type":"string"},"username":{"type":"string"},"disable":{"type":"boolean"},"model_path":{"type":"string"},"policy_path":{"type":"string"}},"type":"object","oneOf":[{"required":["model_path","policy_path","username"]},{"required":["model","policy","username"]}]}},"zipkin":{"version":0.1,"priority":12011,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"endpoint":{"type":"string"},"server_addr":{"description":"default is $server_addr, you can specify your external ip address","type":"string","pattern":"^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"},"disable":{"type":"boolean"},"service_name":{"description":"service name for zipkin reporter","type":"string","default":"APISIX"},"span_version":{"default":2,"enum":[1,2]},"sample_ratio":{"maximum":1,"type":"number","minimum":1e-05}},"type":"object","required":["endpoint","sample_ratio"]}},"clickhouse-logger":{"version":0.1,"priority":398,"metadata_schema":{"type":"object","properties":{"log_format":{"type":"object","default":{"client_ip":"$remote_addr","host":"$host","@timestamp":"$time_iso8601"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"endpoint_addr":{"type":"string","pattern":"^[^\\\/]+:\\\/\\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"disable":{"type":"boolean"},"user":{"type":"string","default":""},"database":{"type":"string","default":""},"logtable":{"type":"string","default":""},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"name":{"type":"string","default":"clickhouse-logger"},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"ssl_verify":{"type":"boolean","default":true},"password":{"type":"string","default":""},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"timeout":{"default":3,"type":"integer","minimum":1}},"type":"object","required":["endpoint_addr","user","password","database","logtable"]}},"referer-restriction":{"version":0.1,"priority":2990,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"bypass_missing":{"type":"boolean","default":false},"disable":{"type":"boolean"},"whitelist":{"minItems":1,"items":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"type":"array"},"blacklist":{"minItems":1,"items":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"type":"array"},"message":{"default":"Your referer host is not allowed","minLength":1,"type":"string","maxLength":1024}},"type":"object","oneOf":[{"required":["whitelist"]},{"required":["blacklist"]}]}},"proxy-rewrite":{"version":0.1,"priority":1008,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"uri":{"description":"new uri for upstream","minLength":1,"maxLength":4096,"type":"string","pattern":"^\\\/.*"},"method":{"description":"proxy route method","type":"string","enum":["HEAD","POST","PUT","DELETE","MKCOL","COPY","MOVE","OPTIONS","PROPFIND","LOCK","UNLOCK","PATCH","TRACE","GET"]},"regex_uri":{"description":"new uri that substitute from client uri for upstream, lower priority than uri property","maxItems":2,"minItems":2,"items":{"description":"regex uri","type":"string"},"type":"array"},"headers":{"description":"new headers for request","type":"object","minProperties":1},"scheme":{"description":"new scheme for upstream","type":"string","enum":["http","https"]},"disable":{"type":"boolean"},"host":{"description":"new host for upstream","type":"string","pattern":"^[0-9a-zA-Z-.]+(:\\d{1,5})?$"}},"type":"object","minProperties":1}},"limit-count":{"version":0.4,"priority":1002,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"count":{"type":"integer","exclusiveMinimum":0},"rejected_msg":{"type":"string","minLength":1},"allow_degradation":{"type":"boolean","default":false},"key":{"type":"string","default":"remote_addr"},"policy":{"default":"local","type":"string","enum":["local","redis","redis-cluster"]},"disable":{"type":"boolean"},"time_window":{"type":"integer","exclusiveMinimum":0},"show_limit_quota_header":{"type":"boolean","default":true},"rejected_code":{"default":503,"maximum":599,"type":"integer","minimum":200},"group":{"type":"string"},"key_type":{"default":"var","type":"string","enum":["var","var_combination","constant"]}},"if":{"properties":{"policy":{"enum":["redis"]}}},"required":["count","time_window"],"else":{"if":{"properties":{"policy":{"enum":["redis-cluster"]}}},"then":{"required":["redis_cluster_nodes","redis_cluster_name"],"properties":{"redis_cluster_nodes":{"minItems":2,"items":{"minLength":2,"type":"string","maxLength":100},"type":"array"},"redis_password":{"type":"string","minLength":0},"redis_cluster_name":{"type":"string"},"redis_timeout":{"default":1000,"type":"integer","minimum":1}}}},"type":"object","then":{"required":["redis_host"],"properties":{"redis_host":{"type":"string","minLength":2},"redis_port":{"default":6379,"type":"integer","minimum":1},"redis_password":{"type":"string","minLength":0},"redis_database":{"default":0,"type":"integer","minimum":0},"redis_timeout":{"default":1000,"type":"integer","minimum":1}}}}},"node-status":{"version":0.1,"priority":1000,"scope":"global","schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"}},"type":"object"}},"cors":{"version":0.1,"priority":4000,"metadata_schema":{"type":"object","properties":{"allow_origins":{"type":"object","additionalProperties":{"type":"string","pattern":"^(\\*|\\*\\*|null|\\w+:\/\/[^,]+(,\\w+:\/\/[^,]+)*)$"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"allow_credential":{"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","default":false},"max_age":{"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","default":5},"allow_methods":{"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","default":"*"},"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","minItems":1,"items":{"minLength":1,"type":"string","maxLength":4096},"type":"array","uniqueItems":true},"allow_origins":{"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: *.","default":"*","type":"string","pattern":"^(\\*|\\*\\*|null|\\w+:\/\/[^,]+(,\\w+:\/\/[^,]+)*)$"},"expose_headers":{"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","default":"*"},"allow_origins_by_metadata":{"description":"set allowed origins by referencing origins in plugin metadata","minItems":1,"items":{"minLength":1,"type":"string","maxLength":4096},"type":"array","uniqueItems":true},"allow_headers":{"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","default":"*"}},"type":"object"}},"redirect":{"version":0.1,"priority":900,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"ret_code":{"default":302,"type":"integer","minimum":200},"regex_uri":{"description":"params for generating new uri that substitute from client uri, first param is regular expression, the second one is uri template","maxItems":2,"minItems":2,"items":{"description":"regex uri","type":"string"},"type":"array"},"http_to_https":{"type":"boolean"},"encode_uri":{"type":"boolean","default":false},"append_query_string":{"type":"boolean","default":false},"disable":{"type":"boolean"},"uri":{"minLength":2,"type":"string","pattern":"(\\\\\\$[0-9a-zA-Z_]+)|\\$\\{([0-9a-zA-Z_]+)\\}|\\$([0-9a-zA-Z_]+)|(\\$|[^$\\\\]+)"}},"type":"object","oneOf":[{"required":["uri"]},{"required":["regex_uri"]},{"required":["http_to_https"]}]}},"ext-plugin-pre-req":{"version":0.1,"priority":12000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"allow_degradation":{"type":"boolean","default":false},"conf":{"minItems":1,"items":{"properties":{"name":{"minLength":1,"type":"string","maxLength":128},"value":{"type":"string"}},"type":"object","required":["name","value"]},"type":"array"},"disable":{"type":"boolean"}},"type":"object"}},"proxy-mirror":{"version":0.1,"priority":1010,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"sample_ratio":{"default":1,"maximum":1,"type":"number","minimum":1e-05},"host":{"type":"string","pattern":"^http(s)?:\\\/\\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?$"},"path":{"type":"string","pattern":"^\/[^?&]+$"}},"type":"object","required":["host"]}},"sls-logger":{"version":0.1,"priority":406,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"host":{"type":"string"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"disable":{"type":"boolean"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"project":{"type":"string"},"logstore":{"type":"string"},"access_key_id":{"type":"string"},"access_key_secret":{"type":"string"},"name":{"type":"string","default":"sls-logger"},"timeout":{"default":5000,"type":"integer","minimum":1},"port":{"type":"integer"},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"include_req_body":{"type":"boolean","default":false}},"type":"object","required":["host","port","project","logstore","access_key_id","access_key_secret"]}},"aws-lambda":{"version":0.1,"priority":-1899,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"authorization":{"type":"object","properties":{"iam":{"properties":{"service":{"description":"the service that is receiving the request","type":"string","default":"execute-api"},"accesskey":{"type":"string","description":"access key id from from aws iam console"},"aws_region":{"description":"the aws region that is receiving the request","type":"string","default":"us-east-1"},"secretkey":{"type":"string","description":"secret access key from from aws iam console"}},"type":"object","required":["accesskey","secretkey"]},"apikey":{"type":"string"}}},"keepalive":{"type":"boolean","default":true},"keepalive_timeout":{"default":60000,"type":"integer","minimum":1000},"disable":{"type":"boolean"},"ssl_verify":{"type":"boolean","default":true},"keepalive_pool":{"default":5,"type":"integer","minimum":1},"function_uri":{"type":"string"},"timeout":{"default":3000,"type":"integer","minimum":100}},"type":"object","required":["function_uri"]}},"log-rotate":{"version":0.1,"priority":100,"scope":"global","schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"}},"type":"object"}},"ext-plugin-post-req":{"version":0.1,"priority":-3000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"allow_degradation":{"type":"boolean","default":false},"conf":{"minItems":1,"items":{"properties":{"name":{"minLength":1,"type":"string","maxLength":128},"value":{"type":"string"}},"type":"object","required":["name","value"]},"type":"array"},"disable":{"type":"boolean"}},"type":"object"}},"real-ip":{"version":0.1,"priority":23000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"source":{"type":"string","minLength":1},"trusted_addresses":{"minItems":1,"items":{"anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"type":"array"},"disable":{"type":"boolean"}},"type":"object","required":["source"]}},"splunk-hec-logging":{"version":0.1,"priority":409,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"endpoint":{"properties":{"uri":{"type":"string","pattern":"^[^\\\/]+:\\\/\\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?"},"timeout":{"default":10,"type":"integer","minimum":1},"token":{"type":"string"},"channel":{"type":"string"}},"type":"object","required":["uri","token"]},"disable":{"type":"boolean"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"name":{"type":"string","default":"splunk-hec-logging"},"ssl_verify":{"type":"boolean","default":true},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"}},"type":"object","required":["endpoint"]}},"response-rewrite":{"version":0.1,"priority":899,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"body":{"description":"new body for response","type":"string"},"body_base64":{"description":"whether new body for response need base64 decode before return","type":"boolean","default":false},"disable":{"type":"boolean"},"headers":{"description":"new headers for response","type":"object","minProperties":1},"status_code":{"description":"new status code for response","maximum":598,"type":"integer","minimum":200},"vars":{"type":"array"}},"type":"object","minProperties":1}},"traffic-split":{"version":0.1,"priority":966,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"rules":{"type":"array","items":{"type":"object","properties":{"weighted_upstreams":{"maxItems":20,"default":[{"weight":1}],"minItems":1,"items":{"type":"object","properties":{"weight":{"description":"used to split traffic between differentupstreams for plugin configuration","minimum":0,"type":"integer","default":1},"upstream_id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"upstream":{"properties":{"retries":{"type":"integer","minimum":0},"retry_timeout":{"type":"number","minimum":0},"keepalive_pool":{"type":"object","properties":{"idle_timeout":{"minimum":0,"type":"number","default":60},"requests":{"minimum":1,"type":"integer","default":1000},"size":{"minimum":1,"type":"integer","default":320}}},"type":{"description":"algorithms of load balancing","type":"string"},"update_time":{"type":"integer"},"name":{"minLength":1,"type":"string","maxLength":100},"labels":{"description":"key\/value pairs to specify attributes","type":"object","patternProperties":{".*":{"description":"value of label","minLength":1,"maxLength":64,"type":"string","pattern":"^\\S+$"}}},"discovery_type":{"description":"discovery type","type":"string"},"id":{"anyOf":[{"pattern":"^[a-zA-Z0-9-_.]+$","minLength":1,"type":"string","maxLength":64},{"type":"integer","minimum":1}]},"discovery_args":{"type":"object","properties":{"namespace_id":{"description":"namespace id","type":"string"},"group_name":{"description":"group name","type":"string"}}},"checks":{"anyOf":[{"required":["active"]},{"required":["active","passive"]}],"properties":{"active":{"type":"object","properties":{"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"req_headers":{"minItems":1,"items":{"type":"string","uniqueItems":true},"type":"array"},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"port":{"maximum":65535,"type":"integer","minimum":1},"healthy":{"type":"object","properties":{"interval":{"default":1,"type":"integer","minimum":1},"http_statuses":{"default":[200,302],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"successes":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":1},"http_statuses":{"default":[429,404,500,501,502,503,504,505],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"timeouts":{"default":3,"maximum":254,"type":"integer","minimum":1},"interval":{"default":1,"type":"integer","minimum":1},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":1}}},"concurrency":{"type":"integer","default":10},"http_path":{"type":"string","default":"\/"},"https_verify_certificate":{"type":"boolean","default":true},"timeout":{"type":"number","default":1}}},"passive":{"properties":{"healthy":{"type":"object","properties":{"successes":{"default":5,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}},"type":{"default":"http","type":"string","enum":["http","https","tcp"]},"unhealthy":{"type":"object","properties":{"http_failures":{"default":5,"maximum":254,"type":"integer","minimum":0},"tcp_failures":{"default":2,"maximum":254,"type":"integer","minimum":0},"timeouts":{"default":7,"maximum":254,"type":"integer","minimum":0},"http_statuses":{"default":[429,500,503],"minItems":1,"items":{"maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true}}}},"type":"object","default":{"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]},"type":"http","unhealthy":{"http_failures":0,"tcp_failures":0,"timeouts":0,"http_statuses":[429,500,503]}}}},"type":"object"},"service_name":{"minLength":1,"type":"string","maxLength":256},"desc":{"type":"string","maxLength":256},"key":{"description":"the key of chash for dynamic load balancing","type":"string"},"upstream_host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"pass_host":{"description":"mod of host passing","default":"pass","type":"string","enum":["pass","node","rewrite"]},"timeout":{"properties":{"connect":{"type":"number","exclusiveMinimum":0},"send":{"type":"number","exclusiveMinimum":0},"read":{"type":"number","exclusiveMinimum":0}},"type":"object","required":["connect","send","read"]},"hash_on":{"default":"vars","type":"string","enum":["vars","header","cookie","consumer","vars_combinations"]},"nodes":{"anyOf":[{"type":"object","patternProperties":{".*":{"description":"weight of node","type":"integer","minimum":0}}},{"type":"array","items":{"properties":{"weight":{"description":"weight of node","type":"integer","minimum":0},"host":{"type":"string","pattern":"^\\*?[0-9a-zA-Z-._]+$"},"priority":{"description":"priority of node","type":"integer","default":0},"metadata":{"description":"metadata of node","type":"object"},"port":{"description":"port of node","type":"integer","minimum":1}},"type":"object","required":["host","port","weight"]}}]},"scheme":{"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.","default":"http","enum":["grpc","grpcs","http","https","tcp","tls","udp"]},"tls":{"properties":{"client_cert":{"minLength":128,"type":"string","maxLength":65536},"client_key":{"minLength":128,"type":"string","maxLength":65536}},"type":"object","required":["client_cert","client_key"]},"create_time":{"type":"integer"}},"type":"object","oneOf":[{"required":["type","nodes"]},{"required":["type","service_name","discovery_type"]}]}}},"type":"array"},"match":{"type":"array","items":{"type":"object","properties":{"vars":{"type":"array"}}}}}}}},"type":"object"}},"prometheus":{"version":0.2,"priority":500,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"prefer_name":{"type":"boolean","default":false}},"type":"object"}},"skywalking-logger":{"version":0.1,"priority":408,"metadata_schema":{"type":"object","properties":{"log_format":{"type":"object","default":{"client_ip":"$remote_addr","host":"$host","@timestamp":"$time_iso8601"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"service_name":{"type":"string","default":"APISIX"},"endpoint_addr":{"type":"string","pattern":"^[^\\\/]+:\\\/\\\/([\\da-zA-Z.-]+|\\[[\\da-fA-F:]+\\])(:\\d+)?"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"disable":{"type":"boolean"},"service_instance_name":{"type":"string","default":"APISIX Instance Name"},"name":{"type":"string","default":"skywalking logger"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"timeout":{"default":3,"type":"integer","minimum":1},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"include_req_body":{"type":"boolean","default":false}},"type":"object","required":["endpoint_addr"]}},"ldap-auth":{"consumer_schema":{"title":"work with consumer object","properties":{"user_dn":{"type":"string"}},"type":"object","required":["user_dn"]},"version":0.1,"priority":2540,"type":"auth","schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"uid":{"type":"string"},"disable":{"type":"boolean"},"base_dn":{"type":"string"},"ldap_uri":{"type":"string"},"use_tls":{"type":"boolean"}},"required":["base_dn","ldap_uri"],"title":"work with route or service object","type":"object"}},"jwt-auth":{"consumer_schema":{"dependencies":{"algorithm":{"oneOf":[{"properties":{"algorithm":{"default":"HS256","enum":["HS256","HS512"]}}},{"required":["public_key","private_key"],"properties":{"public_key":{"type":"string"},"private_key":{"type":"string"},"algorithm":{"enum":["RS256"]}}},{"required":["vault"],"properties":{"vault":{"type":"object","properties":{}},"algorithm":{"enum":["RS256"]}}}]}},"properties":{"vault":{"type":"object","properties":{}},"algorithm":{"default":"HS256","type":"string","enum":["HS256","HS512","RS256"]},"secret":{"type":"string"},"exp":{"default":86400,"type":"integer","minimum":1},"base64_secret":{"type":"boolean","default":false},"key":{"type":"string"}},"type":"object","required":["key"]},"version":0.1,"priority":2510,"type":"auth","schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"cookie":{"type":"string","default":"jwt"},"header":{"type":"string","default":"authorization"},"disable":{"type":"boolean"},"query":{"type":"string","default":"jwt"}},"type":"object"}},"public-api":{"version":0.1,"priority":501,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"uri":{"type":"string"},"disable":{"type":"boolean"}},"type":"object"}},"ua-restriction":{"version":0.1,"priority":2999,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"bypass_missing":{"type":"boolean","default":false},"disable":{"type":"boolean"},"allowlist":{"minItems":1,"items":{"type":"string","minLength":1},"type":"array"},"denylist":{"minItems":1,"items":{"type":"string","minLength":1},"type":"array"},"message":{"default":"Not allowed","minLength":1,"type":"string","maxLength":1024}},"type":"object"}},"file-logger":{"version":0.1,"priority":399,"metadata_schema":{"type":"object","properties":{"log_format":{"type":"object","default":{"client_ip":"$remote_addr","host":"$host","@timestamp":"$time_iso8601"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"path":{"type":"string"}},"type":"object","required":["path"]}},"server-info":{"scope":"global","priority":990,"version":0.1,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"}},"type":"object"}},"rocketmq-logger":{"version":0.1,"priority":402,"metadata_schema":{"type":"object","properties":{"log_format":{"type":"object","default":{"client_ip":"$remote_addr","host":"$host","@timestamp":"$time_iso8601"}}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"include_resp_body":{"type":"boolean","default":false},"include_resp_body_expr":{"minItems":1,"items":{"type":"array"},"type":"array"},"disable":{"type":"boolean"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"nameserver_list":{"minItems":1,"items":{"type":"string"},"type":"array"},"topic":{"type":"string"},"meta_format":{"default":"default","type":"string","enum":["default","origin"]},"name":{"type":"string","default":"rocketmq logger"},"use_tls":{"type":"boolean","default":false},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"include_req_body_expr":{"minItems":1,"items":{"type":"array"},"type":"array"},"key":{"type":"string"},"access_key":{"type":"string","default":""},"secret_key":{"type":"string","default":""},"tag":{"type":"string"},"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"timeout":{"default":3,"type":"integer","minimum":1},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"include_req_body":{"type":"boolean","default":false}},"type":"object","required":["nameserver_list","topic"]}},"ip-restriction":{"version":0.1,"priority":3000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"whitelist":{"minItems":1,"items":{"anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"type":"array"},"blacklist":{"minItems":1,"items":{"anyOf":[{"title":"IPv4","type":"string","format":"ipv4"},{"title":"IPv4\/CIDR","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":"IPv6","type":"string","format":"ipv6"},{"title":"IPv6\/CIDR","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}$"}]},"type":"array"},"message":{"default":"Your IP address is not allowed","minLength":1,"type":"string","maxLength":1024},"disable":{"type":"boolean"}},"type":"object","oneOf":[{"required":["whitelist"]},{"required":["blacklist"]}]}},"mocking":{"version":0.1,"priority":10900,"schema":{"anyOf":[{"required":["response_example"]},{"required":["response_schema"]}],"properties":{"response_status":{"minimum":100,"type":"integer","default":200},"content_type":{"type":"string","default":"application\/json;charset=utf8"},"response_example":{"type":"string"},"delay":{"type":"integer","default":0},"with_mock_header":{"type":"boolean","default":true},"disable":{"type":"boolean"},"response_schema":{"type":"object"}},"type":"object","$comment":"this is a mark for our injected plugin schema"}},"example-plugin":{"version":0.1,"priority":0,"metadata_schema":{"properties":{"skey":{"type":"string"},"ikey":{"type":"number","minimum":0}},"type":"object","required":["ikey","skey"]},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"s":{"type":"string"},"t":{"type":"array","minItems":1},"disable":{"type":"boolean"},"i":{"type":"number","minimum":0},"ip":{"type":"string"},"port":{"type":"integer"}},"type":"object","required":["i"]}},"proxy-cache":{"version":0.2,"priority":1009,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"cache_control":{"type":"boolean","default":false},"cache_bypass":{"minItems":1,"items":{"type":"string","pattern":"(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)"},"type":"array"},"no_cache":{"minItems":1,"items":{"type":"string","pattern":"(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)"},"type":"array"},"cache_zone":{"default":"disk_cache_one","minLength":1,"type":"string","maxLength":100},"cache_strategy":{"default":"disk","type":"string","enum":["disk","memory"]},"cache_ttl":{"default":300,"type":"integer","minimum":1},"cache_http_status":{"default":[200,301,404],"minItems":1,"items":{"description":"http response status","maximum":599,"type":"integer","minimum":200},"type":"array","uniqueItems":true},"disable":{"type":"boolean"},"cache_method":{"default":["GET","HEAD"],"minItems":1,"items":{"description":"supported http method","type":"string","enum":["GET","POST","HEAD"]},"type":"array","uniqueItems":true},"cache_key":{"minItems":1,"items":{"description":"a key for caching","type":"string","pattern":"(^[^\\$].+$|^\\$[0-9a-zA-Z_]+$)"},"type":"array","default":["$host","$request_uri"]},"hide_cache_headers":{"type":"boolean","default":false}},"type":"object"}},"openid-connect":{"version":0.1,"priority":2599,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"introspection_endpoint":{"type":"string"},"introspection_endpoint_auth_method":{"type":"string","default":"client_secret_basic"},"bearer_only":{"type":"boolean","default":false},"realm":{"type":"string","default":"apisix"},"logout_path":{"type":"string","default":"\/logout"},"redirect_uri":{"type":"string","description":"use ngx.var.request_uri if not configured"},"post_logout_redirect_uri":{"type":"string","description":"the URI will be redirect when request logout_path"},"token_signing_alg_values_expected":{"type":"string"},"set_access_token_header":{"description":"Whether the access token should be added as a header to the request for downstream","type":"boolean","default":true},"access_token_in_authorization_header":{"description":"Whether the access token should be added in the Authorization header as opposed to the X-Access-Token header.","type":"boolean","default":false},"set_id_token_header":{"description":"Whether the ID token should be added in the X-ID-Token header to the request for downstream.","type":"boolean","default":true},"client_id":{"type":"string"},"discovery":{"type":"string"},"disable":{"type":"boolean"},"set_userinfo_header":{"description":"Whether the user info token should be added in the X-Userinfo header to the request for downstream.","type":"boolean","default":true},"scope":{"type":"string","default":"openid"},"ssl_verify":{"type":"boolean","default":false},"client_secret":{"type":"string"},"public_key":{"type":"string"},"timeout":{"description":"timeout in seconds","default":3,"type":"integer","minimum":1}},"type":"object","required":["client_id","client_secret","discovery"]}},"request-validation":{"version":0.1,"priority":2800,"type":"validation","schema":{"anyOf":[{"required":["header_schema"]},{"required":["body_schema"]}],"properties":{"header_schema":{"type":"object"},"body_schema":{"type":"object"},"rejected_msg":{"minLength":1,"type":"string","maxLength":256},"disable":{"type":"boolean"},"rejected_code":{"default":400,"maximum":599,"type":"integer","minimum":200}},"type":"object","$comment":"this is a mark for our injected plugin schema"}},"request-id":{"version":0.1,"priority":11010,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"include_in_response":{"type":"boolean","default":true},"disable":{"type":"boolean"},"algorithm":{"default":"uuid","type":"string","enum":["uuid","snowflake"]},"header_name":{"type":"string","default":"X-Request-Id"}},"type":"object"}},"serverless-post-function":{"version":0.1,"priority":-2000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"phase":{"default":"access","type":"string","enum":["rewrite","access","header_filter","body_filter","log","before_proxy"]},"functions":{"minItems":1,"items":{"type":"string"},"type":"array"},"disable":{"type":"boolean"}},"type":"object","required":["functions"]}},"openwhisk":{"version":0.1,"priority":-1901,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"keepalive_timeout":{"default":60000,"type":"integer","minimum":1000},"keepalive_pool":{"default":5,"type":"integer","minimum":1},"disable":{"type":"boolean"},"keepalive":{"type":"boolean","default":true},"api_host":{"type":"string"},"service_token":{"type":"string"},"namespace":{"pattern":"\\A([\\w]|[\\w][\\w@ .-]*[\\[email protected]]+)\\z","type":"string","maxLength":256},"package":{"pattern":"\\A([\\w]|[\\w][\\w@ .-]*[\\[email protected]]+)\\z","type":"string","maxLength":256},"ssl_verify":{"type":"boolean","default":true},"action":{"pattern":"\\A([\\w]|[\\w][\\w@ .-]*[\\[email protected]]+)\\z","type":"string","maxLength":256},"result":{"type":"boolean","default":true},"timeout":{"description":"timeout in milliseconds","default":3000,"minimum":1,"maximum":60000,"type":"integer"}},"type":"object","required":["api_host","service_token","namespace","action"]}},"uri-blocker":{"version":0.1,"priority":2900,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"rejected_code":{"default":403,"type":"integer","minimum":200},"rejected_msg":{"type":"string","minLength":1},"block_rules":{"uniqueItems":true,"items":{"minLength":1,"type":"string","maxLength":4096},"type":"array"},"case_insensitive":{"type":"boolean","default":false},"disable":{"type":"boolean"}},"type":"object","required":["block_rules"]}},"forward-auth":{"version":0.1,"priority":2002,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"upstream_headers":{"description":"authorization response header that will be sent to the upstream","items":{"type":"string"},"type":"array","default":{}},"client_headers":{"description":"authorization response header that will be sent tothe client when authorizing failed","items":{"type":"string"},"type":"array","default":{}},"keepalive_pool":{"default":5,"type":"integer","minimum":1},"uri":{"type":"string"},"keepalive":{"type":"boolean","default":true},"disable":{"type":"boolean"},"ssl_verify":{"type":"boolean","default":true},"keepalive_timeout":{"default":60000,"type":"integer","minimum":1000},"request_headers":{"description":"client request header that will be sent to the authorization service","items":{"type":"string"},"type":"array","default":{}},"timeout":{"description":"timeout in milliseconds","default":3000,"minimum":1,"maximum":60000,"type":"integer"}},"type":"object","required":["uri"]}},"client-control":{"version":0.1,"priority":22000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"max_body_size":{"type":"integer","minimum":0},"disable":{"type":"boolean"}},"type":"object"}},"azure-functions":{"version":0.1,"priority":-1900,"metadata_schema":{"type":"object","properties":{"master_clientid":{"type":"string","default":""},"master_apikey":{"type":"string","default":""}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"authorization":{"type":"object","properties":{"clientid":{"type":"string"},"apikey":{"type":"string"}}},"keepalive":{"type":"boolean","default":true},"keepalive_timeout":{"default":60000,"type":"integer","minimum":1000},"disable":{"type":"boolean"},"ssl_verify":{"type":"boolean","default":true},"keepalive_pool":{"default":5,"type":"integer","minimum":1},"function_uri":{"type":"string"},"timeout":{"default":3000,"type":"integer","minimum":100}},"type":"object","required":["function_uri"]}},"loggly":{"version":0.1,"priority":411,"metadata_schema":{"type":"object","properties":{"host":{"type":"string","default":"logs-01.loggly.com"},"log_format":{"type":"object"},"port":{"type":"integer","default":514},"protocol":{"default":"syslog","type":"string","enum":["syslog","http","https"]},"timeout":{"default":5000,"type":"integer","minimum":1}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"include_resp_body":{"type":"boolean","default":false},"include_resp_body_expr":{"minItems":1,"items":{"type":"array"},"type":"array"},"disable":{"type":"boolean"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"customer_token":{"type":"string"},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"severity":{"description":"base severity log level","default":"INFO","type":"string","enum":["DEBUG","debug","NOTICE","notice","ALERT","alert","CRIT","crit","ERR","err","EMEGR","emegr","WARNING","warning","INFO","info"]},"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"name":{"type":"string","default":"loggly"},"include_req_body":{"type":"boolean","default":false},"ssl_verify":{"type":"boolean","default":true},"tags":{"minItems":1,"items":{"type":"string","pattern":"^(?!tag=)[ -~]*"},"type":"array","default":["apisix"]},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"severity_map":{"description":"upstream response code vs syslog severity mapping","additionalProperties":false,"type":"object","patternProperties":{"^[1-5][0-9]{2}$":{"description":"keys are HTTP status code, values are severity","type":"string","enum":["DEBUG","debug","NOTICE","notice","ALERT","alert","CRIT","crit","ERR","err","EMEGR","emegr","WARNING","warning","INFO","info"]}}}},"type":"object","required":["customer_token"]}},"fault-injection":{"version":0.1,"priority":11000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"abort":{"properties":{"http_status":{"type":"integer","minimum":200},"percentage":{"maximum":100,"type":"integer","minimum":0},"body":{"type":"string","minLength":0},"vars":{"maxItems":20,"type":"array","items":{"type":"array"}}},"type":"object","required":["http_status"]},"disable":{"type":"boolean"},"delay":{"properties":{"percentage":{"maximum":100,"type":"integer","minimum":0},"duration":{"type":"number","minimum":0},"vars":{"maxItems":20,"type":"array","items":{"type":"array"}}},"type":"object","required":["duration"]}},"type":"object","minProperties":1}},"wolf-rbac":{"version":0.1,"priority":2555,"type":"auth","schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"appid":{"type":"string","default":"unset"},"server":{"type":"string","default":"http:\/\/127.0.0.1:12180"},"header_prefix":{"type":"string","default":"X-"}},"type":"object"}},"proxy-control":{"version":0.1,"priority":21990,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"request_buffering":{"type":"boolean","default":true},"disable":{"type":"boolean"}},"type":"object"}},"consumer-restriction":{"version":0.1,"priority":2400,"schema":{"anyOf":[{"required":["blacklist"]},{"required":["whitelist"]},{"required":["allowed_by_methods"]}],"properties":{"rejected_code":{"default":403,"type":"integer","minimum":200},"allowed_by_methods":{"type":"array","items":{"type":"object","properties":{"user":{"type":"string"},"methods":{"minItems":1,"items":{"description":"HTTP method","type":"string","enum":["GET","POST","PUT","DELETE","PATCH","HEAD","OPTIONS","CONNECT","TRACE"]},"type":"array"}}}},"disable":{"type":"boolean"},"whitelist":{"minItems":1,"items":{"type":"string"},"type":"array"},"blacklist":{"minItems":1,"items":{"type":"string"},"type":"array"},"type":{"default":"consumer_name","type":"string","enum":["consumer_name","service_id","route_id"]},"rejected_msg":{"type":"string"}},"type":"object","$comment":"this is a mark for our injected plugin schema"}},"syslog":{"version":0.1,"priority":401,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"sock_type":{"default":"tcp","type":"string","enum":["tcp","udp"]},"disable":{"type":"boolean"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"name":{"type":"string","default":"sys logger"},"tls":{"type":"boolean","default":false},"host":{"type":"string"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"},"timeout":{"default":3,"type":"integer","minimum":1},"flush_limit":{"default":4096,"type":"integer","minimum":1},"port":{"type":"integer"},"retry_interval":{"type":"integer","minimum":0},"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"drop_limit":{"type":"integer","default":1048576},"pool_size":{"default":5,"type":"integer","minimum":5},"max_retry_times":{"type":"integer","minimum":1},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"include_req_body":{"type":"boolean","default":false}},"type":"object","required":["host","port"]}},"datadog":{"version":0.1,"priority":495,"metadata_schema":{"type":"object","properties":{"constant_tags":{"items":{"type":"string"},"type":"array","default":["source:apisix"]},"namespace":{"type":"string","default":"apisix"},"host":{"type":"string","default":"127.0.0.1"},"port":{"default":8125,"type":"integer","minimum":0}}},"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"prefer_name":{"type":"boolean","default":true},"name":{"type":"string","default":"datadog"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"disable":{"type":"boolean"},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"}},"type":"object"}},"echo":{"version":0.1,"priority":412,"schema":{"anyOf":[{"required":["before_body"]},{"required":["body"]},{"required":["after_body"]}],"properties":{"body":{"description":"body to replace upstream response.","type":"string"},"disable":{"type":"boolean"},"headers":{"description":"new headers for response","type":"object","minProperties":1},"before_body":{"description":"body before the filter phase.","type":"string"},"after_body":{"description":"body after the modification of filter phase.","type":"string"}},"$comment":"this is a mark for our injected plugin schema","type":"object","minProperties":1}},"serverless-pre-function":{"version":0.1,"priority":10000,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"phase":{"default":"access","type":"string","enum":["rewrite","access","header_filter","body_filter","log","before_proxy"]},"functions":{"minItems":1,"items":{"type":"string"},"type":"array"},"disable":{"type":"boolean"}},"type":"object","required":["functions"]}},"google-cloud-logging":{"version":0.1,"priority":407,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"batch_max_size":{"minimum":1,"default":1000,"type":"integer"},"disable":{"type":"boolean"},"inactive_timeout":{"minimum":1,"default":5,"type":"integer"},"auth_file":{"type":"string"},"name":{"type":"string","default":"google-cloud-logging"},"auth_config":{"properties":{"private_key":{"type":"string"},"project_id":{"type":"string"},"token_uri":{"type":"string","default":"https:\/\/oauth2.googleapis.com\/token"},"scopes":{"default":["https:\/\/www.googleapis.com\/auth\/logging.read","https:\/\/www.googleapis.com\/auth\/logging.write","https:\/\/www.googleapis.com\/auth\/logging.admin","https:\/\/www.googleapis.com\/auth\/cloud-platform"],"minItems":1,"items":{"description":"Google OAuth2 Authorization Scopes","type":"string"},"type":"array","uniqueItems":true},"entries_uri":{"type":"string","default":"https:\/\/logging.googleapis.com\/v2\/entries:write"}},"type":"object","required":["private_key","project_id","token_uri"]},"resource":{"default":{"type":"global"},"properties":{"type":{"type":"string"},"labels":{"type":"object"}},"type":"object","required":["type"]},"retry_delay":{"minimum":0,"default":1,"type":"integer"},"ssl_verify":{"type":"boolean","default":true},"max_retry_count":{"minimum":0,"default":0,"type":"integer"},"log_id":{"type":"string","default":"apisix.apache.org%2Flogs"},"buffer_duration":{"minimum":1,"default":60,"type":"integer"}},"type":"object","oneOf":[{"required":["auth_config"]},{"required":["auth_file"]}]}},"csrf":{"version":0.1,"priority":2980,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"disable":{"type":"boolean"},"name":{"description":"the csrf token name","type":"string","default":"apisix-csrf-token"},"expires":{"description":"expires time(s) for csrf token","type":"integer","default":7200},"key":{"description":"use to generate csrf token","type":"string"}},"type":"object","required":["key"]}},"opa":{"version":0.1,"priority":2001,"schema":{"$comment":"this is a mark for our injected plugin schema","properties":{"keepalive_timeout":{"default":60000,"type":"integer","minimum":1000},"keepalive_pool":{"default":5,"type":"integer","minimum":1},"disable":{"type":"boolean"},"host":{"type":"string"},"policy":{"type":"string"},"with_service":{"type":"boolean","default":false},"with_route":{"type":"boolean","default":false},"ssl_verify":{"type":"boolean","default":true},"with_consumer":{"type":"boolean","default":false},"keepalive":{"type":"boolean","default":true},"timeout":{"description":"timeout in milliseconds","default":3000,"minimum":1,"maximum":60000,"type":"integer"}},"type":"object","required":["host","policy"]}}}}

kind: ConfigMap
metadata:
  labels:
  name: apisix-dashboard-schema-cm
  namespace: apisix
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
  name: apisix-dashboard
  namespace: apisix
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apisix-dashboard
  template:
    metadata:
      labels:
        app: apisix-dashboard
    spec:
      containers:
      - image: artifactory.dep.devops.cmit.cloud:20101/panji_middleware/apisix-dashboard:2.13
        ports:
          - name: http
            containerPort: 9000
            protocol: TCP
        imagePullPolicy: Always
        name: apisix-dashboard
        resources:
          limits:
            cpu: 1
            memory: 2Gi
            ephemeral-storage: "2Gi"
          requests:
            cpu: 0.5
            memory: 1Gi
            ephemeral-storage: "1Gi"
        livenessProbe:
          httpGet:
            path: /ping
            port: http
            scheme: HTTP
          timeoutSeconds: 1
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ping
            port: http
            scheme: HTTP
          timeoutSeconds: 1
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        volumeMounts:
        - mountPath: /etc/localtime
          name: timezone
        - mountPath: /usr/local/apisix-dashboard/conf/conf.yaml
          name: apisix-conf-path
          subPath: path/to/conf.yaml
        - mountPath: /usr/local/apisix-dashboard/conf/schema.json
          name: apisix-schema
          subPath: path/to/schema.json
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      serviceAccount: apisix-dashboard-sa
      serviceAccountName: apisix-dashboard-sa
      volumes:
      - configMap:
          items:
          - key: conf.yaml
            path: path/to/conf.yaml
          name: apisix-dashboard-cm
        name: apisix-conf-path
      - configMap:
          items:
          - key: schema.json
            path: path/to/schema.json
          name: apisix-dashboard-schema-cm
        name: apisix-schema
      - hostPath:
          path: /etc/localtime
        name: timezone
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: apisix-dashboard
  name: apisix-dashboard
  namespace: apisix
spec:
  ports:
  - name: http-dashboard
    port: 27114
    protocol: TCP
    targetPort: 9000
  selector:
    app: apisix-dashboard
  sessionAffinity: None
  type: ClusterIP

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
  name: apisix-dashboard
  namespace: apisix
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apisix-dashboard
  template:
    metadata:
      labels:
        app: apisix-dashboard
    spec:
      containers:
      - image: artifactory.dep.devops.cmit.cloud:20101/panji_middleware/apisix-dashboard:2.13
        ports:
          - name: http
            containerPort: 9000
            protocol: TCP
        imagePullPolicy: Always
        name: apisix-dashboard
        resources:
          limits:
            cpu: 1
            memory: 2Gi
            ephemeral-storage: "2Gi"
          requests:
            cpu: 0.5
            memory: 1Gi
            ephemeral-storage: "1Gi"
        livenessProbe:
          httpGet:
            path: /ping
            port: http
            scheme: HTTP
          timeoutSeconds: 1
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /ping
            port: http
            scheme: HTTP
          timeoutSeconds: 1
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
        volumeMounts:
        - mountPath: /etc/localtime
          name: timezone
        - mountPath: /usr/local/apisix/dashboard/conf/conf.yaml
          name: apisix-conf-path
          subPath: path/to/conf.yaml
        - mountPath: /usr/local/apisix/dashboard/conf/schema.json
          name: apisix-schema
          subPath: path/to/schema.json
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      serviceAccount: apisix-dashboard-sa
      serviceAccountName: apisix-dashboard-sa
      volumes:
      - configMap:
          items:
          - key: conf.yaml
            path: path/to/conf.yaml
          name: apisix-dashboard-cm
        name: apisix-conf-path
      - configMap:
          items:
          - key: schema.json
            path: path/to/schema.json
          name: apisix-dashboard-schema-cm
        name: apisix-schema
      - hostPath:
          path: /etc/localtime
        name: timezone
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: apisix-dashboard
  name: apisix-dashboard
  namespace: apisix
spec:
  ports:
  - name: http-dashboard
    port: 27114
    protocol: TCP
    targetPort: 9000
  selector:
    app: apisix-dashboard
  sessionAffinity: None
  type: ClusterIP

标签:string,default,object,minimum,干货,API,integer,type,APISIX
From: https://blog.csdn.net/qq_40477248/article/details/143903981

相关文章

  • 无法从我的应用程序连接到位于本地主机8000的FAST API服务器,该应用程序在停靠容器下运
    无法从我的应用程序连接到位于本地主机8000的FASTAPI服务器,该应用程序在停靠容器下运行问题:无法从我的应用程序连接到位于本地主机8000的FASTAPI服务器解决步骤:1.首先,确保你的本地电脑上已经安装了Docker。如果没有安装,可以前往Docker官网下载并安装。2.安装完成后,你需......
  • Ocelot集成Consul实现api网关与服务发现
    前言没看dotnet微服务之API网关Ocelot的请先看,这篇文章接上面文章安装consul#自定义网络,自定义网络可以指定容器IP,这样服务器重启consul集群也可以正常运行。dockernetworkcreate--driverbridge--subnet=172.21.0.0/16--gateway=172.21.0.16adnc_consuldockerrun-d......
  • webapi调用
    一、查询即时库存内容  client=K3CloudApiClient("https://suninfinit.ik3cloud.com/K3Cloud/");  loginResult=client.ValidateLogin("1361434108470788096","王传志","1qaz@WSX3edc",2052);    resultType=JObject.Parse(logi......
  • litellm - 简化大模型 API 调用的工具
    更多AI开源软件:AI开源-小众AIhttps://www.aiinn.cn/sources11000Stars1300Forks445Issues275贡献者MITLicensePython语言代码:GitHub-BerriAI/litellm:PythonSDK,ProxyServer(LLMGateway)tocall100+LLMAPIsinOpenAIformat-[Bedrock,Azur......
  • 开发一份API接口,需要注意这些,看你做到了几项
    在实际工作中,我们需要经常跟外部三方系统打交道,可能会提供API接口给外部三方系统调用。API接口通常通过WebController来实现。如果设计一个优雅的API接口,能够满足安全性、稳定性、易维护等多方面需求呢?下面几项,看你做到了哪些。1.数字签名为了防止API接口中的数据被篡改,我们......
  • 【2024最新股票数据接口】API接口大全,包含最新实时数据、历史数据等各项数据接口(三)
    在量化分析这一领域,实时且准确的数据接口是必不可少的。经过大量实际测试后,我可以确定下面所列举的数据接口全都稳定且能正常使用,而且我已经为大家准备好了可以直接点击的超链接。只要轻轻点击一下,就能获取相应的数据,同时马上验证接口是否有效。此刻,我非常愿意把这些珍贵的资源......
  • 个人做量化,获取 L2 数据的高性价比之选:必盈 API
    在量化投资的世界里,数据就是黄金。对于个人量化投资者而言,专业数据库高昂的价格常常让人望而却步,而L2数据(二级行情数据)又对交易策略的制定有着至关重要的作用。今天就给大家介绍一个绝佳的解决方案——biyingapi.com。一、为什么需要L2数据L2数据包含了比普通行情数据......
  • arcgis api 3.x for js 入门开发系列十叠加 SHP 图层(附源码下载)
    前言关于本篇功能实现用到的api涉及类看不懂的,请参照esri官网的arcgisapi3.xforjs:esri官网api,里面详细的介绍arcgisapi3.x各个类的介绍,还有就是在线例子:esri官网在线例子,这个也是学习arcgisapi3.x的好素材。内容概览基于arcgisapi3.x叠加SHP......
  • arcgis api 3.x for js 入门开发系列十四最近设施点路径分析(附源码下载)
    前言关于本篇功能实现用到的api涉及类看不懂的,请参照esri官网的arcgisapi3.xforjs:esri官网api,里面详细的介绍arcgisapi3.x各个类的介绍,还有就是在线例子:esri官网在线例子,这个也是学习arcgisapi3.x的好素材。内容概览基于arcgisapi3.x实现最近设......
  • Java API 进阶指南:从核心API到高级应用的全面提升
    文章目录JavaAPI进阶学习指南1.深入理解核心API1.1集合框架(CollectionsFramework)1.2输入输出流(I/OStreams)1.3并发编程(Concurrency)1.4反射(Reflection)1.5泛型(Generics)2.高级API应用2.1网络编程2.2数据库访问2.3日志记录2.4性能优化3.最佳实践3.1代码规......