diff --git a/ui/app/utils/all-engines-metadata.ts b/ui/app/utils/all-engines-metadata.ts index 3f829f720c..1d7451b295 100644 --- a/ui/app/utils/all-engines-metadata.ts +++ b/ui/app/utils/all-engines-metadata.ts @@ -197,8 +197,9 @@ export const ALL_ENGINES: EngineDisplayData[] = [ pluginCategory: 'generic', displayName: 'Kubernetes', engineRoute: 'kubernetes.overview', + configRoute: 'kubernetes.configuration', glyph: 'kubernetes-color', - isOldEngine: true, + isConfigurable: true, mountCategory: ['auth', 'secret'], type: 'kubernetes', }, diff --git a/ui/lib/kubernetes/addon/components/kubernetes-header.hbs b/ui/lib/kubernetes/addon/components/kubernetes-header.hbs index 28343771ac..8dca4cfee7 100644 --- a/ui/lib/kubernetes/addon/components/kubernetes-header.hbs +++ b/ui/lib/kubernetes/addon/components/kubernetes-header.hbs @@ -3,26 +3,34 @@ SPDX-License-Identifier: BUSL-1.1 }} - + <:breadcrumbs> <:actions> - - - Configure - Delete - + {{#if @configRoute}} + + {{else}} + + + Configure + Delete + + {{/if}} @@ -38,7 +46,6 @@ {{/if}} diff --git a/ui/lib/kubernetes/addon/components/page/configuration.hbs b/ui/lib/kubernetes/addon/components/page/configuration.hbs index 3f4deb68a8..dd3150da95 100644 --- a/ui/lib/kubernetes/addon/components/page/configuration.hbs +++ b/ui/lib/kubernetes/addon/components/page/configuration.hbs @@ -3,8 +3,12 @@ SPDX-License-Identifier: BUSL-1.1 }} -{{! TODO: VAULT-40884 Add @configRoute argument with value "configuration" so mount config tabs show }} - + {{#if @config}} Edit configuration @@ -29,12 +33,4 @@ {{/if}} -{{else}} - -{{/if}} - - \ No newline at end of file +{{/if}} \ No newline at end of file diff --git a/ui/lib/kubernetes/addon/components/page/configure.hbs b/ui/lib/kubernetes/addon/components/page/configure.hbs index 79c64b5d34..cbea343b5d 100644 --- a/ui/lib/kubernetes/addon/components/page/configure.hbs +++ b/ui/lib/kubernetes/addon/components/page/configure.hbs @@ -3,12 +3,12 @@ SPDX-License-Identifier: BUSL-1.1 }} -{{! TODO: VAULT-40884 Update Page::Header to use Kubernetes::Header and pass @configRoute argument with value "configure" for mount config tabs to show}} - - <:breadcrumbs> - - - +
diff --git a/ui/lib/kubernetes/addon/routes/configuration.ts b/ui/lib/kubernetes/addon/routes/configuration.ts index 2f1ed9c15d..ec619c7727 100644 --- a/ui/lib/kubernetes/addon/routes/configuration.ts +++ b/ui/lib/kubernetes/addon/routes/configuration.ts @@ -11,6 +11,7 @@ import type { KubernetesApplicationModel } from './application'; import type SecretMountPath from 'vault/services/secret-mount-path'; import type Controller from '@ember/controller'; import type { Breadcrumb } from 'vault/app-types'; +import type RouterService from '@ember/routing/router-service'; interface RouteController extends Controller { breadcrumbs: Array; @@ -21,6 +22,7 @@ export type KubernetesConfigureModel = ModelFrom; export default class KubernetesConfigureRoute extends Route { @service declare readonly secretMountPath: SecretMountPath; + @service('app-router') declare readonly router: RouterService; model() { const { config, configError, secretsEngine, promptConfig } = this.modelFor( @@ -33,6 +35,12 @@ export default class KubernetesConfigureRoute extends Route { return { secretsEngine, config, promptConfig }; } + afterModel(resolvedModel: KubernetesConfigureModel) { + if (!resolvedModel.config) { + this.router.transitionTo('vault.cluster.secrets.backend.kubernetes.configure'); + } + } + setupController(controller: RouteController, resolvedModel: KubernetesConfigureModel) { super.setupController(controller, resolvedModel); const { currentPath } = this.secretMountPath; diff --git a/ui/lib/kubernetes/addon/routes/configure.ts b/ui/lib/kubernetes/addon/routes/configure.ts index d1f5b7087a..164df2a0af 100644 --- a/ui/lib/kubernetes/addon/routes/configure.ts +++ b/ui/lib/kubernetes/addon/routes/configure.ts @@ -23,9 +23,9 @@ export default class KubernetesConfigureRoute extends Route { @service declare readonly secretMountPath: SecretMountPath; async model() { - const { config } = this.modelFor('application') as KubernetesApplicationModel; + const { config, secretsEngine } = this.modelFor('application') as KubernetesApplicationModel; const data = config || { disable_local_ca_jwt: false }; - return new KubernetesConfigForm(data, { isNew: !config }); + return { form: new KubernetesConfigForm(data, { isNew: !config }), secretsEngine }; } setupController(controller: RouteController, resolvedModel: KubernetesConfigureModel) { diff --git a/ui/lib/kubernetes/addon/templates/configure.hbs b/ui/lib/kubernetes/addon/templates/configure.hbs index addcbb9ebf..2e9202e7f2 100644 --- a/ui/lib/kubernetes/addon/templates/configure.hbs +++ b/ui/lib/kubernetes/addon/templates/configure.hbs @@ -3,4 +3,4 @@ SPDX-License-Identifier: BUSL-1.1 }} - \ No newline at end of file + \ No newline at end of file diff --git a/ui/tests/acceptance/secrets/backend/kubernetes/configuration-test.js b/ui/tests/acceptance/secrets/backend/kubernetes/configuration-test.js index d8e7546112..9e132c9e60 100644 --- a/ui/tests/acceptance/secrets/backend/kubernetes/configuration-test.js +++ b/ui/tests/acceptance/secrets/backend/kubernetes/configuration-test.js @@ -68,9 +68,8 @@ module('Acceptance | kubernetes | configuration', function (hooks) { await this.visitConfiguration(); assert.strictEqual( currentRouteName(), - 'vault.cluster.secrets.backend.kubernetes.configuration', - 'Transitions to configuration route on fetch 404' + 'vault.cluster.secrets.backend.kubernetes.configure', + 'Transitions to configure route on fetch 404' ); - assert.dom('[data-test-empty-state-title]').hasText('Kubernetes not configured', 'Config cta renders'); }); }); diff --git a/ui/tests/integration/components/kubernetes/kubernetes-header-test.js b/ui/tests/integration/components/kubernetes/kubernetes-header-test.js index 29d7be06e5..e6fdd7d07b 100644 --- a/ui/tests/integration/components/kubernetes/kubernetes-header-test.js +++ b/ui/tests/integration/components/kubernetes/kubernetes-header-test.js @@ -7,7 +7,7 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { setupEngine } from 'ember-engines/test-support'; import { setupMirage } from 'ember-cli-mirage/test-support'; -import { render } from '@ember/test-helpers'; +import { click, render } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; import { GENERAL } from 'vault/tests/helpers/general-selectors'; import sinon from 'sinon'; @@ -71,7 +71,6 @@ module('Integration | Component | kubernetes | KubernetesHeader', function (hook ); assert.dom('[data-test-tab="overview"]').hasText('Overview', 'Overview tab renders'); assert.dom('[data-test-tab="roles"]').hasText('Roles', 'Roles tab renders'); - assert.dom('[data-test-tab="config"]').hasText('Configuration', 'Configuration tab renders'); }); test('it should render filter for roles', async function (assert) { @@ -96,4 +95,27 @@ module('Integration | Component | kubernetes | KubernetesHeader', function (hook .dom('.toolbar-actions [data-test-yield]') .hasText('It yields!', 'Block is yielded for toolbar actions'); }); + + test('it should render a dropdown when configRoute is omitted', async function (assert) { + await render( + hbs``, + { + owner: this.engine, + } + ); + assert.dom(GENERAL.dropdownToggle('Manage')).hasText('Manage', 'Manage dropdown renders'); + await click(GENERAL.dropdownToggle('Manage')); + assert.dom(GENERAL.menuItem('Configure')).exists('Configure dropdown item renders'); + assert.dom(GENERAL.menuItem('Delete')).exists('Configure dropdown item renders'); + }); + + test('it should render exit configuration button when configRoute is provided', async function (assert) { + await render( + hbs``, + { + owner: this.engine, + } + ); + assert.dom(GENERAL.button('Exit configuration')).exists('Exit configuration button renders'); + }); }); diff --git a/ui/tests/integration/components/kubernetes/page/configuration-test.js b/ui/tests/integration/components/kubernetes/page/configuration-test.js index 4f3ca2da76..228452c203 100644 --- a/ui/tests/integration/components/kubernetes/page/configuration-test.js +++ b/ui/tests/integration/components/kubernetes/page/configuration-test.js @@ -49,16 +49,15 @@ module('Integration | Component | kubernetes | Page::Configuration', function (h }; }); - test('it should render tab page header, config cta and mount config', async function (assert) { + test('it should render tab page header', async function (assert) { await this.renderComponent(); assert .dom(GENERAL.icon('kubernetes-color')) .hasClass('hds-icon-kubernetes-color', 'Kubernetes icon renders in title'); - assert.dom(GENERAL.hdsPageHeaderTitle).hasText('kubernetes-test', 'Mount path renders in title'); + assert + .dom(GENERAL.hdsPageHeaderTitle) + .hasText('kubernetes-test configuration', 'Mount path renders in title'); assert.dom(SES.configure).doesNotExist('Toolbar action does not render when engine is not configured'); - assert.dom(GENERAL.emptyStateTitle).hasText('Kubernetes not configured'); - assert.dom(GENERAL.emptyStateActions).hasText('Configure Kubernetes'); - assert.dom('[data-test-mount-config]').exists('Mount config renders'); }); test('it should render message for inferred configuration', async function (assert) {