diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml
index c6bc36ef9..046c502d2 100644
--- a/addons/core/translations/resources/en-us.yaml
+++ b/addons/core/translations/resources/en-us.yaml
@@ -374,27 +374,31 @@ target:
diagram:
client: Client
any-worker: Any worker
- front-line-worker: Front line worker
+ frontline-worker: Frontline worker
hcp-worker: HCP worker
egress-worker: Egress worker
ingress-worker: Ingress worker
host: Host
network: Private network
filter-explainer:
- any-worker: In this configuration, the client will attemt to connect through any client-accessible worker.
- egress-worker: In this configuration, the client will attemt to connect through any filtered egress worker.
- ingress-worker: In this configuration, the client will attempt to conect through any filtered ingress worker.
+ any-worker: In this configuration, the client will attempt to connect through any client-accessible worker.
+ egress-worker: In this configuration, the client will attempt to connect through any filtered egress worker.
+ ingress-worker: In this configuration, the client will attempt to connect through any filtered ingress worker.
hcp-worker: In this configuration, the client will attempt to connect through any HCP-managed worker.
- ent-dual-egress-on: In this configuration, the client will attempt to connect through any client-accessible "frontline" worker and reach the host through any filtered egress worker.
- hcp-dual-egress-on: In this configuration, the client will attempt to connect through any HC-managed worker and reach the host through any filtered egress worker.
- dual-egress-on-ingress-on: In this configuration, the client will attempt to connect through any filtered ingress worker and reach the house through any filtered egress worker.
+ dual-egress-on: In this configuration, the client will attempt to connect through any client-accessible "frontline" worker and reach the host through any filtered egress worker.
+ dual-egress-on-ingress-on: In this configuration, the client will attempt to connect through any filtered ingress worker and reach the host through any filtered egress worker.
+ hcp-dual-egress-on: In this configuration, the client will attempt to connect through any HCP-managed worker and reach the host through any filtered egress worker.
+ filter:
+ title: Filter
+ description: Boolean expression.
egress_worker_filter:
title: Egress worker filter
description: Specify workers that have access to the target (such as within a private network).
- filter:
- title: Filter
- description: Boolean expression.
- update_filter: Update Filter
+ ingress_worker_filter:
+ title: Ingress worker filter
+ description: Specify workers Boundary should use to start the route to this target.
+ actions:
+ update-filter: Update Filter
credential-store:
title: Credential Store
title_plural: Credential Stores
diff --git a/ui/admin/app/components/form/target/details/index.hbs b/ui/admin/app/components/form/target/details/index.hbs
index 76c78bb02..b509150e0 100644
--- a/ui/admin/app/components/form/target/details/index.hbs
+++ b/ui/admin/app/components/form/target/details/index.hbs
@@ -176,6 +176,7 @@
{{#if (feature-flag 'target-worker-filters-v2')}}
+
{{/if}}
{{/if}}
+
+ {{#if this.showTargetFilters}}
+ {{#if this.workerDiagramHCPDualFilter}}
+
+ {{else if this.workerDiagramDualFilter}}
+
+ {{else}}
+
+ {{/if}}
- {{#if this.showEgressFilter}}
-
-
+ {{#if (feature-flag 'target-worker-filters-v2-ingress')}}
+
+ {{#if @model.errors.ingress_worker_filter}}
+
+ {{#each @model.errors.ingress_worker_filter as |error|}}
+ {{error.message}}
+ {{/each}}
+
+ {{/if}}
+
+ {{/if}}
-
-
-
- {{/if}}
-
- {{#if @model.isNew}}
-
-
-
-
-
- {{#if @model.errors.egress_worker_filter}}
-
- {{#each @model.errors.egress_worker_filter as |error|}}
- {{error.message}}
- {{/each}}
-
- {{/if}}
-
-
- {{/if}}
-
+ {{/if}}
+
{{else}}
@@ -326,4 +320,5 @@
@cancelText={{t 'actions.cancel'}}
/>
{{/if}}
+
\ No newline at end of file
diff --git a/ui/admin/app/components/form/target/details/index.js b/ui/admin/app/components/form/target/details/index.js
index 966ee18bc..aad39f007 100644
--- a/ui/admin/app/components/form/target/details/index.js
+++ b/ui/admin/app/components/form/target/details/index.js
@@ -2,6 +2,7 @@ import Component from '@glimmer/component';
import { TYPES_TARGET } from 'api/models/target';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
+import { inject as service } from '@ember/service';
// NOTE: this is all a temporary solution till we have a resource type helper.
const types = [...TYPES_TARGET].reverse();
@@ -9,13 +10,13 @@ const icons = {
ssh: 'terminal-screen',
tcp: 'network',
};
-
export default class FormTargetComponent extends Component {
// =properties
- @tracked egressWorkerFilterEnabled =
- this.args.model.egress_worker_filter?.length;
+ @tracked egressWorkerFilterEnabled = this.args.model.egress_worker_filter;
+ @tracked ingressWorkerFilterEnabled = this.args.model.ingress_worker_filter;
- // =properties
+ // =services
+ @service features;
/**
* maps resource type with icon
* @type {object}
@@ -49,28 +50,56 @@ export default class FormTargetComponent extends Component {
* @type {boolean}
*/
get showUpdateWorkerFilterButton() {
- return this.args.model.worker_filter?.length;
+ return this.args.model.worker_filter;
}
- get showEgressFilter() {
- return !this.args.model.worker_filter?.length && !this.args.model.isNew;
+ /**
+ * determines when the filters should be shown
+ * @type {boolean}
+ */
+ get showTargetFilters() {
+ return !this.args.model.worker_filter;
+ }
+
+ //note: these getters will go away when we refactor worker diagram
+ /**
+ * determines when the enterprise dual filter diagrams should be shown
+ * @type {boolean}
+ */
+ get workerDiagramDualFilter() {
+ return this.features.isEnabled('target-worker-filters-v2-ingress');
+ }
+ /**
+ * determines when the hcp dual filter diagrams should be shown
+ * @type {boolean}
+ */
+ get workerDiagramHCPDualFilter() {
+ return this.features.isEnabled('target-worker-filters-v2-hcp');
}
//actions
@action
- toggleEgressWorkerFilter() {
+ toggleEgressFilter() {
this.egressWorkerFilterEnabled = !this.egressWorkerFilterEnabled;
if (!this.egressWorkerFilterEnabled) {
this.args.model.egress_worker_filter = '';
}
}
- // =actions
+ @action
+ toggleIngressFilter() {
+ this.ingressWorkerFilterEnabled = !this.ingressWorkerFilterEnabled;
+ if (!this.ingressWorkerFilterEnabled) {
+ this.args.model.ingress_worker_filter = '';
+ }
+ }
@action
migrateWorkerFilters() {
this.egressWorkerFilterEnabled = true;
+ this.ingressWorkerFilterEnabled = true;
// When update is clicked, copy worker filter value into egress filter and clear the worker_filter
this.args.model.egress_worker_filter = this.args.model.worker_filter;
+ this.args.model.ingress_worker_filter = this.args.model.worker_filter;
this.args.model.worker_filter = '';
}
@@ -82,7 +111,9 @@ export default class FormTargetComponent extends Component {
cancel() {
this.args.cancel();
// Reset the tracked variable for toggles after rollback
- this.egressWorkerFilterEnabled =
- this.args.model.egress_worker_filter?.length;
+
+ this.egressWorkerFilterEnabled = this.args.model.egress_worker_filter;
+
+ this.ingressWorkerFilterEnabled = this.args.model.ingress_worker_filter;
}
}
diff --git a/ui/admin/app/components/form/target/worker-filter/index.hbs b/ui/admin/app/components/form/target/worker-filter/index.hbs
index d10c67b0a..f1a7f5cb1 100644
--- a/ui/admin/app/components/form/target/worker-filter/index.hbs
+++ b/ui/admin/app/components/form/target/worker-filter/index.hbs
@@ -1,8 +1,8 @@
-
+
- {{t
- (concat 'resources.target.workers.' @name '.filter.title')
- }}
- {{t
- (concat 'resources.target.workers.' @name '.filter.description')
- }}
+ {{t 'resources.target.workers.filter.title'}}
+
+ {{t 'resources.target.workers.filter.description'}}
{{t 'actions.learn-more'}}
diff --git a/ui/admin/app/components/worker-diagram/dual-filter/hcp/index.hbs b/ui/admin/app/components/worker-diagram/dual-filter/hcp/index.hbs
index e42afa1d1..456646ee4 100644
--- a/ui/admin/app/components/worker-diagram/dual-filter/hcp/index.hbs
+++ b/ui/admin/app/components/worker-diagram/dual-filter/hcp/index.hbs
@@ -21,7 +21,9 @@
- {{t 'resources.target.workers.filter-explainer.hcp-dual-egress-on'}}
+ {{t
+ 'resources.target.workers.filter-explainer.dual-egress-on-ingress-on'
+ }}
{{else if @ingressFilter}}
@@ -56,7 +58,7 @@
{{#if (feature-flag 'target-worker-filters-v2-hcp')}}
{{t 'resources.target.workers.diagram.hcp-worker'}}
{{else}}
- {{t 'resources.target.workers.diagram.front-line-worker'}}
+ {{t 'resources.target.workers.diagram.frontline-worker'}}
{{/if}}
- {{t 'resources.target.workers.filter-explainer.egress-on'}}
+ {{t 'resources.target.workers.filter-explainer.hcp-dual-egress-on'}}
{{else}}
diff --git a/ui/admin/app/components/worker-diagram/dual-filter/index.hbs b/ui/admin/app/components/worker-diagram/dual-filter/index.hbs
index 16a51bde6..c3e8ada91 100644
--- a/ui/admin/app/components/worker-diagram/dual-filter/index.hbs
+++ b/ui/admin/app/components/worker-diagram/dual-filter/index.hbs
@@ -49,7 +49,7 @@
{{t 'resources.target.workers.diagram.client'}}
- {{t 'resources.target.workers.diagram.front-line-worker'}}
+ {{t 'resources.target.workers.diagram.frontline-worker'}}
- {{t 'resources.target.workers.filter-explainer.egress-worker'}}
+ {{t 'resources.target.workers.filter-explainer.dual-egress-on'}}
{{else}}
diff --git a/ui/admin/tests/acceptance/targets/create-test.js b/ui/admin/tests/acceptance/targets/create-test.js
index d5136da91..652b1f485 100644
--- a/ui/admin/tests/acceptance/targets/create-test.js
+++ b/ui/admin/tests/acceptance/targets/create-test.js
@@ -136,6 +136,7 @@ module('Acceptance | targets | create', function (hooks) {
'random filter'
);
});
+
test('can create type `tcp` when `target-worker-filters-v2` is disabled', async function (assert) {
featuresService.disable('target-worker-filters-v2');
assert.expect(4);
@@ -161,6 +162,7 @@ module('Acceptance | targets | create', function (hooks) {
'random filter'
);
});
+
test('can create type `tcp` when `target-worker-filters-v2` is enabled', async function (assert) {
featuresService.enable('target-worker-filters-v2');
assert.expect(4);
@@ -188,6 +190,42 @@ module('Acceptance | targets | create', function (hooks) {
'random filter'
);
});
+
+ test('can create type `tcp` when `target-worker-filters-v2` and `target-worker-filters-v2-ingress` is enabled', async function (assert) {
+ featuresService.enable('target-worker-filters-v2');
+ featuresService.enable('target-worker-filters-v2-ingress');
+ assert.expect(4);
+ const targetCount = getTargetCount();
+ const tcpTargetCount = getTCPTargetCount();
+ await visit(urls.targets);
+
+ await click(`[href="${urls.newTarget}"]`);
+ await click('[value="tcp"]');
+ await fillIn('[name="name"]', 'random string');
+ await click(
+ '[data-test-filter="egress_worker_filter"] .hds-form-toggle__control'
+ );
+ await fillIn('[name="egress_worker_filter"]', 'random filter');
+ await click(
+ '[data-test-filter="ingress_worker_filter"] .hds-form-toggle__control'
+ );
+ await fillIn('[name="ingress_worker_filter"]', 'random filter');
+
+ await click('[type="submit"]');
+
+ assert.strictEqual(getTargetCount(), targetCount + 1);
+ assert.strictEqual(getTCPTargetCount(), tcpTargetCount + 1);
+ assert.strictEqual(
+ this.server.schema.targets.all().models[getTargetCount() - 1].name,
+ 'random string'
+ );
+ assert.strictEqual(
+ this.server.schema.targets.all().models[getTargetCount() - 1]
+ .egressWorkerFilter,
+ 'random filter'
+ );
+ });
+
test('default port is not marked required for SSH targets', async function (assert) {
assert.expect(1);
await visit(urls.newTarget);
diff --git a/ui/admin/tests/integration/components/form/target/details-test.js b/ui/admin/tests/integration/components/form/target/details-test.js
new file mode 100644
index 000000000..599aeaab1
--- /dev/null
+++ b/ui/admin/tests/integration/components/form/target/details-test.js
@@ -0,0 +1,57 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render, getContext } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+import { setupIntl } from 'ember-intl/test-support';
+
+module('Integration | Component | form/target/details', function (hooks) {
+ setupRenderingTest(hooks);
+ setupIntl(hooks);
+
+ let featuresService;
+
+ hooks.beforeEach(function () {
+ const { owner } = getContext();
+ featuresService = owner.lookup('service:features');
+ this.model = { type: 'ssh' };
+ this.submit = () => {};
+ this.cancel = () => {};
+ this.changeType = () => {};
+ });
+
+ test('shows the correct worker diagram when `target-worker-filters-v2` is enabled', async function (assert) {
+ featuresService.enable('target-worker-filters-v2');
+ featuresService.disable('target-worker-filters-v2-ingress');
+ featuresService.disable('target-worker-filters-v2-hcp');
+ assert.expect(1);
+ await render(
+ hbs``
+ );
+
+ assert.dom('[data-test-single-filter-egress-off]').isVisible();
+ });
+
+ test('shows the correct worker diagram when `target-worker-filters-v2` and `target-worker-filters-v2-ingress` is enabled', async function (assert) {
+ featuresService.enable('target-worker-filters-v2');
+ featuresService.enable('target-worker-filters-v2-ingress');
+ featuresService.disable('target-worker-filters-v2-hcp');
+ assert.expect(1);
+ await render(
+ hbs``
+ );
+
+ assert.dom('[data-test-dual-filters]').isVisible();
+ });
+
+ test('shows the correct worker diagram when `target-worker-filters-v2` and `target-worker-filters-v2-ingress` and `target-worker-filters-v2-hcp` is enabled', async function (assert) {
+ featuresService.enable('target-worker-filters-v2');
+ featuresService.enable('target-worker-filters-v2-ingress');
+ featuresService.enable('target-worker-filters-v2-hcp');
+ assert.expect(1);
+ await render(
+ hbs``
+ );
+
+ assert.dom('[data-test-dual-filters-hcp]').isVisible();
+ });
+});
diff --git a/ui/admin/tests/integration/components/form/target/worker-filter-test.js b/ui/admin/tests/integration/components/form/target/worker-filter-test.js
new file mode 100644
index 000000000..1cd0f4652
--- /dev/null
+++ b/ui/admin/tests/integration/components/form/target/worker-filter-test.js
@@ -0,0 +1,34 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'ember-qunit';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+import { setupIntl } from 'ember-intl/test-support';
+
+module('Integration | Component | form/target/worker-filter', function (hooks) {
+ setupRenderingTest(hooks);
+ setupIntl(hooks);
+
+ test('it only renders a toggle field when "toggleEnabled" is false', async function (assert) {
+ assert.expect(2);
+ this.onChange = () => {};
+ this.toggleAction = () => {};
+ await render(
+ hbs``
+ );
+
+ assert.dom('.hds-form-toggle').isVisible();
+ assert.dom('.hds-form-text-input').doesNotExist();
+ });
+
+ test('it renders a toggle field and text input field when "toggleEnabled" is true', async function (assert) {
+ assert.expect(2);
+ this.onChange = () => {};
+ this.toggleAction = () => {};
+ await render(
+ hbs``
+ );
+
+ assert.dom('.hds-form-toggle').isVisible();
+ assert.dom('.hds-form-text-input').isVisible();
+ });
+});