d99742c6c5
* initial setup * initial validation setup for empty path object. * removal console logs * validation on keyup for kv * in progress * making some progress * more progress * closer * done with create page now to fix edit page that I broke * fix secret edit display on create * test and final touches * cleanup mountbackendform * cleanup * add changelog * address pr comments * address styling pr comment
271 lines
9.3 KiB
Handlebars
271 lines
9.3 KiB
Handlebars
<PageHeader as |p|>
|
|
<p.top>
|
|
<KeyValueHeader @baseKey={{baseKey}} @path="vault.cluster.secrets.backend.list" @mode={{mode}} @root={{root}} @showCurrent={{true}} />
|
|
</p.top>
|
|
<p.levelLeft>
|
|
<h1 class="title is-3">
|
|
{{#if (eq mode "create") }}
|
|
Create secret
|
|
{{else if (and isV2 (eq mode 'edit'))}}
|
|
Create new version
|
|
{{else if (eq mode 'edit')}}
|
|
Edit secret
|
|
{{else}}
|
|
{{key.id}}
|
|
{{/if}}
|
|
</h1>
|
|
</p.levelLeft>
|
|
</PageHeader>
|
|
|
|
<Toolbar>
|
|
{{#unless (and (eq mode 'show') isWriteWithoutRead)}}
|
|
<ToolbarFilters>
|
|
<Toggle
|
|
@name="json"
|
|
@status="success"
|
|
@size="small"
|
|
@disabled={{and (eq mode 'show') secretDataIsAdvanced}}
|
|
@checked={{showAdvancedMode}}
|
|
@onChange={{action "toggleAdvanced"}}
|
|
>
|
|
<span class="has-text-grey">JSON</span>
|
|
</Toggle>
|
|
</ToolbarFilters>
|
|
{{/unless}}
|
|
<ToolbarActions>
|
|
{{#if (eq mode 'show')}}
|
|
<SecretDeleteMenu
|
|
@modelForData={{this.modelForData}}
|
|
@model={{this.model}}
|
|
@navToNearestAncestor={{this.navToNearestAncestor}}
|
|
@isV2={{isV2}}
|
|
@refresh={{action 'refresh'}}
|
|
/>
|
|
{{/if}}
|
|
{{#if (and (eq mode 'show') (or canEditV2Secret canEdit))}}
|
|
{{#let (concat 'vault.cluster.secrets.backend.' (if (eq mode 'show') 'edit' 'show')) as |targetRoute|}}
|
|
{{#unless (and isV2 (or isWriteWithoutRead modelForData.destroyed modelForData.deleted))}}
|
|
<BasicDropdown
|
|
@class="popup-menu"
|
|
@horizontalPosition="auto-right"
|
|
@verticalPosition="below"
|
|
@onClose={{action "clearWrappedData"}}
|
|
as |D|
|
|
>
|
|
<D.trigger
|
|
data-test-popup-menu-trigger="true"
|
|
@class={{concat "toolbar-link" (if D.isOpen " is-active")}}
|
|
@tagName="button"
|
|
>
|
|
Copy
|
|
<Chevron @direction="down" @isButton={{true}} />
|
|
</D.trigger>
|
|
<D.content @class="popup-menu-content is-wide">
|
|
<nav class="box menu">
|
|
<ul class="menu-list">
|
|
<li class="action">
|
|
<CopyButton
|
|
@class="link link-plain has-text-weight-semibold is-ghost"
|
|
@clipboardText={{codemirrorString}}
|
|
@success={{action (set-flash-message "JSON Copied!")}}
|
|
data-test-copy-button
|
|
>
|
|
Copy JSON
|
|
</CopyButton>
|
|
</li>
|
|
<li class="action">
|
|
{{#if showWrapButton}}
|
|
<button
|
|
class="link link-plain has-text-weight-semibold is-ghost {{if isWrapping "is-loading"}}"
|
|
type="button"
|
|
{{action "handleWrapClick"}}
|
|
data-test-wrap-button
|
|
disabled={{isWrapping}}
|
|
>
|
|
Wrap secret
|
|
</button>
|
|
{{else}}
|
|
<MaskedInput
|
|
@class="has-padding"
|
|
@displayOnly={{true}}
|
|
@allowCopy={{true}}
|
|
@value={{wrappedData}}
|
|
@success={{action "handleCopySuccess"}}
|
|
@error={{action "handleCopyError"}}
|
|
/>
|
|
{{/if}}
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
</D.content>
|
|
</BasicDropdown>
|
|
{{/unless}}
|
|
{{/let}}
|
|
{{/if}}
|
|
|
|
{{#if (and (eq @mode "show") this.isV2 (not @model.failedServerRead))}}
|
|
<SecretVersionMenu
|
|
@version={{this.modelForData}}
|
|
@onRefresh={{action 'refresh'}}
|
|
@model={{this.model}}
|
|
/>
|
|
{{/if}}
|
|
|
|
{{#if (and (eq mode 'show') (or canEditV2Secret canEdit))}}
|
|
{{#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=this.modelForData.version)}}
|
|
@data-test-secret-edit="true"
|
|
@replace={{true}}
|
|
@type="add"
|
|
>
|
|
Create new version
|
|
</ToolbarLink>
|
|
{{else}}
|
|
<ToolbarLink
|
|
@params={{array targetRoute model.id}}
|
|
@data-test-secret-edit="true"
|
|
@replace={{true}}
|
|
>
|
|
Edit secret
|
|
</ToolbarLink>
|
|
{{/if}}
|
|
{{/let}}
|
|
{{/if}}
|
|
</ToolbarActions>
|
|
</Toolbar>
|
|
{{#if (eq mode "create")}}
|
|
<form class="{{if showAdvancedMode 'advanced-edit' 'simple-edit'}}" onsubmit={{action "createOrUpdateKey" "create"}}>
|
|
<div class="field box is-fullwidth is-sideless is-marginless">
|
|
<NamespaceReminder @mode="create" @noun="secret" />
|
|
<MessageError @model={{modelForData}} @errorMessage={{error}} />
|
|
<label class="is-label" for="kv-key">Path for this secret</label>
|
|
<p class="control is-expanded">
|
|
<Input
|
|
@autocomplete="off"
|
|
@spellcheck="false"
|
|
data-test-secret-path="true"
|
|
@id="kv-key"
|
|
class="input {{if (get validationMessages 'path') "has-error-border"}}"
|
|
@value={{get modelForData modelForData.pathAttr}}
|
|
onkeyup={{perform waitForKeyUp "path" value="target.value"}}
|
|
/>
|
|
</p>
|
|
{{#if (get validationMessages 'path')}}
|
|
<AlertInline
|
|
@type="danger"
|
|
@message={{get validationMessages 'path'}}
|
|
@paddingTop=true
|
|
@isMarginless=true
|
|
/>
|
|
{{/if}}
|
|
{{#if modelForData.isFolder}}
|
|
<p class="help is-danger">
|
|
The secret path may not end in <code>/</code>
|
|
</p>
|
|
{{/if}}
|
|
</div>
|
|
<SecretEditDisplay
|
|
@showAdvancedMode={{showAdvancedMode}}
|
|
@codemirrorString={{codemirrorString}}
|
|
@secretData={{secretData}}
|
|
@isV2={{isV2}}
|
|
@model={{model}}
|
|
@canEditV2Secret={{canEditV2Secret}}
|
|
@editActions={{hash
|
|
codemirrorUpdated=(action "codemirrorUpdated")
|
|
formatJSON=(action "formatJSON")
|
|
handleKeyDown=(action "handleKeyDown")
|
|
handleChange=(action "handleChange")
|
|
deleteRow=(action "deleteRow")
|
|
addRow=(action "addRow")
|
|
}}
|
|
@onKeyUp={{perform waitForKeyUp}}
|
|
@validationMessages={{validationMessages}}
|
|
/>
|
|
<div class="field is-grouped box is-fullwidth is-bottomless">
|
|
<div class="control">
|
|
<button
|
|
type="submit"
|
|
disabled={{or buttonDisabled validationErrorCount}}
|
|
class="button is-primary"
|
|
data-test-secret-save=true
|
|
>
|
|
Save
|
|
</button>
|
|
</div>
|
|
<div class="control">
|
|
<SecretLink @mode="list" @secret={{model.parentKey}} @class="button">
|
|
Cancel
|
|
</SecretLink>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
{{else if (eq mode "edit")}}
|
|
<form onsubmit={{action "createOrUpdateKey" "update"}}>
|
|
<div class="box is-sideless is-fullwidth is-marginless is-paddingless">
|
|
<MessageError @model={{modelForData}} @errorMessage={{error}} />
|
|
<NamespaceReminder @mode="edit" @noun="secret" />
|
|
{{#if (and (not model.failedServerRead) (not model.selectedVersion.failedServerRead) (not-eq model.selectedVersion.version model.currentVersion))}}
|
|
<div class="form-section">
|
|
<AlertBanner
|
|
@type="warning"
|
|
@class="is-marginless"
|
|
@message="You are creating a new version based on data from Version {{model.selectedVersion.version}}. The current version for {{model.id}} is Version {{model.currentVersion}}."
|
|
/>
|
|
</div>
|
|
{{/if}}
|
|
<SecretEditDisplay
|
|
@showAdvancedMode={{showAdvancedMode}}
|
|
@codemirrorString={{codemirrorString}}
|
|
@secretData={{secretData}}
|
|
@isV2={{isV2}}
|
|
@canEditV2Secret={{canEditV2Secret}}
|
|
@showWriteWithoutReadWarning={{isWriteWithoutRead}}
|
|
@model={{model}}
|
|
@editActions={{hash
|
|
codemirrorUpdated=(action "codemirrorUpdated")
|
|
formatJSON=(action "formatJSON")
|
|
handleKeyDown=(action "handleKeyDown")
|
|
handleChange=(action "handleChange")
|
|
deleteRow=(action "deleteRow")
|
|
addRow=(action "addRow")
|
|
}}
|
|
@onKeyUp={{perform waitForKeyUp}}
|
|
@validationMessages={{validationMessages}}
|
|
/>
|
|
</div>
|
|
<div class="field is-grouped is-grouped-split is-fullwidth box is-bottomless">
|
|
<div class="field is-grouped">
|
|
<div class="control">
|
|
<button
|
|
data-test-secret-save
|
|
type="submit"
|
|
disabled={{or buttonDisabled validationErrorCount}}
|
|
class="button is-primary"
|
|
>
|
|
Save
|
|
</button>
|
|
</div>
|
|
<div class="control">
|
|
<SecretLink @mode="show" @secret={{model.id}} @class="button" @queryParams={{query-params version=this.modelForData.version}}>
|
|
Cancel
|
|
</SecretLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
{{else if (eq mode "show")}}
|
|
<SecretFormShow
|
|
@isV2={{isV2}}
|
|
@modelForData={{modelForData}}
|
|
@isWriteWithoutRead={{isWriteWithoutRead}}
|
|
@showAdvancedMode={{showAdvancedMode}}
|
|
/>
|
|
{{else}}
|
|
<EmptyState
|
|
@title="No secret view was selected"
|
|
/>
|
|
{{/if}}
|