mirror of
https://github.com/status-im/consul.git
synced 2025-01-10 05:45:46 +00:00
02772e46a2
* Add templating to inject JSON into an application/json script tag Plus an external script in order to pick it out and inject the values we need injecting into ember's environment meta tag. The UI still uses env style naming (CONSUL_*) but we uses the new style JSON/golang props behind the scenes. Co-authored-by: Paul Banks <banks@banksco.de>
191 lines
7.1 KiB
JavaScript
191 lines
7.1 KiB
JavaScript
import { runInDebug } from '@ember/debug';
|
|
// 'environment' getter
|
|
// there are currently 3 levels of environment variables:
|
|
// 1. Those that can be set by the user by setting localStorage values
|
|
// 2. Those that can be set by the operator either via ui_config, or inferring
|
|
// from other server type properties (protocol)
|
|
// 3. Those that can be set only during development by adding cookie values
|
|
// via the browsers Web Inspector, or via the browsers hash (#COOKIE_NAME=1),
|
|
// which is useful for showing the UI with various settings enabled/disabled
|
|
export default function(config = {}, win = window, doc = document) {
|
|
// look at the hash in the URL and transfer anything after the hash into
|
|
// cookies to enable linking of the UI with various settings enabled
|
|
runInDebug(() => {
|
|
if (
|
|
typeof win.location !== 'undefined' &&
|
|
typeof win.location.hash === 'string' &&
|
|
win.location.hash.length > 0
|
|
) {
|
|
doc.cookie = win.location.hash.substr(1);
|
|
}
|
|
});
|
|
const dev = function(str = doc.cookie) {
|
|
return str
|
|
.split(';')
|
|
.filter(item => item !== '')
|
|
.map(item => {
|
|
const [key, ...rest] = item.trim().split('=');
|
|
return [key, rest.join('=')];
|
|
});
|
|
};
|
|
const user = function(str) {
|
|
const item = win.localStorage.getItem(str);
|
|
return item === null ? undefined : item;
|
|
};
|
|
const getResourceFor = function(src) {
|
|
try {
|
|
return (
|
|
win.performance.getEntriesByType('resource').find(item => {
|
|
return item.initiatorType === 'script' && src === item.name;
|
|
}) || {}
|
|
);
|
|
} catch (e) {
|
|
return {};
|
|
}
|
|
};
|
|
const operatorConfig = JSON.parse(
|
|
doc.querySelector(`[data-${config.modulePrefix}-config]`).textContent
|
|
);
|
|
const ui_config = operatorConfig.UIConfig || {};
|
|
const scripts = doc.getElementsByTagName('script');
|
|
// we use the currently executing script as a reference
|
|
// to figure out where we are for other things such as
|
|
// base url, api url etc
|
|
const currentSrc = scripts[scripts.length - 1].src;
|
|
let resource;
|
|
// TODO: Potentially use ui_config {}, for example
|
|
// turning off blocking queries if its a busy cluster
|
|
// forcing/providing amount of possible HTTP connections
|
|
// re-setting the base url for the API etc
|
|
const operator = function(str, env) {
|
|
let protocol, dashboards, provider, proxy;
|
|
switch (str) {
|
|
case 'CONSUL_NSPACES_ENABLED':
|
|
return typeof operatorConfig.NamespacesEnabled === 'undefined'
|
|
? false
|
|
: operatorConfig.NamespacesEnabled;
|
|
case 'CONSUL_SSO_ENABLED':
|
|
return typeof operatorConfig.SSOEnabled === 'undefined' ? false : operatorConfig.SSOEnabled;
|
|
case 'CONSUL_ACLS_ENABLED':
|
|
return typeof operatorConfig.ACLsEnabled === 'undefined'
|
|
? false
|
|
: operatorConfig.ACLsEnabled;
|
|
case 'CONSUL_DATACENTER_LOCAL':
|
|
return operatorConfig.LocalDatacenter;
|
|
case 'CONSUL_UI_CONFIG':
|
|
dashboards = {};
|
|
provider = env('CONSUL_METRICS_PROVIDER');
|
|
proxy = env('CONSUL_METRICS_PROXY_ENABLED');
|
|
dashboards.service = env('CONSUL_SERVICE_DASHBOARD_URL');
|
|
if (provider) {
|
|
ui_config.metrics_provider = provider;
|
|
}
|
|
if (proxy) {
|
|
ui_config.metrics_proxy_enabled = proxy;
|
|
}
|
|
if (dashboards.service) {
|
|
ui_config.dashboard_url_templates = dashboards;
|
|
}
|
|
return ui_config;
|
|
case 'CONSUL_BASE_UI_URL':
|
|
return currentSrc
|
|
.split('/')
|
|
.slice(0, -2)
|
|
.join('/');
|
|
case 'CONSUL_HTTP_PROTOCOL':
|
|
if (typeof resource === 'undefined') {
|
|
// resource needs to be retrieved lazily as entries aren't guaranteed
|
|
// to be available at script execution time (caching seems to affect this)
|
|
// waiting until we retrieve this value lazily at runtime means that
|
|
// the entries are always available as these values are only retrieved
|
|
// after initialization
|
|
// current is based on the assumption that whereever this script is it's
|
|
// likely to be the same as the xmlhttprequests
|
|
resource = getResourceFor(currentSrc);
|
|
}
|
|
return resource.nextHopProtocol || 'http/1.1';
|
|
case 'CONSUL_HTTP_MAX_CONNECTIONS':
|
|
protocol = env('CONSUL_HTTP_PROTOCOL');
|
|
// http/2, http2+QUIC/39 and SPDY don't have connection limits
|
|
switch (true) {
|
|
case protocol.indexOf('h2') === 0:
|
|
case protocol.indexOf('hq') === 0:
|
|
case protocol.indexOf('spdy') === 0:
|
|
// TODO: Change this to return -1 so we try to consistently
|
|
// return a value from env vars
|
|
return;
|
|
default:
|
|
// generally 6 are available
|
|
// reserve 1 for traffic that we can't manage
|
|
return 5;
|
|
}
|
|
}
|
|
};
|
|
const ui = function(key) {
|
|
let $;
|
|
switch (config.environment) {
|
|
case 'development':
|
|
case 'staging':
|
|
case 'coverage':
|
|
case 'test':
|
|
$ = dev().reduce(function(prev, [key, value]) {
|
|
switch (key) {
|
|
case 'CONSUL_ACLS_ENABLE':
|
|
prev['CONSUL_ACLS_ENABLED'] = !!JSON.parse(String(value).toLowerCase());
|
|
break;
|
|
case 'CONSUL_NSPACES_ENABLE':
|
|
prev['CONSUL_NSPACES_ENABLED'] = !!JSON.parse(String(value).toLowerCase());
|
|
break;
|
|
case 'CONSUL_SSO_ENABLE':
|
|
prev['CONSUL_SSO_ENABLED'] = !!JSON.parse(String(value).toLowerCase());
|
|
break;
|
|
case 'CONSUL_METRICS_PROXY_ENABLE':
|
|
prev['CONSUL_METRICS_PROXY_ENABLED'] = !!JSON.parse(String(value).toLowerCase());
|
|
break;
|
|
case 'CONSUL_UI_CONFIG':
|
|
prev['CONSUL_UI_CONFIG'] = JSON.parse(value);
|
|
break;
|
|
default:
|
|
prev[key] = value;
|
|
}
|
|
return prev;
|
|
}, {});
|
|
if (typeof $[key] !== 'undefined') {
|
|
return $[key];
|
|
}
|
|
break;
|
|
}
|
|
return config[key];
|
|
};
|
|
return function env(str) {
|
|
switch (str) {
|
|
// All user providable values should start with CONSUL_UI
|
|
// We allow the user to set these ones via localStorage
|
|
// user value is preferred.
|
|
case 'CONSUL_UI_DISABLE_REALTIME':
|
|
case 'CONSUL_UI_DISABLE_ANCHOR_SELECTION':
|
|
// these are booleans cast things out
|
|
return !!JSON.parse(String(user(str) || 0).toLowerCase()) || ui(str);
|
|
case 'CONSUL_UI_REALTIME_RUNNER':
|
|
// these are strings
|
|
return user(str) || ui(str);
|
|
case 'CONSUL_UI_CONFIG':
|
|
case 'CONSUL_DATACENTER_LOCAL':
|
|
case 'CONSUL_ACLS_ENABLED':
|
|
case 'CONSUL_NSPACES_ENABLED':
|
|
case 'CONSUL_SSO_ENABLED':
|
|
case 'CONSUL_METRICS_PROVIDER':
|
|
case 'CONSUL_METRICS_PROXY_ENABLE':
|
|
case 'CONSUL_SERVICE_DASHBOARD_URL':
|
|
case 'CONSUL_BASE_UI_URL':
|
|
case 'CONSUL_HTTP_PROTOCOL':
|
|
case 'CONSUL_HTTP_MAX_CONNECTIONS':
|
|
// We allow the operator to set these ones via various methods
|
|
// although UI developer config is preferred
|
|
return ui(str) || operator(str, env);
|
|
default:
|
|
return ui(str);
|
|
}
|
|
};
|
|
}
|