1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Evaluate global-config env on startup

This commit is contained in:
Nick O'Leary 2023-06-23 09:35:00 +01:00
parent 1c5fdb6ab6
commit f196493402
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
5 changed files with 45 additions and 58 deletions

View File

@ -172,11 +172,24 @@ class Flow {
this.statusNodes = []; this.statusNodes = [];
this.completeNodeMap = {}; this.completeNodeMap = {};
if (this.env) {
this._env = await flowUtil.evaluateEnvProperties(this, this.env, credentials.get(this.id)) if (this.isGlobalFlow) {
// console.log('env', this.env) // This is the global flow. It needs to go find the `global-config`
// console.log('_env', this._env) // node and extract any env properties from it
const configNodes = Object.keys(this.flow.configs);
for (let i = 0; i < configNodes.length; i++) {
const node = this.flow.configs[configNodes[i]]
if (node.type === 'global-config' && node.env) {
const nodeEnv = await flowUtil.evaluateEnvProperties(this, node.env, credentials.get(node.id))
this._env = { ...this._env, ...nodeEnv }
} }
}
}
if (this.env) {
this._env = { ...this._env, ...await flowUtil.evaluateEnvProperties(this, this.env, credentials.get(this.id)) }
}
for (let i = 0; i < this.groupOrder.length; i++) { for (let i = 0; i < this.groupOrder.length; i++) {
// Start the groups in the right order so they // Start the groups in the right order so they
// can setup their env vars knowning their parent // can setup their env vars knowning their parent

View File

@ -359,7 +359,7 @@ async function start(type,diff,muteLog,isDeploy) {
if (activeFlowConfig.flows.hasOwnProperty(id)) { if (activeFlowConfig.flows.hasOwnProperty(id)) {
if (!activeFlowConfig.flows[id].disabled && !activeFlows[id]) { if (!activeFlowConfig.flows[id].disabled && !activeFlows[id]) {
// This flow is not disabled, nor is it currently active, so create it // This flow is not disabled, nor is it currently active, so create it
activeFlows[id] = Flow.create(flowAPI,activeFlowConfig,activeFlowConfig.flows[id]); activeFlows[id] = Flow.create(activeFlows['global'],activeFlowConfig,activeFlowConfig.flows[id]);
log.debug("red/nodes/flows.start : starting flow : "+id); log.debug("red/nodes/flows.start : starting flow : "+id);
} else { } else {
log.debug("red/nodes/flows.start : not starting disabled flow : "+id); log.debug("red/nodes/flows.start : not starting disabled flow : "+id);
@ -379,7 +379,7 @@ async function start(type,diff,muteLog,isDeploy) {
activeFlows[id].update(activeFlowConfig,activeFlowConfig.flows[id]); activeFlows[id].update(activeFlowConfig,activeFlowConfig.flows[id]);
} else { } else {
// This flow didn't previously exist, so create it // This flow didn't previously exist, so create it
activeFlows[id] = Flow.create(flowAPI,activeFlowConfig,activeFlowConfig.flows[id]); activeFlows[id] = Flow.create(activeFlows['global'],activeFlowConfig,activeFlowConfig.flows[id]);
log.debug("red/nodes/flows.start : starting flow : "+id); log.debug("red/nodes/flows.start : starting flow : "+id);
} }
} else { } else {
@ -784,17 +784,6 @@ const flowAPI = {
log: m => log.log(m) log: m => log.log(m)
} }
function getGlobalConfig() {
let gconf = null;
eachNode((n) => {
if (n.type === "global-config") {
gconf = n;
}
});
return gconf;
}
module.exports = { module.exports = {
init: init, init: init,
@ -808,9 +797,6 @@ module.exports = {
get:getNode, get:getNode,
eachNode: eachNode, eachNode: eachNode,
getGlobalConfig: getGlobalConfig,
/** /**
* Gets the current flow configuration * Gets the current flow configuration
*/ */

View File

@ -318,37 +318,6 @@ function parseConfig(config) {
return flow; return flow;
} }
function getGlobalEnv(name) {
const nodes = _runtime.nodes;
if (!nodes) {
return null;
}
const gconf = nodes.getGlobalConfig();
const env = gconf ? gconf.env : null;
if (env) {
const cred = (gconf ? credentials.get(gconf.id) : null) || {
map: {}
};
const map = cred.map;
for (let i = 0; i < env.length; i++) {
const item = env[i];
if (item.name === name) {
if (item.type === "cred") {
return {
name: name,
value: map[name],
type: "cred"
};
}
return item;
}
}
}
return null;
}
module.exports = { module.exports = {
init: function(runtime) { init: function(runtime) {
_runtime = runtime; _runtime = runtime;
@ -359,11 +328,6 @@ module.exports = {
}, },
getEnvVar: function(k) { getEnvVar: function(k) {
if (!envVarExcludes[k]) { if (!envVarExcludes[k]) {
const item = getGlobalEnv(k);
if (item) {
const val = redUtil.evaluateNodeProperty(item.value, item.type, null, null, null);
return val;
}
return process.env[k]; return process.env[k];
} }
return undefined; return undefined;

View File

@ -205,7 +205,6 @@ module.exports = {
getNode: flows.get, getNode: flows.get,
eachNode: flows.eachNode, eachNode: flows.eachNode,
getContext: context.get, getContext: context.get,
getGlobalConfig: flows.getGlobalConfig,
clearContext: context.clear, clearContext: context.clear,

View File

@ -1369,6 +1369,31 @@ describe('Flow', function() {
await flow.stop() await flow.stop()
}); });
it("global flow can access global-config defined environment variables", async function () {
after(function() {
delete process.env.V0;
})
const config = flowUtils.parseConfig([
{id:"gc", type:"global-config", env:[
{"name": "GC0", value: "3+4", type: "jsonata"}
]},
{id:"t1",type:"tab" },
{id:"1",x:10,y:10,z:"t1",type:"test",foo:"${GC0}",wires:[]},
]);
// Two-arg call - makes this the global flow that handles global-config nodes
const globalFlow = Flow.create({getSetting:v=>process.env[v]},config);
await globalFlow.start();
// Pass the globalFlow in as the parent flow to allow global-config lookup
const flow = Flow.create(globalFlow,config,config.flows["t1"]);
await flow.start();
var activeNodes = flow.getActiveNodes();
activeNodes["1"].foo.should.equal(7);
await flow.stop()
await globalFlow.stop()
});
}); });
}); });