Skip to content

Commit

Permalink
feat: support pulling env vars from yaml keys (apache#9855)
Browse files Browse the repository at this point in the history
  • Loading branch information
shreemaan-abhishek authored and rubikplanet committed Aug 8, 2023
1 parent ef5460a commit 43c97ac
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 29 deletions.
81 changes: 53 additions & 28 deletions apisix/cli/file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,43 +54,67 @@ 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
return nil, err
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
Expand All @@ -108,6 +132,7 @@ local function resolve_conf_var(conf)

conf[key] = new_val
end
::continue::
end

return true
Expand Down
13 changes: 13 additions & 0 deletions docs/en/latest/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
13 changes: 13 additions & 0 deletions docs/zh/latest/admin-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 会检查资源间的引用关系,将会拒绝删除正在使用中的资源。
Expand Down
29 changes: 28 additions & 1 deletion t/cli/test_standalone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ standalone() {

trap standalone EXIT

# support environment variables
# support environment variables in yaml values
echo '
apisix:
enable_admin: false
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit 43c97ac

Please sign in to comment.