This is an automated email from the ASF dual-hosted git repository.
monkeydluffy 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 d80fc3bc9 feat: support pulling env vars from yaml keys (#9855)
d80fc3bc9 is described below
commit d80fc3bc97158617287a406c269f1bce2d67ab64
Author: Abhishek Choudhary <[email protected]>
AuthorDate: Fri Aug 4 14:40:32 2023 +0545
feat: support pulling env vars from yaml keys (#9855)
---
apisix/cli/file.lua | 81 +++++++++++++++++++++++++++++----------------
docs/en/latest/admin-api.md | 13 ++++++++
docs/zh/latest/admin-api.md | 13 ++++++++
t/cli/test_standalone.sh | 29 +++++++++++++++-
4 files changed, 107 insertions(+), 29 deletions(-)
diff --git a/apisix/cli/file.lua b/apisix/cli/file.lua
index af071a840..149c4e913 100644
--- a/apisix/cli/file.lua
+++ b/apisix/cli/file.lua
@@ -54,8 +54,59 @@ local function tab_is_array(t)
end
+local function var_sub(val)
+ local err
+ local var_used = false
+ -- we use '${{var}}' because '$var' and '${var}' are taken
+ -- by Nginx
+ local new_val = val:gsub("%$%{%{%s*([%w_]+[%:%=]?.-)%s*%}%}", function(var)
+ local i, j = var:find("%:%=")
+ local default
+ if i and j then
+ default = var:sub(i + 2, #var)
+ default = default:gsub('^%s*(.-)%s*$', '%1')
+ var = var:sub(1, i - 1)
+ end
+
+ local v = getenv(var) or default
+ if v then
+ if not exported_vars then
+ exported_vars = {}
+ end
+
+ exported_vars[var] = v
+ var_used = true
+ return v
+ end
+
+ err = "failed to handle configuration: " ..
+ "can't find environment variable " .. var
+ return ""
+ end)
+ return new_val, var_used, err
+end
+
+
local function resolve_conf_var(conf)
+ local new_keys = {}
for key, val in pairs(conf) do
+ -- avoid re-iterating the table for already iterated key
+ if new_keys[key] then
+ goto continue
+ end
+ -- substitute environment variables from conf keys
+ if type(key) == "string" then
+ local new_key, _, err = var_sub(key)
+ if err then
+ return nil, err
+ end
+ if new_key ~= key then
+ new_keys[new_key] = "dummy" -- we only care about checking the
key
+ conf.key = nil
+ conf[new_key] = val
+ key = new_key
+ end
+ end
if type(val) == "table" then
local ok, err = resolve_conf_var(val)
if not ok then
@@ -63,34 +114,7 @@ local function resolve_conf_var(conf)
end
elseif type(val) == "string" then
- local err
- local var_used = false
- -- we use '${{var}}' because '$var' and '${var}' are taken
- -- by Nginx
- local new_val = val:gsub("%$%{%{%s*([%w_]+[%:%=]?.-)%s*%}%}",
function(var)
- local i, j = var:find("%:%=")
- local default
- if i and j then
- default = var:sub(i + 2, #var)
- default = default:gsub('^%s*(.-)%s*$', '%1')
- var = var:sub(1, i - 1)
- end
-
- local v = getenv(var) or default
- if v then
- if not exported_vars then
- exported_vars = {}
- end
-
- exported_vars[var] = v
- var_used = true
- return v
- end
-
- err = "failed to handle configuration: " ..
- "can't find environment variable " .. var
- return ""
- end)
+ local new_val, var_used, err = var_sub(val)
if err then
return nil, err
@@ -108,6 +132,7 @@ local function resolve_conf_var(conf)
conf[key] = new_val
end
+ ::continue::
end
return true
diff --git a/docs/en/latest/admin-api.md b/docs/en/latest/admin-api.md
index 3071a3e00..787a61e98 100644
--- a/docs/en/latest/admin-api.md
+++ b/docs/en/latest/admin-api.md
@@ -103,6 +103,19 @@ deployment:
This will find the environment variable `ADMIN_KEY` first, and if it does not
exist, it will use `edd1c9f034335f136f87ad84b625c8f1` as the default value.
+You can also specify environment variables in yaml keys. This is specifically
useful in the `standalone` [mode](./deployment-modes.md#standalone) where you
can specify the upstream nodes as follows:
+
+```yaml title="./conf/apisix.yaml"
+routes:
+ -
+ uri: "/test"
+ upstream:
+ nodes:
+ "${{HOST_IP}}:${{PORT}}": 1
+ type: roundrobin
+#END
+```
+
### Force Delete
By default, the Admin API checks for references between resources and will
refuse to delete resources in use.
diff --git a/docs/zh/latest/admin-api.md b/docs/zh/latest/admin-api.md
index ab2625d94..e1fd063e8 100644
--- a/docs/zh/latest/admin-api.md
+++ b/docs/zh/latest/admin-api.md
@@ -105,6 +105,19 @@ deployment:
首先查找环境变量 `ADMIN_KEY`,如果该环境变量不存在,它将使用 `edd1c9f034335f136f87ad84b625c8f1` 作为默认值。
+您还可以在 yaml 键中指定环境变量。这在 `standalone` 模式 中特别有用,您可以在其中指定上游节点,如下所示:
+
+```yaml title="./conf/apisix.yaml"
+routes:
+ -
+ uri: "/test"
+ upstream:
+ nodes:
+ "${{HOST_IP}}:${{PORT}}": 1
+ type: roundrobin
+#END
+```
+
### 强制删除 {#force-delete}
默认情况下,Admin API 会检查资源间的引用关系,将会拒绝删除正在使用中的资源。
diff --git a/t/cli/test_standalone.sh b/t/cli/test_standalone.sh
index 2a3add666..a0d91c11c 100755
--- a/t/cli/test_standalone.sh
+++ b/t/cli/test_standalone.sh
@@ -26,7 +26,7 @@ standalone() {
trap standalone EXIT
-# support environment variables
+# support environment variables in yaml values
echo '
apisix:
enable_admin: false
@@ -69,6 +69,33 @@ 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: