blob: c1e728d7ace97054d4ee164800de4e9a0fd5855c [file]
#!/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
standalone() {
rm -f conf/apisix.yaml.link
clean_up
git checkout conf/apisix.yaml
}
trap standalone EXIT
# support environment variables in yaml values
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: ${{var_test_path}}
plugins:
proxy-rewrite:
uri: ${{var_test_proxy_rewrite_uri:=/apisix/nginx_status}}
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
# check for resolve variables
var_test_path=/test make init
if ! grep "env var_test_path;" conf/nginx.conf > /dev/null; then
echo "failed: failed to resolve variables"
exit 1
fi
# variable is valid
var_test_path=/test make run
sleep 0.1
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test)
if [ ! $code -eq 200 ]; then
echo "failed: resolve variables in apisix.yaml conf failed"
exit 1
fi
echo "passed: resolve variables in apisix.yaml conf success"
# support environment variables in yaml keys
echo '
routes:
-
uri: "/test"
plugins:
proxy-rewrite:
uri: "/apisix/nginx_status"
upstream:
nodes:
"${{HOST_IP}}:${{PORT}}": 1
type: roundrobin
#END
' > conf/apisix.yaml
# variable is valid
HOST_IP="127.0.0.1" PORT="9091" make init
HOST_IP="127.0.0.1" PORT="9091" make run
sleep 0.1
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test)
if [ ! $code -eq 200 ]; then
echo "failed: resolve variables in apisix.yaml conf failed"
fi
echo "passed: resolve variables in apisix.yaml conf success"
# configure standalone via deployment
echo '
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
var_test_path=/test make run
sleep 0.1
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/apisix/admin/routes)
if [ ! $code -eq 404 ]; then
echo "failed: admin API should be disabled automatically"
exit 1
fi
echo "passed: admin API should be disabled automatically"
# support environment variables
echo '
routes:
-
uri: ${{var_test_path}}
plugins:
proxy-rewrite:
uri: ${{var_test_proxy_rewrite_uri:=/apisix/nginx_status}}
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
var_test_path=/test make run
sleep 0.1
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test)
if [ ! $code -eq 200 ]; then
echo "failed: resolve variables in apisix.yaml conf failed"
exit 1
fi
echo "passed: resolve variables in apisix.yaml conf success"
# Avoid unnecessary config reloads
## Wait for a second else `st_ctime` won't increase
sleep 1
expected_config_reloads=$(grep "config file $(pwd)/conf/apisix.yaml reloaded." logs/error.log | wc -l)
## Create a symlink to change the link count and as a result `st_ctime`
ln conf/apisix.yaml conf/apisix.yaml.link
sleep 1
actual_config_reloads=$(grep "config file $(pwd)/conf/apisix.yaml reloaded." logs/error.log | wc -l)
if [ $expected_config_reloads -ne $actual_config_reloads ]; then
echo "failed: apisix.yaml was reloaded"
exit 1
fi
echo "passed: apisix.yaml was not reloaded"
make stop
sleep 0.5
# test: environment variable with large number should be preserved as string
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-large-number
plugins:
response-rewrite:
body: "${{APISIX_CLIENT_ID}}"
status_code: 200
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
# Test with large number that exceeds Lua double precision
APISIX_CLIENT_ID="356002209726529540" make init
if ! APISIX_CLIENT_ID="356002209726529540" make run > output.log 2>&1; then
cat output.log
echo "failed: large number in env var should not cause type conversion error"
exit 1
fi
sleep 0.1
# Verify the response body matches the exact large numeric string
code=$(curl -o /tmp/response_body -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-large-number)
body=$(cat /tmp/response_body)
if [ "$code" -ne 200 ]; then
echo "failed: expected 200 for /test-large-number, but got: $code, body: $body"
exit 1
fi
if [ "$body" != "356002209726529540" ]; then
echo "failed: large number env var was not preserved as string, got: $body"
exit 1
fi
make stop
sleep 0.5
echo "passed: large number in env var preserved as string in apisix.yaml"
# test: small numeric env vars in apisix.yaml should still be converted to number
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-small-number
plugins:
response-rewrite:
body: "hello"
status_code: ${{REWRITE_STATUS}}
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
REWRITE_STATUS="200" make init
if ! REWRITE_STATUS="200" make run > output.log 2>&1; then
cat output.log
echo "failed: small numeric env var should be converted to number in apisix.yaml"
exit 1
fi
sleep 0.1
code=$(curl -o /tmp/response_body -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-small-number)
body=$(cat /tmp/response_body)
if [ "$code" -ne 200 ]; then
echo "failed: expected 200 for /test-small-number, but got: $code, body: $body"
exit 1
fi
make stop
sleep 0.5
echo "passed: small numeric env var converted to number in apisix.yaml"
# test: config.yaml should still support type conversion (boolean)
echo '
routes: []
#END
' > conf/apisix.yaml
echo '
apisix:
enable_admin: ${{ENABLE_ADMIN}}
deployment:
role: traditional
role_traditional:
config_provider: yaml
etcd:
host:
- "http://127.0.0.1:2379"
' > conf/config.yaml
ENABLE_ADMIN=false make init
ENABLE_ADMIN=false make run
sleep 0.1
# If type conversion works, enable_admin is boolean false and admin API is disabled (404)
# If type conversion fails, enable_admin stays string "false" which is truthy, admin API is enabled
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/apisix/admin/routes)
if [ "$code" -ne 404 ]; then
echo "failed: expected 404 when admin API is disabled, but got: $code"
exit 1
fi
make stop
sleep 0.5
echo "passed: config.yaml still converts boolean env vars correctly"
# test: numeric env vars for upstream weight and retries in apisix.yaml
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-upstream-env
plugins:
proxy-rewrite:
uri: /apisix/nginx_status
upstream:
nodes:
"127.0.0.1:9091": ${{WEIGHT}}
type: roundrobin
retries: ${{RETRIES}}
#END
' > conf/apisix.yaml
WEIGHT="1" RETRIES="3" make init
if ! WEIGHT="1" RETRIES="3" make run > output.log 2>&1; then
cat output.log
echo "failed: numeric env vars for weight/retries should be converted to number"
exit 1
fi
sleep 0.1
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-upstream-env)
if [ "$code" -ne 200 ]; then
echo "failed: expected 200 for /test-upstream-env, but got: $code"
exit 1
fi
make stop
sleep 0.5
echo "passed: numeric env vars for upstream weight and retries converted to number in apisix.yaml"
# test: boolean env vars in apisix.yaml should be converted to boolean
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-bool-env
plugins:
redirect:
http_to_https: ${{REDIRECT_HTTPS}}
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
REDIRECT_HTTPS="true" make init
if ! REDIRECT_HTTPS="true" make run > output.log 2>&1; then
cat output.log
echo "failed: boolean env var should be converted to boolean in apisix.yaml"
exit 1
fi
sleep 0.1
# If boolean conversion works, redirect plugin returns 301
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-bool-env)
if [ "$code" -ne 301 ]; then
echo "failed: expected 301 redirect for /test-bool-env, but got: $code"
exit 1
fi
make stop
sleep 0.5
echo "passed: boolean env var converted to boolean in apisix.yaml"
# test: config.yaml should still support numeric type conversion
echo '
routes: []
#END
' > conf/apisix.yaml
echo '
apisix:
resolver_timeout: ${{RESOLVER_TIMEOUT}}
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
if ! RESOLVER_TIMEOUT=5 make init > output.log 2>&1; then
cat output.log
echo "failed: config.yaml should convert numeric env vars to number"
exit 1
fi
echo "passed: config.yaml still converts numeric env vars correctly"
# test: small numeric env var inside quoted string should stay as string
# (the exact scenario from issue #12932 — key-auth key expects a string,
# previously substituted numeric values were coerced to numbers and failed
# schema validation)
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-quoted-numeric
plugins:
key-auth: {}
proxy-rewrite:
uri: /apisix/nginx_status
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
consumers:
-
username: testuser
plugins:
key-auth:
key: "${{TEST_KEY}}"
#END
' > conf/apisix.yaml
TEST_KEY="12345" make init
if ! TEST_KEY="12345" make run > output.log 2>&1; then
cat output.log
echo "failed: quoted numeric env var should stay string and pass schema validation"
exit 1
fi
sleep 0.1
# With correct key header → 200
code=$(curl -o /dev/null -s -m 5 -w %{http_code} -H "apikey: 12345" http://127.0.0.1:9080/test-quoted-numeric)
if [ "$code" -ne 200 ]; then
echo "failed: expected 200 with correct apikey, but got: $code"
cat logs/error.log
exit 1
fi
# Without header → 401
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-quoted-numeric)
if [ "$code" -ne 401 ]; then
echo "failed: expected 401 without apikey, but got: $code"
exit 1
fi
make stop
sleep 0.5
echo "passed: quoted numeric env var preserved as string for key-auth consumer key"
# test: boolean env var inside quoted string should stay as string
# (previously a quoted "${{V}}" with V=true got post-parse coerced to a Lua
# boolean, which failed schema validation for string-typed plugin fields)
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-quoted-bool
plugins:
response-rewrite:
body: "${{BODY_VAL}}"
status_code: 200
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
BODY_VAL="true" make init
if ! BODY_VAL="true" make run > output.log 2>&1; then
cat output.log
echo "failed: quoted boolean env var should stay string"
exit 1
fi
sleep 0.1
code=$(curl -o /tmp/response_body -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-quoted-bool)
body=$(cat /tmp/response_body)
if [ "$code" -ne 200 ]; then
echo "failed: expected 200 for /test-quoted-bool, but got: $code, body: $body"
exit 1
fi
if [ "$body" != "true" ]; then
echo "failed: quoted bool env var was not preserved as string, got: $body"
exit 1
fi
make stop
sleep 0.5
echo "passed: quoted boolean env var preserved as string in apisix.yaml"
# test: default value fallback still works for unset env var
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-default-val
plugins:
response-rewrite:
body: "hello"
status_code: ${{UNSET_STATUS:=202}}
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
unset UNSET_STATUS
make init
if ! make run > output.log 2>&1; then
cat output.log
echo "failed: default value fallback should work"
exit 1
fi
sleep 0.1
code=$(curl -o /dev/null -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-default-val)
if [ "$code" -ne 202 ]; then
echo "failed: expected 202 from default fallback, but got: $code"
exit 1
fi
make stop
sleep 0.5
echo "passed: default value fallback (\${{VAR:=default}}) works"
# test: env var substitution inside a YAML key
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-key-sub
plugins:
"${{PLUGIN_NAME}}":
body: "key-sub-ok"
status_code: 200
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
PLUGIN_NAME="response-rewrite" make init
if ! PLUGIN_NAME="response-rewrite" make run > output.log 2>&1; then
cat output.log
echo "failed: env var in YAML key should be substituted before parsing"
exit 1
fi
sleep 0.1
code=$(curl -o /tmp/response_body -s -m 5 -w %{http_code} http://127.0.0.1:9080/test-key-sub)
body=$(cat /tmp/response_body)
if [ "$code" -ne 200 ] || [ "$body" != "key-sub-ok" ]; then
echo "failed: expected 200/key-sub-ok for /test-key-sub, got code: $code body: $body"
exit 1
fi
make stop
sleep 0.5
echo "passed: env var substitution inside YAML key"
# test: missing env var (no default) should produce a clear startup error
echo '
apisix:
enable_admin: false
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
' > conf/config.yaml
echo '
routes:
-
uri: /test-missing-var
plugins:
response-rewrite:
body: "hello"
status_code: ${{DEFINITELY_NOT_SET_VAR}}
upstream:
nodes:
"127.0.0.1:9091": 1
type: roundrobin
#END
' > conf/apisix.yaml
unset DEFINITELY_NOT_SET_VAR
if make init > output.log 2>&1; then
echo "failed: make init should fail when required env var is missing"
cat output.log
exit 1
fi
if ! grep "can't find environment variable DEFINITELY_NOT_SET_VAR" output.log > /dev/null; then
echo "failed: expected missing-env-var error message in init output"
cat output.log
exit 1
fi
echo "passed: missing env var produces clear startup error"
git checkout conf/config.yaml
git checkout conf/apisix.yaml