Skip to content

Commit dea16d7

Browse files
committed
fix(standalone): resolve env var references in config pushed via Admin API
In standalone mode, the file-based config path resolves ${{VAR}} / $ENV:// references in config_yaml.parse(), but config pushed through the Admin API (`PUT /apisix/admin/configs`) is JSON-decoded straight into _update_config and bypassed that step, so the references were kept literal. Resolve them in the Admin API update path before applying the config, so both standalone config sources behave consistently. Adds a test that pushes a route whose proxy-rewrite uri uses a ${{VAR:=default}} reference and verifies the gateway resolves it.
1 parent cb72d0e commit dea16d7

2 files changed

Lines changed: 44 additions & 0 deletions

File tree

apisix/admin/standalone.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ local events = require("apisix.events")
2828
local core = require("apisix.core")
2929
local config_yaml = require("apisix.core.config_yaml")
3030
local config_validate = require("apisix.admin.config_validate")
31+
local file = require("apisix.cli.file")
3132

3233
local ALL_RESOURCE_KEYS = config_validate.get_all_resource_keys()
3334

@@ -327,6 +328,16 @@ function _M.init_worker()
327328
-- this table is generated by json decode, so there is no need to clone it
328329
config[METADATA_LAST_MODIFIED] = nil
329330
config[METADATA_DIGEST] = nil
331+
332+
-- resolve ${{VAR}} / $ENV:// references in the config pushed via the
333+
-- Admin API. The file-based standalone path resolves these in
334+
-- config_yaml.parse(), but the Admin API path decodes JSON straight
335+
-- into _update_config and would otherwise keep them literal.
336+
local ok, err = file.resolve_conf_var(config)
337+
if not ok then
338+
core.log.error("failed to resolve variables in config: ", err)
339+
return
340+
end
330341
config_yaml._update_config(config)
331342
end
332343
events:register(update_config, EVENT_UPDATE, EVENT_UPDATE)

t/admin/standalone.spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,4 +944,37 @@ describe('Validate API - Standalone', () => {
944944
});
945945
});
946946
});
947+
948+
describe('Variable resolution', () => {
949+
it('resolves ${{VAR}} references in config pushed via the Admin API', async () => {
950+
mockDigest += 1;
951+
const config = {
952+
routes: [
953+
{
954+
id: 'r_var',
955+
uri: '/r_var',
956+
upstream: {
957+
nodes: { '127.0.0.1:1980': 1 },
958+
type: 'roundrobin',
959+
},
960+
// The proxy-rewrite uri uses a ${{VAR:=default}} reference. The
961+
// gateway must resolve it to the default ("/hello"); if it were
962+
// left literal, the upstream would receive "${{...}}" instead of
963+
// "/hello" and would not return the hello body.
964+
plugins: {
965+
'proxy-rewrite': { uri: '${{STANDALONE_ENV_TEST:=/hello}}' },
966+
},
967+
},
968+
],
969+
};
970+
const putResp = await client.put(ENDPOINT, config, {
971+
headers: { [HEADER_DIGEST]: mockDigest },
972+
});
973+
expect(putResp.status).toEqual(202);
974+
975+
const resp = await client.get('/r_var');
976+
expect(resp.status).toEqual(200);
977+
expect(resp.data).toEqual('hello world\n');
978+
});
979+
});
947980
});

0 commit comments

Comments
 (0)