From e8af948dc1a235e05a81a849e888f9db59efb27b Mon Sep 17 00:00:00 2001 From: Zhihe Li Date: Wed, 2 Nov 2022 14:30:10 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Auto-populate=20hcp=20cl?= =?UTF-8?q?uster=20id=20(#1389)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ Closes: ICU-6200 --- addons/core/addon/services/browser-object.js | 31 +++++++ addons/core/app/services/browser-object.js | 1 + .../unit/services/browser-object-test.js | 21 +++++ .../form/worker/create-worker-led/index.hbs | 5 +- .../form/worker/create-worker-led/index.js | 17 +++- .../templates/scopes/scope/workers/new.hbs | 2 +- .../tests/acceptance/workers/create-test.js | 13 ++- .../form/worker/create-worker-led-test.js | 85 +++++++++++++++++++ 8 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 addons/core/addon/services/browser-object.js create mode 100644 addons/core/app/services/browser-object.js create mode 100644 addons/core/tests/unit/services/browser-object-test.js create mode 100644 ui/admin/tests/integration/components/form/worker/create-worker-led-test.js diff --git a/addons/core/addon/services/browser-object.js b/addons/core/addon/services/browser-object.js new file mode 100644 index 000000000..90e0f8079 --- /dev/null +++ b/addons/core/addon/services/browser-object.js @@ -0,0 +1,31 @@ +import Service from '@ember/service'; + +/** + * A simple service that wraps around the global window and + * document variables that allows us to mock them in testing + */ +export default class BrowserObjectService extends Service { + /** + * The global window object + * @returns {Window} + */ + get window() { + return window; + } + + /** + * The global document object + * @returns {Document} + */ + get document() { + return this.window?.document; + } + + /** + * The hostname of the current location of the URL + * @returns {string} + */ + get hostname() { + return this.window?.location?.hostname; + } +} diff --git a/addons/core/app/services/browser-object.js b/addons/core/app/services/browser-object.js new file mode 100644 index 000000000..8650db8d9 --- /dev/null +++ b/addons/core/app/services/browser-object.js @@ -0,0 +1 @@ +export { default } from 'core/services/browser-object'; diff --git a/addons/core/tests/unit/services/browser-object-test.js b/addons/core/tests/unit/services/browser-object-test.js new file mode 100644 index 000000000..14520778b --- /dev/null +++ b/addons/core/tests/unit/services/browser-object-test.js @@ -0,0 +1,21 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Service | browser-object', function (hooks) { + setupTest(hooks); + + test('it contains a window', function (assert) { + let service = this.owner.lookup('service:browser-object'); + assert.ok(service.window, 'Service contains a window'); + }); + + test('it contains a document', function (assert) { + let service = this.owner.lookup('service:browser-object'); + assert.ok(service.document, 'Service contains a document'); + }); + + test('it contains a hostname', function (assert) { + let service = this.owner.lookup('service:browser-object'); + assert.ok(service.hostname, 'Service contains a hostname'); + }); +}); diff --git a/ui/admin/app/components/form/worker/create-worker-led/index.hbs b/ui/admin/app/components/form/worker/create-worker-led/index.hbs index 9d8e8b972..ef4bd5259 100644 --- a/ui/admin/app/components/form/worker/create-worker-led/index.hbs +++ b/ui/admin/app/components/form/worker/create-worker-led/index.hbs @@ -1,6 +1,5 @@ {{t 'actions.done'}} diff --git a/ui/admin/app/components/form/worker/create-worker-led/index.js b/ui/admin/app/components/form/worker/create-worker-led/index.js index 33e776cb1..b1c804d60 100644 --- a/ui/admin/app/components/form/worker/create-worker-led/index.js +++ b/ui/admin/app/components/form/worker/create-worker-led/index.js @@ -17,10 +17,11 @@ class Tag { export default class FormWorkerCreateWorkerLedComponent extends Component { // =services @service features; + @service browserObject; // =attributes @tracked generatedWorkerAuthToken; - @tracked clusterId; + @tracked clusterID = this.clusterIDFromURL; @tracked ipAddress; @tracked configFilePath; @tracked initialUpstreams; @@ -28,8 +29,18 @@ export default class FormWorkerCreateWorkerLedComponent extends Component { @tracked newWorkerKey; @tracked newWorkerValue; - // =properties + get clusterIDFromURL() { + const hostname = this.browserObject.hostname; + // Match against a guid with either the prod, int, or dev hcp domain + const clusterIDMatcher = + /^(?[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\.boundary\.(?:hashicorp\.cloud|hcp\.to|hcp\.dev)$/; + + // Return the cluster ID otherwise return null if it doesn't match + return hostname?.match(clusterIDMatcher)?.groups?.clusterID; + } + + // =properties /** * Returns directory creation text for ``. * @type {string} @@ -46,7 +57,7 @@ touch ${this.configFilePath || ''}/pki-worker.hcl`; */ get workerConfigText() { const clusterText = `hcp_boundary_cluster_id = "${ - this.clusterId || '' + this.clusterID || '' }"`; const tagsText = `tags { diff --git a/ui/admin/app/templates/scopes/scope/workers/new.hbs b/ui/admin/app/templates/scopes/scope/workers/new.hbs index e92e76085..42c885606 100644 --- a/ui/admin/app/templates/scopes/scope/workers/new.hbs +++ b/ui/admin/app/templates/scopes/scope/workers/new.hbs @@ -12,11 +12,11 @@ - diff --git a/ui/admin/tests/acceptance/workers/create-test.js b/ui/admin/tests/acceptance/workers/create-test.js index d7044b741..e49fac281 100644 --- a/ui/admin/tests/acceptance/workers/create-test.js +++ b/ui/admin/tests/acceptance/workers/create-test.js @@ -9,7 +9,6 @@ import { //currentSession, //invalidateSession, } from 'ember-simple-auth/test-support'; -import { getOwner } from '@ember/application'; module('Acceptance | workers | create', function (hooks) { setupApplicationTest(hooks); @@ -41,9 +40,9 @@ module('Acceptance | workers | create', function (hooks) { test('cluster id input field is visible for `hcp` binary', async function (assert) { assert.expect(2); - const config = getOwner(this).resolveRegistration('config:environment'); - config.featureFlags['byow-pki-hcp-cluster-id'] = true; - config.featureFlags['byow-pki-upstream'] = false; + const featuresService = this.owner.lookup('service:features'); + featuresService.enable('byow-pki-hcp-cluster-id'); + featuresService.disable('byow-pki-upstream'); await visit(newWorkerURL); const labels = findAll('label.rose-form-label'); assert.dom(labels[0]).hasText('Boundary Cluster ID'); @@ -52,9 +51,9 @@ module('Acceptance | workers | create', function (hooks) { test('initial upstreams input field is visible for `oss` binary', async function (assert) { assert.expect(2); - const config = getOwner(this).resolveRegistration('config:environment'); - config.featureFlags['byow-pki-hcp-cluster-id'] = false; - config.featureFlags['byow-pki-upstream'] = true; + const featuresService = this.owner.lookup('service:features'); + featuresService.disable('byow-pki-hcp-cluster-id'); + featuresService.enable('byow-pki-upstream'); await visit(newWorkerURL); const labels = findAll('label.rose-form-label'); assert.dom(labels[0]).doesNotIncludeText('Boundary Cluster ID'); diff --git a/ui/admin/tests/integration/components/form/worker/create-worker-led-test.js b/ui/admin/tests/integration/components/form/worker/create-worker-led-test.js new file mode 100644 index 000000000..91e5e0e32 --- /dev/null +++ b/ui/admin/tests/integration/components/form/worker/create-worker-led-test.js @@ -0,0 +1,85 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { v1 } from 'ember-uuid'; + +module( + 'Integration | Component | form/worker/create-worker-led', + function (hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function () { + const featuresService = this.owner.lookup('service:features'); + featuresService.enable('byow-pki-hcp-cluster-id'); + featuresService.disable('byow-pki-upstream'); + }); + + test('it correctly populates the cluster id for an hcp dev cluster', async function (assert) { + const guid = v1(); + this.model = {}; + this.submit = () => {}; + this.refresh = () => {}; + const service = { hostname: `${guid}.boundary.hcp.dev` }; + this.owner.register('service:browser-object', service, { + instantiate: false, + }); + + await render( + hbs`` + ); + + assert.dom('[name="cluster_id"]').hasValue(guid); + }); + + test('it correctly populates the cluster id for an hcp int cluster', async function (assert) { + const guid = v1(); + this.model = {}; + this.submit = () => {}; + this.refresh = () => {}; + const service = { hostname: `${guid}.boundary.hcp.to` }; + this.owner.register('service:browser-object', service, { + instantiate: false, + }); + + await render( + hbs`` + ); + + assert.dom('[name="cluster_id"]').hasValue(guid); + }); + + test('it correctly populates the cluster id for an hcp prod cluster', async function (assert) { + const guid = v1(); + this.model = {}; + this.submit = () => {}; + this.refresh = () => {}; + const service = { hostname: `${guid}.boundary.hashicorp.cloud` }; + this.owner.register('service:browser-object', service, { + instantiate: false, + }); + + await render( + hbs`` + ); + + assert.dom('[name="cluster_id"]').hasValue(guid); + }); + + test('it leaves the cluster id as blank for any other url', async function (assert) { + this.model = {}; + this.submit = () => {}; + this.refresh = () => {}; + const service = { hostname: `personal.website.com` }; + this.owner.register('service:browser-object', service, { + instantiate: false, + }); + + await render( + hbs`` + ); + + assert.dom('[name="cluster_id"]').hasNoValue(); + }); + } +);