mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
add support of environtment variable for tab & group
This commit is contained in:
@@ -396,6 +396,17 @@ class Flow {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a group node instance
|
||||
* @param {String} id
|
||||
* @return {Node} group node
|
||||
*/
|
||||
getGroupNode(id) {
|
||||
const groups = this.global.groups;
|
||||
return groups[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the nodes instantiated within this flow
|
||||
* @return {[type]} [description]
|
||||
@@ -404,6 +415,57 @@ class Flow {
|
||||
return this.activeNodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a flow setting value deined in this flow.
|
||||
* @param {String} key
|
||||
* @return {Object} result containinig val property or null
|
||||
*/
|
||||
getFlowSetting(name) {
|
||||
const flow = this.flow;
|
||||
if (flow.env) {
|
||||
if (!name.startsWith("$parent.")) {
|
||||
if (!flow._env) {
|
||||
const envs = flow.env;
|
||||
const entries = envs.map((env) => [env.name, env]);
|
||||
flow._env = Object.fromEntries(entries);
|
||||
}
|
||||
const env = flow._env[name];
|
||||
if (env) {
|
||||
let value = env.value;
|
||||
const type = env.type;
|
||||
if ((type !== "env") || (value !== name)) {
|
||||
if (type === "env") {
|
||||
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
|
||||
}
|
||||
try {
|
||||
if (type === "bool") {
|
||||
const val = ((value === "true") ||
|
||||
(value === true));
|
||||
return {
|
||||
val: val
|
||||
};
|
||||
}
|
||||
if (type === "cred") {
|
||||
return {
|
||||
val: value
|
||||
};
|
||||
}
|
||||
var val = redUtil.evaluateNodeProperty(value, type, null, null, null);
|
||||
return {
|
||||
val: val
|
||||
};
|
||||
}
|
||||
catch (e) {
|
||||
this.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a flow setting value. This currently automatically defers to the parent
|
||||
* flow which, as defined in ./index.js returns `process.env[key]`.
|
||||
@@ -412,6 +474,10 @@ class Flow {
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
getSetting(key) {
|
||||
const result = this.getFlowSetting(key);
|
||||
if (result) {
|
||||
return result.val;
|
||||
}
|
||||
return this.parent.getSetting(key);
|
||||
}
|
||||
|
||||
|
@@ -43,6 +43,54 @@ function evaluateInputValue(value, type, node) {
|
||||
return redUtil.evaluateNodeProperty(value, type, node, null, null);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get value of environment variable defined in group node.
|
||||
* @param {String} group - group node
|
||||
* @param {String} name - name of variable
|
||||
* @return {Object} object containing the value in val property or null if not defined
|
||||
*/
|
||||
function getGroupSetting(node, group, flow, name) {
|
||||
if (group) {
|
||||
if (!name.startsWith("$parent.")) {
|
||||
if (group.env) {
|
||||
if (!group._env) {
|
||||
const envs = group.env;
|
||||
const entries = envs.map((env) => [env.name, env]);
|
||||
group._env = Object.fromEntries(entries);
|
||||
}
|
||||
const env = group._env[name];
|
||||
if (env) {
|
||||
let value = env.value;
|
||||
const type = env.type;
|
||||
if ((type !== "env") || (value !== name)) {
|
||||
if (type === "env") {
|
||||
value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
|
||||
}
|
||||
try {
|
||||
const val = evaluateInputValue(value, type, node);
|
||||
return {
|
||||
val: val
|
||||
};
|
||||
}
|
||||
catch (e) {
|
||||
this.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
name = name.substring(8);
|
||||
}
|
||||
if (group.g && flow) {
|
||||
const parent = flow.getGroupNode(group.g);
|
||||
return getGroupSetting(node, parent, flow, name);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents a subflow - which is handled as a special type of Flow
|
||||
*/
|
||||
@@ -370,6 +418,16 @@ class Subflow extends Flow {
|
||||
// name starts $parent. ... so delegate to parent automatically
|
||||
name = name.substring(8);
|
||||
}
|
||||
const node = this.subflowInstance;
|
||||
if (node.g) {
|
||||
const group = this.getGroupNode(node.g);
|
||||
const result = getGroupSetting(node, group, this, name);
|
||||
if (result) {
|
||||
return result.val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var parent = this.parent;
|
||||
if (parent) {
|
||||
var val = parent.getSetting(name);
|
||||
|
@@ -539,6 +539,9 @@ async function addFlow(flow, user) {
|
||||
if (flow.hasOwnProperty('disabled')) {
|
||||
tabNode.disabled = flow.disabled;
|
||||
}
|
||||
if (flow.hasOwnProperty('env')) {
|
||||
tabNode.env = flow.env;
|
||||
}
|
||||
|
||||
var nodes = [tabNode];
|
||||
|
||||
@@ -599,6 +602,9 @@ function getFlow(id) {
|
||||
if (flow.hasOwnProperty('info')) {
|
||||
result.info = flow.info;
|
||||
}
|
||||
if (flow.hasOwnProperty('env')) {
|
||||
result.env = flow.env;
|
||||
}
|
||||
if (id !== 'global') {
|
||||
result.nodes = [];
|
||||
}
|
||||
@@ -694,6 +700,9 @@ async function updateFlow(id,newFlow, user) {
|
||||
if (newFlow.hasOwnProperty('disabled')) {
|
||||
tabNode.disabled = newFlow.disabled;
|
||||
}
|
||||
if (newFlow.hasOwnProperty('env')) {
|
||||
tabNode.env = newFlow.env;
|
||||
}
|
||||
|
||||
nodes = [tabNode].concat(newFlow.nodes||[]).concat(newFlow.configs||[]);
|
||||
nodes.forEach(function(n) {
|
||||
|
@@ -44,24 +44,25 @@ function diffNodes(oldNode,newNode) {
|
||||
var EnvVarPropertyRE_old = /^\$\((\S+)\)$/;
|
||||
var EnvVarPropertyRE = /^\${(\S+)}$/;
|
||||
|
||||
function mapEnvVarProperties(obj,prop,flow) {
|
||||
|
||||
function mapEnvVarProperties(obj,prop,flow,config) {
|
||||
var v = obj[prop];
|
||||
if (Buffer.isBuffer(v)) {
|
||||
return;
|
||||
} else if (Array.isArray(v)) {
|
||||
for (var i=0;i<v.length;i++) {
|
||||
mapEnvVarProperties(v,i,flow);
|
||||
mapEnvVarProperties(v,i,flow,config);
|
||||
}
|
||||
} else if (typeof obj[prop] === 'string') {
|
||||
if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) {
|
||||
var envVar = v.substring(2,v.length-1);
|
||||
var r = flow.getSetting(envVar);
|
||||
obj[prop] = r!==undefined?r:obj[prop];
|
||||
var r = redUtil.getSetting(config, envVar, flow);
|
||||
obj[prop] = r ? r : obj[prop];
|
||||
}
|
||||
} else {
|
||||
for (var p in v) {
|
||||
if (v.hasOwnProperty(p)) {
|
||||
mapEnvVarProperties(v,p,flow);
|
||||
mapEnvVarProperties(v,p,flow,config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,7 +79,7 @@ function createNode(flow,config) {
|
||||
delete conf.credentials;
|
||||
for (var p in conf) {
|
||||
if (conf.hasOwnProperty(p)) {
|
||||
mapEnvVarProperties(conf,p,flow);
|
||||
mapEnvVarProperties(conf,p,flow,conf);
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
@@ -38,6 +38,7 @@ function Node(n) {
|
||||
this.id = n.id;
|
||||
this.type = n.type;
|
||||
this.z = n.z;
|
||||
this.g = n.g;
|
||||
this._closeCallbacks = [];
|
||||
this._inputCallback = null;
|
||||
this._inputCallbacks = null;
|
||||
|
@@ -103,7 +103,7 @@ function createNode(node,def) {
|
||||
// allow $(foo) syntax to substitute env variables for credentials also...
|
||||
for (var p in creds) {
|
||||
if (creds.hasOwnProperty(p)) {
|
||||
flowUtil.mapEnvVarProperties(creds,p,node._flow);
|
||||
flowUtil.mapEnvVarProperties(creds,p,node._flow,node);
|
||||
}
|
||||
}
|
||||
node.credentials = creds;
|
||||
|
Reference in New Issue
Block a user