Skip to content

Commit

Permalink
UI/fix kv data cache (#14489)
Browse files Browse the repository at this point in the history
* KV fetches recent version on every page, no longer disallow new version without metadata access

* Don't flash no read permissions warning

* Send noMetadataVersion on destroy if version is undefined

* test coverage

* add changelog, fix tests

* Fix failing test
  • Loading branch information
hashishaw committed Mar 16, 2022
1 parent 5f8df11 commit 186ad79
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 28 deletions.
3 changes: 3 additions & 0 deletions changelog/14489.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
ui: Fixes caching issue on kv new version create
```
1 change: 1 addition & 0 deletions ui/app/adapters/secret-v2-version.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export default ApplicationAdapter.extend({
} else if (deleteType === 'soft-delete') {
return this.softDelete(backend, path, version);
} else {
version = version || currentVersionForNoReadMetadata;
return this.deleteByDeleteType(backend, path, deleteType, version);
}
},
Expand Down
15 changes: 1 addition & 14 deletions ui/app/routes/vault/cluster/secrets/backend/secret-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,20 +248,7 @@ export default Route.extend(UnloadModelRoute, {
if (modelType === 'secret-v2') {
// after the the base model fetch, kv-v2 has a second associated
// version model that contains the secret data

// if no read access to metadata, return current Version from secret data.
if (!secretModel.currentVersion) {
let adapter = this.store.adapterFor('secret-v2-version');
try {
secretModel.currentVersion = await adapter.getSecretDataVersion(backend, secret);
} catch {
// will get error if you have deleted the secret
// if this is the case do nothing
}
secretModel = await this.fetchV2Models(capabilities, secretModel, params);
} else {
secretModel = await this.fetchV2Models(capabilities, secretModel, params);
}
secretModel = await this.fetchV2Models(capabilities, secretModel, params);
}
return {
secret: secretModel,
Expand Down
4 changes: 2 additions & 2 deletions ui/app/templates/components/secret-create-or-update.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@
<form onsubmit={{action "createOrUpdateKey" "edit"}}>
<div class="box is-sideless is-fullwidth is-marginless padding-top">
<MessageError @model={{@modelForData}} @errorMessage={{this.error}} />
{{#unless @canReadSecretData}}
{{#if (eq @canReadSecretData false)}}
<AlertBanner
@type="warning"
@message="You do not have read permissions. If a secret exists here creating a new secret will overwrite it."
data-test-warning-no-read-permissions
/>
{{/unless}}
{{/if}}
<NamespaceReminder @mode="edit" @noun="secret" />
{{#if this.isCreateNewVersionFromOldVersion}}
<div class="form-section">
Expand Down
9 changes: 6 additions & 3 deletions ui/app/templates/components/secret-edit-toolbar.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,15 @@
{{#let (concat "vault.cluster.secrets.backend." (if (eq @mode "show") "edit" "show")) as |targetRoute|}}
{{#if @isV2}}
<ToolbarLink
@params={{array targetRoute @model.id (query-params version=@modelForData.version)}}
{{! Always create new version from latest if no metadata read access }}
@params={{array
targetRoute
@model.id
(query-params version=(if @model.canReadMetadata @modelForData.version ""))
}}
@data-test-secret-edit="true"
@replace={{true}}
@type="add"
@disabled={{@model.failedServerRead}}
@disabledTooltip="Metadata read access is required to create new version"
>
Create new version
</ToolbarLink>
Expand Down
3 changes: 1 addition & 2 deletions ui/tests/acceptance/access/identity/_shared-alias-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,13 @@ export const testAliasDeleteFromForm = async function (name, itemType, assert) {
`${itemType}: navigates to edit on create`
);
await page.editForm.delete();
await settled();
await page.editForm.waitForConfirm();
await page.editForm.confirmDelete();
await settled();
assert.ok(
aliasIndexPage.flashMessage.latestMessage.startsWith('Successfully deleted'),
`${itemType}: shows flash message`
);

assert.equal(
currentRouteName(),
'vault.cluster.access.identity.aliases.index',
Expand Down
26 changes: 19 additions & 7 deletions ui/tests/acceptance/secrets/backend/kv/secret-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -607,11 +607,22 @@ module('Acceptance | secrets/secret/create', function (hooks) {
await assert
.dom('[data-test-value-div="secret-key"]')
.exists('secret view page and info table row with secret-key value');
// create new version should be disabled with no metadata read access
assert.dom('[data-test-secret-edit]').hasClass('disabled', 'Create new version action is disabled');
assert
.dom('[data-test-popup-menu-trigger="version"]')
.doesNotExist('the version drop down menu does not show');

// Create new version
assert.dom('[data-test-secret-edit]').doesNotHaveClass('disabled', 'Create new version is not disabled');
await click('[data-test-secret-edit]');

// create new version should not include version in the URL
assert.equal(
currentURL(),
`/vault/secrets/${enginePath}/edit/${secretPath}`,
'edit route does not include version query param'
);
// Update key
await editPage.secretKey('newKey');
await editPage.secretValue('some-value');
await editPage.save();
assert.dom('[data-test-value-div="newKey"]').exists('Info row table exists at newKey');

// check metadata tab
await click('[data-test-secret-metadata-tab]');
Expand Down Expand Up @@ -683,8 +694,9 @@ module('Acceptance | secrets/secret/create', function (hooks) {
await settled(); // eslint-disable-line
await click('[data-test-secret-tab]');
await settled(); // eslint-disable-line
let text = document.querySelector('[data-test-empty-state-title]').innerText.trim();
assert.equal(text, 'Version 1 of this secret has been permanently destroyed');
assert
.dom('[data-test-empty-state-title]')
.includesText('Version 1 of this secret has been permanently destroyed');
});

test('version 2 with policy with only delete option does not show modal and undelete is an option', async function (assert) {
Expand Down
7 changes: 7 additions & 0 deletions ui/tests/pages/components/identity/edit-form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { clickable, fillable, attribute } from 'ember-cli-page-object';
import { waitFor } from '@ember/test-helpers';
import fields from '../form-field';

export default {
Expand All @@ -13,4 +14,10 @@ export default {
submit: clickable('[data-test-identity-submit]'),
delete: clickable('[data-test-confirm-action-trigger]'),
confirmDelete: clickable('[data-test-confirm-button]'),
waitForConfirm() {
return waitFor('[data-test-confirm-button]');
},
waitForFlash() {
return waitFor('[data-test-flash-message-body]');
},
};

0 comments on commit 186ad79

Please sign in to comment.