diff --git a/.circleci/config.yml b/.circleci/config.yml index a3755648a..fac4584bd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -704,6 +704,7 @@ jobs: environment: EMBER_TEST_REPORT: test-results/report-ent.xml #outputs test report for CircleCI test summary EMBER_TEST_PARALLEL: true #enables test parallelization with ember-exam + CONSUL_NSPACES_ENABLED: 1 parallelism: 4 steps: - checkout diff --git a/ui-v2/config/environment.js b/ui-v2/config/environment.js index a6dca6b2b..485fe35d1 100644 --- a/ui-v2/config/environment.js +++ b/ui-v2/config/environment.js @@ -1,16 +1,49 @@ 'use strict'; -const fs = require('fs'); const path = require('path'); -module.exports = function (environment, $ = process.env) { +const utils = require('./utils'); + +const repositoryRoot = path.resolve(__dirname, '../../'); + +const repositoryYear = utils.repositoryYear; +const repositorySHA = utils.repositorySHA; +const binaryVersion = utils.binaryVersion(repositoryRoot); + +module.exports = function(environment, $ = process.env) { + // basic 'get env var with fallback' accessor + const env = function(flag, fallback) { + // a fallback value MUST be set + if (typeof fallback === 'undefined') { + throw new Error(`Please provide a fallback value for $${flag}`); + } + // return the env var if set + if (typeof $[flag] !== 'undefined') { + if (typeof fallback === 'boolean') { + // if we are expecting a boolean JSON parse strings to numbers/booleans + return !!JSON.parse($[flag]); + } + return $[flag]; + } + // If the fallback is a function call it and return the result. + // Lazily calling the function means binaries used for fallback don't need + // to be available if we are sure the environment variables will be set + if (typeof fallback === 'function') { + return fallback(); + } + // just return the fallback value + return fallback; + }; + let ENV = { modulePrefix: 'consul-ui', environment, rootURL: '/ui/', locationType: 'auto', - // We use a complete dynamically (from Consul) configured - // torii provider. We provide this object here to - // prevent ember from giving a log message when starting ember up + + // We use a complete dynamically (from Consul) configured torii provider. + // We provide this object here to prevent ember from giving a log message + // when starting ember up torii: {}, + EmberENV: { FEATURES: { // Here you can enable experimental features on an ember canary build @@ -29,52 +62,42 @@ module.exports = function (environment, $ = process.env) { injectionFactories: ['view', 'controller', 'component'], }, }; + + // The following 'environment variables' are set at build-time and compiled + // into a meta tag in generated index.html file. + // They can be accessed in the UI by using either: + // + // 1. The 'env' service from within javascript: `@service('env') env;` (../app/services/env.js) + // 2. The 'env' helper from within hbs: `{{env 'VARIABLE_NAME'}}` (../app/helpers/env.js) + // + // These variables can be overwritten depending on certain environments. + // For example for a production release the binary will overwrite some + // variables at runtime, during development some variables can be + // overwritten by adding cookie values using the browsers' Web Inspector + // TODO: These should probably go onto APP ENV = Object.assign({}, ENV, { - CONSUL_UI_DISABLE_REALTIME: typeof process.env.CONSUL_UI_DISABLE_REALTIME !== 'undefined', - CONSUL_UI_DISABLE_ANCHOR_SELECTION: - typeof process.env.CONSUL_UI_DISABLE_ANCHOR_SELECTION !== 'undefined', - CONSUL_COPYRIGHT_YEAR: (function (val) { - if (val) { - return val; - } - return require('child_process') - .execSync('git show -s --format=%ci HEAD') - .toString() - .trim() - .split('-') - .shift(); - })(process.env.CONSUL_COPYRIGHT_YEAR), - CONSUL_GIT_SHA: (function (val) { - if (val) { - return val; - } + // The following variables are compile-time variables that are set during + // the consul build process and baked into the generated assetsfs file that + // is later added to the consul binary itself. Some values, if not set, + // will automatically pull information from the git repository which means + // these values are guaranteed to be set/correct during development. + CONSUL_COPYRIGHT_YEAR: env('CONSUL_COPYRIGHT_YEAR', repositoryYear), + CONSUL_GIT_SHA: env('CONSUL_GIT_SHA', repositorySHA), + CONSUL_VERSION: env('CONSUL_VERSION', binaryVersion), + CONSUL_BINARY_TYPE: env('CONSUL_BINARY_TYPE', 'oss'), - return require('child_process') - .execSync('git rev-parse --short HEAD') - .toString() - .trim(); - })(process.env.CONSUL_GIT_SHA), - CONSUL_VERSION: (function (val) { - if (val) { - return val; - } - // see /scripts/dist.sh:8 - const version_go = `${path.dirname(path.dirname(__dirname))}/version/version.go`; - const contents = fs.readFileSync(version_go).toString(); - return contents - .split('\n') - .find(function (item, i, arr) { - return item.indexOf('Version =') !== -1; - }) - .trim() - .split('"')[1]; - })(process.env.CONSUL_VERSION), - CONSUL_BINARY_TYPE: process.env.CONSUL_BINARY_TYPE ? process.env.CONSUL_BINARY_TYPE : 'oss', + // These can be overwritten by the UI user at runtime by setting localStorage values + CONSUL_UI_DISABLE_REALTIME: env('CONSUL_UI_DISABLE_REALTIME', false), + CONSUL_UI_DISABLE_ANCHOR_SELECTION: env('CONSUL_UI_DISABLE_ANCHOR_SELECTION', false), + + // The following variables are runtime variables that are overwritten when + // the go binary services the index.html page CONSUL_ACLS_ENABLED: false, CONSUL_NSPACES_ENABLED: false, CONSUL_SSO_ENABLED: false, + // Static variables used in multiple places throughout the UI CONSUL_HOME_URL: 'https://www.consul.io', CONSUL_REPO_ISSUES_URL: 'https://github.com/hashicorp/consul/issues/new/choose', CONSUL_DOCS_URL: 'https://www.consul.io/docs', @@ -82,22 +105,16 @@ module.exports = function (environment, $ = process.env) { CONSUL_DOCS_API_URL: 'https://www.consul.io/api', CONSUL_COPYRIGHT_URL: 'https://www.hashicorp.com', }); - const isTestLike = ['staging', 'test'].indexOf(environment) > -1; - const isDevLike = ['development', 'staging', 'test'].indexOf(environment) > -1; - const isProdLike = ['production', 'staging'].indexOf(environment) > -1; switch (true) { case environment === 'test': ENV = Object.assign({}, ENV, { locationType: 'none', - CONSUL_NSPACES_TEST: true, - CONSUL_NSPACES_ENABLED: - typeof $['CONSUL_NSPACES_ENABLED'] !== 'undefined' - ? !!JSON.parse(String($['CONSUL_NSPACES_ENABLED']).toLowerCase()) - : true, - CONSUL_SSO_ENABLED: - typeof $['CONSUL_SSO_ENABLED'] !== 'undefined' - ? !!JSON.parse(String($['CONSUL_SSO_ENABLED']).toLowerCase()) - : false, + + // During testing ACLs default to being turned on + CONSUL_ACLS_ENABLED: env('CONSUL_ACLS_ENABLED', true), + CONSUL_NSPACES_ENABLED: env('CONSUL_NSPACES_ENABLED', false), + CONSUL_SSO_ENABLED: env('CONSUL_SSO_ENABLED', false), + '@hashicorp/ember-cli-api-double': { 'auto-import': false, enabled: true, @@ -109,6 +126,11 @@ module.exports = function (environment, $ = process.env) { LOG_ACTIVE_GENERATION: false, LOG_VIEW_LOOKUPS: false, + // LOG_RESOLVER: true, + // LOG_ACTIVE_GENERATION: true, + // LOG_TRANSITIONS: true, + // LOG_TRANSITIONS_INTERNAL: true, + rootElement: '#ember-testing', autoboot: false, }), @@ -116,8 +138,14 @@ module.exports = function (environment, $ = process.env) { break; case environment === 'staging': ENV = Object.assign({}, ENV, { - CONSUL_NSPACES_ENABLED: true, - CONSUL_SSO_ENABLED: true, + // On staging sites everything defaults to being turned on by + // different staging sites can be built with certain features disabled + // by setting an environment variable to 0 during building (e.g. + // CONSUL_NSPACES_ENABLED=0 make build) + CONSUL_ACLS_ENABLED: env('CONSUL_ACLS_ENABLED', true), + CONSUL_NSPACES_ENABLED: env('CONSUL_NSPACES_ENABLED', true), + CONSUL_SSO_ENABLED: env('CONSUL_SSO_ENABLED', true), + '@hashicorp/ember-cli-api-double': { enabled: true, endpoints: { @@ -134,7 +162,7 @@ module.exports = function (environment, $ = process.env) { // tag which obscured the Go template tag syntax. // // __RUNTIME_BOOL_Xxxx__ will be replaced with either "true" or "false" - // depending on whether the named variable is true or valse in the data + // depending on whether the named variable is true or false in the data // returned from `uiTemplateDataFromConfig`. CONSUL_ACLS_ENABLED: '__RUNTIME_BOOL_ACLsEnabled__', CONSUL_SSO_ENABLED: '__RUNTIME_BOOL_SSOEnabled__', @@ -142,21 +170,5 @@ module.exports = function (environment, $ = process.env) { }); break; } - switch (true) { - case isTestLike: - ENV = Object.assign({}, ENV, { - CONSUL_ACLS_ENABLED: true, - // 'APP': Object.assign({}, ENV.APP, { - // 'LOG_RESOLVER': true, - // 'LOG_ACTIVE_GENERATION': true, - // 'LOG_TRANSITIONS': true, - // 'LOG_TRANSITIONS_INTERNAL': true, - // 'LOG_VIEW_LOOKUPS': true, - // }) - }); - break; - case isProdLike: - break; - } return ENV; }; diff --git a/ui-v2/config/utils.js b/ui-v2/config/utils.js new file mode 100644 index 000000000..cc16e26ac --- /dev/null +++ b/ui-v2/config/utils.js @@ -0,0 +1,32 @@ +const read = require('fs').readFileSync; +const exec = require('child_process').execSync; + +// See tests ../node-tests/config/utils.js +const repositoryYear = function(date = exec('git show -s --format=%ci HEAD')) { + return date + .toString() + .trim() + .split('-') + .shift(); +}; +const repositorySHA = function(sha = exec('git rev-parse --short HEAD')) { + return sha.toString().trim(); +}; +const binaryVersion = function(repositoryRoot) { + return function(versionFileContents = read(`${repositoryRoot}/version/version.go`)) { + // see /scripts/dist.sh:8 + return versionFileContents + .toString() + .split('\n') + .find(function(item, i, arr) { + return item.indexOf('Version =') !== -1; + }) + .trim() + .split('"')[1]; + }; +}; +module.exports = { + repositoryYear: repositoryYear, + repositorySHA: repositorySHA, + binaryVersion: binaryVersion, +}; diff --git a/ui-v2/node-tests/config/environment.js b/ui-v2/node-tests/config/environment.js index 1c55034e4..6b5b5fca2 100644 --- a/ui-v2/node-tests/config/environment.js +++ b/ui-v2/node-tests/config/environment.js @@ -14,16 +14,6 @@ test( CONSUL_NSPACES_ENABLED: '__RUNTIME_BOOL_NamespacesEnabled__', }, { - environment: 'test', - CONSUL_BINARY_TYPE: 'oss', - CONSUL_ACLS_ENABLED: true, - CONSUL_NSPACES_ENABLED: true, - CONSUL_SSO_ENABLED: false, - }, - { - $: { - CONSUL_NSPACES_ENABLED: 0 - }, environment: 'test', CONSUL_BINARY_TYPE: 'oss', CONSUL_ACLS_ENABLED: true, @@ -32,7 +22,7 @@ test( }, { $: { - CONSUL_SSO_ENABLED: 0 + CONSUL_NSPACES_ENABLED: 1 }, environment: 'test', CONSUL_BINARY_TYPE: 'oss', @@ -40,6 +30,16 @@ test( CONSUL_NSPACES_ENABLED: true, CONSUL_SSO_ENABLED: false, }, + { + $: { + CONSUL_SSO_ENABLED: 1 + }, + environment: 'test', + CONSUL_BINARY_TYPE: 'oss', + CONSUL_ACLS_ENABLED: true, + CONSUL_NSPACES_ENABLED: false, + CONSUL_SSO_ENABLED: true, + }, { environment: 'staging', CONSUL_BINARY_TYPE: 'oss', diff --git a/ui-v2/node-tests/config/utils.js b/ui-v2/node-tests/config/utils.js new file mode 100644 index 000000000..d9bf3a8a7 --- /dev/null +++ b/ui-v2/node-tests/config/utils.js @@ -0,0 +1,28 @@ +const test = require('tape'); + +const utils = require('../../config/utils.js'); + +test( + 'utils.respositoryYear parses the year out correctly', + function(t) { + const expected = '2020'; + const actual = utils.repositoryYear('2020-10-14 16:34:57 -0700') + t.equal(actual, expected, 'It parses the year correctly'); + t.end(); + } +); +test( + 'utils.binaryVersion parses the version out correctly', + function(t) { + const expected = '1.9.0'; + const actual = utils.binaryVersion()(` + + Version = "1.9.0" + + VersionPrerelease = "dev" + +`) + t.equal(actual, expected, 'It parses the version correctly'); + t.end(); + } +);