Skip to content
Open
Show file tree
Hide file tree
Changes from all 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/ngx_tpl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,9 @@ http {
{% if enable_admin then %}
server {
{%if https_admin then%}
{% for _, admin_server_addr in ipairs(admin_server_addrs) do %}
listen {* admin_server_addr *} ssl;
{% end %}

ssl_certificate {* admin_api_mtls.admin_ssl_cert *};
ssl_certificate_key {* admin_api_mtls.admin_ssl_cert_key *};
Expand All @@ -636,7 +638,9 @@ http {
{% end %}

{% else %}
{% for _, admin_server_addr in ipairs(admin_server_addrs) do %}
listen {* admin_server_addr *};
{% end %}
{%end%}
log_not_found off;

Expand Down
28 changes: 19 additions & 9 deletions apisix/cli/ops.lua
Original file line number Diff line number Diff line change
Expand Up @@ -426,20 +426,30 @@ Please modify "admin_key" in conf/config.yaml .
default_port, configured_port)
local ip = configured_ip or default_ip
local port = tonumber(configured_port) or default_port
if ports_to_check[port] ~= nil then
-- allow the same service (e.g. admin) to reuse one port across multiple
-- listen addresses, which is required by IPv4 + IPv6 dual-stack listening
if ports_to_check[port] ~= nil and ports_to_check[port] ~= port_name then
util.die(port_name .. " ", port, " conflicts with ", ports_to_check[port], "\n")
end
ports_to_check[port] = port_name
return ip .. ":" .. port
end

-- listen in admin use a separate port, support specific IP, compatible with the original style
local admin_server_addr
-- admin_listen supports both a single {ip=, port=} object and an array of them.
-- The array form allows listening on multiple addresses, e.g. IPv4 + IPv6 dual-stack.
local admin_server_addrs = {}
if yaml_conf.apisix.enable_admin then
local ip = yaml_conf.deployment.admin.admin_listen.ip
local port = yaml_conf.deployment.admin.admin_listen.port
admin_server_addr = validate_and_get_listen_addr("admin port", "0.0.0.0", ip,
9180, port)
local admin_listen = yaml_conf.deployment.admin.admin_listen
if admin_listen[1] ~= nil then
for _, listen in ipairs(admin_listen) do
table_insert(admin_server_addrs, validate_and_get_listen_addr(
"admin port", "0.0.0.0", listen.ip, 9180, listen.port))
end
else
table_insert(admin_server_addrs, validate_and_get_listen_addr(
"admin port", "0.0.0.0", admin_listen.ip, 9180, admin_listen.port))
end
end

local status_server_addr
Expand Down Expand Up @@ -701,9 +711,9 @@ Please modify "admin_key" in conf/config.yaml .
local role = yaml_conf.deployment.role
env.deployment_role = role

if role == "control_plane" and not admin_server_addr then
if role == "control_plane" and #admin_server_addrs == 0 then
local listen = node_listen[1]
admin_server_addr = str_format("%s:%s", listen.ip, listen.port)
table_insert(admin_server_addrs, str_format("%s:%s", listen.ip, listen.port))
end
end

Expand All @@ -728,7 +738,7 @@ Please modify "admin_key" in conf/config.yaml .
enabled_stream_plugins = enabled_stream_plugins,
dubbo_upstream_multiplex_count = dubbo_upstream_multiplex_count,
status_server_addr = status_server_addr,
admin_server_addr = admin_server_addr,
admin_server_addrs = admin_server_addrs,
control_server_addr = control_server_addr,
prometheus_server_addr = prometheus_server_addr,
proxy_mirror_timeouts = proxy_mirror_timeouts,
Expand Down
26 changes: 22 additions & 4 deletions apisix/cli/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,30 @@ local admin_schema = {
}
},
admin_listen = {
properties = {
listen = { type = "string" },
port = { type = "integer" },
-- compatible with both the single-address object form and the
-- multi-address array form (IPv4 + IPv6 dual-stack)
oneOf = {
{
type = "object",
properties = {
ip = { type = "string" },
port = { type = "integer" },
},
},
{
type = "array",
minItems = 1,
items = {
type = "object",
properties = {
ip = { type = "string" },
port = { type = "integer" },
},
},
},
},
default = {
listen = "0.0.0.0",
ip = "0.0.0.0",
port = 9180,
}
},
Expand Down
7 changes: 7 additions & 0 deletions conf/config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,13 @@ deployment: # Deployment configurations
admin_listen: # Set the Admin API listening addresses.
ip: 0.0.0.0 # Set listening IP.
port: 9180 # Set listening port. Beware of port conflict with node_listen.
# admin_listen also accepts an array to listen on multiple addresses at once,
# for example IPv4 + IPv6 dual-stack (the same port may be reused across them):
# admin_listen:
# - ip: 0.0.0.0
# port: 9180
# - ip: "[::]"
# port: 9180

# https_admin: true # Enable SSL for Admin API on IP and port specified in admin_listen.
# Use admin_api_mtls.admin_ssl_cert and admin_api_mtls.admin_ssl_cert_key.
Expand Down
30 changes: 30 additions & 0 deletions t/cli/test_admin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,36 @@ make stop

echo "passed: admin https enabled"

# check admin_listen supports an array of addresses (IPv4 + IPv6 dual-stack)

git checkout conf/config.yaml

echo '
apisix:
enable_admin: true
deployment:
admin:
admin_listen:
- ip: 0.0.0.0
port: 9180
- ip: "[::]"
port: 9180
' > conf/config.yaml

make init

if ! grep "listen 0.0.0.0:9180;" conf/nginx.conf > /dev/null; then
echo "failed: admin_listen array should generate the IPv4 listen directive"
exit 1
fi

if ! grep "listen \[::\]:9180;" conf/nginx.conf > /dev/null; then
echo "failed: admin_listen array should generate the IPv6 listen directive"
exit 1
fi

echo "passed: admin_listen supports IPv4 + IPv6 dual-stack"

echo '
apisix:
enable_admin: true
Expand Down
Loading