Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support configurating the node listening address #4856

Merged
merged 13 commits into from
Sep 2, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apisix/cli/file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ local function path_is_multi_type(path, type_val)
return true
end

if path == "apisix->ssl->listen" and type_val == "number" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we remove it now?

return true
end

return false
end

Expand Down
17 changes: 3 additions & 14 deletions apisix/cli/ngx_tpl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,11 @@ http {

server {
{% for _, item in ipairs(node_listen) do %}
listen {* item.port *} default_server {% if enable_reuseport then %} reuseport {% end %} {% if item.enable_http2 then %} http2 {% end %};
listen {* item.ip *}:{* item.port *} default_server {% if item.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
{% end %}
{% if ssl.enable then %}
{% for _, port in ipairs(ssl.listen_port) do %}
listen {* port *} ssl default_server {% if ssl.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
{% for _, item in ipairs(ssl.listen) do %}
listen {* item.ip *}:{* item.port *} ssl default_server {% if item.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
{% end %}
{% end %}
{% if proxy_protocol and proxy_protocol.listen_http_port then %}
Expand All @@ -473,17 +473,6 @@ http {
listen {* proxy_protocol.listen_https_port *} ssl default_server {% if ssl.enable_http2 then %} http2 {% end %} proxy_protocol;
{% end %}

{% if enable_ipv6 then %}
{% for _, item in ipairs(node_listen) do %}
listen [::]:{* item.port *} default_server {% if enable_reuseport then %} reuseport {% end %} {% if item.enable_http2 then %} http2 {% end %};
{% end %}
{% if ssl.enable then %}
{% for _, port in ipairs(ssl.listen_port) do %}
listen [::]:{* port *} ssl default_server {% if ssl.enable_http2 then %} http2 {% end %} {% if enable_reuseport then %} reuseport {% end %};
{% end %}
{% end %}
{% end %} {% -- if enable_ipv6 %}

server_name _;

{% if ssl.enable then %}
Expand Down
127 changes: 107 additions & 20 deletions apisix/cli/ops.lua
Original file line number Diff line number Diff line change
Expand Up @@ -461,45 +461,132 @@ Please modify "admin_key" in conf/config.yaml .
end
end

-- support multiple ports listen, compatible with the original style
if type(yaml_conf.apisix.node_listen) == "number" then
local ip_port_to_check = {}

local function listen_table_insert(listen_table, scheme, ip, port, enable_http2, enable_ipv6)
if type(ip) ~= "string" then
util.die(scheme, " listen ip format error, must be string", "\n")
end

if type(port) ~= "number" then
util.die(scheme, " listen port format error, must be number", "\n")
end

if ports_to_check[port] ~= nil then
util.die(scheme, " listen port ", port, " conflicts with ",
ports_to_check[port], "\n")
end

local addr = ip .. ":" .. port
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add scheme to this key so that we can reduce a branch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the config apisix.node_listen[] also has the property enable_http2, the branch can be reduced.
Port conflicts should be checked at the TCP layer, not the scheme http/https, so the scheme would not be add to this key.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


if ports_to_check[yaml_conf.apisix.node_listen] ~= nil then
util.die("node_listen port ", yaml_conf.apisix.node_listen,
" conflicts with ", ports_to_check[yaml_conf.apisix.node_listen], "\n")
if ip_port_to_check[addr] == nil then
table_insert(listen_table,
{ip = ip, port = port, enable_http2 = enable_http2})
ip_port_to_check[addr] = scheme
end

local node_listen = {{port = yaml_conf.apisix.node_listen}}
yaml_conf.apisix.node_listen = node_listen
if enable_ipv6 then
ip = "[::]"
addr = ip .. ":" .. port

if ip_port_to_check[addr] == nil then
table_insert(listen_table,
{ip = ip, port = port, enable_http2 = enable_http2})
ip_port_to_check[addr] = scheme
end
end
end

local node_listen = {}
-- listen in http, support multiple ports and specific IP, compatible with the original style
if type(yaml_conf.apisix.node_listen) == "number" then
listen_table_insert(node_listen, "http", "0.0.0.0", yaml_conf.apisix.node_listen,
false, yaml_conf.apisix.enable_ipv6)
elseif type(yaml_conf.apisix.node_listen) == "table" then
local node_listen = {}
for index, value in ipairs(yaml_conf.apisix.node_listen) do
for _, value in ipairs(yaml_conf.apisix.node_listen) do
if type(value) == "number" then
listen_table_insert(node_listen, "http", "0.0.0.0", value,
false, yaml_conf.apisix.enable_ipv6)
elseif type(value) == "table" then
local ip = value.ip
local port = value.port
local enable_ipv6 = false
local enable_http2 = value.enable_http2

if ip == nil then
ip = "0.0.0.0"
if yaml_conf.apisix.enable_ipv6 then
enable_ipv6 = true
end
end

if port == nil then
port = 9080
end

if ports_to_check[value] ~= nil then
util.die("node_listen port ", value, " conflicts with ",
ports_to_check[value], "\n")
if enable_http2 == nil then
enable_http2 = false
end

table_insert(node_listen, index, {port = value})
listen_table_insert(node_listen, "http", ip, port,
enable_http2, enable_ipv6)
end
end
end
yaml_conf.apisix.node_listen = node_listen

local ssl_listen = {}
-- listen in https, support multiple ports, support specific IP
if type(yaml_conf.apisix.ssl.listen) == "number" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, the related code has also been removed.

listen_table_insert(ssl_listen, "https", "0.0.0.0", yaml_conf.apisix.ssl.listen,
yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
elseif type(yaml_conf.apisix.ssl.listen) == "table" then
for _, value in ipairs(yaml_conf.apisix.ssl.listen) do
if type(value) == "number" then
listen_table_insert(ssl_listen, "https", "0.0.0.0", value,
yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
elseif type(value) == "table" then
local ip = value.ip
local port = value.port
local enable_ipv6 = false
local enable_http2 = (value.enable_http2 or yaml_conf.apisix.ssl.enable_http2)

if ip == nil then
ip = "0.0.0.0"
if yaml_conf.apisix.enable_ipv6 then
enable_ipv6 = true
end
end

if port == nil then
port = 9443
end

if type(value.port) == "number" and ports_to_check[value.port] ~= nil then
util.die("node_listen port ", value.port, " conflicts with ",
ports_to_check[value.port], "\n")
if enable_http2 == nil then
enable_http2 = false
end

table_insert(node_listen, index, value)
listen_table_insert(ssl_listen, "https", ip, port,
enable_http2, enable_ipv6)
end
end
yaml_conf.apisix.node_listen = node_listen
end

-- listen in https, compatible with the original style
if type(yaml_conf.apisix.ssl.listen_port) == "number" then
local listen_port = {yaml_conf.apisix.ssl.listen_port}
yaml_conf.apisix.ssl.listen_port = listen_port
listen_table_insert(ssl_listen, "https", "0.0.0.0", yaml_conf.apisix.ssl.listen_port,
yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
elseif type(yaml_conf.apisix.ssl.listen_port) == "table" then
for _, value in ipairs(yaml_conf.apisix.ssl.listen_port) do
if type(value) == "number" then
listen_table_insert(ssl_listen, "https", "0.0.0.0", value,
yaml_conf.apisix.ssl.enable_http2, yaml_conf.apisix.enable_ipv6)
end
end
end

yaml_conf.apisix.ssl.listen = ssl_listen

if yaml_conf.apisix.ssl.ssl_trusted_certificate ~= nil then
local cert_path = yaml_conf.apisix.ssl.ssl_trusted_certificate
-- During validation, the path is relative to PWD
Expand Down
16 changes: 14 additions & 2 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ 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_debug: false
Expand Down Expand Up @@ -115,8 +120,15 @@ apisix:
enable_resolv_search_opt: true # enable search option in resolv.conf
ssl:
enable: true
enable_http2: true
listen_port: 9443
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)
Expand Down
1 change: 1 addition & 0 deletions t/admin/plugins-reload.t
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ Instance report fails
ngx.status = code
end
ngx.say(body)
ngx.sleep(0.1)
}
}
--- request
Expand Down
2 changes: 1 addition & 1 deletion t/cli/test_control.sh
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ apisix:
' > conf/config.yaml

out=$(make init 2>&1 || true)
if ! echo "$out" | grep "node_listen port 9090 conflicts with control"; then
if ! echo "$out" | grep "http listen port 9090 conflicts with control"; then
echo "failed: can't detect port conflicts"
exit 1
fi
Expand Down
58 changes: 53 additions & 5 deletions t/cli/test_main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ echo "passed: error_log directive uses warn level by default"

# check whether the 'reuseport' is in nginx.conf .

grep -E "listen 9080.*reuseport" conf/nginx.conf > /dev/null
grep -E "listen 0.0.0.0:9080.*reuseport" conf/nginx.conf > /dev/null
if [ ! $? -eq 0 ]; then
echo "failed: nginx.conf file is missing reuseport configuration"
exit 1
Expand All @@ -64,7 +64,7 @@ apisix:

make init

grep "listen 8443 ssl" conf/nginx.conf > /dev/null
grep "listen 0.0.0.0:8443 ssl" conf/nginx.conf > /dev/null
if [ ! $? -eq 0 ]; then
echo "failed: failed to update ssl port"
exit 1
Expand Down Expand Up @@ -95,7 +95,7 @@ apisix:

make init

count_http_ipv4=`grep -c "listen 908." conf/nginx.conf || true`
count_http_ipv4=`grep -c "listen 0.0.0.0:908." conf/nginx.conf || true`
if [ $count_http_ipv4 -ne 3 ]; then
echo "failed: failed to support multiple ports listen in http with ipv4"
exit 1
Expand All @@ -107,7 +107,7 @@ if [ $count_http_ipv6 -ne 3 ]; then
exit 1
fi

count_https_ipv4=`grep -c "listen 944. ssl" conf/nginx.conf || true`
count_https_ipv4=`grep -c "listen 0.0.0.0:944. ssl" conf/nginx.conf || true`
if [ $count_https_ipv4 -ne 3 ]; then
echo "failed: failed to support multiple ports listen in https with ipv4"
exit 1
Expand All @@ -121,6 +121,54 @@ fi

echo "passed: support multiple ports listen in http and https"

# check support specific IP listen in http and https

echo "
apisix:
node_listen:
- ip: 127.0.0.1
port: 9081
- ip: 127.0.0.2
port: 9082
enable_http2: true
ssl:
enable_http2: false
tzssangglass marked this conversation as resolved.
Show resolved Hide resolved
listen:
- ip: 127.0.0.3
port: 9444
- ip: 127.0.0.4
port: 9445
enable_http2: true
" > conf/config.yaml

make init

count_http_specific_ip=`grep -c "listen 127.0.0..:908." conf/nginx.conf || true`
if [ $count_http_specific_ip -ne 2 ]; then
echo "failed: failed to support specific IP listen in http"
exit 1
fi

count_http_specific_ip_and_enable_http2=`grep -c "listen 127.0.0..:908. default_server http2" conf/nginx.conf || true`
if [ $count_http_specific_ip_and_enable_http2 -ne 1 ]; then
echo "failed: failed to support specific IP and enable http2 listen in http"
exit 1
fi

count_https_specific_ip=`grep -c "listen 127.0.0..:944. ssl" conf/nginx.conf || true`
if [ $count_https_specific_ip -ne 2 ]; then
echo "failed: failed to support specific IP listen in https"
exit 1
fi

count_https_specific_ip_and_enable_http2=`grep -c "listen 127.0.0..:944. ssl default_server http2" conf/nginx.conf || true`
if [ $count_https_specific_ip_and_enable_http2 -ne 1 ]; then
echo "failed: failed to support specific IP and enable http2 listen in https"
exit 1
fi

echo "passed: support specific IP listen in http and https"

# check default env
echo "
nginx_config:
Expand Down Expand Up @@ -345,7 +393,7 @@ if [ $count -ne 1 ]; then
exit 1
fi

count=`grep -c "listen 9080.*reuseport" conf/nginx.conf || true`
count=`grep -c "listen 0.0.0.0:9080.*reuseport" conf/nginx.conf || true`
if [ $count -ne 0 ]; then
echo "failed: reuseport should be disabled when enable enable_dev_mode"
exit 1
Expand Down
2 changes: 1 addition & 1 deletion t/cli/test_prometheus.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ plugin_attr:
' > conf/config.yaml

out=$(IP=127.0.0.1 PORT=9092 make init 2>&1 || true)
if ! echo "$out" | grep "node_listen port 9092 conflicts with prometheus"; then
if ! echo "$out" | grep "http listen port 9092 conflicts with prometheus"; then
echo "failed: can't detect port conflicts"
exit 1
fi
Expand Down