mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	UI: Show error when seal fails (#23921)
* Show error when seal fails * cleanup, add headers * add changelog * Fix test
This commit is contained in:
		
							
								
								
									
										3
									
								
								changelog/23921.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/23921.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:bug | ||||||
|  | ui: show error from API when seal fails | ||||||
|  | ``` | ||||||
							
								
								
									
										34
									
								
								ui/app/components/seal-action.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ui/app/components/seal-action.hbs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | {{! | ||||||
|  |   Copyright (c) HashiCorp, Inc. | ||||||
|  |   SPDX-License-Identifier: BUSL-1.1 | ||||||
|  | ~}} | ||||||
|  |  | ||||||
|  | <div class="box is-sideless is-fullwidth is-marginless"> | ||||||
|  |   {{#if this.error}} | ||||||
|  |     <Hds::Alert @type="inline" @color="critical" class="has-bottom-margin-m" data-test-seal-error as |A|> | ||||||
|  |       <A.Title>Error</A.Title> | ||||||
|  |       <A.Description> | ||||||
|  |         {{this.error}} | ||||||
|  |       </A.Description> | ||||||
|  |     </Hds::Alert> | ||||||
|  |   {{/if}} | ||||||
|  |   <p> | ||||||
|  |     Sealing a vault tells the Vault server to stop responding to any access operations until it is unsealed again. A sealed | ||||||
|  |     vault throws away its root key to unlock the data, so it physically is blocked from responding to operations again until | ||||||
|  |     the Vault is unsealed again with the "unseal" command or via the API. | ||||||
|  |   </p> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <div class="field is-grouped box is-fullwidth is-bottomless"> | ||||||
|  |   <ConfirmAction | ||||||
|  |     @buttonClasses="button is-primary" | ||||||
|  |     @confirmTitle="Seal this cluster?" | ||||||
|  |     @confirmMessage="You will not be able to read or write any data until the cluster is unsealed again." | ||||||
|  |     @confirmButtonText="Seal" | ||||||
|  |     @horizontalPosition="auto-left" | ||||||
|  |     @onConfirmAction={{this.handleSeal}} | ||||||
|  |     data-test-seal | ||||||
|  |   > | ||||||
|  |     Seal | ||||||
|  |   </ConfirmAction> | ||||||
|  | </div> | ||||||
							
								
								
									
										22
									
								
								ui/app/components/seal-action.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ui/app/components/seal-action.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | /** | ||||||
|  |  * Copyright (c) HashiCorp, Inc. | ||||||
|  |  * SPDX-License-Identifier: BUSL-1.1 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import { action } from '@ember/object'; | ||||||
|  | import Component from '@glimmer/component'; | ||||||
|  | import { tracked } from '@glimmer/tracking'; | ||||||
|  | import errorMessage from 'vault/utils/error-message'; | ||||||
|  |  | ||||||
|  | export default class SealActionComponent extends Component { | ||||||
|  |   @tracked error; | ||||||
|  |  | ||||||
|  |   @action | ||||||
|  |   async handleSeal() { | ||||||
|  |     try { | ||||||
|  |       await this.args.onSeal(); | ||||||
|  |     } catch (e) { | ||||||
|  |       this.error = errorMessage(e, 'Seal attempt failed. Check Vault logs for details.'); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -12,26 +12,7 @@ | |||||||
| </PageHeader> | </PageHeader> | ||||||
|  |  | ||||||
| {{#if this.model.seal.canUpdate}} | {{#if this.model.seal.canUpdate}} | ||||||
|   <div class="box is-sideless is-fullwidth is-marginless"> |   <SealAction @onSeal={{action "seal"}} /> | ||||||
|     <p> |  | ||||||
|       Sealing a vault tells the Vault server to stop responding to any access operations until it is unsealed again. A sealed |  | ||||||
|       vault throws away its root key to unlock the data, so it physically is blocked from responding to operations again |  | ||||||
|       until the Vault is unsealed again with the "unseal" command or via the API. |  | ||||||
|     </p> |  | ||||||
|   </div> |  | ||||||
|   <div class="field is-grouped box is-fullwidth is-bottomless"> |  | ||||||
|     <ConfirmAction |  | ||||||
|       @buttonClasses="button is-primary" |  | ||||||
|       @confirmTitle="Seal this cluster?" |  | ||||||
|       @confirmMessage="You will not be able to read or write any data until the cluster is unsealed again." |  | ||||||
|       @confirmButtonText="Seal" |  | ||||||
|       @horizontalPosition="auto-left" |  | ||||||
|       @onConfirmAction={{action "seal"}} |  | ||||||
|       data-test-seal="true" |  | ||||||
|     > |  | ||||||
|       Seal |  | ||||||
|     </ConfirmAction> |  | ||||||
|   </div> |  | ||||||
| {{else}} | {{else}} | ||||||
|   <EmptyState @title="This token does not have sufficient capabilities to seal this vault" /> |   <EmptyState @title="This token does not have sufficient capabilities to seal this vault" /> | ||||||
| {{/if}} | {{/if}} | ||||||
							
								
								
									
										45
									
								
								ui/tests/integration/components/seal-action-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								ui/tests/integration/components/seal-action-test.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | /** | ||||||
|  |  * Copyright (c) HashiCorp, Inc. | ||||||
|  |  * SPDX-License-Identifier: BUSL-1.1 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import { module, test } from 'qunit'; | ||||||
|  | import { setupRenderingTest } from 'vault/tests/helpers'; | ||||||
|  | import { click, render } from '@ember/test-helpers'; | ||||||
|  | import { hbs } from 'ember-cli-htmlbars'; | ||||||
|  | import sinon from 'sinon'; | ||||||
|  |  | ||||||
|  | const SEAL_WHEN_STANDBY_MSG = 'vault cannot seal when in standby mode; please restart instead'; | ||||||
|  |  | ||||||
|  | module('Integration | Component | seal-action', function (hooks) { | ||||||
|  |   setupRenderingTest(hooks); | ||||||
|  |  | ||||||
|  |   hooks.beforeEach(function () { | ||||||
|  |     this.sealSuccess = sinon.spy(() => new Promise((resolve) => resolve({}))); | ||||||
|  |     this.sealError = sinon.stub().throws({ message: SEAL_WHEN_STANDBY_MSG }); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   test('it handles success', async function (assert) { | ||||||
|  |     this.set('handleSeal', this.sealSuccess); | ||||||
|  |     await render(hbs`<SealAction @onSeal={{action this.handleSeal}} />`); | ||||||
|  |  | ||||||
|  |     // attempt seal | ||||||
|  |     await click('[data-test-seal] button'); | ||||||
|  |     await click('[data-test-confirm-button]'); | ||||||
|  |  | ||||||
|  |     assert.ok(this.sealSuccess.calledOnce, 'called onSeal action'); | ||||||
|  |     assert.dom('[data-test-seal-error]').doesNotExist('Does not show error when successful'); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   test('it handles error', async function (assert) { | ||||||
|  |     this.set('handleSeal', this.sealError); | ||||||
|  |     await render(hbs`<SealAction @onSeal={{action this.handleSeal}} />`); | ||||||
|  |  | ||||||
|  |     // attempt seal | ||||||
|  |     await click('[data-test-seal] button'); | ||||||
|  |     await click('[data-test-confirm-button]'); | ||||||
|  |  | ||||||
|  |     assert.ok(this.sealError.calledOnce, 'called onSeal action'); | ||||||
|  |     assert.dom('[data-test-seal-error]').includesText(SEAL_WHEN_STANDBY_MSG, 'Shows error returned from API'); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
		Reference in New Issue
	
	Block a user
	 Chelsea Shaw
					Chelsea Shaw