This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 5822eca9a feat: sync conf via gRPC (#8450)
5822eca9a is described below
commit 5822eca9a28ff7b92dc7fc0431281eb62dd60ba8
Author: 罗泽轩 <[email protected]>
AuthorDate: Wed Dec 7 17:38:03 2022 +0800
feat: sync conf via gRPC (#8450)
---
.gitignore | 2 +
apisix/cli/env.lua | 12 ++
apisix/cli/ngx_tpl.lua | 16 +--
apisix/cli/ops.lua | 11 +-
apisix/cli/snippet.lua | 169 ++++++++++++----------
apisix/core/config_etcd.lua | 124 ++++++++++++++--
apisix/core/etcd.lua | 104 +++++++++++---
apisix/init.lua | 12 +-
rockspec/apisix-master-0.rockspec | 2 +-
t/APISIX.pm | 2 +
t/certs/mtls_ca.crt | 36 ++---
t/certs/mtls_ca.key | 27 ++++
t/certs/mtls_client.crt | 85 +++--------
t/certs/mtls_client.key | 50 +++----
t/certs/mtls_server.crt | 86 +++--------
t/certs/mtls_server.key | 50 +++----
t/cli/test_etcd_grpc_mtls.sh | 181 +++++++++++++++++++++++
t/cli/test_etcd_grpc_tls.sh | 78 ++++++++++
t/core/config_etcd.t | 1 +
t/core/etcd-auth-fail.t | 2 +-
t/core/etcd-grpc-mtls.t | 292 ++++++++++++++++++++++++++++++++++++++
t/core/etcd-sync.t | 21 +--
t/core/etcd.t | 10 ++
t/deployment/conf_server.t | 4 +-
t/deployment/grpc/conf_server.t | 165 +++++++++++++++++++++
t/deployment/grpc/mtls.t | 118 +++++++++++++++
t/discovery/nacos.t | 1 +
t/node/ewma.t | 1 +
t/node/grpc-proxy-mtls.t | 8 +-
t/node/healthcheck-stop-checker.t | 34 ++++-
t/plugin/grpc-transcode2.t | 10 +-
t/stream-node/random.t | 1 +
32 files changed, 1366 insertions(+), 349 deletions(-)
diff --git a/.gitignore b/.gitignore
index bd0b1dbb1..49dbbfe57 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,8 @@ luac.out
*.orig
*.rej
t/servroot
+t/certs/*.csr
+t/certs/*.srl
t/xds-library/libxds.h
conf/apisix.uid
conf/nginx.conf
diff --git a/apisix/cli/env.lua b/apisix/cli/env.lua
index f0e1a36e7..363148364 100644
--- a/apisix/cli/env.lua
+++ b/apisix/cli/env.lua
@@ -89,12 +89,24 @@ return function (apisix_home, pkg_cpath_org, pkg_path_org)
local openresty_args = openresty_path_abs .. [[ -p ]] .. apisix_home .. [[
-c ]]
.. apisix_home .. [[/conf/nginx.conf]]
+ local or_info, err = util.execute_cmd("openresty -V 2>&1")
+ if not or_info then
+ error("failed to exec cmd \'openresty -V 2>&1\', err: " .. err)
+ end
+
+ local use_apisix_base = true
+ if not or_info:find("apisix-nginx-module", 1, true) then
+ use_apisix_base = false
+ end
+
local min_etcd_version = "3.4.0"
return {
apisix_home = apisix_home,
is_root_path = is_root_path,
openresty_args = openresty_args,
+ openresty_info = or_info,
+ use_apisix_base = use_apisix_base,
pkg_cpath_org = pkg_cpath_org,
pkg_path_org = pkg_path_org,
min_etcd_version = min_etcd_version,
diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua
index b578ec27f..c1e46220a 100644
--- a/apisix/cli/ngx_tpl.lua
+++ b/apisix/cli/ngx_tpl.lua
@@ -57,7 +57,7 @@ env {*name*};
{% end %}
{% end %}
-{% if use_apisix_openresty then %}
+{% if use_apisix_base then %}
thread_pool grpc-client-nginx-module threads=1;
lua {
@@ -90,7 +90,7 @@ http {
}
server {
- {% if use_apisix_openresty then %}
+ {% if use_apisix_base then %}
listen {* prometheus_server_addr *}
enable_process=privileged_agent;
{% else %}
listen {* prometheus_server_addr *};
@@ -215,7 +215,7 @@ stream {
proxy_pass apisix_backend;
- {% if use_apisix_openresty then %}
+ {% if use_apisix_base then %}
set $upstream_sni "apisix_backend";
proxy_ssl_server_name on;
proxy_ssl_name $upstream_sni;
@@ -395,7 +395,7 @@ http {
upstream apisix_backend {
server 0.0.0.1;
- {% if use_apisix_openresty then %}
+ {% if use_apisix_base then %}
keepalive {* http.upstream.keepalive *};
keepalive_requests {* http.upstream.keepalive_requests *};
keepalive_timeout {* http.upstream.keepalive_timeout *};
@@ -431,7 +431,7 @@ http {
}
{% end %}
- {% if use_apisix_openresty then %}
+ {% if use_apisix_base then %}
apisix_delay_client_max_body_check on;
apisix_mirror_on_demand on;
{% end %}
@@ -483,7 +483,7 @@ http {
{% if enabled_plugins["prometheus"] and prometheus_server_addr then %}
server {
- {% if use_apisix_openresty then %}
+ {% if use_apisix_base then %}
listen {* prometheus_server_addr *}
enable_process=privileged_agent;
{% else %}
listen {* prometheus_server_addr *};
@@ -746,7 +746,7 @@ http {
apisix.grpc_access_phase()
}
- {% if use_apisix_openresty then %}
+ {% if use_apisix_base then %}
# For servers which obey the standard, when `:authority` is
missing,
# `host` will be used instead. When used with apisix-base, we can
do
# better by setting `:authority` directly
@@ -799,7 +799,7 @@ http {
location = /proxy_mirror {
internal;
- {% if not use_apisix_openresty then %}
+ {% if not use_apisix_base then %}
if ($upstream_mirror_uri = "") {
return 200;
}
diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua
index 93bd17bf9..ef069f815 100644
--- a/apisix/cli/ops.lua
+++ b/apisix/cli/ops.lua
@@ -259,17 +259,12 @@ Please modify "admin_key" in conf/config.yaml .
util.die("openresty version must >=", need_ver, " current ", or_ver,
"\n")
end
- local or_info = util.execute_cmd("openresty -V 2>&1")
- if or_info and not or_info:find("http_stub_status_module", 1, true) then
+ local or_info = env.openresty_info
+ if not or_info:find("http_stub_status_module", 1, true) then
util.die("'http_stub_status_module' module is missing in ",
"your openresty, please check it out.\n")
end
- local use_apisix_openresty = true
- if or_info and not or_info:find("apisix-nginx-module", 1, true) then
- use_apisix_openresty = false
- end
-
local enable_http = true
if not yaml_conf.apisix.enable_admin and yaml_conf.apisix.stream_proxy and
yaml_conf.apisix.stream_proxy.only ~= false
@@ -543,7 +538,7 @@ Please modify "admin_key" in conf/config.yaml .
os_name = util.trim(util.execute_cmd("uname")),
apisix_lua_home = env.apisix_home,
deployment_role = env.deployment_role,
- use_apisix_openresty = use_apisix_openresty,
+ use_apisix_base = env.use_apisix_base,
error_log = {level = "warn"},
enable_http = enable_http,
enabled_discoveries = enabled_discoveries,
diff --git a/apisix/cli/snippet.lua b/apisix/cli/snippet.lua
index 3b5eb3232..6225c213f 100644
--- a/apisix/cli/snippet.lua
+++ b/apisix/cli/snippet.lua
@@ -21,6 +21,95 @@ local ipairs = ipairs
-- this module provide methods to generate snippets which will be used in the
nginx.conf template
local _M = {}
+local conf_server_tpl = [[
+upstream apisix_conf_backend {
+ server 0.0.0.0:80;
+ balancer_by_lua_block {
+ local conf_server = require("apisix.conf_server")
+ conf_server.balancer()
+ }
+}
+
+{% if trusted_ca_cert then %}
+lua_ssl_trusted_certificate {* trusted_ca_cert *};
+{% end %}
+
+server {
+ {% if control_plane then %}
+ listen {* control_plane.listen *} ssl;
+ ssl_certificate {* control_plane.cert *};
+ ssl_certificate_key {* control_plane.cert_key *};
+
+ {% if control_plane.client_ca_cert then %}
+ ssl_verify_client on;
+ ssl_client_certificate {* control_plane.client_ca_cert *};
+ {% end %}
+
+ {% else %}
+ listen unix:{* home *}/conf/config_listen.sock;
+ {% end %}
+
+ access_log off;
+
+ set $upstream_host '';
+
+ access_by_lua_block {
+ local conf_server = require("apisix.conf_server")
+ conf_server.access()
+ }
+
+ location / {
+ {% if enable_https then %}
+ {* directive_prefix *}_pass {* scheme_name *}s://apisix_conf_backend;
+ {* directive_prefix *}_ssl_protocols TLSv1.2 TLSv1.3;
+ {* directive_prefix *}_ssl_server_name on;
+
+ {% if etcd_tls_verify then %}
+ {* directive_prefix *}_ssl_verify on;
+ {* directive_prefix *}_ssl_trusted_certificate {*
ssl_trusted_certificate *};
+ {% end %}
+
+ {% if sni then %}
+ {* directive_prefix *}_ssl_name {* sni *};
+ {% else %}
+ {* directive_prefix *}_ssl_name $upstream_host;
+ {% end %}
+
+ {% if client_cert then %}
+ {* directive_prefix *}_ssl_certificate {* client_cert *};
+ {* directive_prefix *}_ssl_certificate_key {* client_cert_key *};
+ {% end %}
+
+ {% else %}
+ {* directive_prefix *}_pass {* scheme_name *}://apisix_conf_backend;
+ {% end %}
+
+ {% if scheme_name == "http" then %}
+ proxy_http_version 1.1;
+ proxy_set_header Connection "";
+ {% end %}
+
+ {* directive_prefix *}_set_header Host $upstream_host;
+ {* directive_prefix *}_next_upstream error timeout non_idempotent
+ http_500 http_502 http_503 http_504;
+ }
+
+ log_by_lua_block {
+ local conf_server = require("apisix.conf_server")
+ conf_server.log()
+ }
+}
+]]
+
+
+local function is_grpc_used(env, etcd)
+ local is_grpc_available = env.use_apisix_base
+ if etcd.user then
+ -- TODO: support user/password
+ is_grpc_available = false
+ end
+ return is_grpc_available and etcd.use_grpc
+end
function _M.generate_conf_server(env, conf)
@@ -69,87 +158,13 @@ function _M.generate_conf_server(env, conf)
end
end
- local conf_render = template.compile([[
- upstream apisix_conf_backend {
- server 0.0.0.0:80;
- balancer_by_lua_block {
- local conf_server = require("apisix.conf_server")
- conf_server.balancer()
- }
- }
-
- {% if trusted_ca_cert then %}
- lua_ssl_trusted_certificate {* trusted_ca_cert *};
- {% end %}
-
- server {
- {% if control_plane then %}
- listen {* control_plane.listen *} ssl;
- ssl_certificate {* control_plane.cert *};
- ssl_certificate_key {* control_plane.cert_key *};
-
- {% if control_plane.client_ca_cert then %}
- ssl_verify_client on;
- ssl_client_certificate {* control_plane.client_ca_cert *};
- {% end %}
-
- {% else %}
- listen unix:{* home *}/conf/config_listen.sock;
- {% end %}
-
- access_log off;
-
- set $upstream_host '';
-
- access_by_lua_block {
- local conf_server = require("apisix.conf_server")
- conf_server.access()
- }
-
- location / {
- {% if enable_https then %}
- proxy_pass https://apisix_conf_backend;
- proxy_ssl_protocols TLSv1.2 TLSv1.3;
- proxy_ssl_server_name on;
-
- {% if etcd_tls_verify then %}
- proxy_ssl_verify on;
- proxy_ssl_trusted_certificate {* ssl_trusted_certificate *};
- {% end %}
-
- {% if sni then %}
- proxy_ssl_name {* sni *};
- {% else %}
- proxy_ssl_name $upstream_host;
- {% end %}
-
- {% if client_cert then %}
- proxy_ssl_certificate {* client_cert *};
- proxy_ssl_certificate_key {* client_cert_key *};
- {% end %}
-
- {% else %}
- proxy_pass http://apisix_conf_backend;
- {% end %}
-
- proxy_http_version 1.1;
- proxy_set_header Connection "";
- proxy_set_header Host $upstream_host;
- proxy_next_upstream error timeout non_idempotent http_500 http_502
http_503 http_504;
- }
-
- log_by_lua_block {
- local conf_server = require("apisix.conf_server")
- conf_server.log()
- }
- }
- ]])
-
+ local conf_render = template.compile(conf_server_tpl)
local tls = etcd.tls
local client_cert
local client_cert_key
local ssl_trusted_certificate
local etcd_tls_verify
+ local use_grpc = is_grpc_used(env, etcd)
if tls then
if tls.cert then
client_cert = pl_path.abspath(tls.cert)
@@ -175,6 +190,8 @@ function _M.generate_conf_server(env, conf)
trusted_ca_cert = trusted_ca_cert,
etcd_tls_verify = etcd_tls_verify,
ssl_trusted_certificate = ssl_trusted_certificate,
+ scheme_name = use_grpc and "grpc" or "http",
+ directive_prefix = use_grpc and "grpc" or "proxy",
})
end
diff --git a/apisix/core/config_etcd.lua b/apisix/core/config_etcd.lua
index cff2cdc1e..efec28e8e 100644
--- a/apisix/core/config_etcd.lua
+++ b/apisix/core/config_etcd.lua
@@ -26,12 +26,14 @@ local log = require("apisix.core.log")
local json = require("apisix.core.json")
local etcd_apisix = require("apisix.core.etcd")
local core_str = require("apisix.core.string")
+local core_tab = require("apisix.core.table")
local new_tab = require("table.new")
local check_schema = require("apisix.core.schema").check
local exiting = ngx.worker.exiting
local insert_tab = table.insert
local type = type
local ipairs = ipairs
+local pairs = pairs
local setmetatable = setmetatable
local ngx_sleep = require("apisix.core.utils").sleep
local ngx_timer_at = ngx.timer.at
@@ -49,6 +51,8 @@ local health_check = require("resty.etcd.health_check")
local is_http = ngx.config.subsystem == "http"
+local err_etcd_grpc_engine_timeout = "context deadline exceeded"
+local err_etcd_grpc_ngx_timeout = "timeout"
local err_etcd_unhealthy_all = "has no healthy etcd endpoint available"
local health_check_shm_name = "etcd-cluster-health-check"
if not is_http then
@@ -120,11 +124,46 @@ local function readdir(etcd_cli, key, formatter)
return res
end
-local function waitdir(etcd_cli, key, modified_index, timeout)
- if not etcd_cli then
- return nil, nil, "not inited"
+
+local function grpc_waitdir(self, etcd_cli, key, modified_index, timeout)
+ local watching_stream = self.watching_streams[key]
+ if not watching_stream then
+ local attr = {}
+ attr.start_revision = modified_index
+ local opts = {}
+ opts.timeout = timeout
+
+ local st, err = etcd_cli:create_grpc_watch_stream(key, attr, opts)
+ if not st then
+ log.error("create watch stream failed: ", err)
+ return nil, err
+ end
+
+ log.info("create watch stream for key: ", key, ", modified_index: ",
modified_index)
+
+ self.watching_streams[key] = st
+ watching_stream = st
end
+ return etcd_cli:read_grpc_watch_stream(watching_stream)
+end
+
+
+local function flush_watching_streams(self)
+ local etcd_cli = self.etcd_cli
+ if not etcd_cli.use_grpc then
+ return
+ end
+
+ for _, st in pairs(self.watching_streams) do
+ st:close()
+ end
+
+ core_tab.clear(self.watching_streams)
+end
+
+
+local function http_waitdir(etcd_cli, key, modified_index, timeout)
local opts = {}
opts.start_revision = modified_index
opts.timeout = timeout
@@ -151,7 +190,6 @@ local function waitdir(etcd_cli, key, modified_index,
timeout)
end
if not res then
- -- log.error("failed to get key from etcd: ", err)
return nil, err
end
@@ -162,6 +200,33 @@ local function waitdir(etcd_cli, key, modified_index,
timeout)
end
return nil, err
end
+
+ return res, err
+end
+
+
+local function waitdir(self)
+ local etcd_cli = self.etcd_cli
+ local key = self.key
+ local modified_index = self.prev_index + 1
+ local timeout = self.timeout
+
+ if not etcd_cli then
+ return nil, "not inited"
+ end
+
+ local res, err
+ if etcd_cli.use_grpc then
+ res, err = grpc_waitdir(self, etcd_cli, key, modified_index, timeout)
+ else
+ res, err = http_waitdir(etcd_cli, key, modified_index, timeout)
+ end
+
+ if not res then
+ -- log.error("failed to get key from etcd: ", err)
+ return nil, err
+ end
+
return etcd_apisix.watch_format(res)
end
@@ -301,6 +366,8 @@ local function sync_data(self)
end
if self.need_reload then
+ flush_watching_streams(self)
+
local res, err = readdir(self.etcd_cli, self.key)
if not res then
return false, err
@@ -327,9 +394,9 @@ local function sync_data(self)
return true
end
- local dir_res, err = waitdir(self.etcd_cli, self.key, self.prev_index + 1,
self.timeout)
+ local dir_res, err = waitdir(self)
log.info("waitdir key: ", self.key, " prev_index: ", self.prev_index + 1)
- log.info("res: ", json.delay_encode(dir_res, true))
+ log.info("res: ", json.delay_encode(dir_res, true), ", err: ", err)
if not dir_res then
if err == "compacted" then
@@ -507,7 +574,7 @@ do
end
local _, err
- etcd_cli, _, err = etcd_apisix.switch_proxy(true)
+ etcd_cli, _, err = etcd_apisix.get_etcd_syncer()
return etcd_cli, err
end
end
@@ -547,7 +614,13 @@ local function _automatic_fetch(premature, self)
local ok, err = sync_data(self)
if err then
- if string.find(err, err_etcd_unhealthy_all) then
+ if core_str.find(err, err_etcd_grpc_engine_timeout) or
+ core_str.find(err, err_etcd_grpc_ngx_timeout)
+ then
+ err = "timeout"
+ end
+
+ if core_str.find(err, err_etcd_unhealthy_all) then
local reconnected = false
while err and not reconnected and i <= 32 do
local backoff_duration, backoff_factor, backoff_step =
1, 2, 6
@@ -600,6 +673,7 @@ local function _automatic_fetch(premature, self)
end
if not exiting() and self.running then
+ flush_watching_streams(self)
ngx_timer_at(0, _automatic_fetch, self)
end
end
@@ -668,6 +742,7 @@ function _M.new(key, opts)
conf_version = 0,
values = nil,
need_reload = true,
+ watching_streams = {},
routes_hash = nil,
prev_index = 0,
last_err = nil,
@@ -799,6 +874,39 @@ function _M.init()
return true
end
+ if local_conf.etcd.use_grpc then
+ return true
+ end
+
+ -- don't go through proxy during start because the proxy is not available
+ local etcd_cli, prefix, err = etcd_apisix.new_without_proxy()
+ if not etcd_cli then
+ return nil, "failed to start a etcd instance: " .. err
+ end
+
+ local res, err = readdir(etcd_cli, prefix, create_formatter(prefix))
+ if not res then
+ return nil, err
+ end
+
+ return true
+end
+
+
+function _M.init_worker()
+ local local_conf, err = config_local.local_conf()
+ if not local_conf then
+ return nil, err
+ end
+
+ if table.try_read_attr(local_conf, "apisix",
"disable_sync_configuration_during_start") then
+ return true
+ end
+
+ if not local_conf.etcd.use_grpc then
+ return true
+ end
+
-- don't go through proxy during start because the proxy is not available
local etcd_cli, prefix, err = etcd_apisix.new_without_proxy()
if not etcd_cli then
diff --git a/apisix/core/etcd.lua b/apisix/core/etcd.lua
index a90775845..9e6786c86 100644
--- a/apisix/core/etcd.lua
+++ b/apisix/core/etcd.lua
@@ -74,7 +74,7 @@ local function _new(etcd_conf)
if etcd_conf.use_grpc then
-- TODO: let lua-resty-etcd support more use cases
- if etcd.user or ngx_get_phase() == "init" or ngx_get_phase() ==
"init_worker" then
+ if etcd.user or ngx_get_phase() == "init" then
etcd_conf.use_grpc = false
else
local ok = pcall(require, "resty.grpc")
@@ -108,26 +108,31 @@ local function new_without_proxy()
end
local etcd_conf = clone_tab(local_conf.etcd)
+
+ if local_conf.apisix.ssl and local_conf.apisix.ssl.ssl_trusted_certificate
then
+ etcd_conf.trusted_ca = local_conf.apisix.ssl.ssl_trusted_certificate
+ end
+
return _new(etcd_conf)
end
_M.new_without_proxy = new_without_proxy
-local function new(use_http)
+local function new()
local local_conf, err = fetch_local_conf()
if not local_conf then
return nil, nil, err
end
local etcd_conf = clone_tab(local_conf.etcd)
- if use_http then
- etcd_conf.use_grpc = false
- end
if etcd_conf.use_grpc then
- -- TODO: add grpc proxy support later
return new_without_proxy()
end
+ if local_conf.apisix.ssl and local_conf.apisix.ssl.ssl_trusted_certificate
then
+ etcd_conf.trusted_ca = local_conf.apisix.ssl.ssl_trusted_certificate
+ end
+
local proxy_by_conf_server = false
if local_conf.deployment then
@@ -173,6 +178,10 @@ local function new(use_http)
etcd_conf.tls.key = cert_key
end
end
+
+ if local_conf.deployment.certs and
local_conf.deployment.certs.trusted_ca_cert then
+ etcd_conf.trusted_ca = local_conf.deployment.certs.trusted_ca_cert
+ end
end
-- if an unhealthy etcd node is selected in a single admin read/write etcd
operation,
@@ -193,13 +202,8 @@ end
_M.new = new
--- TODO: add grpc proxy support later, then we can remove "use_http" scaffold
-local function switch_proxy(use_http)
- if ngx_get_phase() == "init" or ngx_get_phase() == "init_worker" then
- return new_without_proxy()
- end
-
- local etcd_cli, prefix, err = new(use_http)
+local function switch_proxy()
+ local etcd_cli, prefix, err = new()
if not etcd_cli or err then
return etcd_cli, prefix, err
end
@@ -215,7 +219,7 @@ local function switch_proxy(use_http)
return etcd_cli, prefix, err
end
-_M.switch_proxy = switch_proxy
+_M.get_etcd_syncer = switch_proxy
-- convert ETCD v3 entry to v2 one
local function kvs_to_node(kvs)
@@ -329,8 +333,61 @@ function _M.watch_format(v3res)
end
+local get_etcd_cli
+do
+ local prefix
+ local etcd_cli_init_phase
+ local etcd_cli
+ local tmp_etcd_cli
+
+ function get_etcd_cli()
+ local err
+ if ngx_get_phase() == "init" or ngx_get_phase() == "init_worker" then
+ if etcd_cli_init_phase == nil then
+ tmp_etcd_cli, prefix, err = new_without_proxy()
+ if not tmp_etcd_cli then
+ return nil, nil, err
+ end
+
+ if tmp_etcd_cli.use_grpc then
+ etcd_cli_init_phase = tmp_etcd_cli
+ end
+
+ return tmp_etcd_cli, prefix
+ end
+
+ return etcd_cli_init_phase, prefix
+ end
+
+ if etcd_cli_init_phase ~= nil then
+ -- we can't share the etcd instance created in init* phase
+ -- they have different configuration
+ etcd_cli_init_phase:close()
+ etcd_cli_init_phase = nil
+ end
+
+ if etcd_cli == nil then
+ tmp_etcd_cli, prefix, err = switch_proxy()
+ if not tmp_etcd_cli then
+ return nil, nil, err
+ end
+
+ if tmp_etcd_cli.use_grpc then
+ etcd_cli = tmp_etcd_cli
+ end
+
+ return tmp_etcd_cli, prefix
+ end
+
+ return etcd_cli, prefix
+ end
+end
+-- export it so we can mock the etcd cli in test
+_M.get_etcd_cli = get_etcd_cli
+
+
function _M.get(key, is_dir)
- local etcd_cli, prefix, err = switch_proxy()
+ local etcd_cli, prefix, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
@@ -349,7 +406,7 @@ end
local function set(key, value, ttl)
- local etcd_cli, prefix, err = switch_proxy()
+ local etcd_cli, prefix, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
@@ -361,7 +418,12 @@ local function set(key, value, ttl)
if not data then
return nil, grant_err
end
+
res, err = etcd_cli:set(prefix .. key, value, {prev_kv = true, lease =
data.body.ID})
+ if not res then
+ return nil, err
+ end
+
res.body.lease_id = data.body.ID
else
res, err = etcd_cli:set(prefix .. key, value, {prev_kv = true})
@@ -393,7 +455,7 @@ _M.set = set
function _M.atomic_set(key, value, ttl, mod_revision)
- local etcd_cli, prefix, err = switch_proxy()
+ local etcd_cli, prefix, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
@@ -452,7 +514,7 @@ end
function _M.push(key, value, ttl)
- local etcd_cli, _, err = switch_proxy()
+ local etcd_cli, _, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
@@ -484,7 +546,7 @@ end
function _M.delete(key)
- local etcd_cli, prefix, err = switch_proxy()
+ local etcd_cli, prefix, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
@@ -522,7 +584,7 @@ end
-- -- etcdserver = "3.5.0"
-- -- }
function _M.server_version()
- local etcd_cli, _, err = switch_proxy()
+ local etcd_cli, _, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
@@ -532,7 +594,7 @@ end
function _M.keepalive(id)
- local etcd_cli, _, err = switch_proxy()
+ local etcd_cli, _, err = get_etcd_cli()
if not etcd_cli then
return nil, err
end
diff --git a/apisix/init.lua b/apisix/init.lua
index fe23f84a0..d968a1244 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -894,15 +894,19 @@ function _M.stream_init_worker()
-- for testing only
core.log.info("random stream test in [1, 10000]: ", math.random(1, 10000))
+ if core.config.init_worker then
+ local ok, err = core.config.init_worker()
+ if not ok then
+ core.log.error("failed to init worker process of ",
core.config.type,
+ " config center, err: ", err)
+ end
+ end
+
plugin.init_worker()
xrpc.init_worker()
router.stream_init_worker()
apisix_upstream.init_worker()
- if core.config == require("apisix.core.config_yaml") then
- core.config.init_worker()
- end
-
load_balancer = require("apisix.balancer")
local_conf = core.config.local_conf()
diff --git a/rockspec/apisix-master-0.rockspec
b/rockspec/apisix-master-0.rockspec
index d42396634..5f558b82a 100644
--- a/rockspec/apisix-master-0.rockspec
+++ b/rockspec/apisix-master-0.rockspec
@@ -34,7 +34,7 @@ dependencies = {
"lua-resty-ctxdump = 0.1-0",
"lua-resty-dns-client = 6.0.2",
"lua-resty-template = 2.0",
- "lua-resty-etcd = 1.10.0",
+ "lua-resty-etcd = 1.10.1",
"api7-lua-resty-http = 0.2.0",
"lua-resty-balancer = 0.04",
"lua-resty-ngxvar = 0.5.2",
diff --git a/t/APISIX.pm b/t/APISIX.pm
index 9223df0ae..22e143ba2 100644
--- a/t/APISIX.pm
+++ b/t/APISIX.pm
@@ -416,6 +416,7 @@ _EOC_
_EOC_
my $stream_extra_init_by_lua = $block->stream_extra_init_by_lua // "";
+ my $stream_extra_init_worker_by_lua =
$block->stream_extra_init_worker_by_lua // "";
$stream_config .= <<_EOC_;
init_by_lua_block {
@@ -424,6 +425,7 @@ _EOC_
}
init_worker_by_lua_block {
apisix.stream_init_worker()
+ $stream_extra_init_worker_by_lua
}
$extra_stream_config
diff --git a/t/certs/mtls_ca.crt b/t/certs/mtls_ca.crt
index b57e39084..f5895b676 100644
--- a/t/certs/mtls_ca.crt
+++ b/t/certs/mtls_ca.crt
@@ -1,20 +1,20 @@
-----BEGIN CERTIFICATE-----
-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
+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
+j4wg2QntJBQWmSc=
-----END CERTIFICATE-----
diff --git a/t/certs/mtls_ca.key b/t/certs/mtls_ca.key
new file mode 100644
index 000000000..94672d79b
--- /dev/null
+++ b/t/certs/mtls_ca.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAukEbWytamYNYFLmlVp9DPIcO9x9+tIR+hLx7RIpfJnp4t1tN
+NB6QrIvyXQ0q97Q+mfPDu8dCE6Dwk9DbAFgNAdiytaLIRZIsiF4quAloH8DPaneR
+iMAO9VlMyeiZKpM9K9zN/6IKNPme0SqCopbwYp6lY02YUaXetw4OXC64DwShRlAT
+H0T5ikoMD0ln1VfOUrh5c6XIHCtPTR4Ei7tg5RRivpVxlkyy7K2+BdBgAMC/5ZOJ
+KZXBytCGQsXySabl8p5qDpoFinGXB4qYL+Pi2OvvCvvC4fRRemVzrlu0S8E2NcKC
+zCitruNHxuAtCFnMofr804rwqye9qUgt62Bl+QIDAQABAoIBABfHXiW6mDuHIESt
+GuW/OYdNuuRj+foz/C8YHSi3/cPc2PKXznh7+n5883lbyAON2HwxOekMXGxDHNPS
+U1Ns6mQ09UPpP2ZabiMO2qdaVBfRtulh0IvD8WTzfLE+Z+eemq2x5/7eAi2XPOZ5
+Zeo6GQCOPpE6A9tQsOlv+vdb45XPCsDdyC2WukeUfB2wsFBFEgMmcW7HLuzMYp9W
+JUuQ6OcOf52ePkGnmEuXIK8Wc3RXitivHlkPLO49Y1LG8t4f61HfG9b2pvgNbHn2
+YdkzemCkBMSjzV4oAoIuG56IWBwuqXETRj2xduVcoxd0t2vLK9qlPADBMCa0hcnW
+uCBqGM0CgYEA3ZjZQuQqer7XrA0qVbXdOdNXal/efUpqfxdxlwMug5sFqt3rSwVF
+S9ZbbtGFeQZp4UAG41o2bWvXuWg59QnKOkKleVQ8zlQdPPjHSOz/7YwXcf/gNYqN
+WHSaT8MqaDYY2m0bo3t9SwSMIBxas05guYuBenisOh3jjcaRPYJELucCgYEA1yuY
+vlIVksPGN+vx6RBaOyY86B8MuXyvi0jVf96UvnL7soUIZDDWojGZvlq3r7ol8Ljj
+LF4Wqdg3MxoOfmUDNWCnSZPjsFo1AUFP/2MJiyCDq75yO0CoVj54QsVYkDTnTosp
+at3CKWTueIeOOtXUAKTObMjrWi9A7cF4rS+siB8CgYBOO2UQcX7xwKhhjHBSvBbz
+EEK/QkNJFlmMrtkiSDRGsBcLILetz5mMUYwMDppBhNsic7k60KGAdd8+DKbRdHhZ
+oyfKMswYx6de3DF29HzR/3BThdNA87486UWFPVCeY+LYUka8q58rOdrCh2AaB2Ss
+fKzkcO/UwLKSXfTusyuhJwKBgEIEslzSuqPJRawqzJKB3e2AEff2buUKiKHnuvn8
+xQ6aIPfpMWXsRi6FoXJySyGzr6hoUetvAu0h1e3r9L57J7zc5vcAVT/qrZCxBWaK
+cIcrdrrfOBVOBVhQ2n1CJ6Y3VTEYKaEMYWJqAXEhxlXu/Zkk9+EQ1IVbMkTAs9IP
+apRpAoGBALd3ZhaP9WvAUVVFs489CKFEP14dZi+SRM6pCsqaQ+zxkW7Cc3Vt72rt
+d+CwIiUMJlac/Efk2Za8MKn/ctMngvRrym8SxGjxJq9jhGo/jSOkHnTy9W//hE/X
+SqlmnJHek5EXl+w0HjgFdukyIo8athDj0jS2ch3OPG4tgavRpKAI
+-----END RSA PRIVATE KEY-----
diff --git a/t/certs/mtls_client.crt b/t/certs/mtls_client.crt
index 847a544ed..378041f9d 100644
--- a/t/certs/mtls_client.crt
+++ b/t/certs/mtls_client.crt
@@ -1,69 +1,20 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 64207 (0xfacf)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=cn, ST=GuangDong, L=ZhuHai, O=api7, OU=ops, CN=ca.apisix.dev
- Validity
- Not Before: Jun 20 13:15:00 2020 GMT
- Not After : Jul 8 13:15:00 2030 GMT
- Subject: C=cn, ST=GuangDong, O=api7, L=ZhuHai, CN=client.apisix.dev
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9f:28:8f:2e:88:41:ff:89:f6:62:91:29:d1:6b:
- 7f:c4:d8:1e:28:85:55:91:c2:3a:3f:23:1c:83:11:
- 6a:26:81:1e:2d:2e:4d:69:48:98:4f:ff:84:82:2d:
- 6b:8c:41:31:56:4d:b4:aa:b7:52:05:63:2e:19:6d:
- 54:87:1f:21:a8:34:f9:89:1a:b1:d1:24:21:84:fa:
- c8:29:7f:39:f4:1a:35:78:95:74:0f:24:3d:24:e8:
- 64:75:09:7d:8c:a3:54:d6:74:5a:92:27:f1:dc:e4:
- 04:30:71:01:67:3d:fa:0b:03:0b:01:cb:8c:aa:ae:
- 59:9f:f7:a6:40:53:2b:65:ff:b6:64:8d:fe:0f:ee:
- 62:64:24:7b:4c:fd:68:12:47:4a:46:86:36:53:00:
- 64:5f:e4:32:56:a0:ee:75:92:2d:e2:dc:92:3e:d7:
- 99:8e:86:69:e7:0a:99:e4:b2:71:95:3d:f9:7d:da:
- af:76:1f:3f:f8:bf:78:aa:13:e5:13:84:f6:11:a5:
- c1:9b:9d:d7:73:32:f3:da:09:78:9a:be:0f:01:fe:
- ed:8b:55:b9:f8:97:46:9d:6a:6a:90:19:ea:4e:02:
- 30:ff:d7:1a:da:39:53:f6:5b:6d:96:d0:fc:ed:0d:
- 72:78:ac:b7:be:71:aa:4d:4b:8a:06:b9:25:1f:90:
- 81:0d
- Exponent: 65537 (0x10001)
- Signature Algorithm: sha256WithRSAEncryption
- 72:a7:1f:15:21:ba:4f:e7:2f:64:a0:e5:40:7c:e0:ea:09:7b:
- 95:cf:80:d0:6f:54:c2:8d:d1:cf:cd:00:f2:95:20:f9:e2:9e:
- f5:1c:1b:f9:87:78:a7:b1:3f:31:34:b0:c8:1a:44:da:2c:ef:
- 93:76:d7:df:44:5f:27:6a:51:cb:09:f2:32:f4:70:db:50:da:
- 4e:49:41:75:e0:d2:7b:4d:0b:8b:6e:0a:02:0a:00:e9:ce:f3:
- bf:72:e6:14:86:df:a7:b9:ef:09:80:a1:52:a7:69:b8:23:7a:
- 3d:3d:cc:6d:64:91:7b:c0:9a:98:2a:a3:17:95:0a:ee:e1:ed:
- f2:be:02:ea:cb:6e:c1:82:4d:a1:e8:03:9a:46:d6:d7:07:0f:
- 12:50:7e:95:5c:6c:17:f0:40:34:81:5b:74:90:8e:24:6a:5f:
- 8e:77:ff:4d:67:c3:a9:1b:39:e2:ca:62:b6:89:ca:c6:86:f1:
- 95:36:2b:cf:96:a5:6e:89:0e:e6:dc:88:78:f0:7d:09:e9:53:
- 65:35:e9:72:a2:be:1c:5e:b8:a6:2b:57:f2:0d:2f:4b:31:8f:
- f7:d9:ad:a3:58:12:bb:c9:5b:38:79:96:5b:c8:74:d2:e6:79:
- 23:e6:bd:be:74:25:42:2c:fa:50:ea:9f:53:28:6d:35:f3:0e:
- 9b:82:15:70
-----BEGIN CERTIFICATE-----
-MIIDOjCCAiICAwD6zzANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJjbjESMBAG
-A1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxDTALBgNVBAoMBGFwaTcx
-DDAKBgNVBAsMA29wczEWMBQGA1UEAwwNY2EuYXBpc2l4LmRldjAeFw0yMDA2MjAx
-MzE1MDBaFw0zMDA3MDgxMzE1MDBaMF0xCzAJBgNVBAYTAmNuMRIwEAYDVQQIDAlH
-dWFuZ0RvbmcxDTALBgNVBAoMBGFwaTcxDzANBgNVBAcMBlpodUhhaTEaMBgGA1UE
-AwwRY2xpZW50LmFwaXNpeC5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQCfKI8uiEH/ifZikSnRa3/E2B4ohVWRwjo/IxyDEWomgR4tLk1pSJhP/4SC
-LWuMQTFWTbSqt1IFYy4ZbVSHHyGoNPmJGrHRJCGE+sgpfzn0GjV4lXQPJD0k6GR1
-CX2Mo1TWdFqSJ/Hc5AQwcQFnPfoLAwsBy4yqrlmf96ZAUytl/7Zkjf4P7mJkJHtM
-/WgSR0pGhjZTAGRf5DJWoO51ki3i3JI+15mOhmnnCpnksnGVPfl92q92Hz/4v3iq
-E+UThPYRpcGbnddzMvPaCXiavg8B/u2LVbn4l0adamqQGepOAjD/1xraOVP2W22W
-0PztDXJ4rLe+capNS4oGuSUfkIENAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHKn
-HxUhuk/nL2Sg5UB84OoJe5XPgNBvVMKN0c/NAPKVIPninvUcG/mHeKexPzE0sMga
-RNos75N2199EXydqUcsJ8jL0cNtQ2k5JQXXg0ntNC4tuCgIKAOnO879y5hSG36e5
-7wmAoVKnabgjej09zG1kkXvAmpgqoxeVCu7h7fK+AurLbsGCTaHoA5pG1tcHDxJQ
-fpVcbBfwQDSBW3SQjiRqX453/01nw6kbOeLKYraJysaG8ZU2K8+WpW6JDubciHjw
-fQnpU2U16XKivhxeuKYrV/INL0sxj/fZraNYErvJWzh5llvIdNLmeSPmvb50JUIs
-+lDqn1MobTXzDpuCFXA=
+MIIDUzCCAjugAwIBAgIURw+Rc5FSNUQWdJD+quORtr9KaE8wDQYJKoZIhvcNAQEN
+BQAwWDELMAkGA1UEBhMCY24xEjAQBgNVBAgMCUd1YW5nRG9uZzEPMA0GA1UEBwwG
+Wmh1SGFpMRYwFAYDVQQDDA1jYS5hcGlzaXguZGV2MQwwCgYDVQQLDANvcHMwHhcN
+MjIxMjAxMTAxOTU3WhcNNDIwODE4MTAxOTU3WjBOMQswCQYDVQQGEwJjbjESMBAG
+A1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxGjAYBgNVBAMMEWNsaWVu
+dC5hcGlzaXguZGV2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzypq
+krsJ8MaqpS0kr2SboE9aRKOJzd6mY3AZLq3tFpio5cK5oIHkQLfeaaLcd4ycFcZw
+FTpxc+Eth6I0X9on+j4tEibc5IpDnRSAQlzHZzlrOG6WxcOza4VmfcrKqj27oodr
+oqXv05r/5yIoRrEN9ZXfA8n2OnjhkP+C3Q68L6dBtPpv+e6HaAuw8MvcsEo+MQwu
+cTZyWqWT2UzKVzToW29dHRW+yZGuYNWRh15X09VSvx+E0s+uYKzN0Cyef2C6VtBJ
+KmJ3NtypAiPqw7Ebfov2Ym/zzU9pyWPi3P1mYPMKQqUT/FpZSXm4iSy0a5qTYhkF
+rFdV1YuYYZL5YGl9aQIDAQABox8wHTAbBgNVHREEFDASghBhZG1pbi5hcGlzaXgu
+ZGV2MA0GCSqGSIb3DQEBDQUAA4IBAQBepRpwWdckZ6QdL5EuufYwU7p5SIqkVL/+
+N4/l5YSjPoAZf/M6XkZu/PsLI9/kPZN/PX4oxjZSDH14dU9ON3JjxtSrebizcT8V
+aQ13TeW9KSv/i5oT6qBmj+V+RF2YCUhyzXdYokOfsSVtSlA1qMdm+cv0vkjYcImV
+l3L9nVHRPq15dY9sbmWEtFBWvOzqNSuQYax+iYG+XEuL9SPaYlwKRC6eS/dbXa1T
+PPWDQad2X/WmhxPzEHvjSl2bsZF1u0GEdKyhXWMOLCLiYIJo15G7bMz8cTUvkDN3
+6WaWBd6bd2g13Ho/OOceARpkR/ND8PU78Y8cq+zHoOSqH+1aly5H
-----END CERTIFICATE-----
diff --git a/t/certs/mtls_client.key b/t/certs/mtls_client.key
index d939c62b1..d7e381de3 100644
--- a/t/certs/mtls_client.key
+++ b/t/certs/mtls_client.key
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+MIIEpAIBAAKCAQEAzypqkrsJ8MaqpS0kr2SboE9aRKOJzd6mY3AZLq3tFpio5cK5
+oIHkQLfeaaLcd4ycFcZwFTpxc+Eth6I0X9on+j4tEibc5IpDnRSAQlzHZzlrOG6W
+xcOza4VmfcrKqj27oodroqXv05r/5yIoRrEN9ZXfA8n2OnjhkP+C3Q68L6dBtPpv
++e6HaAuw8MvcsEo+MQwucTZyWqWT2UzKVzToW29dHRW+yZGuYNWRh15X09VSvx+E
+0s+uYKzN0Cyef2C6VtBJKmJ3NtypAiPqw7Ebfov2Ym/zzU9pyWPi3P1mYPMKQqUT
+/FpZSXm4iSy0a5qTYhkFrFdV1YuYYZL5YGl9aQIDAQABAoIBAD7tUG//lnZnsj/4
+JXONaORaFj5ROrOpFPuRemS+egzqFCuuaXpC2lV6RHnr+XHq6SKII1WfagTb+lt/
+vs760jfmGQSxf1mAUidtqcP+sKc/Pr1mgi/SUTawz8AYEFWD6PHmlqBSLTYml+La
+ckd+0pGtk49wEnYSb9n+cv640hra9AYpm9LXUFaypiFEu+xJhtyKKWkmiVGrt/X9
+3aG6MuYeZplW8Xq1L6jcHsieTOB3T+UBfG3O0bELBgTVexOQYI9O4Ejl9/n5/8WP
+AbIw7PaAYc7fBkwOGh7/qYUdHnrm5o9MiRT6dPxrVSf0PZVACmA+JoNjCPv0Typf
+3MMkHoECgYEA9+3LYzdP8j9iv1fP5hn5K6XZAobCD1mnzv3my0KmoSMC26XuS71f
+vyBhjL7zMxGEComvVTF9SaNMfMYTU4CwOJQxLAuT69PEzW6oVEeBoscE5hwhjj6o
+/lr5jMbt807J9HnldSpwllfj7JeiTuqRcCu/cwqKQQ1aB3YBZ7h5pZkCgYEA1ejo
+KrR1hN2FMhp4pj0nZ5+Ry2lyIVbN4kIcoteaPhyQ0AQ0zNoi27EBRnleRwVDYECi
+XAFrgJU+laKsg1iPjvinHibrB9G2p1uv3BEh6lPl9wPFlENTOjPkqjR6eVVZGP8e
+VzxYxIo2x/QLDUeOpxySdG4pdhEHGfvmdGmr2FECgYBeknedzhCR4HnjcTSdmlTA
+wI+p9gt6XYG0ZIewCymSl89UR9RBUeh++HQdgw0z8r+CYYjfH3SiLUdU5R2kIZeW
+zXiAS55OO8Z7cnWFSI17sRz+RcbLAr3l4IAGoi9MO0awGftcGSc/QiFwM1s3bSSz
+PAzYbjHUpKot5Gae0PCeKQKBgQCHfkfRBQ2LY2WDHxFc+0+Ca6jF17zbMUioEIhi
+/X5N6XowyPlI6MM7tRrBsQ7unX7X8Rjmfl/ByschsTDk4avNO+NfTfeBtGymBYWX
+N6Lr8sivdkwoZZzKOSSWSzdos48ELlThnO/9Ti706Lg3aSQK5iY+aakJiC+fXdfT
+1TtsgQKBgQDRYvtK/Cpaq0W6wO3I4R75lHGa7zjEr4HA0Kk/FlwS0YveuTh5xqBj
+wQz2YyuQQfJfJs7kbWOITBT3vuBJ8F+pktL2Xq5p7/ooIXOGS8Ib4/JAS1C/wb+t
+uJHGva12bZ4uizxdL2Q0/n9ziYTiMc/MMh/56o4Je8RMdOMT5lTsRQ==
-----END RSA PRIVATE KEY-----
diff --git a/t/certs/mtls_server.crt b/t/certs/mtls_server.crt
index 14f48ef7e..965008230 100644
--- a/t/certs/mtls_server.crt
+++ b/t/certs/mtls_server.crt
@@ -1,69 +1,21 @@
-Certificate:
- Data:
- Version: 1 (0x0)
- Serial Number: 64206 (0xface)
- Signature Algorithm: sha256WithRSAEncryption
- Issuer: C=cn, ST=GuangDong, L=ZhuHai, O=api7, OU=ops, CN=ca.apisix.dev
- Validity
- Not Before: Jun 20 13:14:34 2020 GMT
- Not After : Jun 18 13:14:34 2030 GMT
- Subject: C=cn, ST=GuangDong, O=api7, L=ZhuHai, CN=admin.apisix.dev
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:9b:45:2a:e1:c9:6e:a7:af:af:bd:46:5c:5e:5f:
- 72:66:02:78:69:16:fd:f9:69:8e:47:68:0f:8d:35:
- 92:c4:14:40:5c:cf:57:3d:41:ea:13:7b:f4:de:c8:
- ab:e8:62:56:1e:60:61:f6:38:65:5f:30:b5:91:25:
- 79:07:12:45:ce:24:31:86:1f:2c:a6:cb:1d:8b:4b:
- 9e:5f:1f:c7:b6:f3:e8:98:ee:b3:70:c7:9e:5d:10:
- ce:29:e4:22:68:69:9e:df:ae:f6:bb:11:e8:b8:f1:
- 07:bf:2d:d5:57:f2:e4:07:8a:da:d2:7b:8a:53:d1:
- b4:f4:42:19:9a:14:98:01:3e:23:27:3a:0f:ad:d0:
- 1d:c5:31:9a:ee:ae:df:7f:fb:2e:34:0b:51:ca:b4:
- 8c:59:ae:86:5f:95:69:2b:4a:c6:2d:a5:ae:04:46:
- 7a:93:09:15:72:0a:78:ef:98:7d:00:b5:b4:b2:f2:
- e2:a9:2e:04:fb:de:84:ad:da:8e:a3:31:53:3a:d5:
- 91:cd:77:f5:b8:ea:eb:14:aa:d9:62:d1:12:79:87:
- 08:27:6d:c1:b9:e3:7d:f1:07:52:3c:a3:34:6a:c1:
- 96:cf:a2:84:cc:14:50:49:40:0b:38:3c:3b:1e:df:
- 57:6f:f2:05:35:92:9b:4f:b1:21:0b:f7:62:3a:2d:
- 83:c7
- Exponent: 65537 (0x10001)
- Signature Algorithm: sha256WithRSAEncryption
- 7a:1c:a3:d8:d4:97:5d:91:d2:c8:31:c4:40:ef:f1:38:ac:5c:
- b9:74:66:81:94:4f:71:02:38:49:5a:0d:7b:10:17:73:a5:96:
- 3e:de:0e:a4:75:8c:1b:c7:51:f9:f6:eb:9d:f4:bd:4c:1c:92:
- 41:d0:16:c6:73:c1:f9:7c:b6:71:7d:16:53:13:fa:70:90:c0:
- 95:e3:a3:51:30:96:02:f2:32:32:fe:a9:d1:ef:c5:7e:04:58:
- ca:20:ef:d0:43:8c:52:8d:52:3a:71:ed:0f:87:4e:8b:c6:28:
- 51:56:13:fd:71:81:10:cc:2f:2c:aa:8d:6a:93:d7:52:34:08:
- 23:7b:2b:a7:a4:3e:6b:8f:c3:af:59:b9:1c:b8:d8:6c:a3:88:
- c7:bd:b5:e1:eb:6b:6a:f2:7d:a3:89:c6:b0:21:f8:1b:9a:dc:
- bf:ef:d6:21:91:7f:65:99:4d:f4:49:24:ab:46:09:a0:c9:a1:
- 64:14:f4:56:73:ce:1b:22:dd:b7:1f:58:0f:29:ae:6a:6e:41:
- 6e:b4:5c:90:97:4e:59:4e:cf:e3:a1:89:d1:5a:65:a3:68:2f:
- b9:97:82:6f:4c:21:cb:f6:9b:7d:fd:d8:07:70:14:cd:10:fb:
- bf:03:70:fa:51:7c:56:4c:1b:a5:87:d3:1b:18:5c:22:87:6f:
- 04:08:59:53
-----BEGIN CERTIFICATE-----
-MIIDOTCCAiECAwD6zjANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJjbjESMBAG
-A1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxDTALBgNVBAoMBGFwaTcx
-DDAKBgNVBAsMA29wczEWMBQGA1UEAwwNY2EuYXBpc2l4LmRldjAeFw0yMDA2MjAx
-MzE0MzRaFw0zMDA2MTgxMzE0MzRaMFwxCzAJBgNVBAYTAmNuMRIwEAYDVQQIDAlH
-dWFuZ0RvbmcxDTALBgNVBAoMBGFwaTcxDzANBgNVBAcMBlpodUhhaTEZMBcGA1UE
-AwwQYWRtaW4uYXBpc2l4LmRldjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAJtFKuHJbqevr71GXF5fcmYCeGkW/flpjkdoD401ksQUQFzPVz1B6hN79N7I
-q+hiVh5gYfY4ZV8wtZEleQcSRc4kMYYfLKbLHYtLnl8fx7bz6Jjus3DHnl0Qzink
-Imhpnt+u9rsR6LjxB78t1Vfy5AeK2tJ7ilPRtPRCGZoUmAE+Iyc6D63QHcUxmu6u
-33/7LjQLUcq0jFmuhl+VaStKxi2lrgRGepMJFXIKeO+YfQC1tLLy4qkuBPvehK3a
-jqMxUzrVkc139bjq6xSq2WLREnmHCCdtwbnjffEHUjyjNGrBls+ihMwUUElACzg8
-Ox7fV2/yBTWSm0+xIQv3Yjotg8cCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAehyj
-2NSXXZHSyDHEQO/xOKxcuXRmgZRPcQI4SVoNexAXc6WWPt4OpHWMG8dR+fbrnfS9
-TBySQdAWxnPB+Xy2cX0WUxP6cJDAleOjUTCWAvIyMv6p0e/FfgRYyiDv0EOMUo1S
-OnHtD4dOi8YoUVYT/XGBEMwvLKqNapPXUjQII3srp6Q+a4/Dr1m5HLjYbKOIx721
-4etravJ9o4nGsCH4G5rcv+/WIZF/ZZlN9Ekkq0YJoMmhZBT0VnPOGyLdtx9YDymu
-am5BbrRckJdOWU7P46GJ0Vplo2gvuZeCb0why/abff3YB3AUzRD7vwNw+lF8Vkwb
-pYfTGxhcIodvBAhZUw==
+MIIDYDCCAkigAwIBAgIURw+Rc5FSNUQWdJD+quORtr9KaE4wDQYJKoZIhvcNAQEN
+BQAwWDELMAkGA1UEBhMCY24xEjAQBgNVBAgMCUd1YW5nRG9uZzEPMA0GA1UEBwwG
+Wmh1SGFpMRYwFAYDVQQDDA1jYS5hcGlzaXguZGV2MQwwCgYDVQQLDANvcHMwHhcN
+MjIxMjAxMTAxNzI0WhcNNDIwODE4MTAxNzI0WjBbMQswCQYDVQQGEwJjbjESMBAG
+A1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxGTAXBgNVBAMMEGFkbWlu
+LmFwaXNpeC5kZXYxDDAKBgNVBAsMA29wczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAONlOihn9AtXWay72aPDFbwm2zJOe+5ngV1D3B4f2q+KlkAnjAPx
+1GWO1buRDEALL8g5NfbZF3gU9v+wjsEsFK/Sn8ejtziVwJUFVmvRr+PCm/2DEARN
+Re1cp0cwRVQJAKLVFpy19ALlSSTQRoCAjLVXC8tEsIxrvN3DVVet9g6AxnPPd4oR
+LosDGQ+p+qbriQdx20gg5MHmjZX+/ByZq4BIQkshmQW2LnwxAS3xOpqPmFHmdn56
+RXw8JlyvYS3KRiGU3z59uph4wnIic4r/11Puj1LoGd+YtFJash6ZRU/rM6JSdPS7
+b53m8HdRcjGdBG+EnsqN67qZUWbGBntmu2cCAwEAAaMfMB0wGwYDVR0RBBQwEoIQ
+YWRtaW4uYXBpc2l4LmRldjANBgkqhkiG9w0BAQ0FAAOCAQEAMAxCZmKwWEDHuAzW
+PHJUyrdK1eos2UExmeq9TY8c7IluIMClTxS8ui3+7+oc6ZqffyrZL4jx7oe8Ua6V
+bat75H+OF05f9ziGJjJY5PM3wxOP1QvR7HePSkwBkNPhGOQf3bi7rQEhBuqhpRfr
+GfPmzKejaUm9m8IiHnFKxjTfQ7pm3hR8/+P9LKDO21i5Ua3ec+rKv0Y1jsCuv3t/
+APMN7MTDsFqxudqbOG3dufOSe1E7qs16/ygTRvYpIe+kz4rldGWmo0joOrrti43T
+Oi1BAGaC3znJe3aaihr08c37NZ/A6WHiX+h5wBEdboOJc4Htytkicd8jBvU2Svjq
+dZS3wQ==
-----END CERTIFICATE-----
diff --git a/t/certs/mtls_server.key b/t/certs/mtls_server.key
index 5f2c75b98..a6ed4486e 100644
--- a/t/certs/mtls_server.key
+++ b/t/certs/mtls_server.key
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/t/cli/test_etcd_grpc_mtls.sh b/t/cli/test_etcd_grpc_mtls.sh
new file mode 100755
index 000000000..8f37a7112
--- /dev/null
+++ b/t/cli/test_etcd_grpc_mtls.sh
@@ -0,0 +1,181 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+. ./t/cli/common.sh
+
+exit_if_not_customed_nginx
+
+# The 'admin.apisix.dev' is injected by ci/common.sh@set_coredns
+
+# etcd mTLS verify
+echo '
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://admin.apisix.dev:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ verify: false
+ ' > conf/config.yaml
+
+out=$(make init 2>&1 || echo "ouch")
+if echo "$out" | grep "bad certificate"; then
+ echo "failed: apisix should not echo \"bad certificate\""
+ exit 1
+fi
+
+echo "passed: certificate verify success expectedly"
+
+echo '
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://admin.apisix.dev:22379"
+ prefix: "/apisix"
+ tls:
+ verify: false
+ ' > conf/config.yaml
+
+out=$(make init 2>&1 || echo "ouch")
+if ! echo "$out" | grep "bad certificate"; then
+ echo "failed: apisix should echo \"bad certificate\""
+ exit 1
+fi
+
+echo "passed: certificate verify fail expectedly"
+
+# etcd mTLS verify with CA
+echo '
+apisix:
+ ssl:
+ ssl_trusted_certificate: t/certs/mtls_ca.crt
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://admin.apisix.dev:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ ' > conf/config.yaml
+
+out=$(make init 2>&1 || echo "ouch")
+if echo "$out" | grep "certificate verify failed"; then
+ echo "failed: apisix should not echo \"certificate verify failed\""
+ exit 1
+fi
+
+if echo "$out" | grep "ouch"; then
+ echo "failed: apisix should not fail"
+ exit 1
+fi
+
+echo "passed: certificate verify with CA success expectedly"
+
+# etcd mTLS in stream subsystem
+echo '
+apisix:
+ stream_proxy:
+ tcp:
+ - addr: 9100
+ ssl:
+ ssl_trusted_certificate: t/certs/mtls_ca.crt
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://admin.apisix.dev:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ ' > conf/config.yaml
+
+out=$(make init 2>&1 || echo "ouch")
+if echo "$out" | grep "certificate verify failed"; then
+ echo "failed: apisix should not echo \"certificate verify failed\""
+ exit 1
+fi
+
+if echo "$out" | grep "ouch"; then
+ echo "failed: apisix should not fail"
+ exit 1
+fi
+
+rm logs/error.log || true
+make run
+sleep 1
+make stop
+
+if grep "\[error\]" logs/error.log; then
+ echo "failed: veirfy etcd certificate during sync should not fail"
+fi
+
+echo "passed: certificate verify in stream subsystem successfully"
+
+# use host in etcd.host as sni by default
+git checkout conf/config.yaml
+echo '
+apisix:
+ ssl:
+ ssl_trusted_certificate: t/certs/mtls_ca.crt
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.2:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ ' > conf/config.yaml
+
+rm logs/error.log || true
+make init
+make run
+sleep 1
+make stop
+
+if ! grep -E "cannot validate certificate for 127.0.0.2 because it doesn't
contain any IP SANs" logs/error.log; then
+ echo "failed: should got certificate host mismatch when use host in
etcd.host as sni"
+ exit 1
+fi
+
+
+echo "passed: use host in etcd.host as sni by default"
diff --git a/t/cli/test_etcd_grpc_tls.sh b/t/cli/test_etcd_grpc_tls.sh
new file mode 100755
index 000000000..9e429e41b
--- /dev/null
+++ b/t/cli/test_etcd_grpc_tls.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+# 'make init' operates scripts and related configuration files in the current
directory
+# The 'apisix' command is a command in the /usr/local/apisix,
+# and the configuration file for the operation is in the /usr/local/apisix/conf
+
+. ./t/cli/common.sh
+
+exit_if_not_customed_nginx
+
+# Check etcd tls verify failure
+git checkout conf/config.yaml
+
+echo '
+apisix:
+ ssl:
+ ssl_trusted_certificate: t/certs/mtls_ca.crt
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.1:12379"
+ prefix: "/apisix"
+ ' > conf/config.yaml
+
+out=$(make init 2>&1 || true)
+if ! echo "$out" | grep "certificate verify failed"; then
+ echo "failed: apisix should echo \"certificate verify failed\""
+ exit 1
+fi
+
+echo "passed: Show certificate verify failed info successfully"
+
+
+# Check etcd tls without verification
+git checkout conf/config.yaml
+
+echo '
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.1:12379"
+ prefix: "/apisix"
+ tls:
+ verify: false
+ ' > conf/config.yaml
+
+out=$(make init 2>&1 || true)
+if echo "$out" | grep "certificate verify failed"; then
+ echo "failed: apisix should not echo \"certificate verify failed\""
+ exit 1
+fi
+
+echo "passed: Certificate verification successfully"
diff --git a/t/core/config_etcd.t b/t/core/config_etcd.t
index 825e0f225..cdd99d8e3 100644
--- a/t/core/config_etcd.t
+++ b/t/core/config_etcd.t
@@ -337,6 +337,7 @@ qr/healthy check use round robin
config_etcd.test_automatic_fetch(false, {
running = true,
resync_delay = 1,
+ watching_streams = {},
})
ngx.say("passed")
}
diff --git a/t/core/etcd-auth-fail.t b/t/core/etcd-auth-fail.t
index c85f660dc..b7f9374db 100644
--- a/t/core/etcd-auth-fail.t
+++ b/t/core/etcd-auth-fail.t
@@ -63,7 +63,7 @@ __DATA__
--- request
GET /t
--- error_log eval
-qr /insufficient credentials code: 401/
+qr /(insufficient credentials code: 401|etcdserver: user name is empty)/
diff --git a/t/core/etcd-grpc-mtls.t b/t/core/etcd-grpc-mtls.t
new file mode 100644
index 000000000..4e9ca306e
--- /dev/null
+++ b/t/core/etcd-grpc-mtls.t
@@ -0,0 +1,292 @@
+#
+# 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.
+#
+use t::APISIX;
+
+my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
+my $version = eval { `$nginx_binary -V 2>&1` };
+
+if ($version !~ m/\/apisix-nginx-module/) {
+ plan(skip_all => "apisix-nginx-module not installed");
+} else {
+ plan('no_plan');
+}
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: run etcd in init_worker phase
+--- yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.1:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ verify: false
+--- extra_init_worker_by_lua
+ if ngx.worker.id() ~= 0 then
+ return
+ end
+
+ local etcd = require("apisix.core.etcd")
+ assert(etcd.set("/a", "ab"))
+
+ local out = ""
+ local res, err = etcd.get("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ out = out .. res.body.node.value
+
+ local res, err = etcd.delete("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ out = out .. res.status
+
+ local res, err = etcd.get("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ out = out .. res.status
+ ngx.log(ngx.WARN, out)
+--- config
+ location /t {
+ return 200;
+ }
+--- request
+GET /t
+--- grep_error_log eval
+qr/init_worker_by_lua:\d+: [^,]+/
+--- grep_error_log_out
+init_worker_by_lua:31: ab200404
+
+
+
+=== TEST 2: run etcd in init phase (stream)
+--- yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.1:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ verify: false
+--- stream_extra_init_worker_by_lua
+ if ngx.worker.id() ~= 0 then
+ return
+ end
+
+ local etcd = require("apisix.core.etcd")
+ assert(etcd.set("/a", "ab"))
+
+ local out = ""
+ local res, err = etcd.get("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ out = out .. res.body.node.value
+
+ local res, err = etcd.delete("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ out = out .. res.status
+
+ local res, err = etcd.get("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ out = out .. res.status
+ ngx.log(ngx.WARN, out)
+--- stream_server_config
+ content_by_lua_block {
+ ngx.say("ok")
+ }
+--- stream_enable
+--- grep_error_log eval
+qr/init_worker_by_lua:\d+: \S+/
+--- grep_error_log_out
+init_worker_by_lua:31: ab200404,
+
+
+
+=== TEST 3: sync
+--- extra_yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.1:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ verify: false
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local consumers, _ = core.config.new("/consumers", {
+ automatic = true,
+ item_schema = core.schema.consumer,
+ })
+
+ ngx.sleep(0.6)
+ local idx = consumers.prev_index
+
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jobs",
+ "plugins": {
+ "basic-auth": {
+ "username": "jobs",
+ "password": "678901"
+ }
+ }
+ }]])
+
+ ngx.sleep(2)
+ local new_idx = consumers.prev_index
+ if new_idx > idx then
+ ngx.say("prev_index updated")
+ else
+ ngx.say("prev_index not update")
+ end
+ }
+ }
+--- request
+GET /t
+--- response_body
+prev_index updated
+--- error_log
+waitdir key
+
+
+
+=== TEST 4: sync (stream)
+--- extra_yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://127.0.0.1:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+ verify: false
+--- stream_server_config
+ content_by_lua_block {
+ local core = require("apisix.core")
+
+ local sr, _ = core.config.new("/stream_routes", {
+ automatic = true,
+ item_schema = core.schema.stream_routes,
+ })
+
+ ngx.sleep(0.6)
+ local idx = sr.prev_index
+
+ assert(core.etcd.set("/stream_routes/1",
+ {
+ plugins = {
+ }
+ }))
+
+ ngx.sleep(2)
+ local new_idx = sr.prev_index
+ if new_idx > idx then
+ ngx.say("prev_index updated")
+ else
+ ngx.say("prev_index not update")
+ end
+ }
+--- stream_enable
+--- stream_response
+prev_index updated
+--- error_log
+waitdir key
+
+
+
+=== TEST 5: ssl_trusted_certificate
+--- yaml_config
+apisix:
+ ssl:
+ ssl_trusted_certificate: t/certs/mtls_ca.crt
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ host:
+ - "https://admin.apisix.dev:22379"
+ prefix: "/apisix"
+ tls:
+ cert: t/certs/mtls_client.crt
+ key: t/certs/mtls_client.key
+--- extra_init_worker_by_lua
+ if ngx.worker.id() ~= 0 then
+ return
+ end
+
+ local etcd = require("apisix.core.etcd")
+ assert(etcd.set("/a", "ab"))
+ local res, err = etcd.get("/a")
+ if not res then
+ ngx.log(ngx.ERR, err)
+ return
+ end
+ ngx.log(ngx.WARN, res.body.node.value)
+--- config
+ location /t {
+ return 200;
+ }
+--- request
+GET /t
+--- error_log
+init_worker_by_lua:14: ab
diff --git a/t/core/etcd-sync.t b/t/core/etcd-sync.t
index 47e372a79..e74ae19ec 100644
--- a/t/core/etcd-sync.t
+++ b/t/core/etcd-sync.t
@@ -23,14 +23,17 @@ run_tests;
__DATA__
=== TEST 1: minus timeout to watch repeatedly
---- extra_yaml_config
+--- yaml_config
deployment:
- role: traditional
- role_traditional:
- config_provider: etcd
- etcd:
- host:
- - "http://127.0.0.1:2379"
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ # this test requires the HTTP long pull as the gRPC stream is shared
and can't change
+ # default timeout in the fly
+ use_grpc: false
+ admin:
+ admin_key: null
--- config
location /t {
content_by_lua_block {
@@ -72,8 +75,8 @@ deployment:
GET /t
--- response_body
prev_index updated
---- error_log
-cancel watch connection success
+--- error_log eval
+qr/(create watch stream for key|cancel watch connection success)/
diff --git a/t/core/etcd.t b/t/core/etcd.t
index 091fba02e..eaa425ec6 100644
--- a/t/core/etcd.t
+++ b/t/core/etcd.t
@@ -405,10 +405,20 @@ init_by_lua:26: 404
=== TEST 8: error handling in server_version
+--- yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ host:
+ - "http://127.0.0.1:2379"
+ prefix: "/apisix"
--- config
location /t {
content_by_lua_block {
local etcd_lib = require("resty.etcd")
+ -- the mock won't take effect when using gRPC because the
connection will be cached
etcd_lib.new = function()
return nil, "ouch"
end
diff --git a/t/deployment/conf_server.t b/t/deployment/conf_server.t
index 367d0af8b..2e15ed8bd 100644
--- a/t/deployment/conf_server.t
+++ b/t/deployment/conf_server.t
@@ -16,6 +16,8 @@
#
use t::APISIX 'no_plan';
+worker_connections(256);
+
add_block_preprocessor(sub {
my ($block) = @_;
@@ -159,7 +161,7 @@ localhost is resolved to: 127.0.0.2
=== TEST 4: update balancer if the DNS result changed
--- extra_init_by_lua
local etcd = require("apisix.core.etcd")
- etcd.switch_proxy = function ()
+ etcd.get_etcd_syncer = function ()
return etcd.new()
end
diff --git a/t/deployment/grpc/conf_server.t b/t/deployment/grpc/conf_server.t
new file mode 100644
index 000000000..a6ac47a59
--- /dev/null
+++ b/t/deployment/grpc/conf_server.t
@@ -0,0 +1,165 @@
+#
+# 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.
+#
+use t::APISIX;
+
+my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
+my $version = eval { `$nginx_binary -V 2>&1` };
+
+if ($version !~ m/\/apisix-nginx-module/) {
+ plan(skip_all => "apisix-nginx-module not installed");
+} else {
+ plan('no_plan');
+}
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!$block->request) {
+ $block->set_value("request", "GET /t");
+ }
+
+});
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: sync in https
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ local t = require("lib.test_admin").test
+
+ local consumers, _ = core.config.new("/consumers", {
+ automatic = true,
+ item_schema = core.schema.consumer,
+ })
+
+ ngx.sleep(0.6)
+ local idx = consumers.prev_index
+
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jobs",
+ "plugins": {
+ "basic-auth": {
+ "username": "jobs",
+ "password": "678901"
+ }
+ }
+ }]])
+
+ ngx.sleep(2)
+ local new_idx = consumers.prev_index
+ if new_idx > idx then
+ ngx.say("prev_index updated")
+ else
+ ngx.say("prev_index not update")
+ end
+ }
+ }
+--- response_body
+prev_index updated
+--- yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ admin:
+ admin_key: ~
+ etcd:
+ use_grpc: true
+ prefix: "/apisix"
+ host:
+ - https://127.0.0.1:12379
+ tls:
+ verify: false
+
+
+
+=== TEST 2: mix ip & domain
+--- config
+ location /t {
+ content_by_lua_block {
+ local etcd = require("apisix.core.etcd")
+ assert(etcd.set("/apisix/test", "foo"))
+ local res = assert(etcd.get("/apisix/test"))
+ ngx.say(res.body.node.value)
+ }
+ }
+--- yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ prefix: "/apisix"
+ host:
+ - http://127.0.0.2:2379
+ - http://localhost:2379
+ - http://[::1]:2379
+--- response_body
+foo
+
+
+
+=== TEST 3: check default SNI
+--- http_config
+server {
+ listen 12345 http2 ssl;
+ ssl_certificate cert/apisix.crt;
+ ssl_certificate_key cert/apisix.key;
+
+ ssl_certificate_by_lua_block {
+ local ngx_ssl = require "ngx.ssl"
+ ngx.log(ngx.WARN, "Receive SNI: ", ngx_ssl.server_name())
+ }
+
+ location / {
+ grpc_pass grpc://127.0.0.1:2379;
+ }
+}
+--- config
+ location /t {
+ content_by_lua_block {
+ local etcd = require("apisix.core.etcd")
+ assert(etcd.set("/apisix/test", "foo"))
+ local res = assert(etcd.get("/apisix/test"))
+ ngx.say(res.body.node.value)
+ }
+ }
+--- response_body
+foo
+--- yaml_config
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ use_grpc: true
+ prefix: "/apisix"
+ host:
+ - https://127.0.0.1:12379
+ - https://localhost:12345
+ timeout: 1
+ tls:
+ verify: false
+--- error_log
+Receive SNI: localhost
diff --git a/t/deployment/grpc/mtls.t b/t/deployment/grpc/mtls.t
new file mode 100644
index 000000000..abe0ea385
--- /dev/null
+++ b/t/deployment/grpc/mtls.t
@@ -0,0 +1,118 @@
+#
+# 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.
+#
+use t::APISIX;
+
+my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
+my $version = eval { `$nginx_binary -V 2>&1` };
+
+if ($version !~ m/\/apisix-nginx-module/) {
+ plan(skip_all => "apisix-nginx-module not installed");
+} else {
+ plan('no_plan');
+}
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!$block->request) {
+ $block->set_value("request", "GET /t");
+ }
+
+});
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: mTLS for control plane
+--- exec
+curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k
https://localhost:12345/version
+--- response_body eval
+qr/"etcdserver":/
+--- yaml_config
+deployment:
+ role: control_plane
+ role_control_plane:
+ config_provider: etcd
+ conf_server:
+ listen: 0.0.0.0:12345
+ cert: t/certs/mtls_server.crt
+ cert_key: t/certs/mtls_server.key
+ client_ca_cert: t/certs/mtls_ca.crt
+ etcd:
+ use_grpc: true
+ prefix: "/apisix"
+ host:
+ - http://127.0.0.1:2379
+ certs:
+ cert: t/certs/mtls_client.crt
+ cert_key: t/certs/mtls_client.key
+ trusted_ca_cert: t/certs/mtls_ca.crt
+
+
+
+=== TEST 2: no client certificate
+--- exec
+curl -k https://localhost:12345/version
+--- response_body eval
+qr/No required SSL certificate was sent/
+--- yaml_config
+deployment:
+ role: control_plane
+ role_control_plane:
+ config_provider: etcd
+ conf_server:
+ listen: 0.0.0.0:12345
+ cert: t/certs/mtls_server.crt
+ cert_key: t/certs/mtls_server.key
+ client_ca_cert: t/certs/mtls_ca.crt
+ etcd:
+ use_grpc: true
+ prefix: "/apisix"
+ host:
+ - http://127.0.0.1:2379
+ certs:
+ cert: t/certs/mtls_client.crt
+ cert_key: t/certs/mtls_client.key
+ trusted_ca_cert: t/certs/mtls_ca.crt
+
+
+
+=== TEST 3: wrong client certificate
+--- exec
+curl --cert t/certs/apisix.crt --key t/certs/apisix.key -k
https://localhost:12345/version
+--- response_body eval
+qr/The SSL certificate error/
+--- yaml_config
+deployment:
+ role: control_plane
+ role_control_plane:
+ config_provider: etcd
+ conf_server:
+ listen: 0.0.0.0:12345
+ cert: t/certs/mtls_server.crt
+ cert_key: t/certs/mtls_server.key
+ client_ca_cert: t/certs/mtls_ca.crt
+ etcd:
+ use_grpc: true
+ prefix: "/apisix"
+ host:
+ - http://127.0.0.1:2379
+ certs:
+ cert: t/certs/mtls_client.crt
+ cert_key: t/certs/mtls_client.key
+ trusted_ca_cert: t/certs/mtls_ca.crt
diff --git a/t/discovery/nacos.t b/t/discovery/nacos.t
index 39a6717b3..9af1ee14a 100644
--- a/t/discovery/nacos.t
+++ b/t/discovery/nacos.t
@@ -18,6 +18,7 @@ use t::APISIX 'no_plan';
repeat_each(1);
log_level('info');
+worker_connections(256);
no_root_location();
no_shuffle();
workers(4);
diff --git a/t/node/ewma.t b/t/node/ewma.t
index c32dbc01a..776a6512a 100644
--- a/t/node/ewma.t
+++ b/t/node/ewma.t
@@ -20,6 +20,7 @@ repeat_each(1);
#no_long_string();
no_root_location();
log_level('info');
+worker_connections(256);
run_tests;
__DATA__
diff --git a/t/node/grpc-proxy-mtls.t b/t/node/grpc-proxy-mtls.t
index 3c974fed1..b238431e2 100644
--- a/t/node/grpc-proxy-mtls.t
+++ b/t/node/grpc-proxy-mtls.t
@@ -56,8 +56,8 @@ routes:
upstream:
scheme: grpcs
tls:
- client_cert: "-----BEGIN
CERTIFICATE-----\nMIIDOjCCAiICAwD6zzANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJjbjESMBAG\nA1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxDTALBgNVBAoMBGFwaTcx\nDDAKBgNVBAsMA29wczEWMBQGA1UEAwwNY2EuYXBpc2l4LmRldjAeFw0yMDA2MjAx\nMzE1MDBaFw0zMDA3MDgxMzE1MDBaMF0xCzAJBgNVBAYTAmNuMRIwEAYDVQQIDAlH\ndWFuZ0RvbmcxDTALBgNVBAoMBGFwaTcxDzANBgNVBAcMBlpodUhhaTEaMBgGA1UE\nAwwRY2xpZW50LmFwaXNpeC5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQCfKI8uiEH/ifZikSnRa3/E2B4ohVWRwjo/IxyDE
[...]
- client_key: "-----BEGIN RSA PRIVATE
KEY-----\nMIIEpAIBAAKCAQEAnyiPLohB/4n2YpEp0Wt/xNgeKIVVkcI6PyMcgxFqJoEeLS5N\naUiYT/+Egi1rjEExVk20qrdSBWMuGW1Uhx8hqDT5iRqx0SQhhPrIKX859Bo1eJV0\nDyQ9JOhkdQl9jKNU1nRakifx3OQEMHEBZz36CwMLAcuMqq5Zn/emQFMrZf+2ZI3+\nD+5iZCR7TP1oEkdKRoY2UwBkX+QyVqDudZIt4tySPteZjoZp5wqZ5LJxlT35fdqv\ndh8/+L94qhPlE4T2EaXBm53XczLz2gl4mr4PAf7ti1W5+JdGnWpqkBnqTgIw/9ca\n2jlT9lttltD87Q1yeKy3vnGqTUuKBrklH5CBDQIDAQABAoIBAHDe5bPdQ9jCcW3z\nfpGax/DER5b6//UvpfkSoGy/E+Wcmdb2yEVLC2FoVw
[...]
+ client_cert: "-----BEGIN
CERTIFICATE-----\nMIIDUzCCAjugAwIBAgIURw+Rc5FSNUQWdJD+quORtr9KaE8wDQYJKoZIhvcNAQEN\nBQAwWDELMAkGA1UEBhMCY24xEjAQBgNVBAgMCUd1YW5nRG9uZzEPMA0GA1UEBwwG\nWmh1SGFpMRYwFAYDVQQDDA1jYS5hcGlzaXguZGV2MQwwCgYDVQQLDANvcHMwHhcN\nMjIxMjAxMTAxOTU3WhcNNDIwODE4MTAxOTU3WjBOMQswCQYDVQQGEwJjbjESMBAG\nA1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxGjAYBgNVBAMMEWNsaWVu\ndC5hcGlzaXguZGV2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzypq\nkrsJ8MaqpS0kr2SboE9aRKOJzd6mY3AZLq3tFpio5cK5o
[...]
+ client_key: "-----BEGIN RSA PRIVATE
KEY-----\nMIIEpAIBAAKCAQEAzypqkrsJ8MaqpS0kr2SboE9aRKOJzd6mY3AZLq3tFpio5cK5\noIHkQLfeaaLcd4ycFcZwFTpxc+Eth6I0X9on+j4tEibc5IpDnRSAQlzHZzlrOG6W\nxcOza4VmfcrKqj27oodroqXv05r/5yIoRrEN9ZXfA8n2OnjhkP+C3Q68L6dBtPpv\n+e6HaAuw8MvcsEo+MQwucTZyWqWT2UzKVzToW29dHRW+yZGuYNWRh15X09VSvx+E\n0s+uYKzN0Cyef2C6VtBJKmJ3NtypAiPqw7Ebfov2Ym/zzU9pyWPi3P1mYPMKQqUT\n/FpZSXm4iSy0a5qTYhkFrFdV1YuYYZL5YGl9aQIDAQABAoIBAD7tUG//lnZnsj/4\nJXONaORaFj5ROrOpFPuRemS+egzqFCuuaXpC2lV6RH
[...]
nodes:
"127.0.0.1:50053": 1
type: roundrobin
@@ -85,8 +85,8 @@ routes:
upstream:
scheme: grpcs
tls:
- client_cert: "-----BEGIN
CERTIFICATE-----\nMIIDOjCCAiICAwD6zzANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJjbjESMBAG\nA1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxDTALBgNVBAoMBGFwaTcx\nDDAKBgNVBAsMA29wczEWMBQGA1UEAwwNY2EuYXBpc2l4LmRldjAeFw0yMDA2MjAx\nMzE1MDBaFw0zMDA3MDgxMzE1MDBaMF0xCzAJBgNVBAYTAmNuMRIwEAYDVQQIDAlH\ndWFuZ0RvbmcxDTALBgNVBAoMBGFwaTcxDzANBgNVBAcMBlpodUhhaTEaMBgGA1UE\nAwwRY2xpZW50LmFwaXNpeC5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQCfKI8uiEH/ifZikSnRa3/E2B4ohVWRwjo/IxyDE
[...]
- client_key: "-----BEGIN RSA PRIVATE
KEY-----\nMIIEpAIBAAKCAQEAnyiPLohB/4n2YpEp0Wt/xNgeKIVVkcI6PyMcgxFqJoEeLS5N\naUiYT/+Egi1rjEExVk20qrdSBWMuGW1Uhx8hqDT5iRqx0SQhhPrIKX859Bo1eJV0\nDyQ9JOhkdQl9jKNU1nRakifx3OQEMHEBZz36CwMLAcuMqq5Zn/emQFMrZf+2ZI3+\nD+5iZCR7TP1oEkdKRoY2UwBkX+QyVqDudZIt4tySPteZjoZp5wqZ5LJxlT35fdqv\ndh8/+L94qhPlE4T2EaXBm53XczLz2gl4mr4PAf7ti1W5+JdGnWpqkBnqTgIw/9ca\n2jlT9lttltD87Q1yeKy3vnGqTUuKBrklH5CBDQIDAQABAoIBAHDe5bPdQ9jCcW3z\nfpGax/DER5b6//UvpfkSoGy/E+Wcmdb2yEVLC2FoVw
[...]
+ client_cert: "-----BEGIN
CERTIFICATE-----\nMIIDUzCCAjugAwIBAgIURw+Rc5FSNUQWdJD+quORtr9KaE8wDQYJKoZIhvcNAQEN\nBQAwWDELMAkGA1UEBhMCY24xEjAQBgNVBAgMCUd1YW5nRG9uZzEPMA0GA1UEBwwG\nWmh1SGFpMRYwFAYDVQQDDA1jYS5hcGlzaXguZGV2MQwwCgYDVQQLDANvcHMwHhcN\nMjIxMjAxMTAxOTU3WhcNNDIwODE4MTAxOTU3WjBOMQswCQYDVQQGEwJjbjESMBAG\nA1UECAwJR3VhbmdEb25nMQ8wDQYDVQQHDAZaaHVIYWkxGjAYBgNVBAMMEWNsaWVu\ndC5hcGlzaXguZGV2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzypq\nkrsJ8MaqpS0kr2SboE9aRKOJzd6mY3AZLq3tFpio5cK5o
[...]
+ client_key: "-----BEGIN RSA PRIVATE
KEY-----\nMIIEpAIBAAKCAQEAzypqkrsJ8MaqpS0kr2SboE9aRKOJzd6mY3AZLq3tFpio5cK5\noIHkQLfeaaLcd4ycFcZwFTpxc+Eth6I0X9on+j4tEibc5IpDnRSAQlzHZzlrOG6W\nxcOza4VmfcrKqj27oodroqXv05r/5yIoRrEN9ZXfA8n2OnjhkP+C3Q68L6dBtPpv\n+e6HaAuw8MvcsEo+MQwucTZyWqWT2UzKVzToW29dHRW+yZGuYNWRh15X09VSvx+E\n0s+uYKzN0Cyef2C6VtBJKmJ3NtypAiPqw7Ebfov2Ym/zzU9pyWPi3P1mYPMKQqUT\n/FpZSXm4iSy0a5qTYhkFrFdV1YuYYZL5YGl9aQIDAQABAoIBAD7tUG//lnZnsj/4\nJXONaORaFj5ROrOpFPuRemS+egzqFCuuaXpC2lV6RH
[...]
nodes:
"127.0.0.1:50053": 1
type: roundrobin
diff --git a/t/node/healthcheck-stop-checker.t
b/t/node/healthcheck-stop-checker.t
index b8a47dccb..1a5eaf286 100644
--- a/t/node/healthcheck-stop-checker.t
+++ b/t/node/healthcheck-stop-checker.t
@@ -32,6 +32,30 @@ no_root_location();
no_shuffle();
worker_connections(256);
+# the healthcheck stop test requires exiting worker to keep watching etcd for
a while,
+# which is not the case when using gRPC.
+my $yaml_config = <<_EOC_;
+deployment:
+ role: traditional
+ role_traditional:
+ config_provider: etcd
+ etcd:
+ prefix: "/apisix"
+ host:
+ - "http://127.0.0.1:2379"
+ use_grpc: false
+ admin:
+ admin_key: null
+_EOC_
+
+add_block_preprocessor(sub {
+ my ($block) = @_;
+
+ if (!$block->yaml_config) {
+ $block->set_value("yaml_config", $yaml_config);
+ }
+});
+
run_tests();
__DATA__
@@ -141,6 +165,15 @@ create new checker: table: 0x
content_by_lua_block {
local t = require("lib.test_admin").test
+ -- release the clean handler of previous test
+ local code, _, body = t('/apisix/admin/routes/1', "DELETE")
+
+ if code > 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+
local code, _, body = t('/apisix/admin/upstreams/stopchecker',
"PUT",
[[{"type":"roundrobin","nodes":{"127.0.0.1:1980":1,"127.0.0.1:1981":1},"checks":{"active":{"http_path":"/status","healthy":{"interval":1,"successes":1},"unhealthy":{"interval":1,"http_failures":2}}}}]]
@@ -152,7 +185,6 @@ create new checker: table: 0x
return
end
- -- release the clean handler of previous test
local code, _, body = t('/apisix/admin/routes/1',
"PUT",
[[{"uri":"/server_port","upstream_id":"stopchecker"}]]
diff --git a/t/plugin/grpc-transcode2.t b/t/plugin/grpc-transcode2.t
index 7dc42789a..0f7cc8d0b 100644
--- a/t/plugin/grpc-transcode2.t
+++ b/t/plugin/grpc-transcode2.t
@@ -565,8 +565,9 @@ qr/request log: \{.*body":\"\{\\"result\\":3}/
local pb = require("pb")
local old_f = pb.option
pb.option = function(o)
- if o ~= "int64_as_string" then
- -- filter out options set by other components
+ if o ~= "int64_as_string" and o ~= "int64_as_number" then
+ -- filter out options set by other components.
+ -- we can still test some options like enum_as_name
ngx.log(ngx.WARN, "set protobuf option: ", o)
end
return old_f(o)
@@ -675,7 +676,6 @@ set protobuf option: enum_as_name
set protobuf option: auto_default_values
set protobuf option: disable_hooks
set protobuf option: enum_as_name
-set protobuf option: int64_as_number
set protobuf option: enum_as_name
@@ -685,8 +685,9 @@ set protobuf option: enum_as_name
local pb = require("pb")
local old_f = pb.option
pb.option = function(o)
- if o ~= "int64_as_string" then
+ if o ~= "int64_as_string" and o ~= "int64_as_number" then
-- filter out options set by other components
+ -- we can still test some options like enum_as_name
ngx.log(ngx.WARN, "set protobuf option: ", o)
end
return old_f(o)
@@ -793,4 +794,3 @@ qr/set protobuf option: \w+/
set protobuf option: auto_default_values
set protobuf option: disable_hooks
set protobuf option: enum_as_name
-set protobuf option: int64_as_number
diff --git a/t/stream-node/random.t b/t/stream-node/random.t
index 3df62d340..dfe939c3a 100644
--- a/t/stream-node/random.t
+++ b/t/stream-node/random.t
@@ -18,6 +18,7 @@ use t::APISIX 'no_plan';
workers(4);
log_level('info');
+worker_connections(256);
repeat_each(1);
no_long_string();
no_root_location();