vault/ui/lib/replication/addon/templates/components/replication-summary.hbs
Jordan Reimer d4766766f2
Ember Upgrade to 4.4 (#17086)
* 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
2022-10-18 09:46:02 -06:00

375 lines
15 KiB
Handlebars
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{#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 clusters 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}}