mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-18 04:27:02 +02:00
* runs ember-cli-update to 4.4.0 * updates yarn.lock * updates dependencies causing runtime errors (#17135) * Inject Store Service When Accessed Implicitly (#17345) * adds codemod for injecting store service * adds custom babylon parser with decorators-legacy plugin for jscodeshift transforms * updates inject-store-service codemod to only look for .extend object expressions and adds recast options * runs inject-store-service codemod on js files * replace query-params helper with hash (#17404) * Updates/removes dependencies throwing errors in Ember 4.4 (#17396) * updates ember-responsive to latest * updates ember-composable-helpers to latest and uses includes helper since contains was removed * updates ember-concurrency to latest * updates ember-cli-clipboard to latest * temporary workaround for toolbar-link component throwing errors for using params arg with LinkTo * adds missing store injection to auth configure route * fixes issue with string-list component throwing error for accessing prop in same computation * fixes non-iterable query params issue in mfa methods controller * refactors field-to-attrs to handle belongsTo rather than fragments * converts mount-config fragment to belongsTo on auth-method model * removes ember-api-actions and adds tune method to auth-method adapter * converts cluster replication attributes from fragment to relationship * updates ember-data, removes ember-data-fragments and updates yarn to latest * removes fragments from secret-engine model * removes fragment from test-form-model * removes commented out code * minor change to inject-store-service codemod and runs again on js files * Remove LinkTo positional params (#17421) * updates ember-cli-page-object to latest version * update toolbar-link to support link-to args and not positional params * adds replace arg to toolbar-link component * Clean up js lint errors (#17426) * replaces assert.equal to assert.strictEqual * update eslint no-console to error and disables invididual intended uses of console * cleans up hbs lint warnings (#17432) * Upgrade bug and test fixes (#17500) * updates inject-service codemod to take arg for service name and runs for flashMessages service * fixes hbs lint error after merging main * fixes flash messages * updates more deps * bug fixes * test fixes * updates ember-cli-content-security-policy and prevents default form submission throwing errors * more bug and test fixes * removes commented out code * fixes issue with code-mirror modifier sending change event on setup causing same computation error * Upgrade Clean Up (#17543) * updates deprecation workflow and filter * cleans up build errors, removes unused ivy-codemirror and sass and updates ember-cli-sass and node-sass to latest * fixes control groups test that was skipped after upgrade * updates control group service tests * addresses review feedback * updates control group service handleError method to use router.currentURL rather that transition.intent.url * adds changelog entry
375 lines
15 KiB
Handlebars
375 lines
15 KiB
Handlebars
{{#if (not (has-feature "DR Replication"))}}
|
||
<UpgradePage @title="Replication" />
|
||
{{else if (or this.cluster.allReplicationDisabled this.cluster.replicationAttrs.replicationDisabled)}}
|
||
<PageHeader as |p|>
|
||
<p.levelLeft>
|
||
<h1 class="title is-3">
|
||
{{#if this.initialReplicationMode}}
|
||
{{#if (eq this.initialReplicationMode "dr")}}
|
||
Enable Disaster Recovery Replication
|
||
{{else if (eq this.initialReplicationMode "performance")}}
|
||
Enable Performance Replication
|
||
{{/if}}
|
||
{{else}}
|
||
Enable Replication
|
||
{{/if}}
|
||
</h1>
|
||
</p.levelLeft>
|
||
</PageHeader>
|
||
|
||
<form
|
||
onsubmit={{action
|
||
"onSubmit"
|
||
"enable"
|
||
(or this.mode "primary")
|
||
(hash
|
||
token=this.token
|
||
primary_cluster_addr=this.primary_cluster_addr
|
||
primary_api_addr=this.primary_api_addr
|
||
ca_file=this.ca_file
|
||
ca_path=this.ca_path
|
||
replicationMode=this.replicationMode
|
||
)
|
||
}}
|
||
>
|
||
<div class="box is-sideless is-fullwidth is-marginless">
|
||
<MessageError @errors={{this.errors}} />
|
||
{{#if this.initialReplicationMode}}
|
||
{{#if (eq this.initialReplicationMode "dr")}}
|
||
<h3 class="title is-flex-center is-5 is-marginless">
|
||
<Icon @size="24" @name="replication-direct" />
|
||
Disaster Recovery (DR) Replication
|
||
</h3>
|
||
<p class="help has-text-grey-dark">
|
||
{{replication-mode-description "dr"}}
|
||
</p>
|
||
{{else if (eq this.initialReplicationMode "performance")}}
|
||
<h3 class="title is-flex-center is-5 is-marginless">
|
||
<Icon @size="24" @name="replication-perf" />
|
||
Performance Replication
|
||
</h3>
|
||
{{#if (has-feature "Performance Replication")}}
|
||
<p class="help has-text-grey-dark">
|
||
{{replication-mode-description "performance"}}
|
||
</p>
|
||
{{else}}
|
||
<p class="help has-text-grey-dark">
|
||
Performance Replication is a feature of Vault Enterprise Premium
|
||
</p>
|
||
{{/if}}
|
||
{{/if}}
|
||
{{else}}
|
||
<p class="has-text-grey-dark box is-shadowless is-fullwidth has-slim-padding">
|
||
<label for="replication-mode" class="is-label is-block">
|
||
Type of replication
|
||
</label>
|
||
In both Performance and Disaster Recovery (DR) Replication, secondaries share the underlying configuration,
|
||
policies, and supporting secrets as their primary cluster.
|
||
</p>
|
||
<div class="columns">
|
||
<div class="column is-flex">
|
||
<label for="dr" class="box-label is-column {{if (eq this.replicationMode 'dr') 'is-selected'}}">
|
||
<div>
|
||
<h3 class="box-label-header title is-6">
|
||
<Icon @size="24" @name="replication-direct" />
|
||
Disaster Recovery (DR)
|
||
</h3>
|
||
<p class="help has-text-grey-dark">
|
||
{{replication-mode-description "dr"}}
|
||
</p>
|
||
</div>
|
||
<div>
|
||
<RadioButton
|
||
id="dr"
|
||
name="replication-mode"
|
||
@value="dr"
|
||
@groupValue={{this.replicationMode}}
|
||
@onChange={{fn (mut this.replicationMode)}}
|
||
/>
|
||
<label for="dr" data-test-replication-type-select="dr"></label>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
<div class="column is-flex">
|
||
<label
|
||
for="performance"
|
||
class="box-label is-column {{if (eq this.replicationMode 'performance') 'is-selected'}}"
|
||
>
|
||
<div>
|
||
<h3 class="box-label-header title is-6">
|
||
<Icon @size="24" @name="replication-perf" />
|
||
Performance
|
||
</h3>
|
||
{{#if (not (has-feature "Performance Replication"))}}
|
||
<p class="help has-text-grey-dark">
|
||
Performance Replication is a feature of Vault Enterprise Premium
|
||
</p>
|
||
{{else}}
|
||
<p class="help has-text-grey-dark">
|
||
{{replication-mode-description "performance"}}
|
||
</p>
|
||
{{/if}}
|
||
</div>
|
||
<div>
|
||
{{#if (has-feature "Performance Replication")}}
|
||
<RadioButton
|
||
id="performance"
|
||
name="replication-mode"
|
||
@value="performance"
|
||
@groupValue={{this.replicationMode}}
|
||
@onChange={{fn (mut this.replicationMode)}}
|
||
/>
|
||
<label for="performance" data-test-replication-type-select="performance"></label>
|
||
{{/if}}
|
||
</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
{{/if}}
|
||
</div>
|
||
<div class="box is-sideless is-fullwidth is-marginless">
|
||
<label for="replication-mode" class="is-label">
|
||
Cluster mode
|
||
</label>
|
||
<div class="field is-expanded">
|
||
<div class="control select is-fullwidth">
|
||
<select
|
||
onchange={{action (mut this.mode) value="target.value"}}
|
||
id="replication-mode"
|
||
name="replication-mode"
|
||
data-test-replication-cluster-mode-select={{true}}
|
||
>
|
||
{{#each (array "primary" "secondary") as |modeOption|}}
|
||
<option selected={{if this.mode (eq this.mode modeOption) (eq modeOption "primary")}} value={{modeOption}}>
|
||
{{modeOption}}
|
||
</option>
|
||
{{/each}}
|
||
</select>
|
||
</div>
|
||
{{#if (eq this.mode "secondary")}}
|
||
<AlertInline @class="has-top" @type="warning" @message="This will immediately clear all data in this cluster!" />
|
||
{{/if}}
|
||
</div>
|
||
{{#if (eq this.mode "primary")}}
|
||
{{#if this.cluster.canEnablePrimary}}
|
||
<div class="field">
|
||
<label for="primary_cluster_addr" class="is-label">
|
||
Primary cluster address
|
||
<em class="is-optional">(optional)</em>
|
||
</label>
|
||
<div class="control">
|
||
<Input
|
||
class="input"
|
||
id="primary_cluster_addr"
|
||
name="primary_cluster_addr"
|
||
@value={{this.primary_cluster_addr}}
|
||
/>
|
||
</div>
|
||
<p class="help has-text-grey">
|
||
Overrides the cluster address that the primary gives to secondary nodes.
|
||
</p>
|
||
</div>
|
||
{{else}}
|
||
<p>
|
||
The token you are using is not authorized to enable primary replication.
|
||
</p>
|
||
{{/if}}
|
||
{{else}}
|
||
{{#if this.cluster.canEnableSecondary}}
|
||
{{#if
|
||
(and
|
||
(eq this.replicationMode "dr")
|
||
(not this.cluster.performance.replicationDisabled)
|
||
(has-feature "Performance Replication")
|
||
)
|
||
}}
|
||
<div class="has-text-danger">
|
||
<ToggleButton
|
||
@isOpen={{this.showExplanation}}
|
||
@openLabel="Disable Performance Replication in order to enable this cluster as a DR secondary."
|
||
@closedLabel="Disable Performance Replication in order to enable this cluster as a DR secondary."
|
||
@onClick={{fn (mut this.showExplanation)}}
|
||
class="has-text-danger"
|
||
/>
|
||
{{#if this.showExplanation}}
|
||
<p>
|
||
When running as a DR Secondary Vault is read only. For this reason, we don't allow other Replication modes
|
||
to operate at the same time. This cluster is also currently operating as a Performance
|
||
{{capitalize this.cluster.performance.modeForUrl}}.
|
||
</p>
|
||
{{/if}}
|
||
</div>
|
||
{{else}}
|
||
<div class="field">
|
||
<label for="secondary-token" class="is-label">
|
||
Secondary activation token
|
||
</label>
|
||
<div class="control">
|
||
<Textarea @value={{this.token}} id="secondary-token" name="secondary-token" class="textarea" />
|
||
</div>
|
||
</div>
|
||
<div class="field">
|
||
<label for="primary_api_addr" class="is-label">
|
||
Primary API address
|
||
{{#if (not (and this.token (not this.tokenIncludesAPIAddr)))}}
|
||
<em class="is-optional">(optional)</em>
|
||
{{/if}}
|
||
</label>
|
||
<div class="control">
|
||
<Input @value={{this.primary_api_addr}} id="primary_api_addr" name="primary_api_addr" class="input" />
|
||
</div>
|
||
<p class="help {{if (and this.token (not this.tokenIncludesAPIAddr)) 'is-danger' 'has-text-grey'}}">
|
||
{{#if (and this.token (not this.tokenIncludesAPIAddr))}}
|
||
The supplied token does not contain an embedded address for the primary cluster. Please enter the primary
|
||
cluster's API address (normal Vault address).
|
||
{{else}}
|
||
Set this to the API address (normal Vault address) to override the value embedded in the token.
|
||
{{/if}}
|
||
</p>
|
||
</div>
|
||
<div class="field">
|
||
<label for="ca_file" class="is-label">
|
||
CA file
|
||
<em class="is-optional">(optional)</em>
|
||
</label>
|
||
<div class="control">
|
||
<Input @value={{this.ca_file}} id="ca_file" name="ca_file" class="input" />
|
||
</div>
|
||
<p class="help has-text-grey">
|
||
Specifies the path to a CA root file (PEM format) that the secondary can use when unwrapping the token from
|
||
the primary.
|
||
</p>
|
||
</div>
|
||
<div class="field">
|
||
<label for="ca_path" class="is-label">
|
||
CA path
|
||
<em class="is-optional">(optional)</em>
|
||
</label>
|
||
<div class="control">
|
||
<Input @value={{this.ca_path}} id="ca_path" name="ca_file" class="input" />
|
||
</div>
|
||
<p class="help has-text-grey">
|
||
Specifies the path to a CA root directory containing PEM-format files that the secondary can use when
|
||
unwrapping the token from the primary.
|
||
</p>
|
||
</div>
|
||
<p>
|
||
Note: If both
|
||
<code>CA file</code>
|
||
and
|
||
<code>CA path</code>
|
||
are not given, they default to system CA roots.
|
||
</p>
|
||
{{/if}}
|
||
{{else}}
|
||
<p>The token you are using is not authorized to enable secondary replication.</p>
|
||
{{/if}}
|
||
{{/if}}
|
||
</div>
|
||
{{#if
|
||
(or
|
||
(and (eq this.mode "primary") this.cluster.canEnablePrimary)
|
||
(and (eq this.mode "secondary") this.cluster.canEnableSecondary)
|
||
)
|
||
}}
|
||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||
<div class="control">
|
||
<button
|
||
type="submit"
|
||
class="button is-primary"
|
||
disabled={{this.disallowEnable}}
|
||
data-test-replication-enable={{true}}
|
||
>
|
||
Enable Replication
|
||
</button>
|
||
</div>
|
||
</div>
|
||
{{/if}}
|
||
</form>
|
||
{{else if this.showModeSummary}}
|
||
{{#if (not (and this.cluster.dr.replicationEnabled this.cluster.performance.replicationEnabled))}}
|
||
<PageHeader as |p|>
|
||
<p.levelLeft>
|
||
<h1 class="title is-3">
|
||
Replication
|
||
</h1>
|
||
</p.levelLeft>
|
||
</PageHeader>
|
||
{{/if}}
|
||
|
||
{{#if (and (eq this.cluster.dr.mode "primary") (eq this.cluster.performance.mode "primary"))}}
|
||
<ReplicationPage @model={{this.cluster}} as |Page|>
|
||
<Page.header @showTabs={{true}} />
|
||
<Page.dashboard @componentToRender="replication-summary-card" as |Dashboard|>
|
||
<Dashboard.card @title="Disaster Recovery" />
|
||
<Dashboard.card @title="Performance" />
|
||
</Page.dashboard>
|
||
</ReplicationPage>
|
||
{{else}}
|
||
<div class="box is-sideless is-fullwidth is-marginless">
|
||
<h3 class="title is-flex-center is-5 is-marginless">
|
||
<Icon @size="24" @name="replication-direct" />
|
||
Disaster Recovery (DR)
|
||
</h3>
|
||
{{#if this.cluster.dr.replicationEnabled}}
|
||
{{#if this.submit.isRunning}}
|
||
<LayoutLoading />
|
||
{{else}}
|
||
<LinkTo @route="mode.index" @model="dr" class="link-plain">
|
||
<ReplicationModeSummary @mode="dr" @cluster={{this.cluster}} @tagName="span" />
|
||
</LinkTo>
|
||
{{/if}}
|
||
{{else}}
|
||
<ReplicationModeSummary @mode="dr" @cluster={{this.cluster}} @tagName="div" />
|
||
{{/if}}
|
||
</div>
|
||
{{#if (not (and this.submit.isRunning (eq this.cluster.dr.mode "bootstrapping")))}}
|
||
<div class="box is-bottomless is-fullwidth is-marginless">
|
||
<h3 class="title is-flex-center is-5 is-marginless">
|
||
<Icon @size="24" @name="replication-perf" />
|
||
Performance
|
||
</h3>
|
||
<LinkTo @route="mode.index" @model="performance" class="link-plain">
|
||
<ReplicationModeSummary @mode="performance" @cluster={{this.cluster}} @tagName="span" />
|
||
</LinkTo>
|
||
</div>
|
||
{{/if}}
|
||
{{/if}}
|
||
{{else}}
|
||
{{#if (eq this.replicationAttrs.mode "initializing")}}
|
||
The cluster is initializing replication. This may take some time.
|
||
{{else}}
|
||
<p>{{this.cluster.replicationModeStatus.cluster_id}}</p>
|
||
<div class="replication">
|
||
<ReplicationPage @model={{this.cluster}} as |Page|>
|
||
<Page.dashboard
|
||
@data={{this.cluster}}
|
||
@componentToRender={{if
|
||
(eq this.replicationAttrs.mode "secondary")
|
||
"replication-secondary-card"
|
||
"replication-primary-card"
|
||
}}
|
||
as |Dashboard|
|
||
>
|
||
{{#if (eq this.replicationAttrs.mode "secondary")}}
|
||
<Dashboard.card @title="Status" />
|
||
<Dashboard.card @title="Primary cluster" />
|
||
{{else}}
|
||
<Dashboard.card
|
||
@title="State"
|
||
@description="The cluster’s current operating state."
|
||
@glyph={{get (cluster-states this.replicationAttrs.state) "glyph"}}
|
||
@metric={{this.replicationAttrs.state}}
|
||
/>
|
||
<Dashboard.card
|
||
@title="Last WAL entry"
|
||
@description="Index of last Write Ahead Logs entry written on local storage. Updates every ten seconds."
|
||
@metric={{format-number this.replicationAttrs.lastWAL}}
|
||
/>
|
||
<Dashboard.secondaryCard @cluster={{this.cluster}} @replicationAttrs={{this.replicationAttrs}} />
|
||
{{/if}}
|
||
</Page.dashboard>
|
||
</ReplicationPage>
|
||
</div>
|
||
{{/if}}
|
||
{{/if}} |