diff --git a/addons/core/translations/en-us.yaml b/addons/core/translations/en-us.yaml index d398d2854..3cff6634e 100644 --- a/addons/core/translations/en-us.yaml +++ b/addons/core/translations/en-us.yaml @@ -133,3 +133,27 @@ settings: alerts: cache-daemon: There may be a problem with the cache daemon client-agent: There may be a problem with the client agent +worker-filter-generator: + toggle: + title: Show filter generator + description: The generator will automatically generate a pre-formatted filter for you. You can copy the result to the editor above. + filter-generator: + title: Filter generator + description: Choose what you want to format into a filter. + link: Learn more about formatting a worker filter. + input-values: + title: Input values + description: Next, input what you want to format. + formatted-result: + title: Formatted result + description: Copy and paste this into the editor above. + label: Generated result + tag: + label: Tag + helper: Format a worker tag + name: + label: Name + helper: Format a worker name + operator: + matches: matches + contains: contains diff --git a/addons/core/translations/form/en-us.yaml b/addons/core/translations/form/en-us.yaml index d3cfc20d0..8be1621eb 100644 --- a/addons/core/translations/form/en-us.yaml +++ b/addons/core/translations/form/en-us.yaml @@ -136,6 +136,8 @@ key: label: Key value: label: Value +operator: + label: Operator callback_url: label: Callback URL help: The URL to which the third-party provider sends the authentication response. Paste this into the provider configuration. diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index c09d23d66..9098e9a7c 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -502,7 +502,7 @@ storage-bucket: help: The secret access key generated by your storage provider for the IAM user to use with this storage bucket. We will not show this data after it is saved, but you can replace it. worker_filter: label: Worker filter - help: Filter for Boundary workers that have network access to your storage. Boolean expression. + help: Filters to the worker(s) that can handle requests for this storage bucket. disable_credential_rotation: label: Disable credential rotation help: Disabling credential rotation could allow entities outside of Boundary to know the client secret in use. @@ -819,6 +819,7 @@ target: ingress-workers: Ingress workers actions: edit-worker-filter: Edit worker filter + add-worker-filter: Add worker filter credential-store: title: Credential Store title_plural: Credential Stores @@ -828,8 +829,20 @@ credential-store: title: Welcome to Credential Stores titles: new: New Credential Store + worker-filter: + title: Worker Filter + description: The worker filter format for this credential store. + messages: + none: + title: No worker filter added + description: You haven't added a worker filter yet. + edit: + title: Edit Worker Filter + description: Specify workers that have access to the credential store. actions: + add: Add Worker Filter delete: Delete Credential Store + edit: Edit Worker Filter types: vault: Vault static: Static diff --git a/ui/admin/app/components/credential-stores/credential-store/actions/index.hbs b/ui/admin/app/components/credential-stores/credential-store/actions/index.hbs index f205e1110..d7b116d16 100644 --- a/ui/admin/app/components/credential-stores/credential-store/actions/index.hbs +++ b/ui/admin/app/components/credential-stores/credential-store/actions/index.hbs @@ -18,6 +18,12 @@ {{t 'resources.credential.actions.create'}} {{/if}} + {{#if (and (feature-flag 'vault-worker-filter') @model.isVault)}} + + {{/if}} {{#if (can 'delete model' @model)}} diff --git a/ui/admin/app/components/credential-stores/credential-store/nav/index.hbs b/ui/admin/app/components/credential-stores/credential-store/nav/index.hbs index 828895fab..307868cc0 100644 --- a/ui/admin/app/components/credential-stores/credential-store/nav/index.hbs +++ b/ui/admin/app/components/credential-stores/credential-store/nav/index.hbs @@ -8,6 +8,13 @@ {{t 'titles.details'}} {{#if @model.isVault}} + {{#if (feature-flag 'vault-worker-filter')}} + + {{t 'resources.credential-store.worker-filter.title'}} + + {{/if}} {{#if (can 'navigate model' @model collection='credential-libraries')}} - {{#if (feature-flag 'vault-worker-filter')}} - - - {{t 'resources.credential-store.form.worker_filter.label'}} - - - {{t 'resources.credential-store.form.worker_filter.help'}} - - {{t 'actions.learn-more'}} - - - {{#if @model.errors.worker_filter}} - - {{#each @model.errors.worker_filter as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - {{/if}} - {{#if (or @model.isNew form.isEditable)}} - {{t 'resources.storage-bucket.form.worker_filter.label'}} - - {{t 'resources.storage-bucket.form.worker_filter.help'}} - - {{t 'actions.learn-more'}} - - - {{#if @model.errors.worker_filter}} - - {{#each @model.errors.worker_filter as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - + {{#let (unique-id) (unique-id) as |labelId helpId|}} + + {{t + 'resources.storage-bucket.form.worker_filter.label' + }} + + {{t 'resources.storage-bucket.form.worker_filter.help'}} + + {{t 'actions.learn-more'}} + + + + {{#if form.disabled}} + + {{else}} + + {{/if}} + + + {{/let}} {{! JUST for static credentials }} {{#unless this.showDynamicCredentials}} diff --git a/ui/admin/app/components/form/storage-bucket/aws/index.js b/ui/admin/app/components/form/storage-bucket/aws/index.js index 9671c701c..3d8d43bd3 100644 --- a/ui/admin/app/components/form/storage-bucket/aws/index.js +++ b/ui/admin/app/components/form/storage-bucket/aws/index.js @@ -13,10 +13,11 @@ import { tracked } from '@glimmer/tracking'; export default class FormStorageBucketAwsIndexComponent extends Component { // =attributes - @tracked selectedCredentialType = this.args.model.credentialType; + @tracked selectedCredentialType = this.args.model.credentialType; @tracked showDynamicCredentials = this.args.model.credentialType === TYPE_CREDENTIAL_DYNAMIC; + /** * returns an array of available credential types * @type {array} @@ -28,7 +29,7 @@ export default class FormStorageBucketAwsIndexComponent extends Component { // =actions /** * Allows to update the credential type - * @param type {string} + * @param {string} type */ @action updateCredentialTypeSelection(type) { diff --git a/ui/admin/app/components/form/storage-bucket/minio/index.hbs b/ui/admin/app/components/form/storage-bucket/minio/index.hbs index d9011a5aa..1761c2701 100644 --- a/ui/admin/app/components/form/storage-bucket/minio/index.hbs +++ b/ui/admin/app/components/form/storage-bucket/minio/index.hbs @@ -315,30 +315,42 @@ {{/if}} {{! worker_filter }} - - {{t 'resources.storage-bucket.form.worker_filter.label'}} - - {{t 'resources.storage-bucket.form.worker_filter.help'}} - - {{t 'actions.learn-more'}} - - - {{#if @model.errors.worker_filter}} - - {{#each @model.errors.worker_filter as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - + {{#let (unique-id) (unique-id) as |labelId helpId|}} + + {{t + 'resources.storage-bucket.form.worker_filter.label' + }} + + {{t 'resources.storage-bucket.form.worker_filter.help'}} + + {{t 'actions.learn-more'}} + + + + {{#if form.disabled}} + + {{else}} + + {{/if}} + + + {{/let}} {{! disable_credential_rotation }} + + + {{#if (can 'save model' @model)}} + + {{/if}} + \ No newline at end of file diff --git a/ui/admin/app/components/worker-filter-generator/index.hbs b/ui/admin/app/components/worker-filter-generator/index.hbs new file mode 100644 index 000000000..54306a42f --- /dev/null +++ b/ui/admin/app/components/worker-filter-generator/index.hbs @@ -0,0 +1,198 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: BUSL-1.1 +}} + + + + + {{#unless @hideToolbar}} + + {{/unless}} + + + + {{#if (get @model.errors @name)}} + + {{#each (get @model.errors @name) as |error|}} + {{error.message}} + {{/each}} + + {{/if}} + + + + + + {{t 'worker-filter-generator.toggle.title'}} + {{t + 'worker-filter-generator.toggle.description' + }} + + + + +{{#if this.showFilterGenerator}} + + {{t 'worker-filter-generator.filter-generator.title'}} + + {{t 'worker-filter-generator.filter-generator.description'}} +
+ + {{t 'worker-filter-generator.filter-generator.link'}} + +
+ + {{t + 'worker-filter-generator.filter-generator.tag.label' + }} + {{t + 'worker-filter-generator.filter-generator.tag.helper' + }} + + + {{t + 'worker-filter-generator.filter-generator.name.label' + }} + {{t + 'worker-filter-generator.filter-generator.name.helper' + }} + +
+ + {{#let (unique-id) (unique-id) as |labelId helpId|}} + + {{t + 'worker-filter-generator.filter-generator.input-values.title' + }} + {{t + 'worker-filter-generator.filter-generator.input-values.description' + }} + + {{#if (eq this.selectedGeneratorType this.generatorTagType)}} + + {{t 'form.key.label'}} + + {{else}} + + {{t 'form.operator.label'}} + + + {{#each this.operatorOptions as |operator|}} + + {{/each}} + + + {{/if}} + + + + {{t 'form.value.label'}} + + + + {{/let}} + + {{#let (unique-id) (unique-id) as |labelId helpId|}} + + {{t + 'worker-filter-generator.filter-generator.formatted-result.title' + }} + {{t + 'worker-filter-generator.filter-generator.formatted-result.description' + }} + + {{t + 'worker-filter-generator.filter-generator.formatted-result.label' + }} +
+ + {{#if this.generatedResult}} + + {{/if}} +
+
+
+ {{/let}} +{{/if}} \ No newline at end of file diff --git a/ui/admin/app/components/worker-filter-generator/index.js b/ui/admin/app/components/worker-filter-generator/index.js new file mode 100644 index 000000000..bd3afe7e7 --- /dev/null +++ b/ui/admin/app/components/worker-filter-generator/index.js @@ -0,0 +1,70 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Component from '@glimmer/component'; +import { action } from '@ember/object'; +import { tracked } from '@glimmer/tracking'; + +export default class WorkerFilterGeneratorIndexComponent extends Component { + // =attributes + + generatorTagType = 'tag'; + generatorNameType = 'name'; + operatorOptions = ['==', 'matches', 'contains']; + @tracked showFilterGenerator; + @tracked selectedGeneratorType = this.generatorTagType; + @tracked key = ''; + @tracked value = ''; + @tracked operator = ''; + + /** + * @return {string} + */ + get generatedResult() { + let valueResult = this.value ? `"${this.value}"` : ''; + if (this.selectedGeneratorType === 'tag') { + let keyResult = this.key ? `"/tags/${this.key}"` : ''; + return keyResult || valueResult ? `${valueResult} in ${keyResult}` : ''; + } else { + return valueResult || this.operator + ? `"/name" ${this.operator} ${valueResult}` + : ''; + } + } + + // =actions + + /** + * Sets the model filter to the passed in value. + * @param {Model} model + * @param {string} filter + * @param {string} value + */ + @action + setWorkerFilter(model, filter, value) { + model[filter] = value; + } + + /** + * Toggles showFilterGenerator attribute to true or false. + */ + @action + toggleFilterGenerator() { + this.showFilterGenerator = !this.showFilterGenerator; + } + + /** + * Clears out key, value, and operator. + * Sets selectedGeneratorType to a value. + * @param {object} event + */ + @action + setGeneratorType(event) { + this.key = ''; + this.value = ''; + this.operator = ''; + this.selectedGeneratorType = event.target.value; + } +} diff --git a/ui/admin/app/components/worker-filter/index.hbs b/ui/admin/app/components/worker-filter/index.hbs deleted file mode 100644 index ed65622f2..000000000 --- a/ui/admin/app/components/worker-filter/index.hbs +++ /dev/null @@ -1,41 +0,0 @@ -{{! - Copyright (c) HashiCorp, Inc. - SPDX-License-Identifier: BUSL-1.1 -}} - - - - - - - - - - {{#if (get @model.errors @name)}} - - {{#each (get @model.errors @name) as |error|}} - {{error.message}} - {{/each}} - - {{/if}} - - - - \ No newline at end of file diff --git a/ui/admin/app/components/worker-filter/index.js b/ui/admin/app/components/worker-filter/index.js deleted file mode 100644 index 4da609eb1..000000000 --- a/ui/admin/app/components/worker-filter/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Component from '@glimmer/component'; -import { action } from '@ember/object'; - -export default class WorkerFilterComponent extends Component { - // =actions - - /** - * Sets the model filter to the passed in value. - * @param {Model} model - * @param {string} filter - * @param {string} value - */ - @action - setWorkerFilter(model, filter, value) { - model[filter] = value; - } -} diff --git a/ui/admin/app/controllers/scopes/scope/credential-stores/credential-store/edit-worker-filter.js b/ui/admin/app/controllers/scopes/scope/credential-stores/credential-store/edit-worker-filter.js new file mode 100644 index 000000000..136049535 --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/credential-stores/credential-store/edit-worker-filter.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Controller, { inject as controller } from '@ember/controller'; + +export default class ScopesScopeCredentialStoresCredentialStoreEditWorkerFilterController extends Controller { + @controller('scopes/scope/credential-stores/index') credentialStores; +} diff --git a/ui/admin/app/controllers/scopes/scope/credential-stores/credential-store/worker-filter.js b/ui/admin/app/controllers/scopes/scope/credential-stores/credential-store/worker-filter.js new file mode 100644 index 000000000..82616dedc --- /dev/null +++ b/ui/admin/app/controllers/scopes/scope/credential-stores/credential-store/worker-filter.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Controller, { inject as controller } from '@ember/controller'; + +export default class ScopesScopeCredentialStoresCredentialStoreWorkerFilterController extends Controller { + @controller('scopes/scope/credential-stores/index') credentialStores; +} diff --git a/ui/admin/app/controllers/scopes/scope/credential-stores/index.js b/ui/admin/app/controllers/scopes/scope/credential-stores/index.js index fd60e8f17..ad9b2b874 100644 --- a/ui/admin/app/controllers/scopes/scope/credential-stores/index.js +++ b/ui/admin/app/controllers/scopes/scope/credential-stores/index.js @@ -126,4 +126,31 @@ export default class ScopesScopeCredentialStoresIndexController extends Controll this[paramKey] = [...selectedItems]; this.page = 1; } + + /** + * Save worker filter + * @param {CredentialStoreModel} credentialStore + */ + @action + @loading + @notifyError(({ message }) => message, { catch: true }) + @notifySuccess('notifications.add-success') + async saveWorkerFilter(credentialStore) { + await credentialStore.save(); + await this.router.replaceWith( + 'scopes.scope.credential-stores.credential-store.worker-filter', + ); + } + + /** + * Cancel adding or editing a worker filter + * @param {CredentialStoreModel} credentialStore + */ + @action + async cancelWorkerFilter(credentialStore) { + credentialStore.rollbackAttributes(); + await this.router.replaceWith( + 'scopes.scope.credential-stores.credential-store.worker-filter', + ); + } } diff --git a/ui/admin/app/router.js b/ui/admin/app/router.js index 9d4a9af3a..1656c63a6 100644 --- a/ui/admin/app/router.js +++ b/ui/admin/app/router.js @@ -150,6 +150,8 @@ Router.map(function () { function () {}, ); }); + this.route('worker-filter'); + this.route('edit-worker-filter'); }, ); this.route('new'); diff --git a/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/edit-worker-filter.js b/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/edit-worker-filter.js new file mode 100644 index 000000000..751a6d0b5 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/edit-worker-filter.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Route from '@ember/routing/route'; + +export default class ScopesScopeCredentialStoresCredentialStoreEditWorkerFilterRoute extends Route {} diff --git a/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/worker-filter.js b/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/worker-filter.js new file mode 100644 index 000000000..0f32202e5 --- /dev/null +++ b/ui/admin/app/routes/scopes/scope/credential-stores/credential-store/worker-filter.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Route from '@ember/routing/route'; + +export default class ScopesScopeCredentialStoresCredentialStoreWorkerFilterRoute extends Route {} diff --git a/ui/admin/app/styles/app.scss b/ui/admin/app/styles/app.scss index 2c98efe9d..3b0997be6 100644 --- a/ui/admin/app/styles/app.scss +++ b/ui/admin/app/styles/app.scss @@ -1056,3 +1056,30 @@ padding: 0.25rem 0.75rem; } } + +// worker filter generator +.filter-generator-selection { + .hds-form-group__control-field { + margin-bottom: 0; + } +} + +.formatted-results { + p { + margin-bottom: 0.5rem; + } +} + +.generated-results-container { + display: flex; + flex-direction: row; + gap: 0.5rem; + align-items: flex-start; +} + +// storage buckets +.storage-bucket-worker-filter { + .hds-form-field--layout-flag { + margin-bottom: 0; + } +} diff --git a/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/edit-worker-filter.hbs b/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/edit-worker-filter.hbs new file mode 100644 index 000000000..e45c15585 --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/edit-worker-filter.hbs @@ -0,0 +1,37 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: BUSL-1.1 +}} + +{{page-title + (t 'resources.credential-store.worker-filter.messages.edit.title') +}} + + + + + + + + + + {{t 'resources.credential-store.worker-filter.messages.edit.title'}} + + + + {{t 'resources.credential-store.worker-filter.messages.edit.description'}} + + + + + + + \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/worker-filter.hbs b/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/worker-filter.hbs new file mode 100644 index 000000000..f3d1d3a3e --- /dev/null +++ b/ui/admin/app/templates/scopes/scope/credential-stores/credential-store/worker-filter.hbs @@ -0,0 +1,72 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: BUSL-1.1 +}} + +{{page-title (t 'resources.credential-store.worker-filter.title')}} + + + + + + + + + + + + + + + + + + + + + {{#if @model.worker_filter}} + + + {{t 'resources.credential-store.worker-filter.title'}} + + + {{t 'resources.credential-store.worker-filter.description'}} + + + {{else}} + + + + + + + + + + {{/if}} + + \ No newline at end of file diff --git a/ui/admin/app/templates/scopes/scope/targets/target/edit-egress-worker-filter.hbs b/ui/admin/app/templates/scopes/scope/targets/target/edit-egress-worker-filter.hbs index 21a17a612..3a5778062 100644 --- a/ui/admin/app/templates/scopes/scope/targets/target/edit-egress-worker-filter.hbs +++ b/ui/admin/app/templates/scopes/scope/targets/target/edit-egress-worker-filter.hbs @@ -17,7 +17,7 @@

{{t 'resources.target.workers.edit-egress-worker-filter.title'}} - +

{{t 'resources.target.workers.edit-egress-worker-filter.description' @@ -25,7 +25,7 @@ -

{{t 'resources.target.workers.edit-ingress-worker-filter.title'}} - +

{{t 'resources.target.workers.edit-ingress-worker-filter.description' @@ -26,7 +26,7 @@ - @@ -62,6 +66,7 @@ <:content> {{#if @model.ingress_worker_filter}} @@ -110,6 +121,7 @@ <:content> {{#if @model.egress_worker_filter}} + `[data-test-target-${name}-workers-accordion-item] a`; const ACCORDION_DROPDOWN_SELECTOR = (name) => `[data-test-target-${name}-workers-accordion-item] .hds-accordion-item__button`; const CODE_BLOCK_SELECTOR = (name) => @@ -244,6 +246,38 @@ module('Acceptance | targets | workers', function (hooks) { assert.dom(CODE_BLOCK_SELECTOR('egress')).hasText(egressWorkerFilter); }); + test('user will see "Add worker filter" if no filter set', async function (assert) { + featuresService.enable('target-worker-filters-v2-ingress'); + instances.target.update({ + egress_worker_filter: '', + ingress_worker_filter: '', + }); + await visit(urls.target); + + await click(`[href="${urls.targetWorkers}"]`); + + assert + .dom(ACCORDION_DROPDOWN_TEXT_SELECTOR('egress')) + .hasText('Add worker filter'); + assert + .dom(ACCORDION_DROPDOWN_TEXT_SELECTOR('ingress')) + .hasText('Add worker filter'); + }); + + test('user will see "Edit worker filter" if filter is set', async function (assert) { + featuresService.enable('target-worker-filters-v2-ingress'); + await visit(urls.target); + + await click(`[href="${urls.targetWorkers}"]`); + + assert + .dom(ACCORDION_DROPDOWN_TEXT_SELECTOR('egress')) + .hasText('Edit worker filter'); + assert + .dom(ACCORDION_DROPDOWN_TEXT_SELECTOR('ingress')) + .hasText('Edit worker filter'); + }); + test('user can cancel changes to egress worker filter in a target', async function (assert) { const egressWorkerFilter = '"random" in "/worker/filters"'; await visit(urls.target); diff --git a/ui/admin/tests/integration/components/worker-filter-generator/index-test.js b/ui/admin/tests/integration/components/worker-filter-generator/index-test.js new file mode 100644 index 000000000..285bde339 --- /dev/null +++ b/ui/admin/tests/integration/components/worker-filter-generator/index-test.js @@ -0,0 +1,135 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, fillIn, select } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { setupIntl } from 'ember-intl/test-support'; + +module( + 'Integration | Component | worker-filter-generator/index', + function (hooks) { + setupRenderingTest(hooks); + setupIntl(hooks, 'en-us'); + + const CODE_EDITOR = '[data-test-code-editor-field-editor]'; + const CODE_EDITOR_LINE = + '[data-test-code-editor-field-editor] .CodeMirror-line'; + const FILTER_GENERATOR = '[name="filter_generator"]'; + const SHOW_FILTER_GENERATOR = '[name="show_filter_generator"]'; + const TAG_TYPE_OPTION = '[value="tag"]'; + const NAME_TYPE_OPTION = '[value="name"]'; + const TAG_KEY = '[name="tag_key"]'; + const TAG_VALUE = '[name="tag_value"]'; + const NAME_OPERATOR = '[name="name_operator"]'; + const GENERATED_VALUE = '[name="generated_value"]'; + + test('it renders correct content when egress_worker_filter is passed in', async function (assert) { + this.model = { egress_worker_filter: 'egress filter' }; + await render( + hbs``, + ); + + assert.dom(CODE_EDITOR).isVisible(); + assert.dom(CODE_EDITOR_LINE).hasText(this.model.egress_worker_filter); + }); + + test('it renders correct content when ingress_worker_filter is passed in', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + + assert.dom(CODE_EDITOR).isVisible(); + assert.dom(CODE_EDITOR_LINE).hasText(this.model.ingress_worker_filter); + }); + + test('toggleFilterGenerator shows filter generator when toggled on', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + + assert.dom(FILTER_GENERATOR).isNotVisible(); + + await click(SHOW_FILTER_GENERATOR); + + assert.dom(FILTER_GENERATOR).isVisible(); + }); + + test('filter generator tag type shows key and value input boxes', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + await click(SHOW_FILTER_GENERATOR); + await click(TAG_TYPE_OPTION); + + assert.dom(TAG_KEY).isVisible(); + assert.dom(TAG_VALUE).isVisible(); + assert.dom(NAME_OPERATOR).isNotVisible(); + }); + + test('filter generator tag type generates correctly formatted filter', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + await click(SHOW_FILTER_GENERATOR); + await click(TAG_TYPE_OPTION); + await fillIn(TAG_KEY, 'key1'); + await fillIn(TAG_VALUE, 'val1'); + + assert.dom(GENERATED_VALUE).hasValue('"val1" in "/tags/key1"'); + }); + + test('filter generator name type shows operator and value fields', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + + await click(SHOW_FILTER_GENERATOR); + await click(NAME_TYPE_OPTION); + + assert.dom(NAME_OPERATOR).isVisible(); + assert.dom(TAG_VALUE).isVisible(); + assert.dom(TAG_KEY).isNotVisible(); + }); + + test('filter generator name type generates correctly formatted filter', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + + await click(SHOW_FILTER_GENERATOR); + await click(NAME_TYPE_OPTION); + await fillIn(TAG_VALUE, 'val1'); + await select(NAME_OPERATOR, '=='); + + assert.dom(GENERATED_VALUE).hasValue('"/name" == "val1"'); + }); + + test('generated result is cleared when switching filter types', async function (assert) { + this.model = { ingress_worker_filter: 'ingress filter' }; + await render( + hbs``, + ); + + await click(SHOW_FILTER_GENERATOR); + await click(NAME_TYPE_OPTION); + await fillIn(TAG_VALUE, 'val1'); + await select(NAME_OPERATOR, '=='); + + assert.dom(GENERATED_VALUE).hasValue('"/name" == "val1"'); + + await click(TAG_TYPE_OPTION); + + assert.dom(GENERATED_VALUE).hasNoValue(); + }); + }, +); diff --git a/ui/admin/tests/integration/components/worker-filter/index-test.js b/ui/admin/tests/integration/components/worker-filter/index-test.js deleted file mode 100644 index be095b213..000000000 --- a/ui/admin/tests/integration/components/worker-filter/index-test.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: BUSL-1.1 - */ - -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 | worker-filter/index', function (hooks) { - setupRenderingTest(hooks); - setupIntl(hooks, 'en-us'); - - test('it renders correct content when egress_worker_filter is passed in', async function (assert) { - this.onInput = () => {}; - this.submit = () => {}; - this.cancel = () => {}; - this.model = { egress_worker_filter: 'egress filter' }; - await render( - hbs``, - ); - - assert.dom('[data-test-code-editor-field-editor]').isVisible(); - assert - .dom('[data-test-code-editor-field-editor] .CodeMirror-line') - .hasText(this.model.egress_worker_filter); - }); - - test('it renders correct content when ingress_worker_filter is passed in', async function (assert) { - this.onInput = () => {}; - this.submit = () => {}; - this.cancel = () => {}; - this.model = { ingress_worker_filter: 'ingress filter' }; - await render( - hbs``, - ); - - assert.dom('[data-test-code-editor-field-editor]').isVisible(); - assert - .dom('[data-test-code-editor-field-editor] .CodeMirror-line') - .hasText(this.model.ingress_worker_filter); - }); -}); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/credential-stores/credential-store/edit-worker-filter-test.js b/ui/admin/tests/unit/controllers/scopes/scope/credential-stores/credential-store/edit-worker-filter-test.js new file mode 100644 index 000000000..2a2981eb8 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/credential-stores/credential-store/edit-worker-filter-test.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module( + 'Unit | Controller | scopes/scope/credential-stores/credential-store/edit-worker-filter', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/credential-stores/credential-store/edit-worker-filter', + ); + assert.ok(controller); + assert.ok(controller.credentialStores); + }); + }, +); diff --git a/ui/admin/tests/unit/controllers/scopes/scope/credential-stores/credential-store/worker-filter-test.js b/ui/admin/tests/unit/controllers/scopes/scope/credential-stores/credential-store/worker-filter-test.js new file mode 100644 index 000000000..14ee81ec3 --- /dev/null +++ b/ui/admin/tests/unit/controllers/scopes/scope/credential-stores/credential-store/worker-filter-test.js @@ -0,0 +1,22 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module( + 'Unit | Controller | scopes/scope/credential-stores/credential-store/worker-filter', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let controller = this.owner.lookup( + 'controller:scopes/scope/credential-stores/credential-store/worker-filter', + ); + assert.ok(controller); + assert.ok(controller.credentialStores); + }); + }, +); diff --git a/ui/admin/tests/unit/routes/scopes/scope/credential-stores/credential-store/edit-worker-filter-test.js b/ui/admin/tests/unit/routes/scopes/scope/credential-stores/credential-store/edit-worker-filter-test.js new file mode 100644 index 000000000..8de8cb806 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/credential-stores/credential-store/edit-worker-filter-test.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/credential-stores/credential-store/edit-worker-filter', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/credential-stores/credential-store/edit-worker-filter', + ); + assert.ok(route); + }); + }, +); diff --git a/ui/admin/tests/unit/routes/scopes/scope/credential-stores/credential-store/worker-filter-test.js b/ui/admin/tests/unit/routes/scopes/scope/credential-stores/credential-store/worker-filter-test.js new file mode 100644 index 000000000..23f4e1eb3 --- /dev/null +++ b/ui/admin/tests/unit/routes/scopes/scope/credential-stores/credential-store/worker-filter-test.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'admin/tests/helpers'; + +module( + 'Unit | Route | scopes/scope/credential-stores/credential-store/worker-filter', + function (hooks) { + setupTest(hooks); + + test('it exists', function (assert) { + let route = this.owner.lookup( + 'route:scopes/scope/credential-stores/credential-store/worker-filter', + ); + assert.ok(route); + }); + }, +);